<commit_before>const ExecutableCodeTemplate = require('./executable-fragment.monk');

const CodeMirror = require('codemirror');
require('codemirror/lib/codemirror.css');

require('./executable-fragment.scss');

const Monkberry = require('monkberry');
const directives = require('monkberry-directives').default;
require('monkberry-events');

const $ = require('jquery');

function getExceptionCauses(exception) {
  if (exception.cause !== undefined && exception.cause != null) {
    return [exception.cause].concat(getExceptionCauses(exception.cause))
  } else {
    return []
  }
}

function foldCode(codeMirror, range) {
  return codeMirror.markText(range.from, range.to, {
    collapsed: true
  })
}

function findComment(cm, commentText) {
  for (let line = 0; line < cm.lineCount(); line++) {
    let tokens = cm.getLineTokens(line);
    if (tokens.length > 1) continue;

    let token = tokens[0];
    if (token.type != "comment") continue;

    if (token.string == '//' + commentText) {
      return line
    }
  }
}

function getTopFoldRange(cm) {
  return {
    from: {
      line: 0,
      ch: 0
    },
    to: {
      line: findComment(cm, "sampleStart") + 1,
      ch: 0
    }
  }
}

function getBottomFoldRange(cm) {
  return {
    from: {
      line: findComment(cm, "sampleEnd") - 1,
      ch: null
    },
    to: {
      line: cm.lineCount(),
      ch: 0
    }
  }
}

function unEscapeString(s) {
  const tagsToReplace = {
    "&": "&",
    "<": "&lt;",
    ">": "&gt;",
    " ": "%20"
  };
  let unEscapedString = s;
  Object.keys(tagsToReplace).forEach(function (key) {
    unEscapedString = unEscapedString.replace(tagsToReplace[key], key)
  });
  return unEscapedString
}

class ExecutableFragment extends ExecutableCodeTemplate {
  constructor() {
    super();
    this.arrayClasses = [];
    this.initialized = false;
    this.foldMarkers = [];
    this.state = {
      code: '',
      foldButtonHover: false,
      folded: true,
      output: null,
    };
  }

  static render(element) {
    const instance = Monkberry.render(ExecutableFragment, element, {
      'directives': directives
    });

    instance.on('click', '.fold-button', (event) => {
      instance.update({folded: !instance.state.folded});
    });

    return instance;
  }

  update(state) {
    Object.assign(this.state, state);
    super.update(this.state);

    if (!this.initialized) {
      this.initializeCodeMirror();
      this.initialized = true;

      const commentStartLineNo = findComment(this.codemirror, "sampleStart");
      const commentEndLineNo = findComment(this.codemirror, "sampleEnd");
      this.codemirror.markText({
          line: commentStartLineNo,
          ch: 0
        },
        {
          line: commentStartLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
      this.codemirror.markText({
          line: commentEndLineNo,
          ch: 0
        },
        {
          line: commentEndLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
    }

    if (this.state.folded) {
      this.foldCode()
    } else {
      this.unfoldCode()
    }
  }

  onFoldButtonMouseEnter(){
    if(!this.state.foldButtonHover){
      this.update({foldButtonHover: true})
    }
  }

  onFoldButtonMouseLeave(){
    if(this.state.foldButtonHover){
      this.update({foldButtonHover: false})
    }
  }

  unfoldCode() {
    this.foldMarkers.forEach((marker) => {
      marker.clear()
    });
    this.foldMarkers = [];
  }

  foldCode() {
    this.foldMarkers.push(foldCode(this.codemirror, getTopFoldRange(this.codemirror)));
    this.foldMarkers.push(foldCode(this.codemirror, getBottomFoldRange(this.codemirror)));
  }

  execute() {
    const projectJson = JSON.stringify({
      "id": "",
      "name": "",
      "args": "",
      "compilerVersion": null,
      "confType": "java",
      "originUrl": null,
      "files": [
        {
          "name": "File.kt",
          "text": this.codemirror.getValue(),
          "publicId": ""
        }
      ],
      "readOnlyFileNames": []
    });
    $.ajax({
      url: 'http://kotlin-web-demo-cloud.passive.aws.intellij.net/kotlinServer?type=run&runConf=java',
      method: 'post',
      dataType: 'JSON',
      context: this,
      data: {
        project: projectJson
      },
      fail: function (jqXHR, message, errorThrown) {
        console.log(message)
      }
    }).success(function (data) {
      if (data.errors["File.kt"] !== undefined) {
        this.showDiagnostics(data.errors["File.kt"])
      }

      let output;
      if (data.text !== undefined) {
        output = data.text.replace("<outStream>", "")
          .replace("</outStream>", "")
          .replace("<errStream>", "")
          .replace("</errStream>", "");
      } else {
        output = "";
      }

      if (data.exception != null) {
        data.exception.causes = getExceptionCauses(data.exception);
        data.exception.cause = undefined;
      }

      this.update({
        output: output,
        exception: data.exception
      })
    })
  }

  showDiagnostics(diagnostics) {
    this.removeStyles();
    diagnostics.forEach(diagnostic => {
      const interval = diagnostic.interval;
      const errorMessage = unEscapeString(diagnostic.message);
      const severity = diagnostic.severity;

      this.arrayClasses.push(this.codemirror.markText(interval.start, interval.end, {
        "className": diagnostic.className,
        "title": errorMessage
      }));

      if ((this.codemirror.lineInfo(interval.start.line) != null) &&
        (this.codemirror.lineInfo(interval.start.line).gutterMarkers == null)) {
        const gutter = document.createElement("div");
        gutter.className = severity + "gutter";
        gutter.title = errorMessage;

        this.codemirror.setGutterMarker(interval.start.line, "errors-and-warnings-gutter", gutter)
      } else {
        const gutter = this.codemirror.lineInfo(interval.start.line).gutterMarkers["errors-and-warnings-gutter"];
        gutter.title += "\n$errorMessage";
        if (gutter.className.indexOf("ERRORgutter") == -1) {
          gutter.className = severity + "gutter"
        }
      }
    });
  }

  removeStyles() {
    this.arrayClasses.forEach(it => it.clear());
    this.codemirror.clearGutter("errors-and-warnings-gutter")
  }

  initializeCodeMirror() {
    const textarea = this.nodes[0].getElementsByTagName('textarea')[0];
    this.codemirror = CodeMirror.fromTextArea(textarea, {
      lineNumbers: false,
      mode: 'text/x-kotlin',
      indentUnit: 4,
      viewportMargin: Infinity,
      smartIndent: false,
      gutters: [
        "errors-and-warnings-gutter",
        "CodeMirror-foldgutter"
      ]
    });

    this.codemirror.on("change", codemirror => {
      this.removeStyles()
    })
  }
}

module.exports = ExecutableFragment;
<commit_msg>JS-5288: show line numbers if unfolded.<commit_after>const ExecutableCodeTemplate = require('./executable-fragment.monk');

const CodeMirror = require('codemirror');
require('codemirror/lib/codemirror.css');

require('./executable-fragment.scss');

const Monkberry = require('monkberry');
const directives = require('monkberry-directives').default;
require('monkberry-events');

const $ = require('jquery');

function getExceptionCauses(exception) {
  if (exception.cause !== undefined && exception.cause != null) {
    return [exception.cause].concat(getExceptionCauses(exception.cause))
  } else {
    return []
  }
}

function foldCode(codeMirror, range) {
  return codeMirror.markText(range.from, range.to, {
    collapsed: true
  })
}

function findComment(cm, commentText) {
  for (let line = 0; line < cm.lineCount(); line++) {
    let tokens = cm.getLineTokens(line);
    if (tokens.length > 1) continue;

    let token = tokens[0];
    if (token.type != "comment") continue;

    if (token.string == '//' + commentText) {
      return line
    }
  }
}

function getTopFoldRange(cm) {
  return {
    from: {
      line: 0,
      ch: 0
    },
    to: {
      line: findComment(cm, "sampleStart") + 1,
      ch: 0
    }
  }
}

function getBottomFoldRange(cm) {
  return {
    from: {
      line: findComment(cm, "sampleEnd") - 1,
      ch: null
    },
    to: {
      line: cm.lineCount(),
      ch: 0
    }
  }
}

function unEscapeString(s) {
  const tagsToReplace = {
    "&": "&",
    "<": "&lt;",
    ">": "&gt;",
    " ": "%20"
  };
  let unEscapedString = s;
  Object.keys(tagsToReplace).forEach(function (key) {
    unEscapedString = unEscapedString.replace(tagsToReplace[key], key)
  });
  return unEscapedString
}

class ExecutableFragment extends ExecutableCodeTemplate {
  constructor() {
    super();
    this.arrayClasses = [];
    this.initialized = false;
    this.foldMarkers = [];
    this.state = {
      code: '',
      foldButtonHover: false,
      folded: true,
      output: null,
    };
  }

  static render(element) {
    const instance = Monkberry.render(ExecutableFragment, element, {
      'directives': directives
    });

    instance.on('click', '.fold-button', (event) => {
      instance.update({folded: !instance.state.folded});
    });

    return instance;
  }

  update(state) {
    Object.assign(this.state, state);
    super.update(this.state);

    if (!this.initialized) {
      this.initializeCodeMirror();
      this.initialized = true;

      const commentStartLineNo = findComment(this.codemirror, "sampleStart");
      const commentEndLineNo = findComment(this.codemirror, "sampleEnd");
      this.codemirror.markText({
          line: commentStartLineNo,
          ch: 0
        },
        {
          line: commentStartLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
      this.codemirror.markText({
          line: commentEndLineNo,
          ch: 0
        },
        {
          line: commentEndLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
    }

    if (this.state.folded) {
      this.foldCode()
    } else {
      this.unfoldCode()
    }
  }

  onFoldButtonMouseEnter(){
    if(!this.state.foldButtonHover){
      this.update({foldButtonHover: true})
    }
  }

  onFoldButtonMouseLeave() {
    if (this.state.foldButtonHover) {
      this.update({foldButtonHover: false})
    }
  }

  unfoldCode() {
    this.codemirror.setOption("lineNumbers", true);
    this.foldMarkers.forEach((marker) => {
      marker.clear()
    });
    this.foldMarkers = [];
  }

  foldCode() {
    this.codemirror.setOption("lineNumbers", false);
    this.foldMarkers.push(foldCode(this.codemirror, getTopFoldRange(this.codemirror)));
    this.foldMarkers.push(foldCode(this.codemirror, getBottomFoldRange(this.codemirror)));
  }

  execute() {
    const projectJson = JSON.stringify({
      "id": "",
      "name": "",
      "args": "",
      "compilerVersion": null,
      "confType": "java",
      "originUrl": null,
      "files": [
        {
          "name": "File.kt",
          "text": this.codemirror.getValue(),
          "publicId": ""
        }
      ],
      "readOnlyFileNames": []
    });
    $.ajax({
      url: 'http://kotlin-web-demo-cloud.passive.aws.intellij.net/kotlinServer?type=run&runConf=java',
      method: 'post',
      dataType: 'JSON',
      context: this,
      data: {
        project: projectJson
      },
      fail: function (jqXHR, message, errorThrown) {
        console.log(message)
      }
    }).success(function (data) {
      if (data.errors["File.kt"] !== undefined) {
        this.showDiagnostics(data.errors["File.kt"])
      }

      let output;
      if (data.text !== undefined) {
        output = data.text.replace("<outStream>", "")
          .replace("</outStream>", "")
          .replace("<errStream>", "")
          .replace("</errStream>", "");
      } else {
        output = "";
      }

      if (data.exception != null) {
        data.exception.causes = getExceptionCauses(data.exception);
        data.exception.cause = undefined;
      }

      this.update({
        output: output,
        exception: data.exception
      })
    })
  }

  showDiagnostics(diagnostics) {
    this.removeStyles();
    diagnostics.forEach(diagnostic => {
      const interval = diagnostic.interval;
      const errorMessage = unEscapeString(diagnostic.message);
      const severity = diagnostic.severity;

      this.arrayClasses.push(this.codemirror.markText(interval.start, interval.end, {
        "className": diagnostic.className,
        "title": errorMessage
      }));

      if ((this.codemirror.lineInfo(interval.start.line) != null) &&
        (this.codemirror.lineInfo(interval.start.line).gutterMarkers == null)) {
        const gutter = document.createElement("div");
        gutter.className = severity + "gutter";
        gutter.title = errorMessage;

        this.codemirror.setGutterMarker(interval.start.line, "errors-and-warnings-gutter", gutter)
      } else {
        const gutter = this.codemirror.lineInfo(interval.start.line).gutterMarkers["errors-and-warnings-gutter"];
        gutter.title += "\n$errorMessage";
        if (gutter.className.indexOf("ERRORgutter") == -1) {
          gutter.className = severity + "gutter"
        }
      }
    });
  }

  removeStyles() {
    this.arrayClasses.forEach(it => it.clear());
    this.codemirror.clearGutter("errors-and-warnings-gutter")
  }

  initializeCodeMirror() {
    const textarea = this.nodes[0].getElementsByTagName('textarea')[0];
    this.codemirror = CodeMirror.fromTextArea(textarea, {
      lineNumbers: false,
      mode: 'text/x-kotlin',
      indentUnit: 4,
      viewportMargin: Infinity,
      smartIndent: false,
      gutters: [
        "errors-and-warnings-gutter",
        "CodeMirror-foldgutter"
      ]
    });

    this.codemirror.on("change", codemirror => {
      this.removeStyles()
    })
  }
}

module.exports = ExecutableFragment;
<|endoftext|>


<commit_before>var express         = require('express'),
	bodyParser      = require('body-parser');

var sql             = require('mssql'),
	util            = require('../util');

module.exports      = function (configuration) {
	var router      = express.Router(),
	authenticate    = require('azure-mobile-apps/src/express/middleware/authenticate')(configuration),
	authorize       = require('azure-mobile-apps/src/express/middleware/authorize');

	var completeError = function(err, res) {
		if (err) {
			console.error(err);
			if (res) res.sendStatus(500);
		}
	};

	router.post('/', (req, res, next) => {
		console.log('in POST /acceptinvitation');
		if ( ! req.azureMobile.user) {
			console.log('401 - Unauthorized');
			res.status(401);	// 401: Unauthorized
			return next(401);
		}
		var userSid = req.azureMobile.user.id;
		console.log(userSid);
		var voucher = req.body.voucher;
		console.log(voucher);
		console.log('So far so good...');
		sql.connect(util.sqlConfiguration)
		.then(function() {
			new sql.Request()
			.input('userSid', sql.NVarChar(40), userSid)
			.input('token', sql.NVarChar(36), voucher)
			.execute('sp_acceptInvitationToTertulia')
			.then((recordsets) => {
				if (recordsets['returnValue'] == 0) {
					console.log('in 201 ok');
					res.status(201)	// 201: Created
						.type('application/json')
						.json( { result: 'Ok' } );
					return next();
				} else {
					console.log('in 409 error');
					res.status(409)	// 409: Conflict, 422: Unprocessable Entity (WebDAV; RFC 4918)
						.type('application/json')
						.json( { result: 'Voucher unavailable' } );
					return next();
				}
				return;
			})
			.catch(function(err) {
				console.log('in post error');
				next(err);
			});
		});
		return next();
	});

	return router;
};
<commit_msg>wip save<commit_after>var express         = require('express'),
	bodyParser      = require('body-parser');

var sql             = require('mssql'),
	util            = require('../util');

module.exports      = function (configuration) {
	var router      = express.Router(),
	authenticate    = require('azure-mobile-apps/src/express/middleware/authenticate')(configuration),
	authorize       = require('azure-mobile-apps/src/express/middleware/authorize');

	var completeError = function(err, res) {
		if (err) {
			console.error(err);
			if (res) res.sendStatus(500);
		}
	};

	router.post('/', (req, res, next) => {
		console.log('in POST /acceptinvitation');
		if ( ! req.azureMobile.user) {
			console.log('401 - Unauthorized');
			res.status(401);	// 401: Unauthorized
			return next(401);
		}
		console.log(req.azureMobile.user);
		var userSid = req.azureMobile.user.id;
		var voucher = req.body.voucher;
		getUserInfo(req.azureMobile.user, function(voucher, userInfo) {
			console.log(userInfo);
			sql.connect(util.sqlConfiguration)
			.then(function() {
				new sql.Request()
				.input('token', sql.NVarChar(36), voucher)
				.input('userSid', sql.NVarChar(40), userInfo.sid)
				.input('alias', sql.NVarChar(20), userInfo.alias)
	    		.input('email', sql.NVarChar(40), userInfo.email)
	    		.input('firstName', sql.NVarChar(40), userInfo.firstName)
	    		.input('lastName', sql.NVarChar(40), userInfo.lastName)
	    		.input('picture', sql.NVarChar(255), userInfo.picture)
				.execute('sp_acceptInvitationToTertulia')
				.then((recordsets) => {
					if (recordsets['returnValue'] == 0) {
						console.log('in 201 ok');
						res.status(201)	// 201: Created
							.type('application/json')
							.json( { result: 'Ok' } );
						return next();
					} else {
						console.log('in 409 error');
						res.status(409)	// 409: Conflict, 422: Unprocessable Entity (WebDAV; RFC 4918)
							.type('application/json')
							.json( { result: 'Voucher unavailable' } );
						return next();
					}
					return;
				})
				.catch(function(err) {
					console.log('in post error');
					next(err);
				});
			});
		});	    		email: claims.email_verified ? claims.emailaddress : "",
	    		firstName: claims.givenname,
	    		lastName: claims.surname,
	    		picture: claims.picture

		// sql.connect(util.sqlConfiguration)
		// .then(function() {
		// 	new sql.Request()
		// 	.input('userSid', sql.NVarChar(40), userInfo.sid)
		// 	.input('token', sql.NVarChar(36), voucher)
		// 	.execute('sp_acceptInvitationToTertulia')
		// 	.then((recordsets) => {
		// 		if (recordsets['returnValue'] == 0) {
		// 			console.log('in 201 ok');
		// 			res.status(201)	// 201: Created
		// 				.type('application/json')
		// 				.json( { result: 'Ok' } );
		// 			return next();
		// 		} else {
		// 			console.log('in 409 error');
		// 			res.status(409)	// 409: Conflict, 422: Unprocessable Entity (WebDAV; RFC 4918)
		// 				.type('application/json')
		// 				.json( { result: 'Voucher unavailable' } );
		// 			return next();
		// 		}
		// 		return;
		// 	})
		// 	.catch(function(err) {
		// 		console.log('in post error');
		// 		next(err);
		// 	});
		// });
		return next();
	});

	var getUserInfo = function(user, next) {
	    user.getIdentity()
	    .then(function(identity){
	    	var claims = identity.google.claims;
	    	next({
	    		sid: user.id,
	    		alias: "",
	    		email: claims.email_verified ? claims.emailaddress : "",
	    		firstName: claims.givenname,
	    		lastName: claims.surname,
	    		picture: claims.picture
	    	});
	    });
	};

	return router;
};
<|endoftext|>


<commit_before>/**
 * Notification.js
 *
 * @description :: TODO: You might write a short summary of how this model works and what it represents here.
 * @docs        :: http://sailsjs.org/#!documentation/models
 */

module.exports = {
    attributes: {

    },
    getUserNotifications: function (userId) {
        var notifications = {};
        return User.find({id: userId}).populate('coauthors')
                .then(function (user) {
                    notifications.references = user.coauthors;
                    return notifications;
                });
    }
};

<commit_msg>Removed database table of notification model<commit_after>/**
 * Notification.js
 *
 * @description :: TODO: You might write a short summary of how this model works and what it represents here.
 * @docs        :: http://sailsjs.org/#!documentation/models
 */

module.exports = {
    migrate: 'safe',
    attributes: {},
    getUserNotifications: function (userId) {
        var notifications = {};
        return User.find({id: userId}).populate('coauthors')
                .then(function (user) {
                    notifications.references = user.coauthors;
                    return notifications;
                });
    }
};

<|endoftext|>


<commit_before>/** @jsx React.DOM */

var NavigationItem = React.createClass({
  onClick: function() {
    this.props.itemSelected(this.props.item);
  },
  render: function() {
    return (

        {this.props.item.data.display_name}

    );
  }
});

var Navigation = React.createClass({
  setSelectedItem: function(item) {
    this.props.itemSelected(item);
  },
  render: function() {
    var items = this.props.items.map(function(item) {
      return (
        <NavigationItem
          item={item}
          itemSelected={this.setSelectedItem}
          key={item.data.id}
          selected={item.data.url === this.props.activeUrl} />
      );
    }, this);

    return (

Navigation

            {items}

    );
  }
});

var StoryList = React.createClass({
  render: function() {
    var storyNodes = this.props.items.map(function(item) {
      return (

{item.data.score}

                {item.data.title}

              Posted by {item.data.author}

      );
    });

    return (

          {storyNodes}

    );
  }
});

var App = React.createClass({
  componentDidMount: function() {
    var _this = this;
    var cbname = "fn" + Date.now();
    var script = document.createElement("script");
    script.src = "http://www.reddit.com/reddits.json?jsonp=" + cbname;

    window[cbname] = function(jsonData) {
      _this.setState({
        navigationItems: jsonData.data.children
      });
      delete window[cbname];
    };

    document.head.appendChild(script);
  },
  getInitialState: function() {
    return ({
      activeNavigationUrl: "",
      navigationItems: [],
      storyItems: [],
      title: "Please select a sub"
    });
  },
  render: function() {
    return (

{this.state.title}

        <Navigation
          activeUrl={this.state.activeNavigationUrl}
          items={this.state.navigationItems}
          itemSelected={this.setSelectedItem} />
        <StoryList items={this.state.storyItems} />

    );
  },
  setSelectedItem: function(item) {
    var _this = this;
    var cbname = "fn" + Date.now();
    var script = document.createElement("script");
    script.src = "http://www.reddit.com/" + item.data.url +
      ".json?sort=top&t=month&jsonp=" + cbname;

    window[cbname] = function(jsonData) {
      _this.setState({storyItems: jsonData.data.children});
      delete window[cbname];
    };

    document.head.appendChild(script);

    this.setState({
      activeNavigationUrl: item.data.url,
      title: item.data.display_name
    });
  }
});

React.renderComponent(
  <App />,
  document.getElementById("app")
);
<commit_msg>Clear storyItems on click to prevent confusion<commit_after>/** @jsx React.DOM */

var NavigationItem = React.createClass({
  onClick: function() {
    this.props.itemSelected(this.props.item);
  },
  render: function() {
    return (

        {this.props.item.data.display_name}

    );
  }
});

var Navigation = React.createClass({
  setSelectedItem: function(item) {
    this.props.itemSelected(item);
  },
  render: function() {
    var items = this.props.items.map(function(item) {
      return (
        <NavigationItem
          item={item}
          itemSelected={this.setSelectedItem}
          key={item.data.id}
          selected={item.data.url === this.props.activeUrl} />
      );
    }, this);

    return (

Navigation

            {items}

    );
  }
});

var StoryList = React.createClass({
  render: function() {
    var storyNodes = this.props.items.map(function(item) {
      return (

{item.data.score}

                {item.data.title}

              Posted by {item.data.author}

      );
    });

    return (

          {storyNodes}

    );
  }
});

var App = React.createClass({
  componentDidMount: function() {
    var _this = this;
    var cbname = "fn" + Date.now();
    var script = document.createElement("script");
    script.src = "http://www.reddit.com/reddits.json?jsonp=" + cbname;

    window[cbname] = function(jsonData) {
      _this.setState({
        navigationItems: jsonData.data.children
      });
      delete window[cbname];
    };

    document.head.appendChild(script);
  },
  getInitialState: function() {
    return ({
      activeNavigationUrl: "",
      navigationItems: [],
      storyItems: [],
      title: "Please select a sub"
    });
  },
  render: function() {
    return (

{this.state.title}

        <Navigation
          activeUrl={this.state.activeNavigationUrl}
          items={this.state.navigationItems}
          itemSelected={this.setSelectedItem} />
        <StoryList items={this.state.storyItems} />

    );
  },
  setSelectedItem: function(item) {
    var _this = this;
    var cbname = "fn" + Date.now();
    var script = document.createElement("script");
    script.src = "http://www.reddit.com/" + item.data.url +
      ".json?sort=top&t=month&jsonp=" + cbname;

    window[cbname] = function(jsonData) {
      _this.setState({storyItems: jsonData.data.children});
      delete window[cbname];
    };

    document.head.appendChild(script);

    this.setState({
      activeNavigationUrl: item.data.url,
      storyItems: [],
      title: item.data.display_name
    });
  }
});

React.renderComponent(
  <App />,
  document.getElementById("app")
);
<|endoftext|>


<commit_before>function showQuestionsModal() {
	var $modalBackground = $('

').appendTo('body');
	var $modal = $('

').css('height', '400px').appendTo('body');
	$modalBackground.animate({ opacity: .7 });
	$modal.animate({ marginTop: '-200px', top: '50%' }, function() {
		$('#reply-composer').focus();
	});

	$('body').css({
	    'overflow': 'hidden',
	    'height': '100%'
	});

	$modalBackground.on('click', closeQuestionsModal);

	var groupId = $(this).attr('data-group-id');

	$.ajax({
        url: "/dashboard/" + groupId + "/details",
        type: "GET",
        success: function(data) {
        	var template = $('#modal-question').html();

        	data.groupId = groupId;

			$modal.html(Mustache.to_html(template, data));
			$('.modal-close-button').on('click', closeQuestionsModal);

			$('#reply-button').on('click', function(){
				var groupId = $(this).attr('data-group-id');
				$.ajax({
			        url: "/dashboard/" + groupId + "/reply",
			        type: "POST",
			        data: {
			        	message: $('#reply-composer').val()
			        },
				    dataType: "json",
		   		});
		   		$('.questions-list tbody tr[data-group-id="' + groupId + '"]').remove();
		   		closeQuestionsModal();
			});
    	},
	    dataType: "json",
    });

	return false;
}

function closeQuestionsModal() {
	var $modalBackground = $('.modal-background');
	var $modal = $('.modal');
	$modal.animate({ marginTop: '0', top: '100%' }, function() { $modal.remove() });
	$modalBackground.animate({ opacity: 0 }, function() { $modalBackground.remove() });

	$('html, body').css({
	    'overflow': 'auto',
	    'height': 'auto'
	});

	return false;
}

function polling() {

	var eventId = parseInt($('body').attr('data-event-id'), 10);

    $.ajax({
        url: "/dashboard/event/" + eventId + "/polling",
        type: "GET",
        success: function(data) {

            // Update page
            $('.questions-overview .content .value').text(data.questionsNumber);
			$('.users-overview .content .value').text(data.usersOverview);
			$('.questions-list tbody').html('');

			data.unansweredQuestions.sort(function(a,b){return b.frequency-a.frequency});
			data.answeredQuestions.sort(function(a,b){return b.frequency-a.frequency});

			if($('.tabs li.selected a[data-type="unanswered"]').length) {

				jQuery.each(data.unansweredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});

				jQuery.each(data.answeredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});
			} else {

				jQuery.each(data.unansweredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});

				jQuery.each(data.answeredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});
			}

			$('.positive').text('+' + data.totalPositive);
			$('.neutral').text(data.totalNeutral);
			$('.negative').text('-' + data.totalNegative);

			$('.questions-list tbody tr').on('click', showQuestionsModal);
        },
        dataType: "json",
        complete: setTimeout(function() { polling() }, 5000),
        timeout: 2000
    })
}

$(document).ready(function() {
	polling();
	$('.questions-list tbody tr').on('click', showQuestionsModal);

	// Tabs
	$('.tabs a').on('click', function(){
		$('.tabs li').removeClass('selected');
		$(this).parent().addClass('selected');

		if($(this).attr('data-type') == 'answered') {
			$('tr[data-type="answered"]').show();
			$('tr[data-type="unanswered"]').hide();
		} else {
			$('tr[data-type="answered"]').hide();
			$('tr[data-type="unanswered"]').show();
		}
	});
});
<commit_msg>Update NLP thingie<commit_after>function showQuestionsModal() {
	var $modalBackground = $('

').appendTo('body');
	var $modal = $('

').css('height', '400px').appendTo('body');
	$modalBackground.animate({ opacity: .7 });
	$modal.animate({ marginTop: '-200px', top: '50%' }, function() {
		$('#reply-composer').focus();
	});

	$('body').css({
	    'overflow': 'hidden',
	    'height': '100%'
	});

	$modalBackground.on('click', closeQuestionsModal);

	var groupId = $(this).attr('data-group-id');

	$.ajax({
        url: "/dashboard/" + groupId + "/details",
        type: "GET",
        success: function(data) {
        	var template = $('#modal-question').html();

        	data.groupId = groupId;

			$modal.html(Mustache.to_html(template, data));
			$('.modal-close-button').on('click', closeQuestionsModal);

			$('#reply-button').on('click', function(){
				var groupId = $(this).attr('data-group-id');
				$.ajax({
			        url: "/dashboard/" + groupId + "/reply",
			        type: "POST",
			        data: {
			        	message: $('#reply-composer').val()
			        },
				    dataType: "json",
		   		});
		   		$('.questions-list tbody tr[data-group-id="' + groupId + '"]').remove();
		   		closeQuestionsModal();
			});
    	},
	    dataType: "json",
    });

	return false;
}

function closeQuestionsModal() {
	var $modalBackground = $('.modal-background');
	var $modal = $('.modal');
	$modal.animate({ marginTop: '0', top: '100%' }, function() { $modal.remove() });
	$modalBackground.animate({ opacity: 0 }, function() { $modalBackground.remove() });

	$('html, body').css({
	    'overflow': 'auto',
	    'height': 'auto'
	});

	return false;
}

function polling() {

	var eventId = parseInt($('body').attr('data-event-id'), 10);

    $.ajax({
        url: "/dashboard/event/" + eventId + "/polling",
        type: "GET",
        success: function(data) {

            // Update page
            $('.questions-overview .content .value').text(data.questionsNumber);
			$('.users-overview .content .value').text(data.usersOverview);
			$('.questions-list tbody').html('');

			data.unansweredQuestions.sort(function(a,b){return b.frequency-a.frequency});
			data.answeredQuestions.sort(function(a,b){return b.frequency-a.frequency});

			if($('.tabs li.selected a[data-type="unanswered"]').length) {

				jQuery.each(data.unansweredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});

				jQuery.each(data.answeredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});
			} else {

				jQuery.each(data.unansweredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});

				jQuery.each(data.answeredQuestions, function(index, value) {

					if(value.sentiment === 'positive') {
						data.totalPositive++;
						sentiment = 'green';
					} else {
						if(value.sentiment === 'negative') {
							data.totalNegative++;
							sentiment = 'red';
						} else {
							data.totalNeutral++;
							sentiment = 'grey';
						}
					}

					$('.questions-list tbody').append('
\
							\
						' + value.question + '	\
			            ' + value.frequency + '	\

');
				});
			}

			$('.positive').text('+' + data.totalPositive);
			$('.neutral').text(data.totalNeutral);
			$('.negative').text('-' + data.totalNegative);

			$('.questions-list tbody tr').on('click', showQuestionsModal);
        },
        dataType: "json",
        complete: setTimeout(function() { polling() }, 5000),
        timeout: 2000
    })
}

$(document).ready(function() {
	polling();
	$('.questions-list tbody tr').on('click', showQuestionsModal);

	// Tabs
	$('.tabs a').on('click', function(){
		$('.tabs li').removeClass('selected');
		$(this).parent().addClass('selected');

		if($(this).attr('data-type') == 'answered') {
			$('tr[data-type="answered"]').show();
			$('tr[data-type="unanswered"]').hide();
		} else {
			$('tr[data-type="answered"]').hide();
			$('tr[data-type="unanswered"]').show();
		}
	});
});
<|endoftext|>


<commit_before>import _ from 'lodash'
import makeConcurrent from 'make-concurrent'
import { autobind } from 'core-decorators'
import bitcore from 'bitcore'
import cclib from 'coloredcoinjs-lib'
import ElapsedTime from 'elapsed-time'

import config from '../lib/config'
import logger from '../lib/logger'
import SQL from '../lib/sql'
import util from '../lib/util'

const cdefClss = cclib.definitions.Manager.getColorDefinitionClasses()

function callWithLock (target, name, descriptor) {
  let fn = descriptor.value
  descriptor.value = async function () {
    return this.withLock(() => fn.apply(this, arguments))
  }
}

/**
 * @class Sync
 */
export default class Sync {
  /**
   * @constructor
   * @param {Storage} storage
   * @param {Messages} messages
   */
  constructor (storage, messages) {
    this.storage = storage
    this.messages = messages
  }

  /**
   * @param {string} txId
   * @return {Promise.<string>}
   */
  @autobind
  async getTx (txId) {
    let {rows} = await this.storage.executeQuery(SQL.select.transactions.byTxId, [`\\x${txId}`])
    if (rows.length === 0) {
      throw new Error(`Tx ${txId} not found!`)
    }

    return bitcore.Transaction(rows[0].tx.toString('hex'))
  }

  /**
   * @param {pg.Client} client
   * @param {string} txId
   * @param {string} [blockhash]
   * @param {number} [height]
   * @return {Promise<boolean>}
   */
  async _addTx (client, txId, blockhash, height) {
    let {rows} = await client.queryAsync(SQL.select.ccScannedTxIds.isTxScanned, [`\\x${txId}`])
    if (rows[0].exists === true) {
      return false
    }

    let tx = await this.getTx(txId)
    let opts = {executeOpts: {client: client}}

    let query = SQL.insert.ccScannedTxIds.unconfirmed
    let params = [`\\x${txId}`]
    if (blockhash !== undefined) {
      query = SQL.insert.ccScannedTxIds.confirmed
      params.push(`\\x${blockhash}`, height)
    }

    await* _.flattenDeep([
      cdefClss.map((cdefCls) => {
        return this._cdata.fullScanTx(tx, cdefCls, this.getTx, opts)
      }),
      client.queryAsync(query, params)
    ])

    return true
  }

  /**
   */
  @makeConcurrent({concurrency: 1})
  withLock (fn) { return fn() }

  /**
   * @param {string} txId
   * @return {Promise}
   */
  @callWithLock
  async addTx (txId) {
    try {
      let stopwatch = ElapsedTime.new().start()

      let added = await this.storage.executeTransaction((client) => {
        return this._addTx(client, txId)
      })

      if (added) {
        logger.verbose(`Add unconfirmed tx ${txId}, elapsed time: ${stopwatch.getValue()}`)
      }
    } catch (err) {
      logger.error(`Error on adding unconfirmed tx ${txId}: ${err.stack}`)
    }
  }

  /**
   * @param {string} txId
   * @return {Promise}
   */
  @callWithLock
  async removeTx (txId) {
    try {
      let stopwatch = ElapsedTime.new().start()

      let removed = await this.storage.executeTransaction(async (client) => {
        let {rows} = await client.queryAsync(SQL.select.ccScannedTxIds.isTxScanned, [`\\x${txId}`])
        if (rows[0].exists === false) {
          return false
        }

        let opts = {executeOpts: {client: client}}

        await* _.flattenDeep([
          cdefClss.map(async (cdefCls) => {
            let params
            switch (cdefCls.getColorCode()) {
              case 'epobc':
                params = [`epobc:${txId}:\d+:0`]
                break
              default:
                throw new Error(`Unknow cdefCls: ${cdefCls}`)
            }

            let {rows} = await client.queryAsync(SQL.select.ccDefinitions.colorId, params)
            if (rows.length !== 0) {
              let id = parseInt(rows[0].id, 10)
              return await this._cdefManager.remove({id: id}, opts)
            }

            await this._cdata.removeColorValues(txId, cdefCls, opts)
          }),
          client.queryAsync(SQL.delete.ccScannedTxIds.byTxId, [`\\x${txId}`])
        ])

        return true
      })

      if (removed) {
        logger.verbose(`Remove tx ${txId}, elapsed time: ${stopwatch.getValue()}`)
      }
    } catch (err) {
      logger.error(`Error on removing tx ${txId}: ${err.stack}`)
    }
  }

  /**
   * @return {Promise}
   */
  @callWithLock
  async updateBlocks () {
    let stopwatch = new ElapsedTime()

    let running = true
    while (running) {
      try {
        await this.storage.executeTransaction(async (client) => {
          let latest = null
          let result = await client.queryAsync(SQL.select.ccScannedTxIds.latestBlock)
          if (result.rows.length > 0) {
            latest = {
              hash: result.rows[0].blockhash.toString('hex'),
              height: result.rows[0].height
            }

            result = await client.queryAsync(SQL.select.blocks.latest)
            if (latest.hash === result.rows[0].hash.toString('hex')) {
              running = false
              return
            }

            let latest2 = latest
            while (true) {
              let height = Math.min(latest2.height + 1, result.rows[0].height)
              result = await client.queryAsync(SQL.select.blocks.txIdsByHeight, [height])
              let header = bitcore.Block.BlockHeader(result.rows[0].header)
              if (latest2.hash === util.encode(header.prevHash)) {
                break
              }

              result = await client.queryAsync(SQL.select.ccScannedTxIds.blockHash, [height - 1])
              latest2 = {
                hash: result.rows[0].blockhash.toString('hex'),
                height: result.rows[0].height
              }
            }

            if (latest2.hash !== latest.hash) {
              stopwatch.reset().start()
              await client.queryAsync(
                SQL.update.ccScannedTxIds.makeUnconfirmed, [latest2.height])
              logger.warn(`Make reorg to ${latest2.height}, elapsed time: ${stopwatch.getValue()}`)
            }
          }

          stopwatch.reset().start()
          let hash = result.rows[0].hash.toString('hex')
          let height = result.rows[0].height
          let txIds = result.rows[0].txids.toString('hex')
          let toUpdate = await* _.range(txIds.length / 64).map(async (i) => {
            let txId = txIds.slice(i * 64, (i + 1) * 64)
            if (!(await this._addTx(client, txId, hash, height))) {
              return txId
            }
          })

          await client.queryAsync(SQL.update.ccScannedTxIds.makeConfirmed, [
            _.filter(toUpdate).map((txId) => `\\x${txId}`),
            `\\x${hash}`,
            height
          ])
          logger.info(`Import block ${hash}:${height}, elapsed time: ${stopwatch.getValue()}`)
        })
      } catch (err) {
        logger.error(`Update error: ${err.stack}`)
      }
    }

    // update unconfirmed
    while (true) {
      try {
        stopwatch.reset().start()
        let [ccTxIds, txIds] = await* [
          this.storage.executeQuery(SQL.select.ccScannedTxIds.unconfirmed),
          this.storage.executeQuery(SQL.select.transactions.unconfirmed)
        ]

        ccTxIds = ccTxIds.rows.map((row) => row.txid.toString('hex'))
        txIds = txIds.rows.map((row) => row.txid.toString('hex'))

        // remove
        for (let txId of _.difference(ccTxIds, txIds)) {
          this.removeTx(txId)
        }

        // add
        for (let txId of _.difference(txIds, ccTxIds)) {
          this.addTx(txId)
        }

        logger.info(`Unconfirmed updated, elapsed time: ${stopwatch.getValue()}`)

        break
      } catch (err) {
        logger.error(`Update (unconfirmed) error: ${err.stack}`)
      }
    }
  }

  /**
   * @return {Promise}
   */
  async run () {
    this._cdefStorage = new cclib.storage.definitions.PostgreSQL({url: config.get('postgresql.url')})
    this._cdataStorage = new cclib.storage.data.PostgreSQL({url: config.get('postgresql.url')})

    this._cdefManager = new cclib.definitions.Manager(this._cdefStorage, this._cdefStorage)
    this._cdata = new cclib.ColorData(this._cdataStorage, this._cdefManager)

    await* [this._cdefManager.ready, this._cdata.ready]

    // scan all new rows
    await this.updateBlocks()

    // subscribe for tx/block events
    await* [
      this.messages.listen('addtx', (obj) => this.addTx(obj.txId)),
      this.messages.listen('removetx', (obj) => this.removeTx(obj.txId)),
      this.messages.listen('addblock', ::this.updateBlocks),
      this.messages.listen('removeblock', ::this.updateBlocks)
    ]

    // confirm that all new data was scanned
    await this.updateBlocks()
  }
}
<commit_msg>fix cc-scanner (updateBlocks initial condition)<commit_after>import _ from 'lodash'
import makeConcurrent from 'make-concurrent'
import { autobind } from 'core-decorators'
import bitcore from 'bitcore'
import cclib from 'coloredcoinjs-lib'
import ElapsedTime from 'elapsed-time'

import config from '../lib/config'
import logger from '../lib/logger'
import SQL from '../lib/sql'
import util from '../lib/util'

const cdefClss = cclib.definitions.Manager.getColorDefinitionClasses()

function callWithLock (target, name, descriptor) {
  let fn = descriptor.value
  descriptor.value = async function () {
    return this.withLock(() => fn.apply(this, arguments))
  }
}

/**
 * @class Sync
 */
export default class Sync {
  /**
   * @constructor
   * @param {Storage} storage
   * @param {Messages} messages
   */
  constructor (storage, messages) {
    this.storage = storage
    this.messages = messages
  }

  /**
   * @param {string} txId
   * @return {Promise.<string>}
   */
  @autobind
  async getTx (txId) {
    let {rows} = await this.storage.executeQuery(SQL.select.transactions.byTxId, [`\\x${txId}`])
    if (rows.length === 0) {
      throw new Error(`Tx ${txId} not found!`)
    }

    return bitcore.Transaction(rows[0].tx.toString('hex'))
  }

  /**
   * @param {pg.Client} client
   * @param {string} txId
   * @param {string} [blockhash]
   * @param {number} [height]
   * @return {Promise<boolean>}
   */
  async _addTx (client, txId, blockhash, height) {
    let {rows} = await client.queryAsync(SQL.select.ccScannedTxIds.isTxScanned, [`\\x${txId}`])
    if (rows[0].exists === true) {
      return false
    }

    let tx = await this.getTx(txId)
    let opts = {executeOpts: {client: client}}

    let query = SQL.insert.ccScannedTxIds.unconfirmed
    let params = [`\\x${txId}`]
    if (blockhash !== undefined) {
      query = SQL.insert.ccScannedTxIds.confirmed
      params.push(`\\x${blockhash}`, height)
    }

    await* _.flattenDeep([
      cdefClss.map((cdefCls) => {
        return this._cdata.fullScanTx(tx, cdefCls, this.getTx, opts)
      }),
      client.queryAsync(query, params)
    ])

    return true
  }

  /**
   */
  @makeConcurrent({concurrency: 1})
  withLock (fn) { return fn() }

  /**
   * @param {string} txId
   * @return {Promise}
   */
  @callWithLock
  async addTx (txId) {
    try {
      let stopwatch = ElapsedTime.new().start()

      let added = await this.storage.executeTransaction((client) => {
        return this._addTx(client, txId)
      })

      if (added) {
        logger.verbose(`Add unconfirmed tx ${txId}, elapsed time: ${stopwatch.getValue()}`)
      }
    } catch (err) {
      logger.error(`Error on adding unconfirmed tx ${txId}: ${err.stack}`)
    }
  }

  /**
   * @param {string} txId
   * @return {Promise}
   */
  @callWithLock
  async removeTx (txId) {
    try {
      let stopwatch = ElapsedTime.new().start()

      let removed = await this.storage.executeTransaction(async (client) => {
        let {rows} = await client.queryAsync(SQL.select.ccScannedTxIds.isTxScanned, [`\\x${txId}`])
        if (rows[0].exists === false) {
          return false
        }

        let opts = {executeOpts: {client: client}}

        await* _.flattenDeep([
          cdefClss.map(async (cdefCls) => {
            let params
            switch (cdefCls.getColorCode()) {
              case 'epobc':
                params = [`epobc:${txId}:\d+:0`]
                break
              default:
                throw new Error(`Unknow cdefCls: ${cdefCls}`)
            }

            let {rows} = await client.queryAsync(SQL.select.ccDefinitions.colorId, params)
            if (rows.length !== 0) {
              let id = parseInt(rows[0].id, 10)
              return await this._cdefManager.remove({id: id}, opts)
            }

            await this._cdata.removeColorValues(txId, cdefCls, opts)
          }),
          client.queryAsync(SQL.delete.ccScannedTxIds.byTxId, [`\\x${txId}`])
        ])

        return true
      })

      if (removed) {
        logger.verbose(`Remove tx ${txId}, elapsed time: ${stopwatch.getValue()}`)
      }
    } catch (err) {
      logger.error(`Error on removing tx ${txId}: ${err.stack}`)
    }
  }

  /**
   * @return {Promise}
   */
  @callWithLock
  async updateBlocks () {
    let stopwatch = new ElapsedTime()

    let running = true
    while (running) {
      try {
        await this.storage.executeTransaction(async (client) => {
          let latest = null
          let result = await client.queryAsync(SQL.select.ccScannedTxIds.latestBlock)
          if (result.rows.length > 0) {
            latest = {
              hash: result.rows[0].blockhash.toString('hex'),
              height: result.rows[0].height
            }

            result = await client.queryAsync(SQL.select.blocks.latest)
            if (latest.hash === result.rows[0].hash.toString('hex')) {
              running = false
              return
            }

            let latest2 = latest
            while (true) {
              let height = Math.min(latest2.height + 1, result.rows[0].height)
              result = await client.queryAsync(SQL.select.blocks.txIdsByHeight, [height])
              let header = bitcore.Block.BlockHeader(result.rows[0].header)
              if (latest2.hash === util.encode(header.prevHash)) {
                break
              }

              result = await client.queryAsync(SQL.select.ccScannedTxIds.blockHash, [height - 1])
              latest2 = {
                hash: result.rows[0].blockhash.toString('hex'),
                height: result.rows[0].height
              }
            }

            if (latest2.hash !== latest.hash) {
              stopwatch.reset().start()
              await client.queryAsync(
                SQL.update.ccScannedTxIds.makeUnconfirmed, [latest2.height])
              logger.warn(`Make reorg to ${latest2.height}, elapsed time: ${stopwatch.getValue()}`)
            }
          } else {
            result = await client.queryAsync(SQL.select.blocks.txIdsByHeight, [0])
          }

          stopwatch.reset().start()
          let hash = result.rows[0].hash.toString('hex')
          let height = result.rows[0].height
          let txIds = result.rows[0].txids.toString('hex')
          let toUpdate = await* _.range(txIds.length / 64).map(async (i) => {
            let txId = txIds.slice(i * 64, (i + 1) * 64)
            if (!(await this._addTx(client, txId, hash, height))) {
              return txId
            }
          })

          await client.queryAsync(SQL.update.ccScannedTxIds.makeConfirmed, [
            _.filter(toUpdate).map((txId) => `\\x${txId}`),
            `\\x${hash}`,
            height
          ])
          logger.info(`Import block ${hash}:${height}, elapsed time: ${stopwatch.getValue()}`)
        })
      } catch (err) {
        logger.error(`Update error: ${err.stack}`)
      }
    }

    // update unconfirmed
    while (true) {
      try {
        stopwatch.reset().start()
        let [ccTxIds, txIds] = await* [
          this.storage.executeQuery(SQL.select.ccScannedTxIds.unconfirmed),
          this.storage.executeQuery(SQL.select.transactions.unconfirmed)
        ]

        ccTxIds = ccTxIds.rows.map((row) => row.txid.toString('hex'))
        txIds = txIds.rows.map((row) => row.txid.toString('hex'))

        // remove
        for (let txId of _.difference(ccTxIds, txIds)) {
          this.removeTx(txId)
        }

        // add
        for (let txId of _.difference(txIds, ccTxIds)) {
          this.addTx(txId)
        }

        logger.info(`Unconfirmed updated, elapsed time: ${stopwatch.getValue()}`)

        break
      } catch (err) {
        logger.error(`Update (unconfirmed) error: ${err.stack}`)
      }
    }
  }

  /**
   * @return {Promise}
   */
  async run () {
    this._cdefStorage = new cclib.storage.definitions.PostgreSQL({url: config.get('postgresql.url')})
    this._cdataStorage = new cclib.storage.data.PostgreSQL({url: config.get('postgresql.url')})

    this._cdefManager = new cclib.definitions.Manager(this._cdefStorage, this._cdefStorage)
    this._cdata = new cclib.ColorData(this._cdataStorage, this._cdefManager)

    await* [this._cdefManager.ready, this._cdata.ready]

    // scan all new rows
    await this.updateBlocks()

    // subscribe for tx/block events
    await* [
      this.messages.listen('addtx', (obj) => this.addTx(obj.txId)),
      this.messages.listen('removetx', (obj) => this.removeTx(obj.txId)),
      this.messages.listen('addblock', ::this.updateBlocks),
      this.messages.listen('removeblock', ::this.updateBlocks)
    ]

    // confirm that all new data was scanned
    await this.updateBlocks()
  }
}
<|endoftext|>


<commit_before>this.__log = require('/api/Log');
this.__p = require('/api/PlatformRequire');
this.L = require('/api/Localisation').fetchString;
this.assert = require('/api/Assert');
this.closeApp =require('/api/TiShadow').closeApp;
this.launchApp = require('/api/TiShadow').launchApp;
this.clearCache = require('/api/TiShadow').clearCache;
this.runSpec = function() {
  var path_name = require('/api/TiShadow').currentApp.replace(/ /g,"_");
  require("/api/Spec").run(path_name, false);
}
var context = this;
exports.eval = function(message) {
  try {
    var ret = eval.call(context, message.code
      .replace(/Ti(tanium)?.Filesystem.(resourcesDirectory|getResourcesDirectory\(\))/g, "Ti.Filesystem.applicationDataDirectory + '"+ ( require('/api/TiShadow').currentApp ?  require('/api/TiShadow').currentApp.replace(/ /g,"_")+"/'" : "/"))
      .replace(/require\(/g, "__p.require(")
      .replace(/Ti(tanium)?.include\(/g, "__p.include(this,")
      .replace(/Ti.Locale.getString/g, "L")
      .replace(/([ :=\(])(['"])(\/.*?)(['"])/g, "$1__p.file($2$3$4)")
      .replace(/Ti(tanium)?.API/g, "__log")
      .replace(/console./g, "__log."));
    __log.repl(ret);
  } catch (e) {
    var ret =  require('/api/Utils').extractExceptionData(e)
    __log.error(ret);
  }
}
<commit_msg>repl rewrites brought in line with the compiler<commit_after>this.__log = require('/api/Log');
this.__p = require('/api/PlatformRequire');
this.L = require('/api/Localisation').fetchString;
this.assert = require('/api/Assert');
this.closeApp =require('/api/TiShadow').closeApp;
this.launchApp = require('/api/TiShadow').launchApp;
this.clearCache = require('/api/TiShadow').clearCache;
this.runSpec = function() {
  var path_name = require('/api/TiShadow').currentApp.replace(/ /g,"_");
  require("/api/Spec").run(path_name, false);
}
var context = this;
exports.eval = function(message) {
  try {
    var ret = eval.call(context, message.code
      .replace(/Ti(tanium)?.Filesystem.(resourcesDirectory|getResourcesDirectory\(\))/g, "Ti.Filesystem.applicationDataDirectory + '"+ ( require('/api/TiShadow').currentApp ?  require('/api/TiShadow').currentApp.replace(/ /g,"_")+"/'" : "/"))
      .replace(/(^|[^\.])require\(/g, "$1__p.require(")
      .replace(/Ti(tanium)?.include\(/g, "__p.include(this,")
      .replace(/Ti.Locale.getString/g, "L")
      .replace(/([ :=\(])(['"])(\/[^'"].*?)(['"])/g, "$1__p.file($2$3$4)") // ignores "/"
      .replace(/Ti(tanium)?.API/g, "__log")
      .replace(/console./g, "__log."));
    __log.repl(ret);
  } catch (e) {
    var ret =  require('/api/Utils').extractExceptionData(e)
    __log.error(ret);
  }
}
<|endoftext|>


<commit_before>exports = module.exports = function(container, store, logger) {
  var flowstate = require('flowstate');

  var dispatcher = new flowstate.Manager(store);
  return dispatcher;

  // FIXME: Implement this again, when circular dependecny is fixed
  //        (login/task/resume) needs this Dispatcher.
  //        Also, electrolyte needs a test for this in promise based mode.
  var taskDecls = container.specs('http://i.bixbyjs.org/http/workflow/Activityx');
  console.log('LOADING TASKS!');
  console.log(taskDecls);

  return Promise.all(taskDecls.map(function(spec) { return container.create(spec.id); } ))
    .then(function(tasks) {
      console.log('CREATED!');
      console.log(tasks);

      tasks.forEach(function(task, i) {
        var name = taskDecls[i].a['@name'];
        dispatcher.use(name, task.begin, task.resume);
        logger.info('Loaded web-based task: ' + name);
      });
    }, function(err) {
      console.log(err);
      throw err;
    })
    .then(function() {
      return dispatcher;
    });
};

// TODO: Rename this to http/flow/Dispatcher
exports['@implements'] = 'http://i.bixbyjs.org/http/state/Dispatcher';
exports['@singleton'] = true;
exports['@require'] = [
  '!container',
  'http://i.bixbyjs.org/http/workflow/StateStore',
  'http://i.bixbyjs.org/Logger'
];
<commit_msg>Load activity components.<commit_after>exports = module.exports = function(IoC, store, logger) {
  var flowstate = require('flowstate');

  var dispatcher = new flowstate.Manager(store);

  return Promise.resolve(dispatcher)
    .then(function(dispatcher) {
      var components = IoC.components('http://i.bixbyjs.org/http/workflow/Activityx');
      console.log(components)

      return Promise.all(components.map(function(comp) { return comp.create(); } ))
        .then(function(plugins) {
          plugins.forEach(function(plugin, i) {
            logger.info('Loaded HTTP activity: ' + components[i].a['@name']);
            //dispatcher.use(create(plugin));
          });
        })
        .then(function() {
          return dispatcher;
        });
    })
    .then(function(dispatcher) {
      return dispatcher;
    });

  return;

  return dispatcher;

  // FIXME: Implement this again, when circular dependecny is fixed
  //        (login/task/resume) needs this Dispatcher.
  //        Also, electrolyte needs a test for this in promise based mode.
  var taskDecls = container.specs('http://i.bixbyjs.org/http/workflow/Activityx');
  console.log('LOADING TASKS!');
  console.log(taskDecls);

  return Promise.all(taskDecls.map(function(spec) { return container.create(spec.id); } ))
    .then(function(tasks) {
      console.log('CREATED!');
      console.log(tasks);

      tasks.forEach(function(task, i) {
        var name = taskDecls[i].a['@name'];
        dispatcher.use(name, task.begin, task.resume);
        logger.info('Loaded web-based task: ' + name);
      });
    }, function(err) {
      console.log(err);
      throw err;
    })
    .then(function() {
      return dispatcher;
    });
};

// TODO: Rename this to http/flow/Dispatcher
exports['@implements'] = 'http://i.bixbyjs.org/http/state/Dispatcher';
exports['@singleton'] = true;
exports['@require'] = [
  '!container',
  'http://i.bixbyjs.org/http/workflow/StateStore',
  'http://i.bixbyjs.org/Logger'
];
<|endoftext|>


<commit_before>import DS from 'ember-data';

import ENV from 'feed-registry/config/environment';

export default DS.RESTAdapter.extend({
	host: ENV.datastoreHost,
	namespace: 'api/v1',
	ajaxOptions: function(url, type, options) {
		var hash = this._super(url, type, options);
		// only need to include api_key when making GET requests
		// because those are the most frequent type of request.
		// if we include api_key in POSTs or PUTs, Datastore will barf
		if (typeof(ENV.apiProxyKey) !== "undefined" && type === 'GET') {
			let data = {};
			if (typeof(hash.data) === 'string') {
				data = JSON.parse(hash.data);
			} else {
				data = hash.data;
			}
			data["api_key"] = ENV.apiProxyKey;
			hash.data = data;
		}
		return hash;
	}
});<commit_msg>check if data hash is defined else create new data object<commit_after>import DS from 'ember-data';

import ENV from 'feed-registry/config/environment';

export default DS.RESTAdapter.extend({
	host: ENV.datastoreHost,
	namespace: 'api/v1',
	ajaxOptions: function(url, type, options) {
		var hash = this._super(url, type, options);
		// only need to include api_key when making GET requests
		// because those are the most frequent type of request.
		// if we include api_key in POSTs or PUTs, Datastore will barf
		if (typeof(ENV.apiProxyKey) !== "undefined" && type === 'GET') {
			let data = {};
			if (typeof(hash.data) === 'string') {
				data = JSON.parse(hash.data);
			} else if (typeof(hash.data) !== "undefined") {
				data = hash.data;
			} else {
				// use object literal {}?
				data = new Object();
			}
			// use data.api_key here instead of data["api_key"]?
			data["api_key"] = ENV.apiProxyKey;
			hash.data = data;
		}
		return hash;
	}
});<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react';
import { Link, hashHistory } from 'react-router';
import RaisedButton from 'material-ui/RaisedButton';
import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import Slider from 'material-ui/Slider';
import Toggle from 'material-ui/Toggle';
import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton';
import styles from './Home.css';
import { ipcRenderer } from 'electron';

const paperStyle = {
  paddingLeft: '100px',
  paddingRight: '50px',
  paddingTop: '20px',
  paddingBottom: '20px',
  height: '80vh',
  overflow: 'scroll',
}

const contentStyle = {
  width: '50%',
}

export default class FollowUp extends Component {
  constructor() {
    super();
    this.state = {}
  }

  handleChange(name, event) {
    const state = this.state
    state[name] = event.target.value
    this.setState(state)
  }

  handleClick() {
    const toSave = this.state
    const csvString = Object.keys(toSave).map(function(k){return toSave[k]}).join("','")

    console.log(csvString)
    ipcRenderer.send('create-record', '/tmp/followapp_followUp', "'" + csvString + "'\r\n")
    this.state = {}
    hashHistory.push(`/patient`)
  }

  render() {
    return (

        <Paper style={ paperStyle } zDepth={1}>

Follow Up

For those who had labour epidural

            How effective was it for you labour:
            <Slider
              step={0.20}
              onChange={ this.handleChange.bind(this, 'during_labour') }
            />
            How effective during delivery:
            <Slider
              step={0.20}
              onChange={ this.handleChange.bind(this, 'during_delivery') }
            />
            Were you satisfied with your pain relief?
            <RadioButtonGroup
              name="satisfied_with_pain_relief"
              defaultSelected="not_light"
              onChange={ this.handleChange.bind(this, 'satisfied_with_pain_relief') }
            >
              <RadioButton
                value="yes"
                label="Yes"
              /><RadioButton
                value="no"
                label="No"
              /><RadioButton
                value="n/a"
                label="N/A"
              />
            </RadioButtonGroup>

            Did the epidural stop working at any point?

            <RadioButtonGroup
              name="epidural_stop_working"
              defaultSelected="not_light"
              onChange={ this.handleChange.bind(this, 'epidural_stop_working') }
            >
              <RadioButton
                value="yes"
                label="Yes"
              /><RadioButton
                value="no"
                label="No"
              /><RadioButton
                value="n/a"
                label="N/A"
              />
            </RadioButtonGroup>

            Did the epidural 'fall out' at any point?

            <RadioButtonGroup
              name="shipSpeed"
              defaultSelected="not_light"
              onChange={ this.handleChange.bind(this, 'epidural_fall_out') }
            >
              <RadioButton
                value="yes"
                label="Yes"
                style={{ display: 'inline-block' }}
              /><RadioButton
                value="no"
                label="No"
                style={{ display: 'inline-block' }}
              /><RadioButton
                value="n/a"
                label="N/A"
                style={{ display: 'inline-block' }}
              />
            </RadioButtonGroup>

            <RaisedButton label="Save Follow Up Assessment" primary={true} style={{margin: 12}} onClick={() => this.handleClick() } />

        </Paper>

    );
  }
}
<commit_msg>fix sliders<commit_after>// @flow
import React, { Component } from 'react';
import { Link, hashHistory } from 'react-router';
import RaisedButton from 'material-ui/RaisedButton';
import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import Slider from 'material-ui/Slider';
import Toggle from 'material-ui/Toggle';
import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton';
import styles from './Home.css';
import { ipcRenderer } from 'electron';

const paperStyle = {
  paddingLeft: '100px',
  paddingRight: '50px',
  paddingTop: '20px',
  paddingBottom: '20px',
  height: '80vh',
  overflow: 'scroll',
}

const contentStyle = {
  width: '50%',
}

export default class FollowUp extends Component {
  constructor() {
    super();
    this.state = {}
  }

  handleChange(name, event) {
    const state = this.state
    state[name] = event.target.value
    this.setState(state)
  }

  handleSlider(name, event, value) {
    const state = this.state
    state[name] = value
    this.setState(state)
  }

  handleClick() {
    const toSave = this.state
    const csvString = Object.keys(toSave).map(function(k){return toSave[k]}).join("','")
    ipcRenderer.send('create-record', '/tmp/followapp_followUp', "'" + csvString + "'\r\n")
    this.state = {}
    hashHistory.push(`/patient`)
  }

  render() {
    return (

        <Paper style={ paperStyle } zDepth={1}>

Follow Up

For those who had labour epidural

            How effective was it for you labour:
            <Slider
              step={0.20}
              onChange={ this.handleSlider.bind(this, 'during_labour') }
              name="during_labour"
            />
            How effective during delivery:
            <Slider
              step={0.20}
              onChange={ this.handleSlider.bind(this, 'during_delivery') }
            />
            Were you satisfied with your pain relief?
            <RadioButtonGroup
              name="satisfied_with_pain_relief"
              defaultSelected="not_light"
              onChange={ this.handleChange.bind(this, 'satisfied_with_pain_relief') }
            >
              <RadioButton
                value="yes"
                label="Yes"
              /><RadioButton
                value="no"
                label="No"
              /><RadioButton
                value="n/a"
                label="N/A"
              />
            </RadioButtonGroup>

            Did the epidural stop working at any point?

            <RadioButtonGroup
              name="epidural_stop_working"
              defaultSelected="not_light"
              onChange={ this.handleChange.bind(this, 'epidural_stop_working') }
            >
              <RadioButton
                value="yes"
                label="Yes"
              /><RadioButton
                value="no"
                label="No"
              /><RadioButton
                value="n/a"
                label="N/A"
              />
            </RadioButtonGroup>

            Did the epidural 'fall out' at any point?

            <RadioButtonGroup
              name="shipSpeed"
              defaultSelected="not_light"
              onChange={ this.handleChange.bind(this, 'epidural_fall_out') }
            >
              <RadioButton
                value="yes"
                label="Yes"
                style={{ display: 'inline-block' }}
              /><RadioButton
                value="no"
                label="No"
                style={{ display: 'inline-block' }}
              /><RadioButton
                value="n/a"
                label="N/A"
                style={{ display: 'inline-block' }}
              />
            </RadioButtonGroup>

            <RaisedButton label="Save Follow Up Assessment" primary={true} style={{margin: 12}} onClick={() => this.handleClick() } />

        </Paper>

    );
  }
}
<|endoftext|>


<commit_before>"use strict";
module.exports = function(Promise,
                          PromiseArray,
                          apiRejection,
                          tryConvertToPromise,
                          INTERNAL,
                          debug) {
var ASSERT = require("./assert");
var getDomain = Promise._getDomain;
var util = require("./util");
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;
var EMPTY_ARRAY = [];

function MappingPromiseArray(promises, fn, limit, _filter) {
    this.constructor$(promises);
    this._promise._captureStackTrace();
    var domain = getDomain();
    this._callback = domain === null ? fn : domain.bind(fn);
    this._preservedValues = _filter === INTERNAL
        ? new Array(this.length())
        : null;
    this._limit = limit;
    this._inFlight = 0;
    this._queue = limit >= 1 ? [] : EMPTY_ARRAY;
    this._init$(undefined, RESOLVE_ARRAY);
}
util.inherits(MappingPromiseArray, PromiseArray);

// The following hack is required because the super constructor
// might call promiseFulfilled before this.callback = fn is set
//
// The super constructor call must always be first so that fields
// are initialized in the same order so that the sub-class instances
// will share same memory layout as the super class instances

// Override
MappingPromiseArray.prototype._init = function () {};

// Override
MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
    ASSERT(!this._isResolved());
    var values = this._values;
    var length = this.length();
    var preservedValues = this._preservedValues;
    var limit = this._limit;

    // Callback has been called for this index if it's negative
    if (index < 0) {
        // Restore the actual index value
        index = (index * -1) - 1;
        values[index] = value;
        if (limit >= 1) {
            this._inFlight--;
            this._drainQueue();
            if (this._isResolved()) return true;
        }
    } else {
        if (limit >= 1 && this._inFlight >= limit) {
            values[index] = value;
            this._queue.push(index);
            return false;
        }
        if (preservedValues !== null) preservedValues[index] = value;

        var promise = this._promise;
        var callback = this._callback;
        var receiver = promise._boundValue();
        promise._pushContext();
        var ret = tryCatch(callback).call(receiver, value, index, length);
        var promiseCreated = promise._popContext();
        debug.checkForgottenReturns(
            ret,
            promiseCreated,
            preservedValues !== null ? "Promise.filter" : "Promise.map",
            promise
        );
        if (ret === errorObj) {
            this._reject(ret.e);
            return true;
        }

        // If the mapper function returned a promise we simply reuse
        // The MappingPromiseArray as a PromiseArray for round 2.
        // To mark an index as "round 2" its inverted by adding +1 and
        // multiplying by -1
        var maybePromise = tryConvertToPromise(ret, this._promise);
        if (maybePromise instanceof Promise) {
            maybePromise = maybePromise._target();
            var bitField = maybePromise._bitField;
            USE(bitField);
            if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {
                if (limit >= 1) this._inFlight++;
                values[index] = maybePromise;
                maybePromise._proxy(this, (index + 1) * -1);
                return false;
            } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {
                ret = maybePromise._value();
            } else if (BIT_FIELD_CHECK(IS_REJECTED)) {
                this._reject(maybePromise._reason());
                return true;
            } else {
                this._cancel();
                return true;
            }
        }
        values[index] = ret;
    }
    var totalResolved = ++this._totalResolved;
    if (totalResolved >= length) {
        if (preservedValues !== null) {
            this._filter(values, preservedValues);
        } else {
            this._resolve(values);
        }
        return true;
    }
    return false;
};

MappingPromiseArray.prototype._drainQueue = function () {
    var queue = this._queue;
    var limit = this._limit;
    var values = this._values;
    while (queue.length > 0 && this._inFlight < limit) {
        if (this._isResolved()) return;
        var index = queue.pop();
        this._promiseFulfilled(values[index], index);
    }
};

MappingPromiseArray.prototype._filter = function (booleans, values) {
    var len = values.length;
    var ret = new Array(len);
    var j = 0;
    for (var i = 0; i < len; ++i) {
        if (booleans[i]) ret[j++] = values[i];
    }
    ret.length = j;
    this._resolve(ret);
};

MappingPromiseArray.prototype.preservedValues = function () {
    return this._preservedValues;
};

function map(promises, fn, options, _filter) {
    if (typeof fn !== "function") {
        return apiRejection(FUNCTION_ERROR + util.classString(fn));
    }
    var limit = typeof options === "object" && options !== null
        ? options.concurrency
        : 0;
    limit = typeof limit === "number" &&
        isFinite(limit) && limit >= 1 ? limit : 0;
    return new MappingPromiseArray(promises, fn, limit, _filter).promise();
}

Promise.prototype.map = function (fn, options) {
    return map(this, fn, options, null);
};

Promise.map = function (promises, fn, options, _filter) {
    return map(promises, fn, options, _filter);
};

};
<commit_msg>fixes #1097<commit_after>"use strict";
module.exports = function(Promise,
                          PromiseArray,
                          apiRejection,
                          tryConvertToPromise,
                          INTERNAL,
                          debug) {
var ASSERT = require("./assert");
var getDomain = Promise._getDomain;
var util = require("./util");
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;
var EMPTY_ARRAY = [];

function MappingPromiseArray(promises, fn, limit, _filter) {
    this.constructor$(promises);
    this._promise._captureStackTrace();
    var domain = getDomain();
    this._callback = domain === null ? fn : domain.bind(fn);
    this._preservedValues = _filter === INTERNAL
        ? new Array(this.length())
        : null;
    this._limit = limit;
    this._inFlight = 0;
    this._queue = limit >= 1 ? [] : EMPTY_ARRAY;
    this._init$(undefined, RESOLVE_ARRAY);
}
util.inherits(MappingPromiseArray, PromiseArray);

// The following hack is required because the super constructor
// might call promiseFulfilled before this.callback = fn is set
//
// The super constructor call must always be first so that fields
// are initialized in the same order so that the sub-class instances
// will share same memory layout as the super class instances

// Override
MappingPromiseArray.prototype._init = function () {};

// Override
MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
    ASSERT(!this._isResolved());
    var values = this._values;
    var length = this.length();
    var preservedValues = this._preservedValues;
    var limit = this._limit;

    // Callback has been called for this index if it's negative
    if (index < 0) {
        // Restore the actual index value
        index = (index * -1) - 1;
        values[index] = value;
        if (limit >= 1) {
            this._inFlight--;
            this._drainQueue();
            if (this._isResolved()) return true;
        }
    } else {
        if (limit >= 1 && this._inFlight >= limit) {
            values[index] = value;
            this._queue.push(index);
            return false;
        }
        if (preservedValues !== null) preservedValues[index] = value;

        var promise = this._promise;
        var callback = this._callback;
        var receiver = promise._boundValue();
        promise._pushContext();
        var ret = tryCatch(callback).call(receiver, value, index, length);
        var promiseCreated = promise._popContext();
        debug.checkForgottenReturns(
            ret,
            promiseCreated,
            preservedValues !== null ? "Promise.filter" : "Promise.map",
            promise
        );
        if (ret === errorObj) {
            this._reject(ret.e);
            return true;
        }

        // If the mapper function returned a promise we simply reuse
        // The MappingPromiseArray as a PromiseArray for round 2.
        // To mark an index as "round 2" its inverted by adding +1 and
        // multiplying by -1
        var maybePromise = tryConvertToPromise(ret, this._promise);
        if (maybePromise instanceof Promise) {
            maybePromise = maybePromise._target();
            var bitField = maybePromise._bitField;
            USE(bitField);
            if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {
                if (limit >= 1) this._inFlight++;
                values[index] = maybePromise;
                maybePromise._proxy(this, (index + 1) * -1);
                return false;
            } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {
                ret = maybePromise._value();
            } else if (BIT_FIELD_CHECK(IS_REJECTED)) {
                this._reject(maybePromise._reason());
                return true;
            } else {
                this._cancel();
                return true;
            }
        }
        values[index] = ret;
    }
    var totalResolved = ++this._totalResolved;
    if (totalResolved >= length) {
        if (preservedValues !== null) {
            this._filter(values, preservedValues);
        } else {
            this._resolve(values);
        }
        return true;
    }
    return false;
};

MappingPromiseArray.prototype._drainQueue = function () {
    var queue = this._queue;
    var limit = this._limit;
    var values = this._values;
    while (queue.length > 0 && this._inFlight < limit) {
        if (this._isResolved()) return;
        var index = queue.pop();
        this._promiseFulfilled(values[index], index);
    }
};

MappingPromiseArray.prototype._filter = function (booleans, values) {
    var len = values.length;
    var ret = new Array(len);
    var j = 0;
    for (var i = 0; i < len; ++i) {
        if (booleans[i]) ret[j++] = values[i];
    }
    ret.length = j;
    this._resolve(ret);
};

MappingPromiseArray.prototype.preservedValues = function () {
    return this._preservedValues;
};

function map(promises, fn, options, _filter) {
    if (typeof fn !== "function") {
        return apiRejection(FUNCTION_ERROR + util.classString(fn));
    }

    var limit = 0;
    if (options !== undefined) {
        if (typeof options === "object" && options !== null) {
            if (typeof options.concurrency !== "number") {
                return Promise.reject(
                    new TypeError("'concurrency' must be a number but it is " +
                                    util.classString(options.concurrency)));
            }
            limit = options.concurrency;
        } else {
            return Promise.reject(new TypeError(
                            "options argument must be an object but it is " +
                             util.classString(options)));
        }
    }
    limit = typeof limit === "number" &&
        isFinite(limit) && limit >= 1 ? limit : 0;
    return new MappingPromiseArray(promises, fn, limit, _filter).promise();
}

Promise.prototype.map = function (fn, options) {
    return map(this, fn, options, null);
};

Promise.map = function (promises, fn, options, _filter) {
    return map(promises, fn, options, _filter);
};

};
<|endoftext|>


<commit_before>import Ember from 'ember';
import loadAll from 'ember-osf/utils/load-relationship';

export default Ember.Controller.extend({
    fullScreenMFR: false,
    expandedAuthors: true,
    twitterHref: Ember.computed('model', function() {
        return encodeURI('https://twitter.com/intent/tweet?url=' + window.location.href + '&text=' + this.get('model.title') + '&via=OSFramework');
    }),
    facebookHref: Ember.computed('model', function() {
        return encodeURI('https://www.facebook.com/sharer/sharer.php?u=' + window.location.href);
    }),
    linkedinHref: Ember.computed('model', function() {
        return encodeURI('https://www.linkedin.com/cws/share?url=' + window.location.href + '&title=' + this.get('model.title'));
    }),
    emailHref: Ember.computed('model', function() {
        return 'mailto:?subject=' + encodeURIComponent(this.get('model.title') + '&body=' + window.location.href);
    }),
    // The currently selected file (defaults to primary)
    activeFile: null,

    hasTag: Ember.computed('model.tags', function() {
        return this.get('model.tags').length;
    }),

    getAuthors: Ember.observer('model', function() {
        // Cannot be called until preprint has loaded!
        var model = this.get('model');
        if (!model) return [];

        let contributors = Ember.A();
        loadAll(model, 'contributors', contributors).then(()=>
             this.set('authors', contributors));
    }),

    actions: {
        expandMFR() {
            this.toggleProperty('fullScreenMFR');
        },
        expandAuthors() {
            this.toggleProperty('expandedAuthors');
        },
        chooseFile(fileItem) {
            this.set('activeFile', fileItem);
        },
        shareLink(href) {
            window.open(href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=600,height=400');
            return false;
        }
    },
});
<commit_msg>fix email body<commit_after>import Ember from 'ember';
import loadAll from 'ember-osf/utils/load-relationship';

export default Ember.Controller.extend({
    fullScreenMFR: false,
    expandedAuthors: true,
    twitterHref: Ember.computed('model', function() {
        return encodeURI('https://twitter.com/intent/tweet?url=' + window.location.href + '&text=' + this.get('model.title') + '&via=OSFramework');
    }),
    facebookHref: Ember.computed('model', function() {
        return encodeURI('https://www.facebook.com/sharer/sharer.php?u=' + window.location.href);
    }),
    linkedinHref: Ember.computed('model', function() {
        return encodeURI('https://www.linkedin.com/cws/share?url=' + window.location.href + '&title=' + this.get('model.title'));
    }),
    emailHref: Ember.computed('model', function() {
        return 'mailto:?subject=' + encodeURIComponent(this.get('model.title')) + '&body=' + encodeURIComponent(window.location.href);
    }),
    // The currently selected file (defaults to primary)
    activeFile: null,

    hasTag: Ember.computed('model.tags', function() {
        return this.get('model.tags').length;
    }),

    getAuthors: Ember.observer('model', function() {
        // Cannot be called until preprint has loaded!
        var model = this.get('model');
        if (!model) return [];

        let contributors = Ember.A();
        loadAll(model, 'contributors', contributors).then(()=>
             this.set('authors', contributors));
    }),

    actions: {
        expandMFR() {
            this.toggleProperty('fullScreenMFR');
        },
        expandAuthors() {
            this.toggleProperty('expandedAuthors');
        },
        chooseFile(fileItem) {
            this.set('activeFile', fileItem);
        },
        shareLink(href) {
            window.open(href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=600,height=400');
            return false;
        }
    },
});
<|endoftext|>


<commit_before>angular.module('app').controller('IssueShowController', function ($scope, $api, $routeParams, $window, $location, $pageTitle, $anchorScroll, $analytics, Timeline, BountyClaim, Web3Utils, Issue, $modal) {
  var issue_id = parseInt($routeParams.id);

  // load core issue object
  $scope.issue = Issue.get({
    id: issue_id,
    include_body_html: true,
    include_author: true,
    include_tracker: true,
    include_team: true,
    include_counts: true
  }, function(issue) {
    $scope.team = issue.team;
    $pageTitle.set($scope.issue.title, $scope.issue.tracker.name);
  }, function(error){
    $scope.issue_deleted = true;
    $scope.issue_error = error.data.error;
  });

  // get list of 100 events for issue home page
  $scope.events = Timeline.query({
    per_page: 100,
    issue_id: issue_id
  });

  // create bounty box (allow prefil via &amount=123 in query params)
  $scope.usdCart = {
    amount: 0,
    item_type: 'bounty',
    issue_id: issue_id,
    bounty_expiration: null,
    currency: 'USD'
  }

  $scope.checkout = {}

  $scope.setOwner = function (type, owner) {
    switch (type) {
      case ('anonymous'):
        $scope.owner = {
          display_name: 'Anonymous',
          image_url: '<%= asset_path("anon.jpg") %>'
        };
        $scope.usdCart.owner_id = null;
        $scope.usdCart.owner_type = null;
        $scope.usdCart.anonymous = true;
        break;

      case ('person'):
        $scope.owner = angular.copy(owner);
        $scope.usdCart.owner_id = owner.id;
        $scope.usdCart.owner_type = 'Person';
        $scope.usdCart.anonymous = false;
        break;

      case ('team'):
        $scope.owner = angular.copy(owner);
        $scope.usdCart.owner_id = owner.id;
        $scope.usdCart.owner_type = 'Team';
        $scope.usdCart.anonymous = false;
        break;

      default:
        $log.error('Unexpected owner:', type, owner);
    }
  };

  $scope.checkoutUsd = function() {
    $scope.$watch('current_person', function (person) {
      if (angular.isObject(person)) {
        $api.v2.checkout({item: $scope.usdCart, checkout_method: $scope.checkout.checkout_method}).then(function(response) {
          $window.location = response.data.checkout_url;
        });
      } else if (person === false) {
        $api.set_post_auth_url($location.path());
        $location.url('/signin');
      }
    });
  }

  $scope.setUsdAmount = function(amount){
    $scope.usdCart.amount = amount;
  }

  $scope.calculateCartTotal = function () {
    if ($scope.usdCart.tweet) {
      $scope.usdCart.total = $scope.usdCart.amount + 20
    } else {
      $scope.usdCart.total = $scope.usdCart.amount
    }
    return $scope.usdCart.total;
  };

  $scope.bountyExpirationOptions = [
    { value: null, description: 'Never' },
    { value: 3, description: '3 Months ($100 minimum)' },
    { value: 6, description: '6 Months ($250 minimum)' }
  ];

  $scope.bountyUponExpirationOptions = [
    { value: 'refund', description: 'Refund to my Bountysource account' },
    { value: 'donate to project', description: 'Donate to project' }
  ];

  $scope.bountyExpirationValid = function () {
    switch ($scope.usdCart.bounty_expiration) {
      case (3):
        return $scope.usdCart.amount >= 100;

      case (6):
        return $scope.usdCart.amount >= 250;

      default:
        return true;
    }
  };

  $scope.updateUponExpiration = function() {
    if ($scope.usdCart.bounty_expiration === null) { $scope.usdCart.upon_expiration = null; }
  }

  $scope.canCheckout = function () {
    return $scope.usdCart.amount >= 5 && $scope.checkout.checkout_method && $scope.bountyExpirationValid()
  };

  $scope.isMiscCrypto = function(crypto){
    return !['ETH', 'BTC', 'CAN'].includes(crypto);
  }

  $scope.setCrypto = function(crypto){
    $scope.bounty.amount = 0;
    $scope.bounty.token = crypto;
  }

  $scope.isSelectedCrypto = function(crypto){
    return $scope.bounty.token === crypto;
  }

  $scope.setAmount = function(amount){
    $scope.bounty.amount = amount;
  }

  $scope.oneAtATime = true;
  $scope.bioShow = false;
  $scope.issueBodyShow = false;

  $scope.status = {
    usdOpen: false,
    cryptoOpen: false
  };

  $scope.log = function(message){
    console.log(message)
  }

  $api.v2.currencies().then(function(currencies){
    $scope.currencies = currencies.data;
    $scope.cryptoOptions = Object.keys(currencies.data);
  })

  $scope.bounty = {
    token: 'ETH',
    amount: '0'
  };

  $scope.active_tab = function(name) {
    if (name === 'overview' && (/^\/issues\/[a-z-_0-9]+$/i).test($location.path())) { return "active"; }
    if (name === 'backers' && (/^\/issues\/[a-z-_0-9]+\/backers/).test($location.path())) { return "active"; }
  };

  $scope.generate_address = function(issue_id){
    if(($scope.issue.issue_address || {} ).public_address === undefined){
      $api.issue_address_create(issue_id).then(function(issue){
        if(Web3Utils.isMetaMask() && $scope.isSelectedCrypto('ETH')) {
          $scope.issue = issue
          $scope.openMetamaskModal()
        } else {
          $scope.openQRModal()
        }
      })
    } else {
      if(Web3Utils.isMetaMask() && $scope.isSelectedCrypto('ETH')) {
        $scope.openMetamaskModal()
      } else {
        $scope.openQRModal()
      }
    }
  }

  $scope.openHunterBox = function() {
    $modal.open({
      templateUrl: 'common/templates/hunterBoxModal.html',
      backdrop: true,
      size: 'sm',
      controller: function($scope, $modalInstance, bounty, issue, Web3Utils) {
        $scope.bounty = bounty;
        $scope.issue = issue;
        $scope.closeModal = function() {
          $modalInstance.close();
        };
      },
      resolve: {
        bounty: function () {
          return $scope.bounty;
        },
        issue: function () {
          return $scope.issue;
        }
      }

    });
  }

  $scope.openQRModal = function(){
    $modal.open({
      templateUrl: 'common/templates/issueAddressQrModal.html',
      backdrop: true,
      controller: function($scope, $modalInstance, bounty, issue, Web3Utils) {
        $scope.bounty = bounty;
        $scope.issue = issue;
        $scope.closeModal = function() {
          $modalInstance.close();
        };
      },
      resolve: {
        bounty: function () {
          return $scope.bounty;
        },
        issue: function () {
          return $scope.issue;
        }
      }

    });
  }

  $scope.openMetamaskModal = function(){
    $modal.open({
      templateUrl: 'common/templates/metamaskModal.html',
      backdrop: true,
      controller: function($scope, $modalInstance, bounty, issue, openQRModal, Web3Utils) {
        $scope.bounty = bounty;
        $scope.issue = issue;
        $scope.closeModal = function() {
          $modalInstance.close();
          openQRModal()
        };

        $scope.sendThroughMetaMask = function(){
          Web3Utils.sendTransaction($scope.bounty.amount, $scope.issue.issue_address.public_address)
          $scope.closeModal()
        }

        $scope.showQRAddress = function(){
          $scope.closeModal()
          $parent.openQRModal()
        }
      },
      resolve: {
        bounty: function () {
          return $scope.bounty;
        },
        issue: function () {
          return $scope.issue;
        },
        openQRModal: function(){
          return $scope.openQRModal;
        }
      }

    });
  }

  // Fetch teams for person to load Team account checkout method radios
  $scope.$watch('current_person', function(person) {
    if (angular.isObject(person)) {
      $scope.setOwner('person', person);
      $api.person_teams(person.id).then(function(teams) {
        $scope.teams = angular.copy(teams);
      });
    }
  });
});
<commit_msg>fix crypto<commit_after>angular.module('app').controller('IssueShowController', function ($scope, $api, $routeParams, $window, $location, $pageTitle, $anchorScroll, $analytics, Timeline, BountyClaim, Web3Utils, Issue, $modal) {
  var issue_id = parseInt($routeParams.id);

  // load core issue object
  $scope.issue = Issue.get({
    id: issue_id,
    include_body_html: true,
    include_author: true,
    include_tracker: true,
    include_team: true,
    include_counts: true
  }, function(issue) {
    $scope.team = issue.team;
    $pageTitle.set($scope.issue.title, $scope.issue.tracker.name);
  }, function(error){
    $scope.issue_deleted = true;
    $scope.issue_error = error.data.error;
  });

  // get list of 100 events for issue home page
  $scope.events = Timeline.query({
    per_page: 100,
    issue_id: issue_id
  });

  // create bounty box (allow prefil via &amount=123 in query params)
  $scope.usdCart = {
    amount: 0,
    item_type: 'bounty',
    issue_id: issue_id,
    bounty_expiration: null,
    currency: 'USD'
  }

  $scope.checkout = {}

  $scope.setOwner = function (type, owner) {
    switch (type) {
      case ('anonymous'):
        $scope.owner = {
          display_name: 'Anonymous',
          image_url: '<%= asset_path("anon.jpg") %>'
        };
        $scope.usdCart.owner_id = null;
        $scope.usdCart.owner_type = null;
        $scope.usdCart.anonymous = true;
        break;

      case ('person'):
        $scope.owner = angular.copy(owner);
        $scope.usdCart.owner_id = owner.id;
        $scope.usdCart.owner_type = 'Person';
        $scope.usdCart.anonymous = false;
        break;

      case ('team'):
        $scope.owner = angular.copy(owner);
        $scope.usdCart.owner_id = owner.id;
        $scope.usdCart.owner_type = 'Team';
        $scope.usdCart.anonymous = false;
        break;

      default:
        $log.error('Unexpected owner:', type, owner);
    }
  };

  $scope.checkoutUsd = function() {
    $scope.$watch('current_person', function (person) {
      if (angular.isObject(person)) {
        $api.v2.checkout({item: $scope.usdCart, checkout_method: $scope.checkout.checkout_method}).then(function(response) {
          $window.location = response.data.checkout_url;
        });
      } else if (person === false) {
        $api.set_post_auth_url($location.path());
        $location.url('/signin');
      }
    });
  }

  $scope.setUsdAmount = function(amount){
    $scope.usdCart.amount = amount;
  }

  $scope.calculateCartTotal = function () {
    if ($scope.usdCart.tweet) {
      $scope.usdCart.total = $scope.usdCart.amount + 20
    } else {
      $scope.usdCart.total = $scope.usdCart.amount
    }
    return $scope.usdCart.total;
  };

  $scope.bountyExpirationOptions = [
    { value: null, description: 'Never' },
    { value: 3, description: '3 Months ($100 minimum)' },
    { value: 6, description: '6 Months ($250 minimum)' }
  ];

  $scope.bountyUponExpirationOptions = [
    { value: 'refund', description: 'Refund to my Bountysource account' },
    { value: 'donate to project', description: 'Donate to project' }
  ];

  $scope.bountyExpirationValid = function () {
    switch ($scope.usdCart.bounty_expiration) {
      case (3):
        return $scope.usdCart.amount >= 100;

      case (6):
        return $scope.usdCart.amount >= 250;

      default:
        return true;
    }
  };

  $scope.updateUponExpiration = function() {
    if ($scope.usdCart.bounty_expiration === null) { $scope.usdCart.upon_expiration = null; }
  }

  $scope.canCheckout = function () {
    return $scope.usdCart.amount >= 5 && $scope.checkout.checkout_method && $scope.bountyExpirationValid()
  };

  $scope.isMiscCrypto = function(crypto){
    return !['ETH', 'BTC', 'CAN'].includes(crypto);
  }

  $scope.setCrypto = function(crypto){
    $scope.bounty.amount = 0;
    $scope.bounty.token = crypto;
  }

  $scope.isSelectedCrypto = function(crypto){
    return $scope.bounty.token === crypto;
  }

  $scope.setAmount = function(amount){
    $scope.bounty.amount = amount;
  }

  $scope.oneAtATime = true;
  $scope.bioShow = false;
  $scope.issueBodyShow = false;

  $scope.status = {
    usdOpen: false,
    cryptoOpen: false
  };

  $scope.log = function(message){
    console.log(message)
  }

  $api.v2.currencies().then(function(currencies){
    $scope.currencies = currencies.data;
    $scope.cryptoOptions = Object.keys(currencies.data);
  })

  $scope.bounty = {
    token: 'ETH',
    amount: '0'
  };

  $scope.active_tab = function(name) {
    if (name === 'overview' && (/^\/issues\/[a-z-_0-9]+$/i).test($location.path())) { return "active"; }
    if (name === 'backers' && (/^\/issues\/[a-z-_0-9]+\/backers/).test($location.path())) { return "active"; }
  };

  $scope.generate_address = function(issue_id){
    if(($scope.issue.issue_address || {} ).public_address === undefined){
      $api.issue_address_create(issue_id).then(function(issue){
        if(Web3Utils.isMetaMask() && $scope.isSelectedCrypto('ETH')) {
          $scope.issue = issue
          $scope.openMetamaskModal()
        } else {
          $scope.openQRModal()
        }
      })
    } else {
      if(Web3Utils.isMetaMask() && $scope.isSelectedCrypto('ETH')) {
        $scope.openMetamaskModal()
      } else {
        $scope.openQRModal()
      }
    }
  }

  $scope.openHunterBox = function() {
    $modal.open({
      templateUrl: 'common/templates/hunterBoxModal.html',
      backdrop: true,
      size: 'sm',
      controller: function($scope, $modalInstance, bounty, issue, Web3Utils) {
        $scope.bounty = bounty;
        $scope.issue = issue;
        $scope.closeModal = function() {
          $modalInstance.close();
        };
      },
      resolve: {
        bounty: function () {
          return $scope.bounty;
        },
        issue: function () {
          return $scope.issue;
        }
      }

    });
  }

  $scope.openQRModal = function(){
    $modal.open({
      templateUrl: 'common/templates/issueAddressQrModal.html',
      backdrop: true,
      controller: function($scope, $modalInstance, bounty, issue, Web3Utils) {
        $scope.bounty = bounty;
        $scope.issue = issue;
        $scope.closeModal = function() {
          $modalInstance.close();
        };
      },
      resolve: {
        bounty: function () {
          return $scope.bounty;
        },
        issue: function () {
          return $scope.issue;
        }
      }

    });
  }

  $scope.openMetamaskModal = function(){
    $modal.open({
      templateUrl: 'common/templates/metamaskModal.html',
      backdrop: true,
      controller: function($scope, $modalInstance, bounty, issue, openQRModal, Web3Utils) {
        $scope.bounty = bounty;
        $scope.issue = issue;
        $scope.closeModal = function() {
          $modalInstance.close();
          openQRModal()
        };

        $scope.sendThroughMetaMask = function(){
          Web3Utils.sendTransaction($scope.bounty.amount, $scope.issue.issue_address.public_address)
          $scope.closeModal()
        }

        $scope.showQRAddress = function(){
          $scope.closeModal()
          openQRModal()
        }
      },
      resolve: {
        bounty: function () {
          return $scope.bounty;
        },
        issue: function () {
          return $scope.issue;
        },
        openQRModal: function(){
          return $scope.openQRModal;
        }
      }

    });
  }

  // Fetch teams for person to load Team account checkout method radios
  $scope.$watch('current_person', function(person) {
    if (angular.isObject(person)) {
      $scope.setOwner('person', person);
      $api.person_teams(person.id).then(function(teams) {
        $scope.teams = angular.copy(teams);
      });
    }
  });
});
<|endoftext|>