<commit_before>const {assert} = require('chai');
const cp = require('child_process');
const uuid = require(`uuid`);

const grafeas = require('@google-cloud/grafeas');
const client = new grafeas.v1.GrafeasClient();

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const projectId = process.env.GCLOUD_PROJECT;
const formattedParent = `projects/${projectId}`;
const uuidVal = uuid.v4();
const noteId = `test-note-${uuidVal}`;
const formattedNoteName = `projects/${projectId}/notes/${noteId}`;
const resourceUrl = `gcr.io/project/image`;
const subscriptionId = `occurrence-subscription-${uuidVal}`;
const timeoutSeconds = 5;

const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub();
const topicName = 'container-analysis-occurrences-v1beta1';
const topic = pubsub.topic(topicName);

describe('Note tests', function() {
  after(async function() {
    const [allOccurrences] = await client.listOccurrences({
      parent: formattedParent,
      filter: `resourceUrl = "${resourceUrl}"`,
    });

    allOccurrences.forEach(async occurrence => {
      await client.deleteOccurrence({name: occurrence.name});
      console.log(`deleted occurrence ${occurrence.name}`);
    });

    const [allNotes] = await client.listNotes({
      parent: formattedParent,
    });

    allNotes.forEach(async note => {
      await client.deleteNote({name: note.name});
      console.log(`deleted note ${note.name}`);
    });
  });
  it('should create a note', function() {
    const output = execSync(`node createNote.js "${projectId}" "${noteId}"`);
    assert.match(output, new RegExp(`Note ${formattedNoteName} created.`));
  });

  it('should get note', function() {
    const output = execSync(`node getNote.js "${projectId}" "${noteId}"`);
    assert.match(output, new RegExp(`Note name: ${formattedNoteName}`));
  });

  it('should create occurrence', function() {
    const output = execSync(
      `node createOccurrence.js "${projectId}" "${noteId}" "${projectId}" "${resourceUrl}"`
    );
    assert.match(output, new RegExp(`Occurrence created`));
  });

  // TODO: sometimes fails, should try again if no images are found
  it('should get occurrence', async function() {
    const [occurrences] = await client.listOccurrences({
      parent: formattedParent,
    });
    assert(occurrences.length > 0);

    const occurrence = occurrences[0];
    const occurrenceId = occurrence.name.split('/')[3];
    const output = execSync(
      `node getOccurrence.js "${projectId}" "${occurrenceId}"`
    );
    assert.match(output, new RegExp(`Occurrence name: ${occurrence.name}`));
  });

  it('should get occurences for note', function() {
    const output = execSync(
      `node occurrencesForNote.js "${projectId}" "${noteId}"`
    );
    assert.match(output, /Occurrences:/);
  });

  it('should get occurrences for image', function() {
    const output = execSync(
      `node occurrencesForImage.js "${projectId}" "${resourceUrl}"`
    );
    assert.match(output, new RegExp(`Occurrences for ${resourceUrl}`));
  });

  it('should get discovery info for image', async function() {
    const discoveryNoteRequest = {
      parent: formattedParent,
      noteId: `${noteId}-discovery`,
      note: {
        discovery: {},
      },
    };

    await client.createNote(discoveryNoteRequest);

    const occurrenceRequest = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-discovery`,
        discovered: {
          discovered: {
            analysisStatus: 'FINISHED_SUCCESS',
          },
        },
        resource: {
          uri: resourceUrl,
        },
      },
    };

    await client.createOccurrence(occurrenceRequest);

    const output = execSync(
      `node getDiscoveryInfo "${projectId}" "${resourceUrl}"`
    );
    assert.match(
      output,
      new RegExp(`Discovery Occurrences for ${resourceUrl}`)
    );
  });

  it('should get high severity vulnerabilities for image', async function() {
    const criticalNoteReq = {
      parent: formattedParent,
      noteId: `${noteId}-critical`,
      note: {
        vulnerability: {
          severity: 'CRITICAL',
        },
      },
    };

    await client.createNote(criticalNoteReq);

    const criticalOccurrenceReq = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-critical`,
        vulnerability: {
          vulnerability: {
            severity: 'CRITICAL',
          },
        },
        resource: {
          uri: resourceUrl,
        },
      },
    };

    await client.createOccurrence(criticalOccurrenceReq);

    const output = execSync(
      `node highVulnerabilitiesForImage "${projectId}" "${resourceUrl}"`
    );

    assert.match(
      output,
      new RegExp(`High Severity Vulnerabilities for ${resourceUrl}`)
    );
  });

  it('should get all vulnerabilites for image', function() {
    const output = execSync(
      `node vulnerabilityOccurrencesForImage "${projectId}" "${resourceUrl}"`
    );
    assert.match(output, new RegExp(`All Vulnerabilities for ${resourceUrl}`));
  });

  it('should delete occurrence', async function() {
    const [occurrences] = await client.listOccurrences({
      parent: formattedParent,
    });
    assert(occurrences.length > 0);
    const occurrence = occurrences[0];
    const occurrenceId = occurrence.name.split('/')[3];

    const output = execSync(
      `node deleteOccurrence.js "${projectId}" "${occurrenceId}"`
    );
    assert.match(output, new RegExp(`Occurrence deleted.`));
  });
  it('should delete note', function() {
    const output = execSync(`node deleteNote.js "${projectId}" "${noteId}" `);
    assert.match(output, new RegExp(`Note ${formattedNoteName} deleted.`));
  });
});

// TODO:
xdescribe('polling', function() {
  before(async function() {
    const discoveryNoteRequest = {
      parent: formattedParent,
      noteId: `${noteId}-discovery-polling`,
      note: {
        discovery: {
          continuousAnalysis: 'INACTIVE',
        },
      },
    };

    await client.createNote(discoveryNoteRequest);

    const occurrenceRequest = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-discovery-polling`,
        discovered: {
          discovered: {
            analysisStatus: 'FINISHED_SUCCESS',
          },
        },
      },
      resource: {
        uri: resourceUrl,
      },
    };

    await client.createOccurrence(occurrenceRequest);
  });

  after(async function() {
    const [discoveryOccurrences] = await client.listNoteOccurrences({
      name: `${formattedNoteName}-discovery-polling`,
    });
    discoveryOccurrences.forEach(async occurrence => {
      await client.deleteOccurrence({name: occurrence.name});
    });
    await client.deleteNote({name: `${formattedNoteName}-discovery-polling`});
  });
  // it('should poll api until timeout', function() {
  //     const output = execSync(`node pollDiscoveryOccurrenceFinished.js "${projectId}" "${urlWithoutOccurrences}" "${timeoutSeconds}"`);
  //     assert.match(
  //         output,
  //         new RegExp(`'Timeout while retrieving discovery occurrence.`)
  //     );
  // });

  it('should successfully poll latest discovery occurrence', function() {
    const output = execSync(
      `node pollDiscoveryOccurrenceFinished.js "${projectId}" "${resourceUrl}" "${timeoutSeconds}"`
    );
    assert.match(
      output,
      new RegExp(`Polled Discovery Occurrences for ${resourceUrl}`)
    );
  });
});

describe('pubsub', function() {
  beforeEach(async function() {
    await topic.createSubscription(subscriptionId);
    const pubSubNoteReq = {
      parent: formattedParent,
      noteId: `${noteId}-pubsub`,
      note: {
        vulnerability: {},
      },
    };
    await client.createNote(pubSubNoteReq);
  });
  afterEach(async function() {
    await client.deleteNote({name: `${formattedNoteName}-pubsub`});
    await pubsub.subscription(subscriptionId).delete();
  });
  it('should get accurate count of occurrences from pubsub topic', async function() {
    const expectedNum = 3;
    const pubSubOccurrenceReq = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-pubsub`,
        vulnerability: {
          vulnerability: {},
        },
        resource: {
          uri: resourceUrl,
        },
      },
    };
    // empty subscription
    execSync(
      `node occurrencePubSub.js "${projectId}" "${subscriptionId}" "${timeoutSeconds}"`
    );

    // make sure empty
    const empty = execSync(
      `node occurrencePubSub.js "${projectId}" "${subscriptionId}" "${timeoutSeconds}"`
    );

    assert.match(empty, new RegExp(`Polled 0 occurrences`));
    // create test occurrences
    for (let i = 0; i < expectedNum; i++) {
      const [pubSubOccurrence] = await client.createOccurrence(
        pubSubOccurrenceReq
      );
      // const pubSubOccurrenceId = pubSubOccurrence.name.split("/")[3];
      await client.deleteOccurrence({name: pubSubOccurrence.name});
    }
    const output = execSync(
      `node occurrencePubSub.js "${projectId}" "${subscriptionId}" "${timeoutSeconds}"`
    );

    // make sure pubsub number matches
    assert.match(output, new RegExp(`Polled ${expectedNum} occurrences`));
  });
});
<commit_msg>grabs projectId from client, update projectId and vars the refer to it in before hooks, added uuid to test resourceUrl<commit_after>const {assert} = require('chai');
const cp = require('child_process');
const uuid = require(`uuid`);

const grafeas = require('@google-cloud/grafeas');
const client = new grafeas.v1.GrafeasClient();

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const uuidVal = uuid.v4();
const noteId = `test-note-${uuidVal}`;
const resourceUrl = `gcr.io/test-project/test-image-${uuidVal}`;
const subscriptionId = `occurrence-subscription-${uuidVal}`;
const timeoutSeconds = 5;

const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub();
const topicName = 'container-analysis-occurrences-v1beta1';
const topic = pubsub.topic(topicName);

let projectId;
let formattedParent;
let formattedNoteName;

describe('Note tests', function() {
  before(async function() {
    // define projectId and related vars
    projectId = await client.getProjectId();
    formattedParent = `projects/${projectId}`;
    formattedNoteName = `projects/${projectId}/notes/${noteId}`;
  });
  after(async function() {
    const [allOccurrences] = await client.listOccurrences({
      parent: formattedParent,
      filter: `resourceUrl = "${resourceUrl}"`,
    });

    allOccurrences.forEach(async occurrence => {
      await client.deleteOccurrence({name: occurrence.name});
      console.log(`deleted occurrence ${occurrence.name}`);
    });

    const [allNotes] = await client.listNotes({
      parent: formattedParent,
    });

    allNotes.forEach(async note => {
      await client.deleteNote({name: note.name});
      console.log(`deleted note ${note.name}`);
    });
  });
  it('should create a note', function() {
    const output = execSync(`node createNote.js "${projectId}" "${noteId}"`);
    assert.match(output, new RegExp(`Note ${formattedNoteName} created.`));
  });

  it('should get note', function() {
    const output = execSync(`node getNote.js "${projectId}" "${noteId}"`);
    assert.match(output, new RegExp(`Note name: ${formattedNoteName}`));
  });

  it('should create occurrence', function() {
    const output = execSync(
      `node createOccurrence.js "${projectId}" "${noteId}" "${projectId}" "${resourceUrl}"`
    );
    assert.match(output, new RegExp(`Occurrence created`));
  });

  // TODO: sometimes fails, should try again if no images are found
  it('should get occurrence', async function() {
    const [occurrences] = await client.listOccurrences({
      parent: formattedParent,
    });
    assert(occurrences.length > 0);

    const occurrence = occurrences[0];
    const occurrenceId = occurrence.name.split('/')[3];
    const output = execSync(
      `node getOccurrence.js "${projectId}" "${occurrenceId}"`
    );
    assert.match(output, new RegExp(`Occurrence name: ${occurrence.name}`));
  });

  it('should get occurences for note', function() {
    const output = execSync(
      `node occurrencesForNote.js "${projectId}" "${noteId}"`
    );
    assert.match(output, /Occurrences:/);
  });

  it('should get occurrences for image', function() {
    const output = execSync(
      `node occurrencesForImage.js "${projectId}" "${resourceUrl}"`
    );
    assert.match(output, new RegExp(`Occurrences for ${resourceUrl}`));
  });

  it('should get discovery info for image', async function() {
    const discoveryNoteRequest = {
      parent: formattedParent,
      noteId: `${noteId}-discovery`,
      note: {
        discovery: {},
      },
    };

    await client.createNote(discoveryNoteRequest);

    const occurrenceRequest = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-discovery`,
        discovered: {
          discovered: {
            analysisStatus: 'FINISHED_SUCCESS',
          },
        },
        resource: {
          uri: resourceUrl,
        },
      },
    };

    await client.createOccurrence(occurrenceRequest);

    const output = execSync(
      `node getDiscoveryInfo "${projectId}" "${resourceUrl}"`
    );
    assert.match(
      output,
      new RegExp(`Discovery Occurrences for ${resourceUrl}`)
    );
  });

  it('should get high severity vulnerabilities for image', async function() {
    const criticalNoteReq = {
      parent: formattedParent,
      noteId: `${noteId}-critical`,
      note: {
        vulnerability: {
          severity: 'CRITICAL',
        },
      },
    };

    await client.createNote(criticalNoteReq);

    const criticalOccurrenceReq = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-critical`,
        vulnerability: {
          vulnerability: {
            severity: 'CRITICAL',
          },
        },
        resource: {
          uri: resourceUrl,
        },
      },
    };

    await client.createOccurrence(criticalOccurrenceReq);

    const output = execSync(
      `node highVulnerabilitiesForImage "${projectId}" "${resourceUrl}"`
    );

    assert.match(
      output,
      new RegExp(`High Severity Vulnerabilities for ${resourceUrl}`)
    );
  });

  it('should get all vulnerabilites for image', function() {
    const output = execSync(
      `node vulnerabilityOccurrencesForImage "${projectId}" "${resourceUrl}"`
    );
    assert.match(output, new RegExp(`All Vulnerabilities for ${resourceUrl}`));
  });

  it('should delete occurrence', async function() {
    const [occurrences] = await client.listOccurrences({
      parent: formattedParent,
    });
    assert(occurrences.length > 0);
    const occurrence = occurrences[0];
    const occurrenceId = occurrence.name.split('/')[3];

    const output = execSync(
      `node deleteOccurrence.js "${projectId}" "${occurrenceId}"`
    );
    assert.match(output, new RegExp(`Occurrence deleted.`));
  });
  it('should delete note', function() {
    const output = execSync(`node deleteNote.js "${projectId}" "${noteId}" `);
    assert.match(output, new RegExp(`Note ${formattedNoteName} deleted.`));
  });
});

// TODO:
xdescribe('polling', function() {
  before(async function() {
    // define project id and related vars
    projectId = await client.getProjectId();
    formattedParent = `projects/${projectId}`;
    formattedNoteName = `projects/${projectId}/notes/${noteId}`;

    const discoveryNoteRequest = {
      parent: formattedParent,
      noteId: `${noteId}-discovery-polling`,
      note: {
        discovery: {
          continuousAnalysis: 'INACTIVE',
        },
      },
    };

    await client.createNote(discoveryNoteRequest);

    const occurrenceRequest = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-discovery-polling`,
        discovered: {
          discovered: {
            analysisStatus: 'FINISHED_SUCCESS',
          },
        },
      },
      resource: {
        uri: resourceUrl,
      },
    };

    await client.createOccurrence(occurrenceRequest);
  });

  after(async function() {
    const [discoveryOccurrences] = await client.listNoteOccurrences({
      name: `${formattedNoteName}-discovery-polling`,
    });
    discoveryOccurrences.forEach(async occurrence => {
      await client.deleteOccurrence({name: occurrence.name});
    });
    await client.deleteNote({name: `${formattedNoteName}-discovery-polling`});
  });
  // it('should poll api until timeout', function() {
  //     const output = execSync(`node pollDiscoveryOccurrenceFinished.js "${projectId}" "${urlWithoutOccurrences}" "${timeoutSeconds}"`);
  //     assert.match(
  //         output,
  //         new RegExp(`'Timeout while retrieving discovery occurrence.`)
  //     );
  // });

  it('should successfully poll latest discovery occurrence', function() {
    const output = execSync(
      `node pollDiscoveryOccurrenceFinished.js "${projectId}" "${resourceUrl}" "${timeoutSeconds}"`
    );
    assert.match(
      output,
      new RegExp(`Polled Discovery Occurrences for ${resourceUrl}`)
    );
  });
});

describe('pubsub', function() {
  before(async function() {
    // define project id and related vars
    projectId = await client.getProjectId();
    formattedParent = `projects/${projectId}`;
    formattedNoteName = `projects/${projectId}/notes/${noteId}`;
  });

  beforeEach(async function() {
    await topic.createSubscription(subscriptionId);
    const pubSubNoteReq = {
      parent: formattedParent,
      noteId: `${noteId}-pubsub`,
      note: {
        vulnerability: {},
      },
    };
    await client.createNote(pubSubNoteReq);
  });

  afterEach(async function() {
    await client.deleteNote({name: `${formattedNoteName}-pubsub`});
    await pubsub.subscription(subscriptionId).delete();
  });

  it('should get accurate count of occurrences from pubsub topic', async function() {
    const expectedNum = 3;
    const pubSubOccurrenceReq = {
      parent: formattedParent,
      occurrence: {
        noteName: `${formattedNoteName}-pubsub`,
        vulnerability: {
          vulnerability: {},
        },
        resource: {
          uri: resourceUrl,
        },
      },
    };

    // empty subscription
    execSync(
      `node occurrencePubSub.js "${projectId}" "${subscriptionId}" "${timeoutSeconds}"`
    );

    // make sure empty
    const empty = execSync(
      `node occurrencePubSub.js "${projectId}" "${subscriptionId}" "${timeoutSeconds}"`
    );

    assert.match(empty, new RegExp(`Polled 0 occurrences`));
    // create test occurrences
    for (let i = 0; i < expectedNum; i++) {
      const [pubSubOccurrence] = await client.createOccurrence(
        pubSubOccurrenceReq
      );
      // const pubSubOccurrenceId = pubSubOccurrence.name.split("/")[3];
      await client.deleteOccurrence({name: pubSubOccurrence.name});
    }
    const output = execSync(
      `node occurrencePubSub.js "${projectId}" "${subscriptionId}" "${timeoutSeconds}"`
    );

    // make sure pubsub number matches
    assert.match(output, new RegExp(`Polled ${expectedNum} occurrences`));
  });
});
<|endoftext|>


<commit_before>export default function(tx, file, context) {
  let mimeData = file.type.split('/')
  let fig = tx.createElement('fig')
  let path = context.archive.createFile(file)
  fig.append(
   tx.createElement('object-id').text(fig.id),
   tx.createElement('title').text('Figure title'),
   tx.createElement('caption').append(
     tx.createElement('p').text('Figure caption')
   ),
   tx.createElement('graphic').attr({
     'mime-subtype': mimeData[1],
     'mimetype': mimeData[0],
     'xlink:href': path
   })
  )
  return fig
}
<commit_msg>Rely on placeholders instead of default texts.<commit_after>export default function(tx, file, context) {
  let mimeData = file.type.split('/')
  let fig = tx.createElement('fig')
  let path = context.archive.createFile(file)
  fig.append(
   tx.createElement('object-id').text(fig.id),
   tx.createElement('title'),
   tx.createElement('caption').append(
     tx.createElement('p')
   ),
   tx.createElement('graphic').attr({
     'mime-subtype': mimeData[1],
     'mimetype': mimeData[0],
     'xlink:href': path
   })
  )
  return fig
}
<|endoftext|>


<commit_before>(function(global) {

  "use strict";

  var fabric = global.fabric || (global.fabric = { });

  var utilMin = fabric.util.array.min,
      utilMax = fabric.util.array.max;

  if (fabric.FreeDrawing) {
    fabric.warn('fabric.FreeDrawing is already defined');
    return;
  }

  fabric.FreeDrawing = fabric.util.createClass({

    /**
     * Free Drawer handles scribbling on a fabricCanvas.
     * It converts the hand writting to a SVG Path and adds this
     * path to the canvas.
     *
     * @metod init
     * @param fabricCanvas {FabricCanvas}
     *
     */
    initialize: function(fabricCanvas) {
      this.canvas = fabricCanvas;
      this._points = [];
    },

    /**
     * @private
     * @method _addPoint
     *
     */
    _addPoint: function(point) {
      this._points.push(point);
    },

    /**
     * Clear points array and set contextTop canvas
     * style.
     *
     * @private
     * @method _reset
     *
     */
    _reset: function() {
      this._points.length = 0;
      var ctx = this.canvas.contextTop;

      // set freehanddrawing line canvas parameters
      ctx.strokeStyle = this.canvas.freeDrawingColor;
      ctx.lineWidth = this.canvas.freeDrawingLineWidth;
      ctx.lineCap = ctx.lineJoin = 'round';
    },

     /**
     * @method _prepareForDrawing
     */
     _prepareForDrawing: function(pointer) {

      this.canvas._isCurrentlyDrawing = true;
      this.canvas.discardActiveObject().renderAll();

      var p = new fabric.Point(pointer.x, pointer.y);
      this._reset();
      this._addPoint(p);
      this.canvas.contextTop.moveTo(p.x, p.y);
    },

    /**
     * @private
     * @method _captureDrawingPath
     *
     * @param point {pointer} (fabric.util.pointer) actual mouse position
     *   related to the canvas.
     */
    _captureDrawingPath: function(pointer) {
      var pointerPoint = new fabric.Point(pointer.x, pointer.y);
      this._addPoint(pointerPoint);
    },

    /**
     * Draw a smooth path on the topCanvas using
     * quadraticCurveTo.
     *
     * @private
     * @method _render
     *
     */
    _render: function() {
      var ctx  = this.canvas.contextTop;
      ctx.beginPath();

      var p1 = this._points[0];
      var p2 = this._points[1];

      ctx.moveTo(p1.x, p1.y);

      for (var i = 1, len = this._points.length; i < len; i++) {
        // we pick the point between pi+1 & pi+2 as the
        // end point and p1 as our control point.
        var midPoint = p1.midPointFrom(p2);
        ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);

        p1 = this._points[i];
        p2 = this._points[i+1];
      }
      // Draw last line as a straight line while
      // we wait for the next point to be able to calculate
      // the bezier control point
      ctx.lineTo(p1.x, p1.y);
      ctx.stroke();
    },

    /**
     * Return an SVG path based on our
     * captured points and their boundinb box.
     *
     * @private
     * @method _getSVGPathData
     *
     */
    _getSVGPathData: function() {
      this.box = this.getPathBoundingBox(this._points);
      return this.convertPointsToSVGPath(
        this._points, this.box.minx, this.box.maxx, this.box.miny, this.box.maxy);
     },

     /**
     * @method getPathBoundingBox
     * @param points {Array of points}
     */
     getPathBoundingBox: function(points) {
      var xBounds = [],
          yBounds = [],
          p1 = points[0],
          p2 = points[1],
          startPoint = p1;

      for (var i = 1, len = points.length; i < len; i++) {
        var midPoint = p1.midPointFrom(p2);
        // with startPoint, p1 as control point, midpoint as end point
        xBounds.push(startPoint.x);
        xBounds.push(midPoint.x);
        yBounds.push(startPoint.y);
        yBounds.push(midPoint.y);

        p1 = points[i];
        p2 = points[i+1];
        startPoint = midPoint;
     } // end for

     xBounds.push(p1.x);
     yBounds.push(p1.y);

     return {
       minx: utilMin(xBounds),
       miny: utilMin(yBounds),
       maxx: utilMax(xBounds),
       maxy: utilMax(yBounds)
     };
    },

   /**
     * @method convertPointsToSVGPath
     * @param points {Array of points}
     */
    convertPointsToSVGPath: function(points, minX, maxX, minY, maxY) {
      var path = [];
      var p1 = new fabric.Point(points[0].x - minX, points[0].y - minY);
      var p2 = new fabric.Point(points[1].x - minX, points[1].y - minY);

      path.push('M ', points[0].x - minX, ' ', points[0].y - minY, ' ');
      for (var i = 1, len = points.length; i < len; i++) {
        var midPoint = p1.midPointFrom(p2);
        // p1 is our bezier control point
        // midpoint is our endpoint
        // start point is p(i-1) value.
        path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');
        p1 = new fabric.Point(points[i].x - minX, points[i].y - minY);
        if ((i+1) < points.length) {
          p2 = new fabric.Point(points[i+1].x - minX, points[i+1].y - minY);
        }
      }
      path.push('L ', p1.x, ' ', p1.y, ' ');
      return path;
    },

    /**
     * On mouseup after drawing the path on contextTop canvas
     * we use the points captured to create an new fabric path object
     * and add it to the fabric canvas.
     *
     * @method _finalizeAndAddPath
     *
     */

    _finalizeAndAddPath: function() {
      this.canvas._isCurrentlyDrawing = false;
      var ctx = this.canvas.contextTop;
      ctx.closePath();
      var path = this._getSVGPathData();
      path = path.join('');

      if (path === "M 0 0 Q 0 0 0 0 L 0 0") {
        // do not create 0 width/height paths, as they are
        // rendered inconsistently across browsers
        // Firefox 4, for example, renders a dot,
        // whereas Chrome 10 renders nothing
        this.canvas.renderAll();
        return;
      }

      var p = new fabric.Path(path);
      p.fill = null;
      p.stroke = this.canvas.freeDrawingColor;
      p.strokeWidth = this.canvas.freeDrawingLineWidth;
      this.canvas.add(p);

      // set path origin coordinates based on our bounding box
      var originLeft = this.box.minx  + (this.box.maxx - this.box.minx) /2;
      var originTop = this.box.miny  + (this.box.maxy - this.box.miny) /2;

      this.canvas.contextTop.arc(originLeft, originTop, 3, 0, Math.PI * 2);

      p.set({ left: originLeft, top: originTop });

      // does not change position
      p.setCoords();

      this.canvas.renderAll();

      // fire event 'path' created
      this.canvas.fire('path:created', { path: p });
    }
  });

})(typeof exports !== 'undefined' ? exports : this);
<commit_msg>Another freedrawing bug in Firefox 3.6.1 - 3.6.24<commit_after>(function(global) {

  "use strict";

  var fabric = global.fabric || (global.fabric = { });

  var utilMin = fabric.util.array.min,
      utilMax = fabric.util.array.max;

  if (fabric.FreeDrawing) {
    fabric.warn('fabric.FreeDrawing is already defined');
    return;
  }

  fabric.FreeDrawing = fabric.util.createClass({

    /**
     * Free Drawer handles scribbling on a fabricCanvas.
     * It converts the hand writting to a SVG Path and adds this
     * path to the canvas.
     *
     * @metod init
     * @param fabricCanvas {FabricCanvas}
     *
     */
    initialize: function(fabricCanvas) {
      this.canvas = fabricCanvas;
      this._points = [];
    },

    /**
     * @private
     * @method _addPoint
     *
     */
    _addPoint: function(point) {
      this._points.push(point);
    },

    /**
     * Clear points array and set contextTop canvas
     * style.
     *
     * @private
     * @method _reset
     *
     */
    _reset: function() {
      this._points.length = 0;
      var ctx = this.canvas.contextTop;

      // set freehanddrawing line canvas parameters
      ctx.strokeStyle = this.canvas.freeDrawingColor;
      ctx.lineWidth = this.canvas.freeDrawingLineWidth;
      ctx.lineCap = ctx.lineJoin = 'round';
    },

     /**
     * @method _prepareForDrawing
     */
     _prepareForDrawing: function(pointer) {

      this.canvas._isCurrentlyDrawing = true;
      this.canvas.discardActiveObject().renderAll();

      var p = new fabric.Point(pointer.x, pointer.y);
      this._reset();
      this._addPoint(p);
      this.canvas.contextTop.moveTo(p.x, p.y);
    },

    /**
     * @private
     * @method _captureDrawingPath
     *
     * @param point {pointer} (fabric.util.pointer) actual mouse position
     *   related to the canvas.
     */
    _captureDrawingPath: function(pointer) {
      var pointerPoint = new fabric.Point(pointer.x, pointer.y);
      this._addPoint(pointerPoint);
    },

    /**
     * Draw a smooth path on the topCanvas using
     * quadraticCurveTo.
     *
     * @private
     * @method _render
     *
     */
    _render: function() {
      var ctx  = this.canvas.contextTop;
      ctx.beginPath();

      var p1 = this._points[0];
      var p2 = this._points[1];

      ctx.moveTo(p1.x, p1.y);

      for (var i = 1, len = this._points.length; i < len; i++) {
        // we pick the point between pi+1 & pi+2 as the
        // end point and p1 as our control point.
        var midPoint = p1.midPointFrom(p2);
        ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);

        p1 = this._points[i];
        p2 = this._points[i+1];
      }
      // Draw last line as a straight line while
      // we wait for the next point to be able to calculate
      // the bezier control point
      ctx.lineTo(p1.x, p1.y);
      ctx.stroke();
    },

    /**
     * Return an SVG path based on our
     * captured points and their boundinb box.
     *
     * @private
     * @method _getSVGPathData
     *
     */
    _getSVGPathData: function() {
      this.box = this.getPathBoundingBox(this._points);
      return this.convertPointsToSVGPath(
        this._points, this.box.minx, this.box.maxx, this.box.miny, this.box.maxy);
     },

     /**
     * @method getPathBoundingBox
     * @param points {Array of points}
     */
     getPathBoundingBox: function(points) {
      var xBounds = [],
          yBounds = [],
          p1 = points[0],
          p2 = points[1],
          startPoint = p1;

      for (var i = 1, len = points.length; i < len; i++) {
        var midPoint = p1.midPointFrom(p2);
        // with startPoint, p1 as control point, midpoint as end point
        xBounds.push(startPoint.x);
        xBounds.push(midPoint.x);
        yBounds.push(startPoint.y);
        yBounds.push(midPoint.y);

        p1 = points[i];
        p2 = points[i+1];
        startPoint = midPoint;
     } // end for

     xBounds.push(p1.x);
     yBounds.push(p1.y);

     return {
       minx: utilMin(xBounds),
       miny: utilMin(yBounds),
       maxx: utilMax(xBounds),
       maxy: utilMax(yBounds)
     };
    },

   /**
     * @method convertPointsToSVGPath
     * @param points {Array of points}
     */
    convertPointsToSVGPath: function(points, minX, maxX, minY, maxY) {
      var path = [];
      var p1 = new fabric.Point(points[0].x - minX, points[0].y - minY);
      var p2 = new fabric.Point(points[1].x - minX, points[1].y - minY);

      path.push('M ', points[0].x - minX, ' ', points[0].y - minY, ' ');
      for (var i = 1, len = points.length; i < len; i++) {
        var midPoint = p1.midPointFrom(p2);
        // p1 is our bezier control point
        // midpoint is our endpoint
        // start point is p(i-1) value.
        path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');
        p1 = new fabric.Point(points[i].x - minX, points[i].y - minY);
        if ((i+1) < points.length) {
          p2 = new fabric.Point(points[i+1].x - minX, points[i+1].y - minY);
        }
      }
      path.push('L ', p1.x, ' ', p1.y, ' ');
      return path;
    },

    /**
     * On mouseup after drawing the path on contextTop canvas
     * we use the points captured to create an new fabric path object
     * and add it to the fabric canvas.
     *
     * @method _finalizeAndAddPath
     *
     */

    _finalizeAndAddPath: function() {
      this.canvas._isCurrentlyDrawing = false;
      var ctx = this.canvas.contextTop;
      ctx.closePath();
      var path = this._getSVGPathData();
      path = path.join('');

      if (path === "M 0 0 Q 0 0 0 0 L 0 0") {
        // do not create 0 width/height paths, as they are
        // rendered inconsistently across browsers
        // Firefox 4, for example, renders a dot,
        // whereas Chrome 10 renders nothing
        this.canvas.renderAll();
        return;
      }

      var p = new fabric.Path(path);
      p.fill = null;
      p.stroke = this.canvas.freeDrawingColor;
      p.strokeWidth = this.canvas.freeDrawingLineWidth;
      this.canvas.add(p);

      // set path origin coordinates based on our bounding box
      var originLeft = this.box.minx  + (this.box.maxx - this.box.minx) /2;
      var originTop = this.box.miny  + (this.box.maxy - this.box.miny) /2;

      this.canvas.contextTop.arc(originLeft, originTop, 3, 0, Math.PI * 2, false);

      p.set({ left: originLeft, top: originTop });

      // does not change position
      p.setCoords();

      this.canvas.renderAll();

      // fire event 'path' created
      this.canvas.fire('path:created', { path: p });
    }
  });

})(typeof exports !== 'undefined' ? exports : this);
<|endoftext|>


<commit_before>homeActivitiesData = function () {
  return Activities.find().fetch();
};

var optionsObject = {
  columns: [{
    title: 'Duration',
    data: 'duration',
    className: 'nameColumn'
  }]
};

Template.homeActivities.created = function () {
  // Get the home id from data context
  var homeId = this.data._id;

  // Subscribe to all activities for residents of this home
  this.subscribe('homeActivities', homeId);
};

Template.homeActivities.helpers({
  'homeActivitiesFunction': function () {
    return homeActivitiesData;
  },
  'options': function () {
    return optionsObject;
  }
});
<commit_msg>Map array of objects with duration.<commit_after>homeActivitiesData = function () {
  return Activities.find().fetch().map(function (activity) {
    return {
      duration: activity.duration
    }
  });
};

var optionsObject = {
  columns: [
    {
      title: 'Duration',
      data: 'duration',
      className: 'nameColumn'
    }
  ]
};

Template.homeActivities.created = function () {
  // Get the home id from data context
  var homeId = this.data._id;

  // Subscribe to all activities for residents of this home
  this.subscribe('homeActivities', homeId);
};

Template.homeActivities.helpers({
  'homeActivitiesFunction': function () {
    return homeActivitiesData;
  },
  'options': function () {
    return optionsObject;
  }
});
<|endoftext|>


<commit_before>/* global window, $, marked, vex, ace, UsageButton, preview, document, location */

$(() => {
  const editor = ace.edit('markdown_editor');
  const aceSession = editor.getSession();

  const md2html = () => {
    const markdownContent = editor.getValue();
    const markdownSlides = markdownContent.split(/={5,}/);
    const $preview = $('.preview');

    $preview.html('');
    markdownSlides.forEach((v, i) => {
      $preview.append(`<div class="callout secondary slide data-slide-${i}">${marked(v)}</div>`);
    });

    document.getElementById('id_markdown').value = editor.getValue();
  };

 /* $('#create_html').submit((e) => {
    const subject = $('#id_subject').val();
    const isPublic = document.querySelector('#id_is_public').checked;
    const slideList = editor.getValue().split(/={5,}/g).map((v, i) => ({
      slide_order: i,
      markdown: v.trim(),
      html: marked(v.trim()),
    }));

    const presentation = {
      subject,
      is_public: isPublic,
      slide_list: slideList,
    };

    $.ajax({
      url: 'create',
      method: 'POST',
      data: presentation,
    }).done(() => {
      // location.href = '/';
    }).error((xhr, st, err) => {
      console.log(xhr);
      console.error(err);
    });

    e.preventDefault();
  });
*/
  const usageButton = new UsageButton();
  usageButton.init();

  editor.setTheme('ace/theme/chrome');
  aceSession.setMode('ace/mode/markdown_warp');
  editor.renderer.setShowGutter(false);
  editor.on('change', md2html);
  editor.on('changeSelection', () => {
    preview.syncWithEditorCaret(editor);
  });
});
<commit_msg>Update index.js<commit_after>/* global window, $, marked, vex, ace, UsageButton, preview, document, location */

$(() => {
  const editor = ace.edit('markdown_editor');
  const aceSession = editor.getSession();

  const md2html = () => {
    const markdownContent = editor.getValue();
    const markdownSlides = markdownContent.split(/={5,}/);
    const $preview = $('.preview');

    $preview.html('');
    markdownSlides.forEach((v, i) => {
      $preview.append(`<div class="callout secondary slide data-slide-${i}">${marked(v)}</div>`);
    });

    document.getElementById('id_markdown').value = editor.getValue();
  };

  const usageButton = new UsageButton();
  usageButton.init();

  editor.setTheme('ace/theme/chrome');
  aceSession.setMode('ace/mode/markdown_warp');
  editor.renderer.setShowGutter(false);
  editor.on('change', md2html);
  editor.on('changeSelection', () => {
    preview.syncWithEditorCaret(editor);
  });
});
<|endoftext|>


<commit_before>	'use strict';

	$("#barreJ4-1").mouseup(function(e){
		document.getElementById("Budget").value=200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		var echelle =200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		if(echelle<0){
			echelle=0;
		}
		document.getElementById("div1").style.transform = 'scale(' + echelle/200000 + ')';
		if(document.getElementById("barreJ4-1").value==1){
			$(".MaisonJ4-1").fadeIn("slow");
			$(".MaisonJ4-2").fadeOut("slow");
			$(".MaisonJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-1").value==2){
			$(".MaisonJ4-1").fadeIn("slow");
			$(".MaisonJ4-2").fadeOut("slow");
			$(".MaisonJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-1").value==3){
			$(".MaisonJ4-1").fadeIn("slow");
			$(".MaisonJ4-2").fadeIn("slow");
			$(".MaisonJ4-3").fadeIn("slow");
		}

	});

	$("#barreJ4-2").mouseup(function(e){
		document.getElementById("Budget").value=200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		var echelle =200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		if(echelle<0){
			echelle=0;
		}
		document.getElementById("div1").style.transform = 'scale(' + echelle/200000 + ')';
		if(document.getElementById("barreJ4-2").value==1){
			$(".DigueJ4-1").fadeIn("slow");
			$(".DigueJ4-2").fadeOut("slow");
			$(".DigueJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-2").value==2){
			$(".DigueJ4-1").fadeIn("slow");
			$(".DigueJ4-2").fadeOut("slow");
			$(".DigueJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-2").value==3){
			$(".DigueJ4-1").fadeIn("slow");
			$(".DigueJ4-2").fadeIn("slow");
			$(".DigueJ4-3").fadeIn("slow");
		}
	});<commit_msg>Test pour bouton Jeu4<commit_after>	'use strict';

	$("#barreJ4-1").mouseup(function(e){
		document.getElementById("Budget").value=200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		var echelle =200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		if(echelle<0){
			echelle=0;
		}
		document.getElementById("div1").style.transform = 'scale(' + echelle/200000 + ')';
		if(document.getElementById("barreJ4-1").value==1){
			$(".MaisonJ4-1").fadeIn("slow");
			$(".MaisonJ4-2").fadeOut("slow");
			$(".MaisonJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-1").value==2){
			$(".MaisonJ4-1").fadeIn("slow");
			$(".MaisonJ4-2").fadeOut("slow");
			$(".MaisonJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-1").value==3){
			$(".MaisonJ4-1").fadeIn("slow");
			$(".MaisonJ4-2").fadeIn("slow");
			$(".MaisonJ4-3").fadeIn("slow");
		}

	});

	$("#barreJ4-2").mouseup(function(e){
		document.getElementById("Budget").value=200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		var echelle =200000-document.getElementById("barreJ4-1").value*80000+document.getElementById("barreJ4-2").value*50000;
		if(echelle<0){
			echelle=0;
		}
		document.getElementById("div1").style.transform = 'scale(' + echelle/200000 + ')';
		if(document.getElementById("barreJ4-2").value==1){
			$(".DigueJ4-1").fadeIn("slow");
			$(".DigueJ4-2").fadeOut("slow");
			$(".DigueJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-2").value==2){
			$(".DigueJ4-1").fadeIn("slow");
			$(".DigueJ4-2").fadeOut("slow");
			$(".DigueJ4-3").fadeOut("slow");
		}
		else if(document.getElementById("barreJ4-2").value==3){
			$(".DigueJ4-1").fadeIn("slow");
			$(".DigueJ4-2").fadeIn("slow");
			$(".DigueJ4-3").fadeIn("slow");
		}
	});

	$("#vague").click(function(e){
		var rand = Math.floor((Math.random() * 10) + 1);
		if(rand<3){
			alert("inf3");
		}
		if(rand>=3 && rand<=6){
			alert("3-6");
		}
		if(rand>=7){
			alert("sup6");
		}
	});<|endoftext|>


<commit_before>// Common webpack configuration for server bundle

const webpack = require('webpack')
const path = require('path')

const devBuild = process.env.NODE_ENV !== 'production'
const nodeEnv = devBuild ? 'development' : 'production'

module.exports = {

  // the project dir
  context: __dirname,
  entry: [
    'react',
    'react-dom/server',
    './js/startup/serverGlobals'
  ],
  output: {
    filename: 'server-bundle.js',
    path: '../app/assets/webpack'
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],
    alias: {
      actions: path.join(process.cwd(), 'js', 'actions'),
      components: path.join(process.cwd(), 'js', 'components'),
      constants: path.join(process.cwd(), 'js', 'constants'),
      containers: path.join(process.cwd(), 'js', 'containers'),
      libs: path.join(process.cwd(), 'js', 'libs'),
      reducers: path.join(process.cwd(), 'js', 'reducers'),
      store: path.join(process.cwd(), 'js', 'store'),
      routes: path.join(process.cwd(), 'js', 'routes'),
      layouts: path.join(process.cwd(), 'js', 'layouts'),
      pages: path.join(process.cwd(), 'js', 'pages')
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(nodeEnv)
      }
    })
  ],
  module: {
    loaders: [
      { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
      {
        test: /\.css$/,
        loaders: [
          'css/locals?modules&importLoaders=0&localIdentName=[name]__[local]__[hash:base64:5]'
        ]
      },
      {
        test: /\.scss$/,
        loaders: [
          'css/locals?modules&importLoaders=2&localIdentName=[name]__[local]__[hash:base64:5]',
          'sass',
          'sass-resources'
        ]
      },
      { test: /\.(woff2?|svg)$/, loader: 'url?limit=10000' },
      { test: /\.(ttf|eot)$/, loader: 'file' },
      { test: /\.(jpe?g|png|gif|svg|ico)$/, loader: 'url?limit=10000' },

      // React is necessary for the client rendering:
      { test: require.resolve('react'), loader: 'expose?React' },
      { test: require.resolve('react-dom/server'), loader: 'expose?ReactDOMServer' }
    ]
  },

  sassResources: ['./css/app-variables.scss']

}
<commit_msg>Updated webpack server rails to exclude cp -rf font files<commit_after>// Common webpack configuration for server bundle

const webpack = require('webpack')
const path = require('path')

const devBuild = process.env.NODE_ENV !== 'production'
const nodeEnv = devBuild ? 'development' : 'production'

module.exports = {

  // the project dir
  context: __dirname,
  entry: [
    'react',
    'react-dom/server',
    './js/startup/serverGlobals'
  ],
  output: {
    filename: 'server-bundle.js',
    path: '../app/assets/webpack'
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],
    alias: {
      actions: path.join(process.cwd(), 'js', 'actions'),
      components: path.join(process.cwd(), 'js', 'components'),
      constants: path.join(process.cwd(), 'js', 'constants'),
      containers: path.join(process.cwd(), 'js', 'containers'),
      libs: path.join(process.cwd(), 'js', 'libs'),
      reducers: path.join(process.cwd(), 'js', 'reducers'),
      store: path.join(process.cwd(), 'js', 'store'),
      routes: path.join(process.cwd(), 'js', 'routes'),
      layouts: path.join(process.cwd(), 'js', 'layouts'),
      pages: path.join(process.cwd(), 'js', 'pages')
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(nodeEnv)
      }
    })
  ],
  module: {
    loaders: [
      { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
      {
        test: /\.css$/,
        loaders: [
          'css/locals?modules&importLoaders=0&localIdentName=[name]__[local]__[hash:base64:5]'
        ]
      },
      {
        test: /\.scss$/,
        loaders: [
          'css/locals?modules&importLoaders=2&localIdentName=[name]__[local]__[hash:base64:5]',
          'sass',
          'sass-resources'
        ]
      },
      // { test: /\.(woff2?|svg)$/, loader: 'url?limit=10000' },
      // { test: /\.(ttf|eot)$/, loader: 'file' },
      // { test: /\.(jpe?g|png|gif|svg|ico)$/, loader: 'url?limit=10000' },

      // React is necessary for the client rendering:
      { test: require.resolve('react'), loader: 'expose?React' },
      { test: require.resolve('react-dom/server'), loader: 'expose?ReactDOMServer' }
    ]
  },

  sassResources: ['./css/app-variables.scss']

}
<|endoftext|>


<commit_before>module.exports = function(RED){

  console.log('registering comment node client code');

  RED.nodes.registerType('comment',{
    category: 'function',
    color:"#ffffff",
    defaults: {
      name: {value:""},
      info: {value:""}
    },
    inputs:0,
    outputs:0,
    icon: "comment.png",
    label: function() {
      return this.name||"";
    },
    labelStyle: function() {
      return this.name?"node_label_italic":"";
    },
    info: function() {
      return (this.name?"# "+this.name+"\n":"")+(this.info||"");
    },
    oneditprepare: function() {
      var that = this;
      $( "#node-input-outputs" ).spinner({
        min:1
      });
      function functionDialogResize() {
        var rows = $("#dialog-form>div:not(.node-text-editor-row)");
        var height = $("#dialog-form").height();
        for (var i=0;i<rows.size();i++) {
          height -= $(rows[i]).outerHeight(true);
        }
        var editorRow = $("#dialog-form>div.node-text-editor-row");
        height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
        $(".node-text-editor").css("height",height+"px");
        that.editor.resize();
      };
      $( "#dialog" ).on("dialogresize", functionDialogResize);
      $( "#dialog" ).one("dialogopen", function(ev) {
        var size = $( "#dialog" ).dialog('option','sizeCache-function');
        if (size) {
          $("#dialog").dialog('option','width',size.width);
          $("#dialog").dialog('option','height',size.height);
          functionDialogResize();
        }
      });
      $( "#dialog" ).one("dialogclose", function(ev,ui) {
        var height = $( "#dialog" ).dialog('option','height');
        $( "#dialog" ).off("dialogresize",functionDialogResize);
      });
      this.editor = RED.editor.createEditor({
        id: 'node-input-info-editor',
        mode: 'ace/mode/markdown',
        value: $("#node-input-info").val()
      });
      this.editor.focus();
    },
    oneditsave: function() {
      $("#node-input-info").val(this.editor.getValue());
      delete this.editor;
    },
    render: function(){
      return (

              <input type="text" id="node-input-name"/>

              <input type="hidden" id="node-input-info" autofocus="autofocus"/>

);
    },
    renderHelp: function(){
      return (
A node you can use to add comments to your flows.
);
    }
  });

};
<commit_msg>fixing comment nodes console.log<commit_after>module.exports = function(RED){

  RED.nodes.registerType('comment',{
    category: 'function',
    color:"#ffffff",
    defaults: {
      name: {value:""},
      info: {value:""}
    },
    inputs:0,
    outputs:0,
    icon: "comment.png",
    label: function() {
      return this.name||"";
    },
    labelStyle: function() {
      return this.name?"node_label_italic":"";
    },
    info: function() {
      return (this.name?"# "+this.name+"\n":"")+(this.info||"");
    },
    oneditprepare: function() {
      var that = this;
      $( "#node-input-outputs" ).spinner({
        min:1
      });
      function functionDialogResize() {
        var rows = $("#dialog-form>div:not(.node-text-editor-row)");
        var height = $("#dialog-form").height();
        for (var i=0;i<rows.size();i++) {
          height -= $(rows[i]).outerHeight(true);
        }
        var editorRow = $("#dialog-form>div.node-text-editor-row");
        height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
        $(".node-text-editor").css("height",height+"px");
        that.editor.resize();
      };
      $( "#dialog" ).on("dialogresize", functionDialogResize);
      $( "#dialog" ).one("dialogopen", function(ev) {
        var size = $( "#dialog" ).dialog('option','sizeCache-function');
        if (size) {
          $("#dialog").dialog('option','width',size.width);
          $("#dialog").dialog('option','height',size.height);
          functionDialogResize();
        }
      });
      $( "#dialog" ).one("dialogclose", function(ev,ui) {
        var height = $( "#dialog" ).dialog('option','height');
        $( "#dialog" ).off("dialogresize",functionDialogResize);
      });
      this.editor = RED.editor.createEditor({
        id: 'node-input-info-editor',
        mode: 'ace/mode/markdown',
        value: $("#node-input-info").val()
      });
      this.editor.focus();
    },
    oneditsave: function() {
      $("#node-input-info").val(this.editor.getValue());
      delete this.editor;
    },
    render: function(){
      return (

              <input type="text" id="node-input-name"/>

              <input type="hidden" id="node-input-info" autofocus="autofocus"/>

);
    },
    renderHelp: function(){
      return (
A node you can use to add comments to your flows.
);
    }
  });

};
<|endoftext|>


<commit_before>
// To be called before any request that requires user be logged in.
// Action: redirects to user login page, then returns to redirectUrl.
// Args: String redirectUrl defaults to the page function was called form.
function confirmUserAndRedirect(redirectUrl) {
  if (!redirectUrl) {
    redirectUrl = window.location.href;
  }

  fetch(`/login?redirectUrl=${redirectUrl}`).then(response => response.json()).then(json => {
      window.location.replace(json.loginLink);
  });
}

function userLoggedIn() {
  fetch("/user-status").then(response => response.json()).then(userInfo => {
    return userInfo.isUserLoggedIn;
  });
}

// Action: requests logout .
// Args: optional string "redirectUrl" determines location after logout.
//       defaults to index.html.

function logout(redirectUrl) {
  if (!redirectUrl) {
      redirectUrl = "/index.html";
  }

  fetch(`/logout?redirectUrl=${redirectUrl}`).then(response => response.json()).then(json => {
    window.location.replace(json.logoutLink);
  });
}

// sign out with google sign in API
function signOut() {
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () {
        console.log('User signed out.');
        // Disable user options dropdown menu on sign out.
        const dropdown = document.querySelector(".dropdown");
        dropdown.removeEventListener("mouseover", showDropdown);
        dropdown.removeEventListener("mouseleave", hideDropdown);
        dropdown.querySelector(".dropdown-content").style.display = "none";
    });
}

// In case of successfull sign in
function onSignIn() {
    console.log("login success");
    // allows display of user options dropdown menu, only when signed in.
    const dropdown = document.querySelector(".dropdown");
    dropdown.addEventListener("mouseover", showDropdown = function() {
        dropdown.querySelector(".dropdown-content").style.display = "block";
    });
    dropdown.addEventListener("mouseleave", hideDropdown = function() {
        dropdown.querySelector(".dropdown-content").style.display = "none";
    });
    // adds current user name to dropdown
    var auth2 = gapi.auth2.getAuthInstance();
    const userPageAnchor = document.getElementById("user-page-anchor");
    let text = auth2.currentUser.get().getBasicProfile().getGivenName() + "'s Page";
    userPageAnchor.innerText = text;
}

<commit_msg>full g-signin user box with dropdown<commit_after>var auth2;

function onStart() {
  console.log("onstart");
  gapi.load('auth2', initSigninV2);
}

/**
 * initializes google authentication API and sets event listeners.
 */
function initSigninV2() {
  auth2 = gapi.auth2.init({
    client_id : '1034390229233-u07o0iaas2oql8l4jhe7fevpfsbrtv7n.apps.googleusercontent.com'
  });

  auth2.currentUser.listen(function(newGoogleUser) {
    insertUserInfo(newGoogleUser);
  });

  auth2.isSignedIn.listen(function(signedIn) {
    if (signedIn) {
      console.log('enable dropdown');
      enableUserDropdown();
    } else {
      console.log('disable dropdown');
      disableUserDropdown();
    }
  });
}

/**
 * returns a promise that resolves when user signs in,
 * or rejects if user does not sign in.
 * currently doesn't work because auth2.signin resolves before signin is complete
 * for some reason.
 */
function confirmUser() {
  return new Promise((resolve, reject) => {
      if (!auth2.isSignedIn.get()) {
          auth2.signIn().then(resolve()).catch(reject());
      } else {
          console.log("already done");
          resolve();
      }
  })
}

/**
 * signs our current user from g-signin API.
 */
function signOut() {
  auth2.signOut().then(function () {
      console.log('User signed out.');
  });
}

/**
 * To be run in currentUser listener, activates whenever current user changes.
 *
 * @param {GoogleUser} current user to provide profile info.
 */
function insertUserInfo(googleUser) {
  // insert user name into user-page anchor
  let text = googleUser.getBasicProfile().getGivenName() + '\'s Page';
  const userPageAnchor = document.getElementById('user-page-anchor');
  userPageAnchor.innerText = text;
}

function enableUserDropdown() {
  const dropdown = document.querySelector('.dropdown');
  dropdown.addEventListener('mouseover', showDropdown = function() {
    dropdown.querySelector('.dropdown-content').style.display = 'block';
  });
  dropdown.addEventListener('mouseleave', hideDropdown = function() {
    dropdown.querySelector('.dropdown-content').style.display = 'none';
  });
}

function disableUserDropdown() {
  const dropdown = document.querySelector('.dropdown');
  dropdown.removeEventListener('mouseover', showDropdown);
  dropdown.removeEventListener('mouseleave', hideDropdown);
  dropdown.querySelector('.dropdown-content').style.display = 'none';
}<|endoftext|>


<commit_before>function load_document (url, more_urls) {
    'use strict';
    // $('#loader-report').append ("
Loading " + url + "
");
    $.ajax({
        url: 'load-document.xqy?url=' + url,
        // async: false,
        // dataType: 'html'
    }).done(function (data) {
        $('#loader-report').append (data);
        $('#loader-report').trigger ('create');
    }).fail(function(xhr, status, error) {
        $('#loader-report').append ("
An error occurred: " + error + "
");
    }).always(function(){
        if (more_urls.length > 0) {
            load_document (more_urls.shift(), more_urls);
        }
    });
}
<commit_msg>added error message detail<commit_after>function load_document (url, more_urls) {
    'use strict';
    // $('#loader-report').append ("
Loading " + url + "
");
    $.ajax({
        url: 'load-document.xqy?url=' + url,
        // async: false,
        // dataType: 'html'
    }).done(function (data) {
        $('#loader-report').append (data);
        $('#loader-report').trigger ('create');
    }).fail(function(xhr, status, error) {
        $('#loader-report').append
        ("
An error occurred while loading'" +
         url
         + "': " + error + "
");
    }).always(function(){
        if (more_urls.length > 0) {
            load_document (more_urls.shift(), more_urls);
        }
    });
}
<|endoftext|>


<commit_before>import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import config from '../../config';
import _debug from 'debug';

const debug = _debug('app:webpack:production');

export default (webpackConfig) => {
  debug('Create configuration.');

  if (config.compiler_source_maps) {
    debug('Source maps enabled for production.');
    webpackConfig.devtool = 'source-map';
  } else {
    debug('Source maps are disabled in production.');
  }

  debug('Apply ExtractTextPlugin to CSS loaders.');
  webpackConfig.module.loaders = webpackConfig.module.loaders.map(loader => {
    if (!loader.loaders ||
        !loader.loaders.find(name => /css/.test(name.split('?')[0]))) {
      return loader;
    }

    const [first, ...rest] = loader.loaders;
    loader.loader = ExtractTextPlugin.extract(first, rest.join('!'));
    delete loader.loaders;

    return loader;
  });

  debug('Inject ExtractText and UglifyJS plugins.');
  webpackConfig.plugins.push(
    new ExtractTextPlugin('[name].[contenthash].css', {
      allChunks: true
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        unused: true,
        dead_code: true
      }
    })
  );

  return webpackConfig;
};
<commit_msg>disable uglifyJs warnings<commit_after>import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import config from '../../config';
import _debug from 'debug';

const debug = _debug('app:webpack:production');

export default (webpackConfig) => {
  debug('Create configuration.');

  if (config.compiler_source_maps) {
    debug('Source maps enabled for production.');
    webpackConfig.devtool = 'source-map';
  } else {
    debug('Source maps are disabled in production.');
  }

  debug('Apply ExtractTextPlugin to CSS loaders.');
  webpackConfig.module.loaders = webpackConfig.module.loaders.map(loader => {
    if (!loader.loaders ||
        !loader.loaders.find(name => /css/.test(name.split('?')[0]))) {
      return loader;
    }

    const [first, ...rest] = loader.loaders;
    loader.loader = ExtractTextPlugin.extract(first, rest.join('!'));
    delete loader.loaders;

    return loader;
  });

  debug('Inject ExtractText and UglifyJS plugins.');
  webpackConfig.plugins.push(
    new ExtractTextPlugin('[name].[contenthash].css', {
      allChunks: true
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        unused: true,
        dead_code: true
      }
    })
  );

  return webpackConfig;
};
<|endoftext|>


<commit_before>export const SPECIFY_PROPERTY = 'specifyProperty';

function specifyProperty(data, currentState, target) {
  let targetData;
  let targetIndex;
  currentState.forEach((elem, index) => {
    if (elem.id === target) {
      targetData = elem;
      targetIndex = index;
    }
  });
  const updatedData = Object.assign({}, targetData, data);
  const updatedState = Object.assign([], currentState);
  updatedState.splice(targetIndex, 1, updatedData);
  return updatedState;
}

export function generateImageList(type, data, currentState, target) {
  switch (type) {
    case SPECIFY_PROPERTY:
      return specifyProperty(data, currentState, target);
    default:
      throw new Error('This type is not found.');
  }
}
<commit_msg>add comment<commit_after>export const SPECIFY_PROPERTY = 'specifyProperty';

// TODO: dataの中にオブジェクトがあった場合の対応
function specifyProperty(data, currentState, target) {
  let targetData;
  let targetIndex;
  currentState.forEach((elem, index) => {
    if (elem.id === target) {
      targetData = elem;
      targetIndex = index;
    }
  });
  const updatedData = Object.assign({}, targetData, data);
  const updatedState = Object.assign([], currentState);
  updatedState.splice(targetIndex, 1, updatedData);
  return updatedState;
}

export function generateImageList(type, data, currentState, target) {
  switch (type) {
    case SPECIFY_PROPERTY:
      return specifyProperty(data, currentState, target);
    default:
      throw new Error('This type is not found.');
  }
}
<|endoftext|>


<commit_before>import React, { useEffect, useState } from 'react';
import { translate } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import SearchIcon from '@material-ui/icons/Search';
import CloseRoundedIcon from '@material-ui/icons/CloseRounded';
import DeleteForeverRoundedIcon from '@material-ui/icons/DeleteForeverRounded';
import EditRoundedIcon from '@material-ui/icons/EditRounded';
import KeyboardArrowDownRoundedIcon from '@material-ui/icons/KeyboardArrowDownRounded';
import OpenInNewRoundedIcon from '@material-ui/icons/OpenInNewRounded';
import VisibilityRoundedIcon from '@material-ui/icons/VisibilityRounded';
import { Box, Flex } from 'rebass/styled-components';
import map from 'lodash/map';
import filter from 'lodash/filter';
import forEach from 'lodash/forEach';
import get from 'lodash/get';
import includes from 'lodash/includes';
import keyBy from 'lodash/keyBy';
import keys from 'lodash/keys';
import reduce from 'lodash/reduce';
import transform from 'lodash/transform';
import values from 'lodash/values';
import without from 'lodash/without';

import {
  bindPopover,
  bindTrigger,
  usePopupState,
} from 'material-ui-popup-state/hooks';

import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
} from '../../components/elements/Dialog';

import Button from '../../components/elements/Button';
import Checkbox from '../../components/elements/Checkbox';
import Pill from '../../components/elements/Pill';
import Popover from '../../components/elements/Popover';
import PopoverMenu from '../../components/elements/PopoverMenu';
import Table from '../../components/elements/Table';
import TextInput from '../../components/elements/TextInput';
import { Body1, MediumTitle } from '../../components/elements/FontStyles';
import { dateRegex, prescriptionStateOptions } from './prescriptionFormConstants';
import { useToasts } from '../../providers/ToastProvider';
import { useIsFirstRender } from '../../core/hooks';
import * as actions from '../../redux/actions';

const Prescriptions = props => {
  const { t, history, api, trackMetric } = props;
  const dispatch = useDispatch();
  const membershipPermissionsInOtherCareTeams = useSelector((state) => state.blip.membershipPermissionsInOtherCareTeams);
  const prescriptions = useSelector((state) => state.blip.prescriptions);
  const loggedInUserId = useSelector((state) => state.blip.loggedInUserId);
  const selectedClinicId = useSelector((state) => state.blip.selectedClinicId);

  const {
    deletingPrescription,
    fetchingAssociatedAccounts,
    fetchingClinicPrescriptions,
  } = useSelector((state) => state.blip.working);

  // Fetchers
  useEffect(() => {
    if (loggedInUserId && selectedClinicId) {
      forEach([
        {
          workingState: fetchingAssociatedAccounts,
          action: actions.async.fetchAssociatedAccounts.bind(null, api),
        },
        {
          workingState: fetchingClinicPrescriptions,
          action: actions.async.fetchClinicPrescriptions.bind(null, api, selectedClinicId),
        },
      ], ({ workingState, action }) => {
        if (
          !workingState.inProgress &&
          !workingState.completed &&
          !workingState.notification
        ) {
          dispatch(action());
        }
      });
    }
  }, [loggedInUserId, selectedClinicId]);

  const isFirstRender = useIsFirstRender();
  const { set: setToast } = useToasts();
  const prescriptionStates = keyBy(prescriptionStateOptions, 'value');

  const popupFilterState = usePopupState({
    variant: 'popover',
    popupId: 'filterState',
  });

  const initialDeleteDialogState = {
    open: false,
    prescription: {},
  };

  const [deleteDialog, setDeleteDialog] = useState(initialDeleteDialogState);

  function closeDeleteDialog() {
    setDeleteDialog({
      ...deleteDialog,
      open: false,
    });

    // We fully reset the dialog after it's had time to close, so that we don't see the patient name
    // in the delete dialog disappear before it closes.
    setTimeout(() => setDeleteDialog(initialDeleteDialogState), 100);
  }

  const [searchText, setSearchText] = useState('');
  const [filterStateActive, setFilterStateActive] = useState(false);

  const [activeStates, setActiveStates] = useState(reduce(prescriptionStateOptions, (result, { value }) => {
    result[value] = true;
    return result;
  }, {}));

  const activeStatesCount = without(values(activeStates), false).length;

  const [pendingActiveStates, setPendingActiveStates] = useState(activeStates);
  const togglePendingActiveState = (value) => setPendingActiveStates({ ...pendingActiveStates, [value]: !pendingActiveStates[value] })

  const data = filter(
    map(prescriptions, prescription => ({
      birthday: get(prescription, 'latestRevision.attributes.birthday', '').replace(dateRegex, '$2/$3/$1'),
      createdTime: get(prescription, 'latestRevision.attributes.createdTime'),
      firstName: get(prescription, 'latestRevision.attributes.firstName'),
      id: get(prescription, 'id'),
      lastName: get(prescription, 'latestRevision.attributes.lastName'),
      mrn: get(prescription, 'latestRevision.attributes.mrn'),
      patientUserId: get(prescription, 'patientUserId'),
      state: get(prescription, 'state'),
    })),
    prescription => activeStates[prescription.state]
  );

  function handleSearchChange(event) {
    setSearchText(event.target.value);
  }

  function clearSearchText() {
    setSearchText('');
  }

  const handleAddNew = () => props.history.push('/prescriptions/new');

  const handleOpenPrescription = prescription => popupState => {
    props.history.push(`/prescriptions/${prescription.id}`);
  };

  const handleDeletePrescription = prescription => popupState => {
    trackMetric('Clinic - Delete prescription', { clinicId: selectedClinicId });
    popupState.close();
    setDeleteDialog({
      open: true,
      prescription,
    });
  }

  function handleConfirmDeletePrescription(invite) {
    trackMetric('Clinic - Delete prescription confirmed', { clinicId: selectedClinicId });
    dispatch(actions.async.deletePrescription(api, selectedClinicId, deleteDialog.prescription.id));
  }

  function handleRowClick(prescription) {
    return handleOpenPrescription(prescription)();
  }

  const actionMenuItems = prescription => {
    const isEditable = includes(['draft', 'pending'], prescription.state);

    const items = [
      {
        icon: isEditable ? EditRoundedIcon : VisibilityRoundedIcon,
        iconLabel: isEditable ? t('Update') : t('View'),
        iconPosition: 'left',
        id: isEditable ? 'update' : 'view',
        onClick: handleOpenPrescription(prescription),
        text: isEditable ? t('Update prescription') : t('View Prescription'),
        variant: 'actionListItem',
      },
    ];

    if (isEditable) items.push({
      icon: DeleteForeverRoundedIcon,
      iconLabel: 'Delete',
      iconPosition: 'left',
      id: 'delete',
      onClick: handleDeletePrescription(prescription),
      text: t('Delete prescription'),
      variant: 'actionListItemDanger',
      disabled: !isEditable,
    });

    return items;
  };

  const renderMore = (prescription) => (
    <Box onClick={e => {
      // Prevent clicks from propogating up to the table row click handlers
      e.stopPropagation();
    }}>
      <PopoverMenu
        id="more-prescription-actions"
        label="More actions"
        items={actionMenuItems(prescription)}
      />
    </Box>
  );

  const openPatientData = (patientUserId) => {
    const href = history.createHref({
      pathname: `/patients/${patientUserId}/data`,
    });

    window.open(href, '_blank');
  }

  const patientNameFromPrescription = ({ firstName = '', lastName = '' }) => [firstName, lastName].join(' ');

  const renderName = prescription => (
    <React.Fragment>
      {prescription.patientUserId && get(membershipPermissionsInOtherCareTeams, [prescription.patientUserId, 'view']) ? <Button
        p={0}
        m={0}
        color="text.link"
        fontSize={1}
        icon={OpenInNewRoundedIcon}
        iconLabel="Open patient data in new tab"
        variant="textPrimary"
        onClick={(e) => {
          // Prevent clicks from propogating up to the table row click handlers
          e.stopPropagation();
          openPatientData(prescription.patientUserId);
        }}
      >
        {patientNameFromPrescription(prescription)}
      </Button> : patientNameFromPrescription(prescription)
     }
    </React.Fragment>
  );

  const renderState = ({ state }) => {
    const label = get(prescriptionStates, [state, 'label'], '');
    const colorPalette = get(prescriptionStates, [state, 'colorPalette'])
    return <Pill label="prescription status" colorPalette={colorPalette} text={label} />
  }

  const columns = [
    { title: t('Name'), field: 'patient', align: 'left', sortable: true, sortBy: 'firstName', render: renderName, searchable: true, searchBy: ['firstName', 'lastName'] },
    { title: t('MRN'), field: 'mrn', align: 'left', sortable: true, searchable: true },
    { title: t('Date of birth'), field: 'birthday', align: 'left', sortable: true, searchable: true },
    { title: t('Status'), field: 'state', render: renderState, align: 'left', sortable: true },
    { title: '', field: 'more', render: renderMore, align: 'left' },
  ];

  // Handle successful or failed deletion attempts
  useEffect(() => {
    const { inProgress, completed, notification } = deletingPrescription;

    if (!isFirstRender && !inProgress) {
      if (completed) {
        if (deleteDialog.open) {
          closeDeleteDialog();
        }

        setToast({
          message: t('You have successfully {{messageAction}} a Tidepool Loop prescription.', { messageAction: 'deleted' }),
          variant: 'success',
        });
      }

      if (completed === false) {
        setToast({
          message: get(notification, 'message'),
          variant: 'danger',
        });
      }
    }
  }, [deletingPrescription]);

  // Render
  return (
      <Box>
        <Flex mb={4} justifyContent="space-between">
          <Box>
            <Flex>
              <TextInput
                themeProps={{
                  width: 'auto',
                  minWidth: '250px',
                }}
                placeholder={t('Search Entries')}
                icon={searchText ? CloseRoundedIcon : SearchIcon}
                iconLabel="search"
                onClickIcon={searchText ? clearSearchText : null}
                name="search-prescriptions"
                onChange={handleSearchChange}
                value={searchText}
                variant="condensed"
              />

              <Button
                variant="filter"
                active={filterStateActive}
                {...bindTrigger(popupFilterState)}
                icon={KeyboardArrowDownRoundedIcon}
                iconLabel="Filter by status"
                ml={2}
                fontSize={1}
              >
                {t('Status{{count}}', {
                  count: activeStatesCount < keys(prescriptionStates).length ? ` (${activeStatesCount})` : '',
                })}
              </Button>

              <Popover width="15em" {...bindPopover(popupFilterState)}>
                <DialogContent px={2} py={3} dividers>
                  {map(prescriptionStateOptions, ({label, value}) => (
                    <Box>
                      <Checkbox
                        checked={pendingActiveStates[value]}
                        key={`filter-${value}`}
                        name={`filter-${value}`}
                        label={label}
                        onChange={() => togglePendingActiveState(value)}
                      />
                    </Box>
                  ))}
                </DialogContent>

                <DialogActions justifyContent="space-between" p={1}>
                  <Button
                    fontSize={1}
                    variant="textSecondary"
                    onClick={() => {
                      const active = without(values(pendingActiveStates), false).length < keys(prescriptionStates).length;

                      setPendingActiveStates(transform(pendingActiveStates, function(result, value, key) {
                        result[key] = active;
                      }, {}));
                    }}
                  >
                    {(without(values(pendingActiveStates), false).length < keys(prescriptionStates).length) ? t('Select All') : t('Deselect All')}
                  </Button>

                  <Button fontSize={0} variant="textPrimary" onClick={() => {
                    setActiveStates(pendingActiveStates);
                    setFilterStateActive(includes(values(pendingActiveStates), false));
                    popupFilterState.close();
                  }}>
                    {t('Apply')}
                  </Button>
                </DialogActions>
              </Popover>
            </Flex>
          </Box>

          <Button variant="primary" onClick={handleAddNew}>{t('Add New')}</Button>
        </Flex>

        <Table
          fontSize={1}
          label="Prescription List"
          id="prescriptions-table"
          data={data}
          columns={columns}
          rowsPerPage={10}
          searchText={searchText}
          onClickRow={handleRowClick}
          orderBy="createdTime"
          order="desc"
          pagination={data.length > 10}
        />

        <Dialog
          id={'prescription-delete'}
          aria-labelledby="dialog-title"
          open={deleteDialog.open}
          onClose={closeDeleteDialog}
        >
          <DialogTitle onClose={closeDeleteDialog}>
            <MediumTitle mr={2} id="dialog-title">Delete Prescription for {patientNameFromPrescription(deleteDialog.prescription)}</MediumTitle>
          </DialogTitle>

          <DialogContent>
            <Body1>
              Are you sure you want to delete this prescription?
            </Body1>
          </DialogContent>

          <DialogActions>
            <Button variant="secondary" onClick={closeDeleteDialog}>
              Cancel
            </Button>

            <Button
              variant="danger"
              processing={deletingPrescription.inProgress}
              onClick={handleConfirmDeletePrescription}
            >
              Delete Prescription
            </Button>
          </DialogActions>
        </Dialog>
      </Box>
  );
};

export default translate()(Prescriptions);
<commit_msg>[WEB-1219] Ensure prescriptions are filtered to only show results for the selected clinic<commit_after>import React, { useEffect, useState } from 'react';
import { translate } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import SearchIcon from '@material-ui/icons/Search';
import CloseRoundedIcon from '@material-ui/icons/CloseRounded';
import DeleteForeverRoundedIcon from '@material-ui/icons/DeleteForeverRounded';
import EditRoundedIcon from '@material-ui/icons/EditRounded';
import KeyboardArrowDownRoundedIcon from '@material-ui/icons/KeyboardArrowDownRounded';
import OpenInNewRoundedIcon from '@material-ui/icons/OpenInNewRounded';
import VisibilityRoundedIcon from '@material-ui/icons/VisibilityRounded';
import { Box, Flex } from 'rebass/styled-components';
import map from 'lodash/map';
import filter from 'lodash/filter';
import forEach from 'lodash/forEach';
import get from 'lodash/get';
import includes from 'lodash/includes';
import keyBy from 'lodash/keyBy';
import keys from 'lodash/keys';
import reduce from 'lodash/reduce';
import transform from 'lodash/transform';
import values from 'lodash/values';
import without from 'lodash/without';

import {
  bindPopover,
  bindTrigger,
  usePopupState,
} from 'material-ui-popup-state/hooks';

import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
} from '../../components/elements/Dialog';

import Button from '../../components/elements/Button';
import Checkbox from '../../components/elements/Checkbox';
import Pill from '../../components/elements/Pill';
import Popover from '../../components/elements/Popover';
import PopoverMenu from '../../components/elements/PopoverMenu';
import Table from '../../components/elements/Table';
import TextInput from '../../components/elements/TextInput';
import { Body1, MediumTitle } from '../../components/elements/FontStyles';
import { dateRegex, prescriptionStateOptions } from './prescriptionFormConstants';
import { useToasts } from '../../providers/ToastProvider';
import { useIsFirstRender } from '../../core/hooks';
import * as actions from '../../redux/actions';

const Prescriptions = props => {
  const { t, history, api, trackMetric } = props;
  const dispatch = useDispatch();
  const membershipPermissionsInOtherCareTeams = useSelector((state) => state.blip.membershipPermissionsInOtherCareTeams);
  const prescriptions = useSelector((state) => state.blip.prescriptions);
  const loggedInUserId = useSelector((state) => state.blip.loggedInUserId);
  const selectedClinicId = useSelector((state) => state.blip.selectedClinicId);

  const {
    deletingPrescription,
    fetchingAssociatedAccounts,
    fetchingClinicPrescriptions,
  } = useSelector((state) => state.blip.working);

  // Fetchers
  useEffect(() => {
    if (loggedInUserId && selectedClinicId) {
      forEach([
        {
          workingState: fetchingAssociatedAccounts,
          action: actions.async.fetchAssociatedAccounts.bind(null, api),
        },
        {
          workingState: fetchingClinicPrescriptions,
          action: actions.async.fetchClinicPrescriptions.bind(null, api, selectedClinicId),
        },
      ], ({ workingState, action }) => {
        if (
          !workingState.inProgress &&
          !workingState.completed &&
          !workingState.notification
        ) {
          dispatch(action());
        }
      });
    }
  }, [loggedInUserId, selectedClinicId]);

  const isFirstRender = useIsFirstRender();
  const { set: setToast } = useToasts();
  const prescriptionStates = keyBy(prescriptionStateOptions, 'value');

  const popupFilterState = usePopupState({
    variant: 'popover',
    popupId: 'filterState',
  });

  const initialDeleteDialogState = {
    open: false,
    prescription: {},
  };

  const [deleteDialog, setDeleteDialog] = useState(initialDeleteDialogState);

  function closeDeleteDialog() {
    setDeleteDialog({
      ...deleteDialog,
      open: false,
    });

    // We fully reset the dialog after it's had time to close, so that we don't see the patient name
    // in the delete dialog disappear before it closes.
    setTimeout(() => setDeleteDialog(initialDeleteDialogState), 100);
  }

  const [searchText, setSearchText] = useState('');
  const [filterStateActive, setFilterStateActive] = useState(false);

  const [activeStates, setActiveStates] = useState(reduce(prescriptionStateOptions, (result, { value }) => {
    result[value] = true;
    return result;
  }, {}));

  const activeStatesCount = without(values(activeStates), false).length;

  const [pendingActiveStates, setPendingActiveStates] = useState(activeStates);
  const togglePendingActiveState = (value) => setPendingActiveStates({ ...pendingActiveStates, [value]: !pendingActiveStates[value] })

  const data = filter(
    map(filter(prescriptions, { clinicId: selectedClinicId }), prescription => ({
      birthday: get(prescription, 'latestRevision.attributes.birthday', '').replace(dateRegex, '$2/$3/$1'),
      createdTime: get(prescription, 'latestRevision.attributes.createdTime'),
      firstName: get(prescription, 'latestRevision.attributes.firstName'),
      id: get(prescription, 'id'),
      lastName: get(prescription, 'latestRevision.attributes.lastName'),
      mrn: get(prescription, 'latestRevision.attributes.mrn'),
      patientUserId: get(prescription, 'patientUserId'),
      state: get(prescription, 'state'),
    })),
    prescription => activeStates[prescription.state]
  );

  function handleSearchChange(event) {
    setSearchText(event.target.value);
  }

  function clearSearchText() {
    setSearchText('');
  }

  const handleAddNew = () => props.history.push('/prescriptions/new');

  const handleOpenPrescription = prescription => popupState => {
    props.history.push(`/prescriptions/${prescription.id}`);
  };

  const handleDeletePrescription = prescription => popupState => {
    trackMetric('Clinic - Delete prescription', { clinicId: selectedClinicId });
    popupState.close();
    setDeleteDialog({
      open: true,
      prescription,
    });
  }

  function handleConfirmDeletePrescription(invite) {
    trackMetric('Clinic - Delete prescription confirmed', { clinicId: selectedClinicId });
    dispatch(actions.async.deletePrescription(api, selectedClinicId, deleteDialog.prescription.id));
  }

  function handleRowClick(prescription) {
    return handleOpenPrescription(prescription)();
  }

  const actionMenuItems = prescription => {
    const isEditable = includes(['draft', 'pending'], prescription.state);

    const items = [
      {
        icon: isEditable ? EditRoundedIcon : VisibilityRoundedIcon,
        iconLabel: isEditable ? t('Update') : t('View'),
        iconPosition: 'left',
        id: isEditable ? 'update' : 'view',
        onClick: handleOpenPrescription(prescription),
        text: isEditable ? t('Update prescription') : t('View Prescription'),
        variant: 'actionListItem',
      },
    ];

    if (isEditable) items.push({
      icon: DeleteForeverRoundedIcon,
      iconLabel: 'Delete',
      iconPosition: 'left',
      id: 'delete',
      onClick: handleDeletePrescription(prescription),
      text: t('Delete prescription'),
      variant: 'actionListItemDanger',
      disabled: !isEditable,
    });

    return items;
  };

  const renderMore = (prescription) => (
    <Box onClick={e => {
      // Prevent clicks from propogating up to the table row click handlers
      e.stopPropagation();
    }}>
      <PopoverMenu
        id="more-prescription-actions"
        label="More actions"
        items={actionMenuItems(prescription)}
      />
    </Box>
  );

  const openPatientData = (patientUserId) => {
    const href = history.createHref({
      pathname: `/patients/${patientUserId}/data`,
    });

    window.open(href, '_blank');
  }

  const patientNameFromPrescription = ({ firstName = '', lastName = '' }) => [firstName, lastName].join(' ');

  const renderName = prescription => (
    <React.Fragment>
      {prescription.patientUserId && get(membershipPermissionsInOtherCareTeams, [prescription.patientUserId, 'view']) ? <Button
        p={0}
        m={0}
        color="text.link"
        fontSize={1}
        icon={OpenInNewRoundedIcon}
        iconLabel="Open patient data in new tab"
        variant="textPrimary"
        onClick={(e) => {
          // Prevent clicks from propogating up to the table row click handlers
          e.stopPropagation();
          openPatientData(prescription.patientUserId);
        }}
      >
        {patientNameFromPrescription(prescription)}
      </Button> : patientNameFromPrescription(prescription)
     }
    </React.Fragment>
  );

  const renderState = ({ state }) => {
    const label = get(prescriptionStates, [state, 'label'], '');
    const colorPalette = get(prescriptionStates, [state, 'colorPalette'])
    return <Pill label="prescription status" colorPalette={colorPalette} text={label} />
  }

  const columns = [
    { title: t('Name'), field: 'patient', align: 'left', sortable: true, sortBy: 'firstName', render: renderName, searchable: true, searchBy: ['firstName', 'lastName'] },
    { title: t('MRN'), field: 'mrn', align: 'left', sortable: true, searchable: true },
    { title: t('Date of birth'), field: 'birthday', align: 'left', sortable: true, searchable: true },
    { title: t('Status'), field: 'state', render: renderState, align: 'left', sortable: true },
    { title: '', field: 'more', render: renderMore, align: 'left' },
  ];

  // Handle successful or failed deletion attempts
  useEffect(() => {
    const { inProgress, completed, notification } = deletingPrescription;

    if (!isFirstRender && !inProgress) {
      if (completed) {
        if (deleteDialog.open) {
          closeDeleteDialog();
        }

        setToast({
          message: t('You have successfully {{messageAction}} a Tidepool Loop prescription.', { messageAction: 'deleted' }),
          variant: 'success',
        });
      }

      if (completed === false) {
        setToast({
          message: get(notification, 'message'),
          variant: 'danger',
        });
      }
    }
  }, [deletingPrescription]);

  // Render
  return (
      <Box>
        <Flex mb={4} justifyContent="space-between">
          <Box>
            <Flex>
              <TextInput
                themeProps={{
                  width: 'auto',
                  minWidth: '250px',
                }}
                placeholder={t('Search Entries')}
                icon={searchText ? CloseRoundedIcon : SearchIcon}
                iconLabel="search"
                onClickIcon={searchText ? clearSearchText : null}
                name="search-prescriptions"
                onChange={handleSearchChange}
                value={searchText}
                variant="condensed"
              />

              <Button
                variant="filter"
                active={filterStateActive}
                {...bindTrigger(popupFilterState)}
                icon={KeyboardArrowDownRoundedIcon}
                iconLabel="Filter by status"
                ml={2}
                fontSize={1}
              >
                {t('Status{{count}}', {
                  count: activeStatesCount < keys(prescriptionStates).length ? ` (${activeStatesCount})` : '',
                })}
              </Button>

              <Popover width="15em" {...bindPopover(popupFilterState)}>
                <DialogContent px={2} py={3} dividers>
                  {map(prescriptionStateOptions, ({label, value}) => (
                    <Box>
                      <Checkbox
                        checked={pendingActiveStates[value]}
                        key={`filter-${value}`}
                        name={`filter-${value}`}
                        label={label}
                        onChange={() => togglePendingActiveState(value)}
                      />
                    </Box>
                  ))}
                </DialogContent>

                <DialogActions justifyContent="space-between" p={1}>
                  <Button
                    fontSize={1}
                    variant="textSecondary"
                    onClick={() => {
                      const active = without(values(pendingActiveStates), false).length < keys(prescriptionStates).length;

                      setPendingActiveStates(transform(pendingActiveStates, function(result, value, key) {
                        result[key] = active;
                      }, {}));
                    }}
                  >
                    {(without(values(pendingActiveStates), false).length < keys(prescriptionStates).length) ? t('Select All') : t('Deselect All')}
                  </Button>

                  <Button fontSize={0} variant="textPrimary" onClick={() => {
                    setActiveStates(pendingActiveStates);
                    setFilterStateActive(includes(values(pendingActiveStates), false));
                    popupFilterState.close();
                  }}>
                    {t('Apply')}
                  </Button>
                </DialogActions>
              </Popover>
            </Flex>
          </Box>

          <Button variant="primary" onClick={handleAddNew}>{t('Add New')}</Button>
        </Flex>

        <Table
          fontSize={1}
          label="Prescription List"
          id="prescriptions-table"
          data={data}
          columns={columns}
          rowsPerPage={10}
          searchText={searchText}
          onClickRow={handleRowClick}
          orderBy="createdTime"
          order="desc"
          pagination={data.length > 10}
        />

        <Dialog
          id={'prescription-delete'}
          aria-labelledby="dialog-title"
          open={deleteDialog.open}
          onClose={closeDeleteDialog}
        >
          <DialogTitle onClose={closeDeleteDialog}>
            <MediumTitle mr={2} id="dialog-title">Delete Prescription for {patientNameFromPrescription(deleteDialog.prescription)}</MediumTitle>
          </DialogTitle>

          <DialogContent>
            <Body1>
              Are you sure you want to delete this prescription?
            </Body1>
          </DialogContent>

          <DialogActions>
            <Button variant="secondary" onClick={closeDeleteDialog}>
              Cancel
            </Button>

            <Button
              variant="danger"
              processing={deletingPrescription.inProgress}
              onClick={handleConfirmDeletePrescription}
            >
              Delete Prescription
            </Button>
          </DialogActions>
        </Dialog>
      </Box>
  );
};

export default translate()(Prescriptions);
<|endoftext|>


<commit_before>export default function listify(addons) {
	if (!addons) {
		return [];
	}
  return Object.keys(addons)
               .sort()
               .map(slug => addons[slug]);
}
<commit_msg>Tabs -> spaces.<commit_after>export default function listify(addons) {
  if (!addons) {
    return [];
  }
  return Object.keys(addons)
               .sort()
               .map(slug => addons[slug]);
}
<|endoftext|>


<commit_before>goog.provide('ol.RendererHint');
goog.provide('ol.createMap');

goog.require('goog.object');
goog.require('ol.Collection');
goog.require('ol.Map');
goog.require('ol.MapProperty');
goog.require('ol.Projection');
goog.require('ol.dom');
goog.require('ol.dom.MapRenderer');
goog.require('ol.interaction.AltDragRotate');
goog.require('ol.interaction.CenterConstraint');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.DblClickZoom');
goog.require('ol.interaction.DragPan');
goog.require('ol.interaction.KeyboardPan');
goog.require('ol.interaction.KeyboardZoom');
goog.require('ol.interaction.MouseWheelZoom');
goog.require('ol.interaction.ResolutionConstraint');
goog.require('ol.interaction.RotationConstraint');
goog.require('ol.interaction.ShiftDragZoom');
goog.require('ol.webgl');
goog.require('ol.webgl.MapRenderer');

/**
 * @define {string} Default projection code.
 */
ol.DEFAULT_PROJECTION_CODE = 'EPSG:3857';

/**
 * @define {string} Default user projection code.
 */
ol.DEFAULT_USER_PROJECTION_CODE = 'EPSG:4326';

/**
 * @define {boolean} Whether to enable DOM.
 */
ol.ENABLE_DOM = true;

/**
 * @define {boolean} Whether to enable WebGL.
 */
ol.ENABLE_WEBGL = true;

/**
 * @enum {string}
 */
ol.RendererHint = {
  DOM: 'dom',
  WEBGL: 'webgl'
};

/**
 * @type {Array.<ol.RendererHint>}
 */
ol.DEFAULT_RENDERER_HINT = [
  ol.RendererHint.WEBGL,
  ol.RendererHint.DOM
];

/**
 * @param {Element} target Target.
 * @param {Object.<string, *>=} opt_values Values.
 * @param {ol.RendererHint|Array.<ol.RendererHint>=} opt_rendererHints
 *     Renderer hints.
 * @return {ol.Map} Map.
 */
ol.createMap = function(target, opt_values, opt_rendererHints) {

  var values = {};
  if (goog.isDef(opt_values)) {
    goog.object.extend(values, opt_values);
  }

  // FIXME this should be a configuration option
  var centerConstraint = ol.interaction.CenterConstraint.snapToPixel;
  var resolutionConstraint =
      ol.interaction.ResolutionConstraint.createSnapToPower(
          Math.exp(Math.log(2) / 8), ol.Projection.EPSG_3857_HALF_SIZE / 128);
  var rotationConstraint = ol.interaction.RotationConstraint.none;
  var constraints = new ol.interaction.Constraints(
      centerConstraint, resolutionConstraint, rotationConstraint);

  if (!goog.object.containsKey(values, ol.MapProperty.INTERACTIONS)) {
    var interactions = new ol.Collection();
    interactions.push(new ol.interaction.AltDragRotate(constraints));
    interactions.push(new ol.interaction.DblClickZoom(constraints));
    interactions.push(new ol.interaction.DragPan(constraints));
    interactions.push(new ol.interaction.KeyboardPan(constraints, 16));
    interactions.push(new ol.interaction.KeyboardZoom(constraints));
    interactions.push(new ol.interaction.MouseWheelZoom(constraints));
    interactions.push(new ol.interaction.ShiftDragZoom(constraints));
    values[ol.MapProperty.INTERACTIONS] = interactions;
  }

  if (!goog.object.containsKey(values, ol.MapProperty.LAYERS)) {
    values[ol.MapProperty.LAYERS] = new ol.Collection();
  }

  if (!goog.object.containsKey(values, ol.MapProperty.PROJECTION)) {
    values[ol.MapProperty.PROJECTION] =
        ol.Projection.getFromCode(ol.DEFAULT_PROJECTION_CODE);
  }

  if (!goog.object.containsKey(values, ol.MapProperty.USER_PROJECTION)) {
    values[ol.MapProperty.USER_PROJECTION] =
        ol.Projection.getFromCode(ol.DEFAULT_USER_PROJECTION_CODE);
  }

  /**
   * @type {Array.<ol.RendererHint>}
   */
  var rendererHints;
  if (goog.isDef(opt_rendererHints)) {
    if (goog.isArray(opt_rendererHints)) {
      rendererHints = opt_rendererHints;
    } else {
      rendererHints = [opt_rendererHints];
    }
  } else {
    rendererHints = ol.DEFAULT_RENDERER_HINT;
  }

  var i, rendererHint, rendererConstructor;
  for (i = 0; i < rendererHints.length; ++i) {
    rendererHint = rendererHints[i];
    if (rendererHint == ol.RendererHint.DOM) {
      if (ol.ENABLE_DOM && ol.dom.isSupported()) {
        rendererConstructor = ol.dom.MapRenderer;
      }
    } else if (rendererHint == ol.RendererHint.WEBGL) {
      if (ol.ENABLE_WEBGL && ol.webgl.isSupported()) {
        rendererConstructor = ol.webgl.MapRenderer;
      }
    }
  }

  if (goog.isDef(rendererConstructor)) {
    return new ol.Map(target, rendererConstructor, values);
  } else {
    return null;
  }

};
<commit_msg>exit renderer hint for loop when map renderer is found<commit_after>goog.provide('ol.RendererHint');
goog.provide('ol.createMap');

goog.require('goog.object');
goog.require('ol.Collection');
goog.require('ol.Map');
goog.require('ol.MapProperty');
goog.require('ol.Projection');
goog.require('ol.dom');
goog.require('ol.dom.MapRenderer');
goog.require('ol.interaction.AltDragRotate');
goog.require('ol.interaction.CenterConstraint');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.DblClickZoom');
goog.require('ol.interaction.DragPan');
goog.require('ol.interaction.KeyboardPan');
goog.require('ol.interaction.KeyboardZoom');
goog.require('ol.interaction.MouseWheelZoom');
goog.require('ol.interaction.ResolutionConstraint');
goog.require('ol.interaction.RotationConstraint');
goog.require('ol.interaction.ShiftDragZoom');
goog.require('ol.webgl');
goog.require('ol.webgl.MapRenderer');

/**
 * @define {string} Default projection code.
 */
ol.DEFAULT_PROJECTION_CODE = 'EPSG:3857';

/**
 * @define {string} Default user projection code.
 */
ol.DEFAULT_USER_PROJECTION_CODE = 'EPSG:4326';

/**
 * @define {boolean} Whether to enable DOM.
 */
ol.ENABLE_DOM = true;

/**
 * @define {boolean} Whether to enable WebGL.
 */
ol.ENABLE_WEBGL = true;

/**
 * @enum {string}
 */
ol.RendererHint = {
  DOM: 'dom',
  WEBGL: 'webgl'
};

/**
 * @type {Array.<ol.RendererHint>}
 */
ol.DEFAULT_RENDERER_HINT = [
  ol.RendererHint.WEBGL,
  ol.RendererHint.DOM
];

/**
 * @param {Element} target Target.
 * @param {Object.<string, *>=} opt_values Values.
 * @param {ol.RendererHint|Array.<ol.RendererHint>=} opt_rendererHints
 *     Renderer hints.
 * @return {ol.Map} Map.
 */
ol.createMap = function(target, opt_values, opt_rendererHints) {

  var values = {};
  if (goog.isDef(opt_values)) {
    goog.object.extend(values, opt_values);
  }

  // FIXME this should be a configuration option
  var centerConstraint = ol.interaction.CenterConstraint.snapToPixel;
  var resolutionConstraint =
      ol.interaction.ResolutionConstraint.createSnapToPower(
          Math.exp(Math.log(2) / 8), ol.Projection.EPSG_3857_HALF_SIZE / 128);
  var rotationConstraint = ol.interaction.RotationConstraint.none;
  var constraints = new ol.interaction.Constraints(
      centerConstraint, resolutionConstraint, rotationConstraint);

  if (!goog.object.containsKey(values, ol.MapProperty.INTERACTIONS)) {
    var interactions = new ol.Collection();
    interactions.push(new ol.interaction.AltDragRotate(constraints));
    interactions.push(new ol.interaction.DblClickZoom(constraints));
    interactions.push(new ol.interaction.DragPan(constraints));
    interactions.push(new ol.interaction.KeyboardPan(constraints, 16));
    interactions.push(new ol.interaction.KeyboardZoom(constraints));
    interactions.push(new ol.interaction.MouseWheelZoom(constraints));
    interactions.push(new ol.interaction.ShiftDragZoom(constraints));
    values[ol.MapProperty.INTERACTIONS] = interactions;
  }

  if (!goog.object.containsKey(values, ol.MapProperty.LAYERS)) {
    values[ol.MapProperty.LAYERS] = new ol.Collection();
  }

  if (!goog.object.containsKey(values, ol.MapProperty.PROJECTION)) {
    values[ol.MapProperty.PROJECTION] =
        ol.Projection.getFromCode(ol.DEFAULT_PROJECTION_CODE);
  }

  if (!goog.object.containsKey(values, ol.MapProperty.USER_PROJECTION)) {
    values[ol.MapProperty.USER_PROJECTION] =
        ol.Projection.getFromCode(ol.DEFAULT_USER_PROJECTION_CODE);
  }

  /**
   * @type {Array.<ol.RendererHint>}
   */
  var rendererHints;
  if (goog.isDef(opt_rendererHints)) {
    if (goog.isArray(opt_rendererHints)) {
      rendererHints = opt_rendererHints;
    } else {
      rendererHints = [opt_rendererHints];
    }
  } else {
    rendererHints = ol.DEFAULT_RENDERER_HINT;
  }

  var i, rendererHint, rendererConstructor;
  for (i = 0; i < rendererHints.length; ++i) {
    rendererHint = rendererHints[i];
    if (rendererHint == ol.RendererHint.DOM) {
      if (ol.ENABLE_DOM && ol.dom.isSupported()) {
        rendererConstructor = ol.dom.MapRenderer;
        break;
      }
    } else if (rendererHint == ol.RendererHint.WEBGL) {
      if (ol.ENABLE_WEBGL && ol.webgl.isSupported()) {
        rendererConstructor = ol.webgl.MapRenderer;
        break;
      }
    }
  }

  if (goog.isDef(rendererConstructor)) {
    return new ol.Map(target, rendererConstructor, values);
  } else {
    return null;
  }

};
<|endoftext|>