////////////////////////////////////////////////////////////////////////// // // // This is a generated file. You can view the original // // source in your browser if your browser supports source maps. // // Source maps are supported by all recent versions of Chrome, Safari, // // and Firefox, and by Internet Explorer 11. // // // ////////////////////////////////////////////////////////////////////////// (function () { /* Imports */ var Meteor = Package.meteor.Meteor; var global = Package.meteor.global; var meteorEnv = Package.meteor.meteorEnv; var $ = Package.jquery.$; var jQuery = Package.jquery.jQuery; var Random = Package.random.Random; var moment = Package['momentjs:moment'].moment; var validate = Package.validatejs.validate; var SimpleSchema = Package['aldeed:simple-schema'].SimpleSchema; var MongoObject = Package['aldeed:simple-schema'].MongoObject; var cornerstone = Package['ohif:cornerstone'].cornerstone; var cornerstoneMath = Package['ohif:cornerstone'].cornerstoneMath; var cornerstoneTools = Package['ohif:cornerstone'].cornerstoneTools; var cornerstoneWADOImageLoader = Package['ohif:cornerstone'].cornerstoneWADOImageLoader; var dicomParser = Package['ohif:cornerstone'].dicomParser; var dcmjs = Package['ohif:cornerstone'].dcmjs; var HP = Package['ohif:hanging-protocols'].HP; var dialogPolyfill = Package['ohif:viewerbase'].dialogPolyfill; var meteorInstall = Package.modules.meteorInstall; var meteorBabelHelpers = Package['babel-runtime'].meteorBabelHelpers; var Promise = Package.promise.Promise; var Collection2 = Package['aldeed:collection2-core'].Collection2; var Symbol = Package['ecmascript-runtime-client'].Symbol; var Map = Package['ecmascript-runtime-client'].Map; var Set = Package['ecmascript-runtime-client'].Set; var WebApp = Package.webapp.WebApp; var Log = Package.logging.Log; var Tracker = Package.deps.Tracker; var Deps = Package.deps.Deps; var Session = Package.session.Session; var DDP = Package['ddp-client'].DDP; var Mongo = Package.mongo.Mongo; var Blaze = Package.ui.Blaze; var UI = Package.ui.UI; var Handlebars = Package.ui.Handlebars; var Spacebars = Package.spacebars.Spacebars; var Template = Package['templating-runtime'].Template; var check = Package.check.check; var Match = Package.check.Match; var _ = Package.underscore._; var EJSON = Package.ejson.EJSON; var LaunchScreen = Package['launch-screen'].LaunchScreen; var HTML = Package.htmljs.HTML; /* Package-scope variables */ var header, measurementLine, MeasurementSchemaTypes; var require = meteorInstall({"node_modules":{"meteor":{"ohif:measurements":{"both":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./base.js")); module.watch(require("./configuration")); module.watch(require("./schema")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"base.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/base.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); OHIF.measurements = {}; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"configuration":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/configuration/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurements.js")); module.watch(require("./timepoints.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurements.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/configuration/measurements.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Mongo; module.watch(require("meteor/mongo"), { Mongo: function (v) { Mongo = v; } }, 0); var Tracker; module.watch(require("meteor/tracker"), { Tracker: function (v) { Tracker = v; } }, 1); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); var cornerstoneTools; module.watch(require("meteor/ohif:cornerstone"), { cornerstoneTools: function (v) { cornerstoneTools = v; } }, 4); var configuration = {}; var MeasurementApi = /*#__PURE__*/ function () { MeasurementApi.setConfiguration = function () { function setConfiguration(config) { _.extend(configuration, config); } return setConfiguration; }(); MeasurementApi.getConfiguration = function () { function getConfiguration() { return configuration; } return getConfiguration; }(); MeasurementApi.getToolsGroupsMap = function () { function getToolsGroupsMap() { var toolsGroupsMap = {}; configuration.measurementTools.forEach(function (toolGroup) { toolGroup.childTools.forEach(function (tool) { return toolsGroupsMap[tool.id] = toolGroup.id; }); }); return toolsGroupsMap; } return getToolsGroupsMap; }(); function MeasurementApi(timepointApi) { var _this = this; if (timepointApi) { this.timepointApi = timepointApi; } this.toolGroups = {}; this.tools = {}; this.toolsGroupsMap = MeasurementApi.getToolsGroupsMap(); this.changeObserver = new Tracker.Dependency(); configuration.measurementTools.forEach(function (toolGroup) { var groupCollection = new Mongo.Collection(null); groupCollection._debugName = toolGroup.name; groupCollection.attachSchema(toolGroup.schema); _this.toolGroups[toolGroup.id] = groupCollection; toolGroup.childTools.forEach(function (tool) { var collection = new Mongo.Collection(null); collection._debugName = tool.name; collection.attachSchema(tool.schema); _this.tools[tool.id] = collection; var addedHandler = function (measurement) { var measurementNumber; // Get the measurement number var timepoint = _this.timepointApi.timepoints.findOne({ studyInstanceUids: measurement.studyInstanceUid }); // Preventing errors thrown when non-associated (standalone) study is opened... // @TODO: Make sure this logic is correct. if (!timepoint) return; var emptyItem = groupCollection.findOne({ toolId: { $eq: null }, timepointId: timepoint.timepointId }); if (emptyItem) { measurementNumber = emptyItem.measurementNumber; groupCollection.update({ timepointId: timepoint.timepointId, measurementNumber: measurementNumber }, { $set: { toolId: tool.id, toolItemId: measurement._id, createdAt: measurement.createdAt } }); } else { measurementNumber = groupCollection.find({ studyInstanceUid: { $in: timepoint.studyInstanceUids } }).count() + 1; } measurement.measurementNumber = measurementNumber; // Get the current location/description (if already defined) var updateObject = { timepointId: timepoint.timepointId, measurementNumber: measurementNumber }; var baselineTimepoint = timepointApi.baseline(); var baselineGroupEntry = groupCollection.findOne({ timepointId: baselineTimepoint.timepointId }); if (baselineGroupEntry) { var _tool = _this.tools[baselineGroupEntry.toolId]; var found = _tool.findOne({ measurementNumber: measurementNumber }); if (found) { updateObject.location = found.location; if (found.description) { updateObject.description = found.description; } } } // Set the timepoint ID, measurement number, location and description collection.update(measurement._id, { $set: updateObject }); if (!emptyItem) { // Reflect the entry in the tool group collection groupCollection.insert({ toolId: tool.id, toolItemId: measurement._id, timepointId: timepoint.timepointId, studyInstanceUid: measurement.studyInstanceUid, createdAt: measurement.createdAt, measurementNumber: measurementNumber }); } // Enable reactivity _this.changeObserver.changed(); }; var changedHandler = function (measurement) { _this.changeObserver.changed(); }; var removedHandler = function (measurement) { var measurementNumber = measurement.measurementNumber; groupCollection.update({ toolItemId: measurement._id }, { $set: { toolId: null, toolItemId: null } }); var nonEmptyItem = groupCollection.findOne({ measurementNumber: measurementNumber, toolId: { $not: null } }); if (nonEmptyItem) { return; } var groupItems = groupCollection.find({ measurementNumber: measurementNumber }).fetch(); groupItems.forEach(function (groupItem) { // Remove the record from the tools group collection too groupCollection.remove({ _id: groupItem._id }); // Update the measurement numbers only if it is last item var timepoint = _this.timepointApi.timepoints.findOne({ timepointId: groupItem.timepointId }); var filter = { studyInstanceUid: { $in: timepoint.studyInstanceUids }, measurementNumber: measurementNumber }; var remainingItems = groupCollection.find(filter).count(); if (!remainingItems) { filter.measurementNumber = { $gte: measurementNumber }; var operator = { $inc: { measurementNumber: -1 } }; var options = { multi: true }; groupCollection.update(filter, operator, options); toolGroup.childTools.forEach(function (childTool) { var collection = _this.tools[childTool.id]; collection.update(filter, operator, options); }); } }); // Synchronize the new tool data _this.syncMeasurementsAndToolData(); // Enable reactivity _this.changeObserver.changed(); }; collection.find().observe({ added: addedHandler, changed: changedHandler, removed: removedHandler }); }); }); } var _proto = MeasurementApi.prototype; _proto.retrieveMeasurements = function () { function retrieveMeasurements(patientId, timepointIds) { var _this2 = this; var retrievalFn = configuration.dataExchange.retrieve; if (!_.isFunction(retrievalFn)) { return; } return new Promise(function (resolve, reject) { retrievalFn(patientId, timepointIds).then(function (measurementData) { OHIF.log.info('Measurement data retrieval'); OHIF.log.info(measurementData); var toolsGroupsMap = MeasurementApi.getToolsGroupsMap(); var measurementsGroups = {}; Object.keys(measurementData).forEach(function (measurementTypeId) { var measurements = measurementData[measurementTypeId]; measurements.forEach(function (measurement) { var toolType = measurement.toolType; if (toolType && _this2.tools[toolType]) { delete measurement._id; var toolGroup = toolsGroupsMap[toolType]; if (!measurementsGroups[toolGroup]) { measurementsGroups[toolGroup] = []; } measurementsGroups[toolGroup].push(measurement); } }); }); Object.keys(measurementsGroups).forEach(function (groupKey) { var group = measurementsGroups[groupKey]; group.sort(function (a, b) { if (a.measurementNumber > b.measurementNumber) { return 1; } else if (a.measurementNumber < b.measurementNumber) { return -1; } return 0; }); group.forEach(function (m) { return _this2.tools[m.toolType].insert(m); }); }); resolve(); }); }); } return retrieveMeasurements; }(); _proto.storeMeasurements = function () { function storeMeasurements(timepointId) { var _this3 = this; var storeFn = configuration.dataExchange.store; if (!_.isFunction(storeFn)) { return; } var measurementData = {}; configuration.measurementTools.forEach(function (toolGroup) { toolGroup.childTools.forEach(function (tool) { if (!measurementData[toolGroup.id]) { measurementData[toolGroup.id] = []; } measurementData[toolGroup.id] = measurementData[toolGroup.id].concat(_this3.tools[tool.id].find().fetch()); }); }); var timepointFilter = timepointId ? { timepointId: timepointId } : {}; var timepoints = this.timepointApi.all(timepointFilter); var timepointIds = timepoints.map(function (t) { return t.timepointId; }); var patientId = timepoints[0].patientId; var filter = { patientId: patientId, timepointId: { $in: timepointIds } }; OHIF.log.info('Saving Measurements for timepoints:', timepoints); return storeFn(measurementData, filter).then(function () { OHIF.log.info('Measurement storage completed'); }); } return storeMeasurements; }(); _proto.validateMeasurements = function () { function validateMeasurements() { var validateFn = configuration.dataValidation.validateMeasurements; if (validateFn && validateFn instanceof Function) { validateFn(); } } return validateMeasurements; }(); _proto.syncMeasurementsAndToolData = function () { function syncMeasurementsAndToolData() { var _this4 = this; configuration.measurementTools.forEach(function (toolGroup) { toolGroup.childTools.forEach(function (tool) { var measurements = _this4.tools[tool.id].find().fetch(); measurements.forEach(function (measurement) { OHIF.measurements.syncMeasurementAndToolData(measurement); }); }); }); } return syncMeasurementsAndToolData; }(); _proto.sortMeasurements = function () { function sortMeasurements(baselineTimepointId) { var _this5 = this; var tools = configuration.measurementTools; var includedTools = tools.filter(function (tool) { return tool.options && tool.options.caseProgress && tool.options.caseProgress.include; }); // Update Measurement the displayed Measurements includedTools.forEach(function (tool) { var collection = _this5.tools[tool.id]; var measurements = collection.find().fetch(); measurements.forEach(function (measurement) { OHIF.measurements.syncMeasurementAndToolData(measurement); }); }); } return sortMeasurements; }(); _proto.deleteMeasurements = function () { function deleteMeasurements(measurementTypeId, filter) { var _this6 = this; var groupCollection = this.toolGroups[measurementTypeId]; // Stop here if it is a temporary toolGroups if (!groupCollection) return; // Get the entries information before removing them var groupItems = groupCollection.find(filter).fetch(); var entries = []; groupItems.forEach(function (groupItem) { if (!groupItem.toolId) { return; } var collection = _this6.tools[groupItem.toolId]; entries.push(collection.findOne(groupItem.toolItemId)); collection.remove(groupItem.toolItemId); }); // Stop here if no entries were found if (!entries.length) { return; } // If the filter doesn't have the measurement number, get it from the first entry var measurementNumber = filter.measurementNumber || entries[0].measurementNumber; // Synchronize the new data with cornerstone tools var toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState(); _.each(entries, function (entry) { var measurementsData = []; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(entry.toolType), tool = _OHIF$measurements$ge.tool; if (Array.isArray(tool.childTools)) { tool.childTools.forEach(function (key) { var childMeasurement = entry[key]; if (!childMeasurement) return; measurementsData.push(childMeasurement); }); } else { measurementsData.push(entry); } measurementsData.forEach(function (measurementData) { var imagePath = measurementData.imagePath, toolType = measurementData.toolType; var imageId = OHIF.viewerbase.getImageIdForImagePath(imagePath); if (toolState[imageId]) { var toolData = toolState[imageId][toolType]; var measurementEntries = toolData && toolData.data; var measurementEntry = _.findWhere(measurementEntries, { _id: entry._id }); if (measurementEntry) { var index = measurementEntries.indexOf(measurementEntry); measurementEntries.splice(index, 1); } } }); }); cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(toolState); // Synchronize the updated measurements with Cornerstone Tools // toolData to make sure the displayed measurements show 'Target X' correctly var syncFilter = _.clone(filter); delete syncFilter.timepointId; syncFilter.measurementNumber = { $gt: measurementNumber - 1 }; var toolTypes = _.uniq(entries.map(function (entry) { return entry.toolType; })); toolTypes.forEach(function (toolType) { var collection = _this6.tools[toolType]; collection.find(syncFilter).forEach(function (measurement) { OHIF.measurements.syncMeasurementAndToolData(measurement); }); }); } return deleteMeasurements; }(); _proto.getMeasurementById = function () { function getMeasurementById(measurementId) { var foundGroup; _.find(this.toolGroups, function (toolGroup) { foundGroup = toolGroup.findOne({ toolItemId: measurementId }); return !!foundGroup; }); // Stop here if no group was found or if the record is a placeholder if (!foundGroup || !foundGroup.toolId) { return; } return this.tools[foundGroup.toolId].findOne(measurementId); } return getMeasurementById; }(); _proto.fetch = function () { function fetch(toolGroupId, selector, options) { var _this7 = this; if (!this.toolGroups[toolGroupId]) { throw 'MeasurementApi: No Collection with the id: ' + toolGroupId; } selector = selector || {}; options = options || {}; var result = []; var items = this.toolGroups[toolGroupId].find(selector, options).fetch(); items.forEach(function (item) { if (item.toolId) { result.push(_this7.tools[item.toolId].findOne(item.toolItemId)); } else { result.push({ measurementNumber: item.measurementNumber }); } }); return result; } return fetch; }(); return MeasurementApi; }(); OHIF.measurements.MeasurementApi = MeasurementApi; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"timepoints.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/configuration/timepoints.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Mongo; module.watch(require("meteor/mongo"), { Mongo: function (v) { Mongo = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var TimepointSchema; module.watch(require("meteor/ohif:measurements/both/schema/timepoints"), { schema: function (v) { TimepointSchema = v; } }, 3); var configuration = {}; var TimepointApi = /*#__PURE__*/ function () { TimepointApi.setConfiguration = function () { function setConfiguration(config) { _.extend(configuration, config); } return setConfiguration; }(); TimepointApi.getConfiguration = function () { function getConfiguration() { return configuration; } return getConfiguration; }(); function TimepointApi(currentTimepointId) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (currentTimepointId) { this.currentTimepointId = currentTimepointId; } this.options = options; this.timepoints = new Mongo.Collection(null); this.timepoints.attachSchema(TimepointSchema); this.timepoints._debugName = 'Timepoints'; } var _proto = TimepointApi.prototype; _proto.retrieveTimepoints = function () { function retrieveTimepoints(filter) { var _this = this; var retrievalFn = configuration.dataExchange.retrieve; if (!_.isFunction(retrievalFn)) { OHIF.log.error('Timepoint retrieval function has not been configured.'); return; } return new Promise(function (resolve, reject) { retrievalFn(filter).then(function (timepointData) { OHIF.log.info('Timepoint data retrieval'); _.each(timepointData, function (timepoint) { delete timepoint._id; var query = { timepointId: timepoint.timepointId }; _this.timepoints.update(query, { $set: timepoint }, { upsert: true }); }); resolve(); }).catch(function (reason) { OHIF.log.error("Timepoint retrieval function failed: " + reason); reject(reason); }); }); } return retrieveTimepoints; }(); _proto.storeTimepoints = function () { function storeTimepoints() { var storeFn = configuration.dataExchange.store; if (!_.isFunction(storeFn)) { return; } var timepointData = this.timepoints.find().fetch(); OHIF.log.info('Preparing to store timepoints'); OHIF.log.info(JSON.stringify(timepointData, null, 2)); storeFn(timepointData).then(function () { return OHIF.log.info('Timepoint storage completed'); }); } return storeTimepoints; }(); _proto.disassociateStudy = function () { function disassociateStudy(timepointIds, studyInstanceUid) { var _this2 = this; var disassociateFn = configuration.dataExchange.disassociate; disassociateFn(timepointIds, studyInstanceUid).then(function () { OHIF.log.info('Disassociation completed'); _this2.timepoints.remove({}); _this2.retrieveTimepoints({}); }); } return disassociateStudy; }(); _proto.removeTimepoint = function () { function removeTimepoint(timepointId) { var _this3 = this; var removeFn = configuration.dataExchange.remove; if (!_.isFunction(removeFn)) { return; } var timepointData = { timepointId: timepointId }; OHIF.log.info('Preparing to remove timepoint'); OHIF.log.info(JSON.stringify(timepointData, null, 2)); removeFn(timepointData).then(function () { OHIF.log.info('Timepoint removal completed'); _this3.timepoints.remove(timepointData); }); } return removeTimepoint; }(); _proto.updateTimepoint = function () { function updateTimepoint(timepointId, query) { var _this4 = this; var updateFn = configuration.dataExchange.update; if (!_.isFunction(updateFn)) { return; } var timepointData = { timepointId: timepointId }; OHIF.log.info('Preparing to update timepoint'); OHIF.log.info(JSON.stringify(timepointData, null, 2)); OHIF.log.info(JSON.stringify(query, null, 2)); updateFn(timepointData, query).then(function () { OHIF.log.info('Timepoint updated completed'); _this4.timepoints.update(timepointData, query); }); } return updateTimepoint; }(); // Return all timepoints _proto.all = function () { function all() { var filter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return this.timepoints.find(filter, { sort: { latestDate: -1 } }).fetch(); } return all; }(); // Return only the current timepoint _proto.current = function () { function current() { return this.timepoints.findOne({ timepointId: this.currentTimepointId }); } return current; }(); _proto.lock = function () { function lock() { var current = this.current(); if (!current) { return; } this.timepoints.update(current._id, { $set: { locked: true } }); } return lock; }(); // Return the prior timepoint _proto.prior = function () { function prior() { var current = this.current(); if (!current) { return; } var latestDate = current.latestDate; return this.timepoints.findOne({ latestDate: { $lt: latestDate } }, { sort: { latestDate: -1 } }); } return prior; }(); // Return only the current and prior timepoints _proto.currentAndPrior = function () { function currentAndPrior() { var timepoints = []; var current = this.current(); if (current) { timepoints.push(current); } var prior = this.prior(); if (current && prior && prior._id !== current._id) { timepoints.push(prior); } return timepoints; } return currentAndPrior; }(); // Return only the comparison timepoints _proto.comparison = function () { function comparison() { return this.currentAndPrior(); } return comparison; }(); // Return only the baseline timepoint _proto.baseline = function () { function baseline() { return this.timepoints.findOne({ timepointType: 'baseline' }); } return baseline; }(); // Return only the nadir timepoint _proto.nadir = function () { function nadir() { var timepoint = this.timepoints.findOne({ timepointKey: 'nadir' }); return timepoint || this.baseline(); } return nadir; }(); // Return only the key timepoints (current, prior, nadir and baseline) _proto.key = function () { function key() { var filter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var result = []; // Get all the timepoints var all = this.all(filter); // Iterate over each timepoint and insert the key ones in the result _.each(all, function (timepoint, index) { if (index < 2 || index === all.length - 1) { result.push(timepoint); } }); // Return the resulting timepoints return result; } return key; }(); // Return only the timepoints for the given study _proto.study = function () { function study(studyInstanceUid) { var result = []; // Iterate over each timepoint and insert the key ones in the result _.each(this.all(), function (timepoint, index) { if (_.contains(timepoint.studyInstanceUids, studyInstanceUid)) { result.push(timepoint); } }); // Return the resulting timepoints return result; } return study; }(); // Return the timepoint's name _proto.name = function () { function name(timepoint) { // Check if this is a Baseline timepoint, if it is, return 'Baseline' if (timepoint.timepointType === 'baseline') { return 'Baseline'; } else if (timepoint.visitNumber) { return 'Follow-up ' + timepoint.visitNumber; } // Retrieve all of the relevant follow-up timepoints for this patient var followupTimepoints = this.timepoints.find({ patientId: timepoint.patientId, timepointType: timepoint.timepointType }, { sort: { latestDate: 1 } }); // Create an array of just timepointIds, so we can use indexOf // on it to find the current timepoint's relative position var followupTimepointIds = followupTimepoints.map(function (timepoint) { return timepoint.timepointId; }); // Calculate the index of the current timepoint in the array of all // relevant follow-up timepoints var index = followupTimepointIds.indexOf(timepoint.timepointId) + 1; // If index is 0, it means that the current timepoint was not in the list // Log a warning and return here if (!index) { OHIF.log.warn('Current follow-up was not in the list of relevant follow-ups?'); return; } // Return the timepoint name as 'Follow-up N' return 'Follow-up ' + index; } return name; }(); // Build the timepoint title based on its date _proto.title = function () { function title(timepoint) { var timepointName = this.name(timepoint); var all = _.clone(this.all()); var index = -1; var currentIndex = null; for (var i = 0; i < all.length; i++) { var currentTimepoint = all[i]; // Skip the iterations until we can't find the selected timepoint on study list if (this.currentTimepointId === currentTimepoint.timepointId) { currentIndex = 0; } if (_.isNumber(currentIndex)) { index = currentIndex++; } // Break the loop if reached the timepoint to get the title if (currentTimepoint.timepointId === timepoint.timepointId) { break; } } var states = { 0: '(Current)', 1: '(Prior)' }; // TODO: [design] find out how to define the nadir timepoint var parenthesis = states[index] || ''; return timepointName + " " + parenthesis; } return title; }(); return TimepointApi; }(); OHIF.measurements.TimepointApi = TimepointApi; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"schema":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/schema/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurements.js")); module.watch(require("./timepoints.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurements.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/schema/measurements.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ MeasurementSchemaTypes: function () { return MeasurementSchemaTypes; } }); var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var Measurement = new SimpleSchema({ additionalData: { type: Object, label: 'Additional Data', defaultValue: {}, optional: true, blackbox: true }, userId: { type: String, label: 'User ID', optional: true }, patientId: { type: String, label: 'Patient ID', optional: true }, measurementNumber: { type: Number, label: 'Measurement Number', optional: true }, timepointId: { type: String, label: 'Timepoint ID', optional: true }, // Force value to be current date (on server) upon insert // and prevent updates thereafter. createdAt: { type: Date, autoValue: function () { if (this.isInsert) { return new Date(); } else if (this.isUpsert) { return { $setOnInsert: new Date() }; } else {// [PWV-184] Preventing unset due to child tools updating // this.unset(); // Prevent user from supplying their own value } } }, // Force value to be current date (on server) upon update updatedAt: { type: Date, autoValue: function () { if (this.isUpdate) {// return new Date(); } }, optional: true } }); var StudyLevelMeasurement = new SimpleSchema([Measurement, { studyInstanceUid: { type: String, label: 'Study Instance UID' } }]); var SeriesLevelMeasurement = new SimpleSchema([StudyLevelMeasurement, { seriesInstanceUid: { type: String, label: 'Series Instance UID' } }]); var CornerstoneVOI = new SimpleSchema({ windowWidth: { type: Number, label: 'Window Width', decimal: true, optional: true }, windowCenter: { type: Number, label: 'Window Center', decimal: true, optional: true } }); var CornerstoneViewportTranslation = new SimpleSchema({ x: { type: Number, label: 'X', decimal: true, optional: true }, y: { type: Number, label: 'Y', decimal: true, optional: true } }); var CornerstoneViewport = new SimpleSchema({ scale: { type: Number, label: 'Scale', decimal: true, optional: true }, translation: { type: CornerstoneViewportTranslation, label: 'Translation', optional: true }, voi: { type: CornerstoneVOI, label: 'VOI', optional: true }, invert: { type: Boolean, label: 'Invert', optional: true }, pixelReplication: { type: Boolean, label: 'Pixel Replication', optional: true }, hFlip: { type: Boolean, label: 'Horizontal Flip', optional: true }, vFlip: { type: Boolean, label: 'Vertical Flip', optional: true }, rotation: { type: Number, label: 'Rotation (degrees)', decimal: true, optional: true } }); var InstanceLevelMeasurement = new SimpleSchema([StudyLevelMeasurement, SeriesLevelMeasurement, { sopInstanceUid: { type: String, label: 'SOP Instance UID' }, viewport: { type: CornerstoneViewport, label: 'Viewport Parameters', optional: true } }]); var FrameLevelMeasurement = new SimpleSchema([StudyLevelMeasurement, SeriesLevelMeasurement, InstanceLevelMeasurement, { frameIndex: { type: Number, min: 0, label: 'Frame index in Instance' }, imagePath: { type: String, label: 'Identifier for the measurement\'s image' // studyInstanceUid_seriesInstanceUid_sopInstanceUid_frameIndex } }]); var CornerstoneToolMeasurement = new SimpleSchema([StudyLevelMeasurement, SeriesLevelMeasurement, InstanceLevelMeasurement, FrameLevelMeasurement, { toolType: { type: String, label: 'Cornerstone Tool Type', optional: true }, visible: { type: Boolean, label: 'Visible', defaultValue: true }, active: { type: Boolean, label: 'Active', defaultValue: false }, invalidated: { type: Boolean, label: 'Invalidated', defaultValue: false, optional: true } }]); var CornerstoneHandleBoundingBoxSchema = new SimpleSchema({ width: { type: Number, label: 'Width', decimal: true }, height: { type: Number, label: 'Height', decimal: true }, left: { type: Number, label: 'Left', decimal: true }, top: { type: Number, label: 'Top', decimal: true } }); var CornerstoneHandleSchema = new SimpleSchema({ x: { type: Number, label: 'X', decimal: true, optional: true // Not actually optional, but sometimes values like x/y position are missing }, y: { type: Number, label: 'Y', decimal: true, optional: true // Not actually optional, but sometimes values like x/y position are missing }, highlight: { type: Boolean, label: 'Highlight', defaultValue: false }, active: { type: Boolean, label: 'Active', defaultValue: false, optional: true }, drawnIndependently: { type: Boolean, label: 'Drawn Independently', defaultValue: false, optional: true }, movesIndependently: { type: Boolean, label: 'Moves Independently', defaultValue: false, optional: true }, allowedOutsideImage: { type: Boolean, label: 'Allowed Outside Image', defaultValue: false, optional: true }, hasMoved: { type: Boolean, label: 'Has Already Moved', defaultValue: false, optional: true }, hasBoundingBox: { type: Boolean, label: 'Has Bounding Box', defaultValue: false, optional: true }, boundingBox: { type: CornerstoneHandleBoundingBoxSchema, label: 'Bounding Box', optional: true }, index: { // TODO: Remove 'index' from bidirectionalTool since it's useless type: Number, optional: true }, locked: { type: Boolean, label: 'Locked', optional: true, defaultValue: false } }); var MeasurementSchemaTypes = { Measurement: Measurement, StudyLevelMeasurement: StudyLevelMeasurement, SeriesLevelMeasurement: SeriesLevelMeasurement, InstanceLevelMeasurement: InstanceLevelMeasurement, FrameLevelMeasurement: FrameLevelMeasurement, CornerstoneToolMeasurement: CornerstoneToolMeasurement, CornerstoneHandleSchema: CornerstoneHandleSchema }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"timepoints.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/both/schema/timepoints.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ schema: function () { return schema; } }); var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var schema = new SimpleSchema({ patientId: { type: String, label: 'Patient ID', optional: true }, timepointId: { type: String, label: 'Timepoint ID' }, timepointType: { type: String, label: 'Timepoint Type', allowedValues: ['baseline', 'followup'], defaultValue: 'baseline' }, isLocked: { type: Boolean, label: 'Timepoint Locked' }, studyInstanceUids: { type: [String], label: 'Study Instance Uids', defaultValue: [] }, earliestDate: { type: Date, label: 'Earliest Study Date from associated studies' }, latestDate: { type: Date, label: 'Most recent Study Date from associated studies' }, visitNumber: { type: Number, label: 'Number of patient\'s visit', optional: true }, studiesData: { type: [Object], label: 'Studies data to allow lazy loading', optional: true, blackbox: true } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"client":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./conformance")); module.watch(require("./lib")); module.watch(require("./helpers")); module.watch(require("./components")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"components":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./association")); module.watch(require("./caseProgress")); module.watch(require("./measurementTable")); module.watch(require("./measurementLightTable")); module.watch(require("./measureFlow")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"association":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/association/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./associationModal/associationModal.html")); module.watch(require("./associationModal/associationModal.js")); module.watch(require("./associationModal/studyAssociationTable/studyAssociationTable.html")); module.watch(require("./associationModal/studyAssociationTable/studyAssociationTable.styl")); module.watch(require("./associationModal/studyAssociationTable/studyAssociationTable.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"associationModal":{"associationModal.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/association/associationModal/associationModal.html // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.associationModal.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.associationModal.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/association/associationModal/template.associationModal.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("dialogStudyAssociation"); Template["dialogStudyAssociation"] = new Template("Template.dialogStudyAssociation", (function() { var view = this; return Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("extend"), view.lookup("."), Spacebars.kw({ schema: Spacebars.dot(view.lookup("instance"), "schema"), dialogClass: "modal-lg", title: "Study Association", confirmLabel: "Save" })); }, function() { return Spacebars.include(view.lookupTemplate("dialogForm"), function() { return [ "\n ", Spacebars.include(view.lookupTemplate("studyAssociationTable")), "\n " ]; }); }); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"associationModal.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/association/associationModal/associationModal.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Meteor; module.watch(require("meteor/meteor"), { Meteor: function (v) { Meteor = v; } }, 0); var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 1); var Blaze; module.watch(require("meteor/blaze"), { Blaze: function (v) { Blaze = v; } }, 2); var Random; module.watch(require("meteor/random"), { Random: function (v) { Random = v; } }, 3); var moment; module.watch(require("meteor/momentjs:moment"), { moment: function (v) { moment = v; } }, 4); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 5); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 6); Template.dialogStudyAssociation.onCreated(function () { var instance = Template.instance(); instance.data.confirmCallback = function (formData) { OHIF.log.info('Saving associations'); var Timepoints = OHIF.studylist.timepointApi.timepoints; // Find the rows of the study association table var $tableRows = instance.$('#studyAssociationTable table tbody tr'); // Create an empty object to group studies into var studies = {}; // Loop through each row to parse the data $tableRows.each(function () { // Get a selector for this row var $row = $(this); // Check the includeStudy checkbox to see if we should parse this row var includeStudy = $row.find('input.includeStudy[type="checkbox"]').eq(0).prop('checked'); if (!includeStudy) { return; } // Find the selected timepoint option for this study var $timepointInput = $row.find('input.timepointOption[type="radio"]:checked'); // Find the related label and trim it down to actual label (TODO: do this another way) var timepointType = $timepointInput.val(); // Get the study metaData by checking the row with the template engine Blaze var data = Blaze.getData(this); // Concatenate the study data to an array, depending on whether is was marked as baseline // or follow-up if (!studies.hasOwnProperty(timepointType)) { studies[timepointType] = []; } studies[timepointType].push(data); }); var studiesKeys = Object.keys(studies); // TODO: REMOVE - Temporary for RSNA var hasBaseline = _.contains(studiesKeys, 'baseline'); if (hasBaseline) { var patientId = studies[studiesKeys[0]][0].patientId; Timepoints.remove({ patientId: patientId }); } studiesKeys.forEach(function (timepointType) { // Get the studies associated with this timepoint var relatedStudies = studies[timepointType]; // Create an array of all the studyInstanceUids for storage in the Timepoint var studyInstanceUids = relatedStudies.map(function (study) { return study.studyInstanceUid; }); // Create an array of all the studyDates for storage in the Timepoint var studyDates = relatedStudies.map(function (study) { return moment(study.studyDate).toDate(); }); // Sort the study dates, so we can get a range for these values studyDates = studyDates.sort(); // HipaaEventType to log changes in collections var hipaaEventType; var hipaaEvent; // Check if these studies are already associated with an existing Timepoint var existingTimepoint; if (timepointType === 'baseline') { // If we're trying to associate them to the Baseline, we don't need to // check if the studyInstanceUids are already associated with anything else existingTimepoint = Timepoints.findOne({ patientId: relatedStudies[0].patientId, timepointType: 'baseline' }); } else { // If we're trying to associate them to a Follow-up, we should check if any // of them are already part of a Follow-up (e.g. Follow-up 1), so that // the rest will also be associated with Follow-up 1. existingTimepoint = Timepoints.findOne({ patientId: relatedStudies[0].patientId, studyInstanceUids: { $in: studyInstanceUids } }); } var timepointId; if (existingTimepoint) { // If these studies are already associated with an existing Timepoint, // and the desired timepoint type is the same (e.g. Follow-up), update // this Timepoint instead of creating a new one Timepoints.update(existingTimepoint._id, { $set: { studyInstanceUids: studyInstanceUids } }); timepointId = existingTimepoint.timepointId; hipaaEventType = 'modify'; } else { // Create a new timepoint to represent the (baseline or follow-up) studies var timepoint = { timepointType: timepointType, timepointId: Random.id(), studyInstanceUids: studyInstanceUids, patientId: relatedStudies[0].patientId, earliestDate: studyDates[0], latestDate: studyDates[studyDates.length - 1], isLocked: false }; // Insert this timepoint into the Timepoints Collection Timepoints.insert(timepoint); timepointId = timepoint.timepointId; hipaaEventType = 'create'; } // Log hipaaEvent = { eventType: hipaaEventType, userId: Meteor.userId(), userName: Meteor.user().profile.fullName, collectionName: 'Timepoints', recordId: timepointId, patientId: relatedStudies[0].patientId, patientName: relatedStudies[0].patientName }; }); OHIF.studylist.timepointApi.storeTimepoints(); return formData; }; }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"studyAssociationTable":{"studyAssociationTable.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/association/associationModal/studyAssociationTable/studyAss // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.studyAssociationTable.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.studyAssociationTable.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/association/associationModal/studyAssociationTable/template.studyAssoc // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("studyAssociationTable"); Template["studyAssociationTable"] = new Template("Template.studyAssociationTable", (function() { var view = this; return HTML.DIV({ id: "studyAssociationTable" }, "\n ", HTML.DIV({ id: "associationInstructions", class: "row" }, "\n ", HTML.DIV({ class: "col-md-12" }, "\n ", HTML.Raw("
Instructions
"), "\n ", HTML.Raw("

Select the studies you would like to associate to a time point. Only one follow-up time point can be associated at the same time.

"), "\n ", HTML.P("We have automatically retrieved all studies within 14 days (", Blaze.View("lookup:formatDA", function() { return Spacebars.mustache(view.lookup("formatDA"), Spacebars.dot(view.lookup("."), "earliestDate")); }), " to ", Blaze.View("lookup:formatDA", function() { return Spacebars.mustache(view.lookup("formatDA"), view.lookup("latestDate")); }), ") of your selected studies, in case you forgot to select a study."), "\n "), "\n "), HTML.Raw('\n\n
\n
\n '), HTML.TABLE({ class: "table table-responsive" }, "\n ", HTML.THEAD("\n ", HTML.TR("\n ", HTML.TH({ class: "center" }, "Include Study?"), "\n ", HTML.TH({ class: "center" }, "Study Date"), "\n ", HTML.TH({ class: "center" }, "Patient Name"), "\n ", HTML.TH({ class: "center" }, "Study Description"), "\n ", HTML.TH({ class: "center" }, "Timepoint Type"), "\n "), "\n "), "\n\n ", HTML.TBODY("\n ", Blaze.Each(function() { return Spacebars.call(view.lookup("relevantStudies")); }, function() { return [ "\n ", HTML.TR({ class: function() { return Blaze.If(function() { return Spacebars.call(view.lookup("autoselected")); }, function() { return "disabled"; }); } }, "\n ", HTML.TD({ class: "checkboxWrapper center" }, "\n ", HTML.LABEL("\n ", HTML.INPUT(HTML.Attrs({ type: "checkbox", class: "includeStudy" }, function() { return Spacebars.attrMustache(view.lookup("valueIf"), view.lookup("autoselected"), "", "checked"); })), " ", HTML.SPAN(), "\n "), "\n "), "\n ", HTML.TD({ class: "center studyDataCell" }, "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("autoselected")); }, function() { return [ "\n ", HTML.P({ class: "studyDate autoselected", "data-toggle": "tooltip", title: "This study was autoselected." }, "\n ", Blaze.View("lookup:formatDA", function() { return Spacebars.mustache(view.lookup("formatDA"), view.lookup("studyDate")); }), "\n "), "\n " ]; }, function() { return [ "\n ", HTML.P({ class: "studyDate" }, Blaze.View("lookup:formatDA", function() { return Spacebars.mustache(view.lookup("formatDA"), view.lookup("studyDate")); })), "\n " ]; }), "\n "), "\n ", HTML.TD({ class: "center studyDataCell" }, "\n ", HTML.P(Blaze.View("lookup:formatPN", function() { return Spacebars.mustache(view.lookup("formatPN"), view.lookup("patientName")); })), "\n "), "\n ", HTML.TD({ class: "studyDataCell" }, "\n ", HTML.P(Blaze.View("lookup:studyDescription", function() { return Spacebars.mustache(view.lookup("studyDescription")); })), "\n "), "\n ", HTML.TD({ class: "timepointOptions center studyDataCell noselect" }, "\n ", Blaze.Each(function() { return Spacebars.call(view.lookup("timepointOptions")); }, function() { return [ "\n ", HTML.LABEL({ class: "noselect" }, "\n ", HTML.INPUT(HTML.Attrs({ type: "radio", name: function() { return Spacebars.mustache(Spacebars.dot(view.lookup(".."), "_id")); }, value: function() { return Spacebars.mustache(view.lookup("value")); }, class: "timepointOption" }, function() { return Spacebars.attrMustache(view.lookup("valueIf"), view.lookup("checked"), "checked", ""); }, function() { return Spacebars.attrMustache(view.lookup("valueIf"), Spacebars.dot(view.lookup(".."), "autoselected"), "disabled", ""); })), "\n ", HTML.SPAN(), Blaze.View("lookup:name", function() { return Spacebars.mustache(view.lookup("name")); }), "\n "), "\n " ]; }), "\n "), "\n "), "\n " ]; }), "\n "), "\n "), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"studyAssociationTable.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/association/associationModal/studyAssociationTable/studyAssociationTab // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var moment; module.watch(require("meteor/momentjs:moment"), { moment: function (v) { moment = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); /** * Finds related studies within defined time window of =/- 14 days of selected studies * @param selectedStudies * @param range Object */ function getDateRange(selectedStudies, range) { if (range === undefined) { range = { days: 14 }; } if (!selectedStudies.length) { return; } var earliestStudy = selectedStudies[0]; var latestStudy = selectedStudies[selectedStudies.length - 1]; var earliestDate = moment(earliestStudy.studyDate, 'YYYYMMDD'); earliestDate.subtract(range); var latestDate = moment(latestStudy.studyDate, 'YYYYMMDD'); latestDate.add(range); return { earliestDate: earliestDate, latestDate: latestDate }; } /** * Selects all studies related to the currently input studies, * based on various criteria. Returns the entire array of related studies. * * (at the moment, this is only the date range +/- 14 days, with a matching patientId) * * @param selectedStudies A user-selected list of studies * @returns {*} The entire array of related studies */ function autoSelectStudies(selectedStudies) { if (!selectedStudies.length) { return; } var range = getDateRange(selectedStudies); // Fetch autoselected studies based on the date range // Note that we used MongoDB's fetch here so we have a mutable array, // rather than a Cursor var autoselected = OHIF.studylist.collections.Studies.find({ studyDate: { $gte: range.earliestDate.format('YYYYMMDD'), $lte: range.latestDate.format('YYYYMMDD') } }, { sort: { studyDate: 1 } }).fetch(); // Make an array of studyInstanceUids in selectedStudies var studyInstanceUids = selectedStudies.map(function (selectedStudy) { return selectedStudy.studyInstanceUid; }); autoselected.forEach(function (study) { var exists = studyInstanceUids.indexOf(study.studyInstanceUid); if (exists > -1) { study.autoselected = false; return; } study.autoselected = true; }); return autoselected; } Template.studyAssociationTable.helpers({ /** * This helpers includes the user-selected and autoselected studies * to be associated. * * @returns {Array.} */ relevantStudies: function () { var selectedStudies = OHIF.studylist.getSelectedStudies(); return autoSelectStudies(selectedStudies); }, /** * This helper returns the list of Timepoint types the user can set for this study * * @returns {Array.} */ timepointOptions: function () { return [{ value: 'baseline', name: 'Baseline', checked: true }, { value: 'followup', name: 'Follow-up', checked: false }]; }, earliestDate: function () { var selectedStudies = OHIF.studylist.getSelectedStudies(); var range = getDateRange(selectedStudies); if (range) { return range.earliestDate; } }, latestDate: function () { var selectedStudies = OHIF.studylist.getSelectedStudies(); var range = getDateRange(selectedStudies); if (range) { return range.latestDate; } } }); Template.studyAssociationTable.events({ 'change input.includeStudy': function (event, instance) { var checkbox = event.currentTarget; var studyRow = $(checkbox).closest('tr'); var studyDataCells = studyRow.find('td.studyDataCell'); if (checkbox.checked === true) { studyRow.removeClass('disabled'); studyDataCells.find('input').attr('disabled', false); } else { studyRow.addClass('disabled'); studyDataCells.find('input').attr('disabled', true); } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"studyAssociationTable.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/association/associationModal/studyAssociationTable/studyAss // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./studyAssociationTable.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"studyAssociationTable.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/association/associationModal/studyAssociationTable/studyAssociationTab // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n#studyAssociationTable {\n color: #fff;\n}\n#studyAssociationTable .header {\n text-align: center;\n}\n#studyAssociationTable .center {\n text-align: center;\n}\n#studyAssociationTable #associationInstructions {\n margin-bottom: 2px;\n padding: 0 15px;\n}\n#studyAssociationTable #associationInstructions {\n background: #151a1f;\n}\nbody.theme-tide #studyAssociationTable #associationInstructions {\n background: #151a1f;\n}\nbody.theme-tigerlily #studyAssociationTable #associationInstructions {\n background: #151a1f;\n}\nbody.theme-crickets #studyAssociationTable #associationInstructions {\n background: #231c1e;\n}\nbody.theme-honeycomb #studyAssociationTable #associationInstructions {\n background: #18161a;\n}\nbody.theme-mint #studyAssociationTable #associationInstructions {\n background: #15191e;\n}\nbody.theme-overcast #studyAssociationTable #associationInstructions {\n background: #15191e;\n}\nbody.theme-quartz #studyAssociationTable #associationInstructions {\n background: #151a1f;\n}\n#studyAssociationTable .tableHeaderBackground {\n position: absolute;\n height: 51px;\n left: 0;\n width: 100%;\n z-index: 1;\n border-bottom: solid 1px;\n}\n#studyAssociationTable .tableHeaderBackground {\n background-color: #151a1f;\n}\nbody.theme-tide #studyAssociationTable .tableHeaderBackground {\n background-color: #151a1f;\n}\nbody.theme-tigerlily #studyAssociationTable .tableHeaderBackground {\n background-color: #151a1f;\n}\nbody.theme-crickets #studyAssociationTable .tableHeaderBackground {\n background-color: #231c1e;\n}\nbody.theme-honeycomb #studyAssociationTable .tableHeaderBackground {\n background-color: #18161a;\n}\nbody.theme-mint #studyAssociationTable .tableHeaderBackground {\n background-color: #15191e;\n}\nbody.theme-overcast #studyAssociationTable .tableHeaderBackground {\n background-color: #15191e;\n}\nbody.theme-quartz #studyAssociationTable .tableHeaderBackground {\n background-color: #151a1f;\n}\n#studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #6fbde2;\n}\nbody.theme-tide #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #6fbde2;\n}\nbody.theme-tigerlily #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #d47c66;\n}\nbody.theme-crickets #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #d47c66;\n}\nbody.theme-honeycomb #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #d47c66;\n}\nbody.theme-mint #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #76d27d;\n}\nbody.theme-overcast #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #74f1fa;\n}\nbody.theme-quartz #studyAssociationTable .tableHeaderBackground {\n border-bottom-color: #abcdf6;\n}\n#studyAssociationTable table {\n z-index: 2;\n position: relative;\n}\n#studyAssociationTable table thead tr th {\n padding-bottom: 5px;\n border-bottom: solid 1px #6fbde2;\n height: 50px;\n font-weight: normal;\n}\n#studyAssociationTable table tbody tr {\n padding: 5px;\n background-color: #000;\n}\n#studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #151a1f;\n}\nbody.theme-tide #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #151a1f;\n}\nbody.theme-tigerlily #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #151a1f;\n}\nbody.theme-crickets #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #231c1e;\n}\nbody.theme-honeycomb #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #18161a;\n}\nbody.theme-mint #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #15191e;\n}\nbody.theme-overcast #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #15191e;\n}\nbody.theme-quartz #studyAssociationTable table tbody tr:nth-child(even) {\n background-color: #151a1f;\n}\n#studyAssociationTable table tbody tr td {\n position: relative;\n height: 30px;\n line-height: 30px;\n color: #fff;\n border-top: 1px solid #436270;\n border-bottom: 1px solid #436270;\n vertical-align: middle;\n -webkit-transition: all 0.1s ease;\n -moz-transition: all 0.1s ease;\n -ms-transition: all 0.1s ease;\n -o-transition: all 0.1s ease;\n transition: all 0.1s ease;\n}\n#studyAssociationTable table tbody tr td p {\n margin: 0;\n}\n#studyAssociationTable table tbody tr td.timepointOptions label {\n font-weight: 200;\n cursor: pointer;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input {\n margin: 0 3px;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input[type=\"radio\"] {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input + span {\n display: block;\n position: absolute;\n border: 2px solid #c8c8c8;\n -webkit-border-radius: 100%;\n -moz-border-radius: 100%;\n -ms-border-radius: 100%;\n -o-border-radius: 100%;\n border-radius: 100%;\n height: 15px;\n width: 15px;\n top: 2px;\n left: 0;\n padding: 3px;\n z-index: 5;\n -webkit-transition: border;\n -moz-transition: border;\n -ms-transition: border;\n -o-transition: border;\n transition: border;\n -webkit-transition: border 0.25s linear;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input + span:before {\n display: block;\n content: '';\n -webkit-border-radius: 100%;\n -moz-border-radius: 100%;\n -ms-border-radius: 100%;\n -o-border-radius: 100%;\n border-radius: 100%;\n height: 100%;\n width: 100%;\n -webkit-transition: background;\n -moz-transition: background;\n -ms-transition: background;\n -o-transition: background;\n transition: background;\n -webkit-transition: background 0.25s linear;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #20a5d6;\n}\nbody.theme-tide #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #20a5d6;\n}\nbody.theme-tigerlily #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #fa8947;\n}\nbody.theme-crickets #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #d4c3c1;\n}\nbody.theme-honeycomb #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #cda56b;\n}\nbody.theme-mint #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #31b166;\n}\nbody.theme-overcast #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #507d80;\n}\nbody.theme-quartz #studyAssociationTable table tbody tr td.timepointOptions input:checked + span {\n border-color: #7858ce;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #20a5d6;\n}\nbody.theme-tide #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #fa8947;\n}\nbody.theme-crickets #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #cda56b;\n}\nbody.theme-mint #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #31b166;\n}\nbody.theme-overcast #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #507d80;\n}\nbody.theme-quartz #studyAssociationTable table tbody tr td.timepointOptions input:checked + span:before {\n background-color: #7858ce;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input:disabled + span {\n border-color: #535960 !important;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input:disabled:checked + span {\n border-color: #0d4256 !important;\n}\n#studyAssociationTable table tbody tr td.timepointOptions input:disabled:checked + span:before {\n background-color: #0d4256 !important;\n}\n#studyAssociationTable table tbody tr td.timepointOptions label {\n padding: 0 5px;\n padding-left: 20px;\n display: inline-block;\n position: relative;\n line-height: initial;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper label {\n display: block;\n margin: 0;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper input {\n margin: 0 3px;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper input[type=\"checkbox\"] {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper input + span {\n display: block;\n border: 1px solid #b6b6b6;\n background-color: #fff;\n -webkit-border-radius: 2px;\n -moz-border-radius: 2px;\n -ms-border-radius: 2px;\n -o-border-radius: 2px;\n border-radius: 2px;\n height: 16px;\n width: 16px;\n margin: 0 auto;\n z-index: 5;\n -webkit-transition: border;\n -moz-transition: border;\n -ms-transition: border;\n -o-transition: border;\n transition: border;\n -webkit-transition: border 0.25s linear;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper input + span:before {\n display: block;\n position: relative;\n content: '';\n font-size: 9px;\n top: -7px;\n color: #fff;\n background-color: transparent;\n -webkit-transition: background;\n -moz-transition: background;\n -ms-transition: background;\n -o-transition: background;\n transition: background;\n -webkit-transition: background 0.25s linear;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #20a5d6;\n}\nbody.theme-tide #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #fa8947;\n}\nbody.theme-crickets #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #cda56b;\n}\nbody.theme-mint #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #31b166;\n}\nbody.theme-overcast #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #507d80;\n}\nbody.theme-quartz #studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span {\n background-color: #7858ce;\n}\n#studyAssociationTable table tbody tr td.checkboxWrapper input:checked + span:before {\n content: '\\2713';\n}\n#studyAssociationTable table tbody tr.disabled td {\n color: #535960;\n}\n#studyAssociationTable table tbody tr:hover,\n#studyAssociationTable table tbody tr:active,\n#studyAssociationTable table tbody tr.active {\n background-color: #2c363f;\n color: #fff;\n}\n#studyAssociationTable table tbody tr:hover td,\n#studyAssociationTable table tbody tr:active td,\n#studyAssociationTable table tbody tr.active td {\n border-top: 1px solid #436270;\n border-bottom: 1px solid #436270;\n background-color: #2c363f;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}}},"caseProgress":{"caseProgress.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/caseProgress/caseProgress.html // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.caseProgress.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.caseProgress.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/template.caseProgress.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("caseProgress"); Template["caseProgress"] = new Template("Template.caseProgress", (function() { var view = this; return Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("extend"), Spacebars.kw({ class: "caseProgress", api: Spacebars.dot(view.lookup("instance"), "api") })); }, function() { return Spacebars.include(view.lookupTemplate("form"), function() { return [ "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("instance"), "isFollowUp", "get")); }, function() { return [ "\n ", Blaze._TemplateWith(function() { return { isLocked: Spacebars.call(view.lookup("isLocked")), progressPercent: Spacebars.call(view.lookup("progressPercent")), progressText: Spacebars.call(view.lookup("progressText")) }; }, function() { return Spacebars.include(view.lookupTemplate("radialProgressBar")); }), "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("isLocked")); }, function() { return [ "\n ", HTML.DIV({ class: "caseProgressStatus" }, "\n ", HTML.H5("Locked"), "\n "), "\n " ]; }), "\n " ]; }), "\n " ]; }); }); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"caseProgress.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/caseProgress.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); Template.caseProgress.onCreated(function () { var instance = Template.instance(); instance.progressPercent = new ReactiveVar(); instance.progressText = new ReactiveVar(); instance.isLocked = new ReactiveVar(false); instance.isFollowUp = new ReactiveVar(false); }); Template.caseProgress.onRendered(function () { var instance = Template.instance(); var _instance$data = instance.data, timepointApi = _instance$data.timepointApi, measurementApi = _instance$data.measurementApi, timepointId = _instance$data.timepointId; // Stop here if we have no current timepoint ID (and therefore no defined timepointAPI) if (!timepointApi) { instance.progressPercent.set(100); return; } // Get the current and prior timepoints var current = timepointApi.timepoints.findOne({ timepointId: timepointId }); var priorFilter = { latestDate: { $lt: current.latestDate }, patientId: current.patientId }; var priorSorting = { sort: { latestDate: -1 } }; var prior = timepointApi.timepoints.findOne(priorFilter, priorSorting); // Stop here if timepoint is locked if (current && current.isLocked) { return instance.isLocked.set(true); } else { instance.isLocked.set(false); } // Stop here if no current or prior timepoint was found if (!current || !prior || !current.timepointId) { return instance.progressPercent.set(100); } // Retrieve the initial number of targets left to measure at this // follow-up. Note that this is done outside of the reactive function // below so that new lesions don't change the initial target count. var config = OHIF.measurements.MeasurementApi.getConfiguration(); var toolGroups = config.measurementTools; var toolIds = []; toolGroups.forEach(function (toolGroup) { return toolGroup.childTools.forEach(function (tool) { var option = 'options.caseProgress.include'; if (OHIF.utils.ObjectPath.get(tool, option)) { toolIds.push(tool.id); } }); }); var getTimepointFilter = function (timepointId) { return { timepointId: timepointId, toolId: { $in: toolIds } }; }; var getNumMeasurementsAtTimepoint = function (timepointId) { OHIF.log.info('getNumMeasurementsAtTimepoint'); var filter = getTimepointFilter(timepointId); var count = 0; toolGroups.forEach(function (toolGroup) { count += measurementApi.fetch(toolGroup.id, filter).length; }); return count; }; var getNumRemainingBetweenTimepoints = function (currentTimepointId, priorTimepointId) { var currentFilter = getTimepointFilter(currentTimepointId); var priorFilter = getTimepointFilter(priorTimepointId); var totalRemaining = 0; toolGroups.forEach(function (toolGroup) { var toolGroupId = toolGroup.id; var numCurrent = measurementApi.fetch(toolGroupId, currentFilter).length; var numPrior = measurementApi.fetch(toolGroupId, priorFilter).length; var remaining = Math.max(numPrior - numCurrent, 0); totalRemaining += remaining; }); return totalRemaining; }; // If we're currently reviewing a Baseline timepoint, don't do any // progress measurement. if (current.timepointType === 'baseline') { instance.progressPercent.set(100); instance.isFollowUp.set(false); } else { instance.isFollowUp.set(true); // Setup a reactive function to update the progress whenever // a measurement is made instance.autorun(function () { measurementApi.changeObserver.depend(); // Obtain the number of Measurements for which the current Timepoint has // no Measurement data var totalMeasurements = getNumMeasurementsAtTimepoint(prior.timepointId); var numRemainingMeasurements = getNumRemainingBetweenTimepoints(current.timepointId, prior.timepointId); var numMeasurementsMade = totalMeasurements - numRemainingMeasurements; // Update the Case Progress text with the remaining measurement count instance.progressText.set(numRemainingMeasurements); // Calculate the Case Progress as a percentage in order to update the // radial progress bar var progressPercent = Math.min(100, Math.round(100 * numMeasurementsMade / totalMeasurements)); instance.progressPercent.set(progressPercent); }); } }); Template.caseProgress.helpers({ progressPercent: function () { return Template.instance().progressPercent.get(); }, progressText: function () { return Template.instance().progressText.get(); }, isLocked: function () { return Template.instance().isLocked.get(); }, progressComplete: function () { var instance = Template.instance(); if (!instance.data.timepointApi) { return true; } var progressPercent = instance.progressPercent.get(); return progressPercent === 100; } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"caseProgress.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/caseProgress/caseProgress.styl // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./caseProgress.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"caseProgress.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/caseProgress.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.caseProgress {\n -webkit-transition: all 0.3 ease;\n -moz-transition: all 0.3 ease;\n -ms-transition: all 0.3 ease;\n -o-transition: all 0.3 ease;\n transition: all 0.3 ease;\n}\n.caseProgress .radialProgress {\n display: inline-block;\n float: left;\n}\n.caseProgress .caseProgressStatus {\n display: inline-block;\n float: left;\n margin-left: 22px;\n}\n.caseProgress .caseProgressStatus h5 {\n line-height: 40px;\n margin: 0;\n font-size: 15px;\n font-weight: bold;\n}\n.caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-tide .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-tigerlily .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-crickets .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-honeycomb .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-mint .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-overcast .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\nbody.theme-quartz .caseProgress .caseProgressStatus h5 {\n color: #fff;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./caseProgress.html")); module.watch(require("./caseProgress.styl")); module.watch(require("./caseProgress.js")); module.watch(require("./radialProgressBar/radialProgressBar.html")); module.watch(require("./radialProgressBar/radialProgressBar.styl")); module.watch(require("./radialProgressBar/radialProgressBar.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"radialProgressBar":{"radialProgressBar.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/caseProgress/radialProgressBar/radialProgressBar.html // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.radialProgressBar.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.radialProgressBar.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/radialProgressBar/template.radialProgressBar.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("radialProgressBar"); Template["radialProgressBar"] = new Template("Template.radialProgressBar", (function() { var view = this; return HTML.DIV({ class: "radialProgress" }, "\n ", HTML.SVG({ id: "svg", width: "26", height: "26", viewport: "0 0 26 26", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, "\n\n ", HTML.Comment(" stroke-dasharray is 2 * PI * radius !"), "\n ", HTML.CIRCLE({ r: "11", cx: "13", cy: "13", fill: "transparent", "stroke-dasharray": "69.11503837897544", "stroke-dashoffset": "0" }, "\n "), "\n ", Blaze.Unless(function() { return Spacebars.call(view.lookup("isLocked")); }, function() { return [ "\n ", HTML.CIRCLE({ id: "bar", r: "11", cx: "13", cy: "13", fill: "transparent", "stroke-dasharray": "69.11503837897544", style: function() { return [ "stroke-dashoffset: ", Spacebars.mustache(view.lookup("progressRadius")), "px;" ]; } }, "\n "), "\n " ]; }), "\n "), "\n ", HTML.DIV({ class: function() { return [ "progressArea ", Blaze.If(function() { return Spacebars.call(view.lookup("isLocked")); }, function() { return "locked"; }, function() { return Blaze.If(function() { return Spacebars.call(view.lookup("progressComplete")); }, function() { return "complete"; }); }) ]; } }, "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("isLocked")); }, function() { return [ "\n ", HTML.SVG("\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-status-lock"); } }), "\n "), "\n " ]; }, function() { return [ "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("progressComplete")); }, function() { return [ "\n ", HTML.SVG("\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-status-complete"); } }), "\n "), "\n " ]; }, function() { return [ "\n ", Blaze.View("lookup:progressText", function() { return Spacebars.mustache(view.lookup("progressText")); }), "\n " ]; }), "\n " ]; }), "\n "), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"radialProgressBar.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/radialProgressBar/radialProgressBar.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); Template.radialProgressBar.helpers({ progressComplete: function () { var instance = Template.instance(); return instance.data.progressPercent === 100; }, progressRadius: function () { var instance = Template.instance(); var radius = 11 * 2 * Math.PI; var percentLeft = (100 - instance.data.progressPercent) / 100; return percentLeft * radius; } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"radialProgressBar.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/caseProgress/radialProgressBar/radialProgressBar.styl // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./radialProgressBar.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"radialProgressBar.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/caseProgress/radialProgressBar/radialProgressBar.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.radialProgress {\n -webkit-border-radius: 100%;\n -moz-border-radius: 100%;\n -ms-border-radius: 100%;\n -o-border-radius: 100%;\n border-radius: 100%;\n height: 26px;\n margin-top: 3px;\n margin-right: 4px;\n position: relative;\n -webkit-box-shadow: 0 0 1em #000;\n -moz-box-shadow: 0 0 1em #000;\n -ms-box-shadow: 0 0 1em #000;\n -o-box-shadow: 0 0 1em #000;\n -webkit-box-shadow: 0 0 1em #000;\n -moz-box-shadow: 0 0 1em #000;\n -ms-box-shadow: 0 0 1em #000;\n -o-box-shadow: 0 0 1em #000;\n box-shadow: 0 0 1em #000;\n width: 26px;\n}\n.radialProgress #svg circle {\n stroke-dashoffset: 0;\n stroke-width: 3px;\n -webkit-transition: stroke-dashoffset 1s linear;\n -moz-transition: stroke-dashoffset 1s linear;\n -ms-transition: stroke-dashoffset 1s linear;\n -o-transition: stroke-dashoffset 1s linear;\n -webkit-transition: stroke-dashoffset 1s linear;\n -moz-transition: stroke-dashoffset 1s linear;\n -ms-transition: stroke-dashoffset 1s linear;\n -o-transition: stroke-dashoffset 1s linear;\n transition: stroke-dashoffset 1s linear;\n}\n.radialProgress #svg circle {\n stroke: #3c5d80;\n}\nbody.theme-tide .radialProgress #svg circle {\n stroke: #3c5d80;\n}\nbody.theme-tigerlily .radialProgress #svg circle {\n stroke: #744b71;\n}\nbody.theme-crickets .radialProgress #svg circle {\n stroke: #3c5d80;\n}\nbody.theme-honeycomb .radialProgress #svg circle {\n stroke: #3c5d80;\n}\nbody.theme-mint .radialProgress #svg circle {\n stroke: #3c5d80;\n}\nbody.theme-overcast .radialProgress #svg circle {\n stroke: #3c5d80;\n}\nbody.theme-quartz .radialProgress #svg circle {\n stroke: #3c5d80;\n}\n.radialProgress #svg #bar {\n -webkit-transform: rotate(270deg);\n -moz-transform: rotate(270deg);\n -ms-transform: rotate(270deg);\n -o-transform: rotate(270deg);\n -webkit-transform: rotate(270deg);\n -moz-transform: rotate(270deg);\n -ms-transform: rotate(270deg);\n -o-transform: rotate(270deg);\n transform: rotate(270deg);\n -webkit-transform-origin: center center;\n -moz-transform-origin: center center;\n -ms-transform-origin: center center;\n -o-transform-origin: center center;\n -webkit-transform-origin: center center;\n -moz-transform-origin: center center;\n -ms-transform-origin: center center;\n -o-transform-origin: center center;\n transform-origin: center center;\n}\n.radialProgress #svg #bar {\n stroke: #91b9cd;\n}\nbody.theme-tide .radialProgress #svg #bar {\n stroke: #91b9cd;\n}\nbody.theme-tigerlily .radialProgress #svg #bar {\n stroke: #9ccdf8;\n}\nbody.theme-crickets .radialProgress #svg #bar {\n stroke: #8be7b5;\n}\nbody.theme-honeycomb .radialProgress #svg #bar {\n stroke: #fab797;\n}\nbody.theme-mint .radialProgress #svg #bar {\n stroke: #a7e9b3;\n}\nbody.theme-overcast .radialProgress #svg #bar {\n stroke: #73f2fc;\n}\nbody.theme-quartz .radialProgress #svg #bar {\n stroke: #d7e8fe;\n}\n.radialProgress .progressArea {\n display: table;\n font-weight: 700;\n font-size: 12px;\n height: 26px;\n line-height: 26px;\n left: 50%;\n position: absolute;\n text-align: center;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n -moz-transform: translate(-50%, -50%);\n -ms-transform: translate(-50%, -50%);\n -o-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n width: 26px;\n}\n.radialProgress .progressArea {\n color: #91b9cd;\n}\nbody.theme-tide .radialProgress .progressArea {\n color: #91b9cd;\n}\nbody.theme-tigerlily .radialProgress .progressArea {\n color: #9ccdf8;\n}\nbody.theme-crickets .radialProgress .progressArea {\n color: #8be7b5;\n}\nbody.theme-honeycomb .radialProgress .progressArea {\n color: #fab797;\n}\nbody.theme-mint .radialProgress .progressArea {\n color: #a7e9b3;\n}\nbody.theme-overcast .radialProgress .progressArea {\n color: #73f2fc;\n}\nbody.theme-quartz .radialProgress .progressArea {\n color: #d7e8fe;\n}\n.radialProgress .progressArea.locked {\n line-height: 0;\n}\n.radialProgress .progressArea.locked,\n.radialProgress .progressArea.locked svg {\n height: 12px;\n width: 10px;\n}\n.radialProgress .progressArea.complete {\n line-height: 0;\n}\n.radialProgress .progressArea.complete,\n.radialProgress .progressArea.complete svg {\n height: 16px;\n width: 16px;\n}\n.radialProgress .progressArea svg {\n fill: #91b9cd;\n}\nbody.theme-tide .radialProgress .progressArea svg {\n fill: #91b9cd;\n}\nbody.theme-tigerlily .radialProgress .progressArea svg {\n fill: #9ccdf8;\n}\nbody.theme-crickets .radialProgress .progressArea svg {\n fill: #8be7b5;\n}\nbody.theme-honeycomb .radialProgress .progressArea svg {\n fill: #fab797;\n}\nbody.theme-mint .radialProgress .progressArea svg {\n fill: #a7e9b3;\n}\nbody.theme-overcast .radialProgress .progressArea svg {\n fill: #73f2fc;\n}\nbody.theme-quartz .radialProgress .progressArea svg {\n fill: #d7e8fe;\n}\n.radialProgress .progressArea svg {\n stroke: #91b9cd;\n}\nbody.theme-tide .radialProgress .progressArea svg {\n stroke: #91b9cd;\n}\nbody.theme-tigerlily .radialProgress .progressArea svg {\n stroke: #9ccdf8;\n}\nbody.theme-crickets .radialProgress .progressArea svg {\n stroke: #8be7b5;\n}\nbody.theme-honeycomb .radialProgress .progressArea svg {\n stroke: #fab797;\n}\nbody.theme-mint .radialProgress .progressArea svg {\n stroke: #a7e9b3;\n}\nbody.theme-overcast .radialProgress .progressArea svg {\n stroke: #73f2fc;\n}\nbody.theme-quartz .radialProgress .progressArea svg {\n stroke: #d7e8fe;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"measureFlow":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measureFlow/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measureFlow.html")); module.watch(require("./measureFlow.styl")); module.watch(require("./measureFlow.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measureFlow.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measureFlow/measureFlow.html // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measureFlow.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measureFlow.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measureFlow/template.measureFlow.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measureFlow"); Template["measureFlow"] = new Template("Template.measureFlow", (function() { var view = this; return HTML.DIV({ class: function() { return [ "measure-flow ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("."), "threeColumns")); }, function() { return "tree-columns"; }), " ", Spacebars.mustache(Spacebars.dot(view.lookup("instance"), "state", "get")) ]; }, style: function() { return [ "top:", Spacebars.mustache(view.lookup("choose"), Spacebars.dot(view.lookup("position"), "y"), 0), "px; left:", Spacebars.mustache(view.lookup("choose"), Spacebars.dot(view.lookup("position"), "x"), 0), "px" ]; }, tabindex: "-1" }, "\n ", HTML.BUTTON({ class: "btn-add", style: "opacity: 0" }, "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("."), "measurement", "location")); }, function() { return "Edit"; }, function() { return "Add"; }), " label\n "), "\n ", Blaze.If(function() { return Spacebars.dataMustache(view.lookup("eq"), Spacebars.dot(view.lookup("instance"), "state", "get"), "selected"); }, function() { return [ "\n ", HTML.DIV({ class: "tree-leaf" }, "\n ", HTML.I({ class: "icon-check" }), "\n ", HTML.SPAN(Blaze.View("lookup:instance.value.label", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("instance"), "value", "label")); })), "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("instance"), "descriptionEdit", "get")); }, function() { return [ "\n ", HTML.DIV({ class: "description clearfix" }, "\n ", HTML.TEXTAREA({ class: "pull-left", rows: "1", style: function() { return Blaze.Unless(function() { return Spacebars.call(Spacebars.dot(view.lookup("instance"), "description", "get")); }, function() { return "height:0"; }); }, value: function() { return Spacebars.mustache(Spacebars.dot(view.lookup("instance"), "description", "get")); } }), "\n "), "\n " ]; }, function() { return [ "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("instance"), "description", "get")); }, function() { return [ "\n ", HTML.DIV({ class: "descriptionText" }, Blaze.View("lookup:instance.description.get", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("instance"), "description", "get")); })), "\n " ]; }), "\n " ]; }), "\n ", HTML.DIV({ class: "actions clearfix" }, "\n ", HTML.BUTTON({ class: "pull-left btn-rename" }, "Relabel"), "\n ", HTML.BUTTON({ class: "pull-right btn-description" }, Blaze.View("lookup:valueIf", function() { return Spacebars.mustache(view.lookup("valueIf"), Spacebars.dot(view.lookup("instance"), "description", "get"), "Edit", "Add"); }), " description"), "\n "), "\n "), "\n " ]; }), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measureFlow.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measureFlow/measureFlow.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Meteor; module.watch(require("meteor/meteor"), { Meteor: function (v) { Meteor = v; } }, 0); var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 1); var Blaze; module.watch(require("meteor/blaze"), { Blaze: function (v) { Blaze = v; } }, 2); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 3); var Tracker; module.watch(require("meteor/tracker"), { Tracker: function (v) { Tracker = v; } }, 4); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 5); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 6); Template.measureFlow.onCreated(function () { var instance = Template.instance(); instance.value = instance.data.currentValue || ''; instance.state = new ReactiveVar('closed'); instance.description = new ReactiveVar(instance.data.currentDescription || ''); instance.descriptionEdit = new ReactiveVar(false); var items = ['Abdomen/Chest Wall', 'Adrenal', 'Bladder', 'Bone', 'Brain', 'Breast', 'Colon', 'Esophagus', 'Extremities', 'Gallbladder', 'Kidney', 'Liver', 'Lung', 'Lymph Node', 'Mediastinum/Hilum', 'Muscle', 'Neck', 'Other Soft Tissue', 'Ovary', 'Pancreas', 'Pelvis', 'Peritoneum/Omentum', 'Prostate', 'Retroperitoneum', 'Small Bowel', 'Spleen', 'Stomach', 'Subcutaneous']; instance.items = []; _.each(items, function (item) { instance.items.push({ label: item, value: item }); }); var commonItems = ['Abdomen/Chest Wall', 'Lung', 'Lymph Node', 'Liver', 'Mediastinum/Hilum', 'Pelvis', 'Peritoneum/Omentum', 'Retroperitoneum']; instance.commonItems = []; _.each(commonItems, function (item) { instance.commonItems.push({ label: item, value: item }); }); }); Template.measureFlow.onRendered(function () { var instance = Template.instance(); var $measureFlow = instance.$('.measure-flow'); var $btnAdd = instance.$('.btn-add'); // Make the measure flow bounded by the window borders $measureFlow.bounded(); $btnAdd.focus(); if (instance.data.autoClick) { $btnAdd.trigger('click', { clientX: instance.data.position.x, clientY: instance.data.position.Y }); } else { if (instance.data.direction) { var direction = instance.data.direction; var _$measureFlow$offset = $measureFlow.offset(), left = _$measureFlow$offset.left, top = _$measureFlow$offset.top; left = direction.x === -1 ? left -= $btnAdd.outerWidth() : left; top = direction.y === -1 ? top -= $btnAdd.outerHeight() : top; var distance = 5; left += direction.x * distance; top += direction.y * distance; $measureFlow.css({ left: left, top: top }); } // Display the button after reposition it $btnAdd.css('opacity', 1); } }); Template.measureFlow.events({ 'click, mousedown, mouseup': function (event, instance) { event.stopPropagation(); }, 'click .measure-flow .btn-add, click .measure-flow .btn-rename': function (event, instance) { var $measureFlow = instance.$('.measure-flow'); // Set the open state for the component instance.state.set('open'); // Wait template rerender before rendering the selectTree Tracker.afterFlush(function () { // Get the click or rendering position var position; if (_.isUndefined(event.clientX)) { position = { left: instance.data.position.x, top: instance.data.position.y }; } else { position = { left: event.clientX, top: event.clientY }; } // Define the data for selectTreeComponent var data = { key: 'label', items: instance.items, commonItems: instance.commonItems, hideCommon: instance.data.hideCommon, label: 'Assign label', searchPlaceholder: 'Search labels', // storageKey: 'measureLabelCommon', threeColumns: instance.data.threeColumns, position: position }; // Define in which element the selectTree will be rendered in var parentElement = $measureFlow[0]; // Render the selectTree element instance.selectTreeView = Blaze.renderWithData(Template.selectTree, data, parentElement); // Focus the measure flow to handle closing $measureFlow.focus(); }); }, 'click .measure-flow .btn-description': function (event, instance) { // Fade out the action buttons instance.$('.measure-flow .actions').addClass('fadeOut'); // Set the description edit mode instance.descriptionEdit.set(true); // Wait for DOM re-rendering, resize and focus the description textarea Tracker.afterFlush(function () { var $textarea = instance.$('textarea'); $textarea.trigger('input').focus().select(); }); }, 'input textarea, change textarea': function (event, instance) { var element = event.currentTarget; var $element = $(element); // Resize the textarea based on its content length $element.css('max-height', 0); $element.height(element.scrollHeight); $element.css('max-height', ''); // Reposition the measure flow if needed var $measureFlow = instance.$('.measure-flow'); $element.one('transitionend', function () { return $measureFlow.trigger('spatialChanged'); }); }, 'keydown textarea': function (event, instance) { // Unset the description edit mode if ENTER or ESC was pressed if (event.which === 13 || event.which === 27) { instance.$('.measure-flow .actions').removeClass('fadeOut'); instance.descriptionEdit.set(false); instance.$('.measure-flow').focus(); } // Keep the current description if ENTER was pressed if (event.which === 13) { event.preventDefault(); instance.description.set($(event.currentTarget).val()); } }, 'blur textarea': function (event, instance) { instance.$('.measure-flow .actions').removeClass('fadeOut'); instance.descriptionEdit.set(false); instance.description.set($(event.currentTarget).val()); }, 'click .select-tree-common label': function (event, instance) { // Set the common section clicked flag instance.commonClicked = event.currentTarget; }, 'change .select-tree-root': function (event, instance) { // Stop here if it's an inner input event if (event.target !== event.currentTarget) { return; } // Store the selectTree component value before it's removed from DOM var $treeRoot = $(event.currentTarget); instance.value = $treeRoot.data('component').value(); }, 'click .tree-leaf input': function (event, instance) { var $target = $(event.currentTarget); var $label = $target.closest('label'); var $treeRoot = $label.closest('.select-tree-root'); var $container = $treeRoot.find('.tree-options:first'); var labelOffset; // Check if the clicked target was a label inside common section if (instance.commonClicked) { $label = $(instance.commonClicked); labelOffset = $label.data('offset'); } else { labelOffset = $label.offset(); } // Change the measure flow state to selected instance.state.set('selected'); // Wait for the DOM re-rendering Tracker.afterFlush(function () { // Get the measure flow div var $measureFlow = instance.$('.measure-flow'); // Adjust the label position if (instance.commonClicked) { labelOffset.top -= 10; labelOffset.left -= 12; } else { labelOffset.top -= 10; } // Reposition the measure flow based on the clicked label position $measureFlow.css(labelOffset); // Resize the copied label with same width of the clicked one // $measureFlow.children('.tree-leaf').width($label.outerWidth()); $measureFlow.children('.tree-leaf').width(212); // Reset the flag to avoid wrong positioning when clicking normal labels again instance.commonClicked = false; instance.data.updateCallback(instance.value.value, instance.description.get()); Meteor.defer(function () { return !$measureFlow.is(':hover') && $measureFlow.trigger('close'); }); }); // Wait the fade-out transition and remove the selectTree component $container.one('transitionend', function (event) { return Blaze.remove(instance.selectTreeView); }); }, 'blur .measure-flow': function (event, instance) { var $measureFlow = $(event.currentTarget); var element = $measureFlow[0]; Meteor.defer(function () { var focused = $(':focus')[0]; if (element !== focused && !$.contains(element, focused)) { $measureFlow.trigger('close'); } }); }, 'mouseleave .measure-flow': function (event, instance) { var $measureFlow = $(event.currentTarget); var canClose = instance.state.get() === 'selected' && !instance.descriptionEdit.get(); if (canClose && !$.contains($measureFlow[0], event.toElement)) { $measureFlow.trigger('close'); } }, 'mouseenter .measure-flow': function (event, instance) { // Prevent from closing if user go out and in too fast clearTimeout(instance.closingTimeout); $(event.currentTarget).off('animationend').removeClass('fadeOut'); }, 'close .measure-flow': function (event, instance) { var $measureFlow = $(event.currentTarget); // Clear the timeout to prevent executing the close process twice clearTimeout(instance.closingTimeout); instance.closingTimeout = setTimeout(function () { var animationEndHandler = function (event) { // Prevent closing if the animation is coming from actions panel if (event.target !== $measureFlow[0]) { $measureFlow.one('animationend', animationEndHandler); return; } instance.data.doneCallback(); }; $measureFlow.one('animationend', animationEndHandler).addClass('fadeOut'); }, 300); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measureFlow.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measureFlow/measureFlow.styl // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measureFlow.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measureFlow.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measureFlow/measureFlow.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measure-flow {\n outline: none;\n position: fixed;\n z-index: 1;\n}\n.measure-flow.fadeOut {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: fadeOut;\n}\n.measure-flow.open .btn-add,\n.measure-flow.selected .btn-add {\n opacity: 0 !important;\n outline: none !important;\n pointer-events: none !important;\n}\n.measure-flow .btn-add {\n outline: none;\n -webkit-border-radius: 14px;\n -moz-border-radius: 14px;\n -ms-border-radius: 14px;\n -o-border-radius: 14px;\n border-radius: 14px;\n cursor: pointer;\n font-weight: bold;\n height: 24px;\n left: 0;\n line-height: 24px;\n opacity: 1;\n position: absolute;\n padding: 0 14px;\n top: 0;\n -webkit-transition: opacity 0.3s ease;\n -moz-transition: opacity 0.3s ease;\n -ms-transition: opacity 0.3s ease;\n -o-transition: opacity 0.3s ease;\n transition: opacity 0.3s ease;\n white-space: nowrap;\n}\n.measure-flow .btn-add {\n color: #000;\n}\nbody.theme-tide .measure-flow .btn-add {\n color: #000;\n}\nbody.theme-tigerlily .measure-flow .btn-add {\n color: #000;\n}\nbody.theme-crickets .measure-flow .btn-add {\n color: #000;\n}\nbody.theme-honeycomb .measure-flow .btn-add {\n color: #000;\n}\nbody.theme-mint .measure-flow .btn-add {\n color: #000;\n}\nbody.theme-overcast .measure-flow .btn-add {\n color: #000;\n}\nbody.theme-quartz .measure-flow .btn-add {\n color: #000;\n}\n.measure-flow .btn-add {\n background-color: #20a5d6;\n}\nbody.theme-tide .measure-flow .btn-add {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily .measure-flow .btn-add {\n background-color: #fa8947;\n}\nbody.theme-crickets .measure-flow .btn-add {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb .measure-flow .btn-add {\n background-color: #cda56b;\n}\nbody.theme-mint .measure-flow .btn-add {\n background-color: #31b166;\n}\nbody.theme-overcast .measure-flow .btn-add {\n background-color: #507d80;\n}\nbody.theme-quartz .measure-flow .btn-add {\n background-color: #7858ce;\n}\n.measure-flow .btn-add {\n border: 2px solid #44626f;\n}\nbody.theme-tide .measure-flow .btn-add {\n border: 2px solid #44626f;\n}\nbody.theme-tigerlily .measure-flow .btn-add {\n border: 2px solid #875a86;\n}\nbody.theme-crickets .measure-flow .btn-add {\n border: 2px solid #537b76;\n}\nbody.theme-honeycomb .measure-flow .btn-add {\n border: 2px solid #623337;\n}\nbody.theme-mint .measure-flow .btn-add {\n border: 2px solid #214529;\n}\nbody.theme-overcast .measure-flow .btn-add {\n border: 2px solid #404040;\n}\nbody.theme-quartz .measure-flow .btn-add {\n border: 2px solid #885b86;\n}\n.measure-flow .select-tree-root>.tree-content {\n width: 140px;\n}\n.measure-flow .select-tree-root>.tree-content>.tree-options {\n position: relative;\n z-index: 2;\n}\n.measure-flow .select-tree-root>.tree-content .tree-inputs {\n position: relative;\n}\n.measure-flow>.tree-leaf {\n position: relative;\n}\n.measure-flow>.tree-leaf .icon-check {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: zoomIn;\n left: -46px;\n position: absolute;\n top: 3px;\n}\n.measure-flow>.tree-leaf .icon-check {\n background-color: #20a5d6;\n}\nbody.theme-tide .measure-flow>.tree-leaf .icon-check {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily .measure-flow>.tree-leaf .icon-check {\n background-color: #fa8947;\n}\nbody.theme-crickets .measure-flow>.tree-leaf .icon-check {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb .measure-flow>.tree-leaf .icon-check {\n background-color: #cda56b;\n}\nbody.theme-mint .measure-flow>.tree-leaf .icon-check {\n background-color: #31b166;\n}\nbody.theme-overcast .measure-flow>.tree-leaf .icon-check {\n background-color: #507d80;\n}\nbody.theme-quartz .measure-flow>.tree-leaf .icon-check {\n background-color: #7858ce;\n}\n.measure-flow>.tree-leaf span {\n background: #fff;\n font-weight: normal;\n height: 46px;\n line-height: 46px;\n padding: 0 12px;\n}\n.measure-flow>.tree-leaf input,\n.measure-flow>.tree-leaf span {\n display: none;\n}\n.measure-flow>.tree-leaf .actions {\n padding-top: 16px;\n opacity: 0;\n}\n.measure-flow>.tree-leaf .actions:not(.fadeOut) {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: fadeIn;\n animation-delay: 0.3s;\n}\n.measure-flow>.tree-leaf .actions.fadeOut {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: fadeOut;\n}\n.measure-flow>.tree-leaf .actions button {\n -webkit-border-radius: 16px;\n -moz-border-radius: 16px;\n -ms-border-radius: 16px;\n -o-border-radius: 16px;\n border-radius: 16px;\n font-weight: normal;\n height: 31px;\n line-height: 31px;\n padding: 0 12px;\n text-align: center;\n}\n.measure-flow>.tree-leaf .actions button {\n border: 1px solid #44626f;\n}\nbody.theme-tide .measure-flow>.tree-leaf .actions button {\n border: 1px solid #44626f;\n}\nbody.theme-tigerlily .measure-flow>.tree-leaf .actions button {\n border: 1px solid #875a86;\n}\nbody.theme-crickets .measure-flow>.tree-leaf .actions button {\n border: 1px solid #537b76;\n}\nbody.theme-honeycomb .measure-flow>.tree-leaf .actions button {\n border: 1px solid #623337;\n}\nbody.theme-mint .measure-flow>.tree-leaf .actions button {\n border: 1px solid #214529;\n}\nbody.theme-overcast .measure-flow>.tree-leaf .actions button {\n border: 1px solid #404040;\n}\nbody.theme-quartz .measure-flow>.tree-leaf .actions button {\n border: 1px solid #885b86;\n}\n.measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-tide .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-tigerlily .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-crickets .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-honeycomb .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-mint .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-overcast .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\nbody.theme-quartz .measure-flow>.tree-leaf .actions button {\n color: #fff;\n}\n.measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-tide .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-tigerlily .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-crickets .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-honeycomb .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-mint .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-overcast .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\nbody.theme-quartz .measure-flow>.tree-leaf .actions button {\n background-color: #000;\n}\n.measure-flow>.tree-leaf .description {\n margin-top: -10px;\n margin-bottom: 10px;\n}\n.measure-flow>.tree-leaf .description textarea {\n background-color: #fff;\n -webkit-box-shadow: 0;\n -moz-box-shadow: 0;\n -ms-box-shadow: 0;\n -o-box-shadow: 0;\n box-shadow: 0;\n border: 0;\n line-height: 20px;\n outline: none;\n overflow: hidden;\n padding: 0 12px 5px;\n resize: none;\n -webkit-transition: height 0.3s ease;\n -moz-transition: height 0.3s ease;\n -ms-transition: height 0.3s ease;\n -o-transition: height 0.3s ease;\n transition: height 0.3s ease;\n width: 100%;\n}\n.measure-flow>.tree-leaf .descriptionText {\n background-color: #fff;\n -webkit-box-shadow: 0;\n -moz-box-shadow: 0;\n -ms-box-shadow: 0;\n -o-box-shadow: 0;\n box-shadow: 0;\n line-height: 20px;\n margin-bottom: 10px;\n margin-top: -10px;\n padding: 0 12px;\n}\n.measure-flow.selected>.tree-leaf span {\n display: block;\n}\n.measure-flow.tree-columns .select-tree-root.navigated .select-tree-common .content {\n animation-name: none;\n}\n.measure-flow.tree-columns .select-tree-root.selected .select-tree-common .content {\n animation-name: selectTreeCommonCloseLeft;\n}\n.measure-flow.tree-columns .select-tree-root .tree-search input,\n.measure-flow.tree-columns .select-tree-root .tree-search i {\n display: none;\n}\n.measure-flow.tree-columns .select-tree-root .select-tree-common {\n padding-left: 0;\n padding-right: 6px;\n right: auto;\n left: 0;\n width: 180px;\n}\n.measure-flow.tree-columns .select-tree-root>.tree-content {\n -webkit-transform-origin: 0% 50%;\n -moz-transform-origin: 0% 50%;\n -ms-transform-origin: 0% 50%;\n -o-transform-origin: 0% 50%;\n transform-origin: 0% 50%;\n width: 280px;\n}\n.measure-flow.tree-columns .select-tree-root .select-tree-common .content {\n right: -180px;\n}\n.measure-flow.tree-columns .select-tree-root.started .select-tree-common .content {\n right: 46px;\n}\n.measure-flow.tree-columns .select-tree-root.navigated .select-tree-common .content {\n animation-name: selectTreeCommonCloseRight;\n}\n.measure-flow.tree-columns .select-tree-root .tree-inputs>label {\n float: left;\n width: 50%;\n}\n.icon-check {\n background-color: #fff;\n -webkit-border-radius: 20px;\n -moz-border-radius: 20px;\n -ms-border-radius: 20px;\n -o-border-radius: 20px;\n border-radius: 20px;\n display: block;\n height: 40px;\n overflow: hidden;\n position: relative;\n width: 40px;\n}\n.icon-check:before {\n border: 2px solid #000;\n border-left-width: 0;\n border-top-width: 0;\n content: '';\n display: block;\n height: 18px;\n left: 15px;\n position: absolute;\n top: 9px;\n -webkit-transform: rotate(45deg);\n -moz-transform: rotate(45deg);\n -ms-transform: rotate(45deg);\n -o-transform: rotate(45deg);\n transform: rotate(45deg);\n width: 9px;\n}\n@-moz-keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n@-webkit-keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n@-o-keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n@keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementLightTable":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementEditDescription/measurementEditDescription.html")); module.watch(require("./measurementEditDescription/measurementEditDescription.js")); module.watch(require("./measurementLightTable.html")); module.watch(require("./measurementLightTable.styl")); module.watch(require("./measurementLightTableHeaderRow/measurementLightTableHeaderRow.html")); module.watch(require("./measurementLightTableHeaderRow/measurementLightTableHeaderRow.styl")); module.watch(require("./measurementLightTableRow/measurementLightTableRow.html")); module.watch(require("./measurementLightTableRow/measurementLightTableRow.styl")); module.watch(require("./measurementLightTableRow/measurementLightTableRow.js")); module.watch(require("./measurementLightTableView/measurementLightTableView.html")); module.watch(require("./measurementLightTableView/measurementLightTableView.styl")); module.watch(require("./measurementLightTableView/measurementLightTableView.js")); module.watch(require("./measurementRelabel/measurementRelabel.html")); module.watch(require("./measurementRelabel/measurementRelabel.styl")); module.watch(require("./measurementRelabel/measurementRelabel.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTable.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTable.html // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementLightTable.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementLightTable.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/template.measurementLightTable.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementLightTable"); Template["measurementLightTable"] = new Template("Template.measurementLightTable", (function() { var view = this; return HTML.DIV({ id: "measurementLightTableContainer", class: "flex-v" }, "\n ", HTML.DIV({ class: "measurementLightTableHeaderContainer" }, "\n ", HTML.DIV({ class: "measurementLightTableHeader" }, "\n ", HTML.Raw('
\n Study date:\n
'), "\n ", HTML.DIV({ class: "studyDate" }, "\n ", Blaze.View("lookup:formatDA", function() { return Spacebars.mustache(view.lookup("formatDA"), Spacebars.dot(view.lookup("."), "timepointApi", "all", "0", "latestDate"), "DD-MMM-YY"); }), "\n "), "\n "), "\n "), "\n ", Blaze._TemplateWith(function() { return { class: Spacebars.call("measurementLightTableView flex-grow fit"), scrollStep: Spacebars.call(63) }; }, function() { return Spacebars.include(view.lookupTemplate("scrollArea"), function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup(".")); }, function() { return Spacebars.include(view.lookupTemplate("measurementLightTableView")); }), "\n " ]; }); }), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTable.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTable.styl // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementLightTable.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTable.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTable.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n#measurementLightTableContainer {\n height: 100%;\n width: 100%;\n}\n#measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-tide #measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-tigerlily #measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-crickets #measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-honeycomb #measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-mint #measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-overcast #measurementLightTableContainer {\n background-color: #000;\n}\nbody.theme-quartz #measurementLightTableContainer {\n background-color: #000;\n}\n.measurementLightTableHeaderContainer {\n display: flex;\n padding: 0 2px 0 44px;\n position: relative;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader {\n flex: 1;\n justify-content: space-around;\n padding-top: 2px;\n position: relative;\n margin: 0.4em 0;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel,\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n font-weight: 400;\n padding-left: 12px;\n text-align: left;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel,\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #44626f;\n}\nbody.theme-tide .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #44626f;\n}\nbody.theme-tide .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #44626f;\n}\nbody.theme-tigerlily .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #875a86;\n}\nbody.theme-tigerlily .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #875a86;\n}\nbody.theme-crickets .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #537b76;\n}\nbody.theme-crickets .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #537b76;\n}\nbody.theme-honeycomb .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #623337;\n}\nbody.theme-honeycomb .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #623337;\n}\nbody.theme-mint .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #214529;\n}\nbody.theme-mint .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #214529;\n}\nbody.theme-overcast .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #404040;\n}\nbody.theme-overcast .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #404040;\n}\nbody.theme-quartz .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n border-left: 1px solid #885b86;\n}\nbody.theme-quartz .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n border-left: 1px solid #885b86;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n font-size: 12px;\n line-height: 12px;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #91b9cd;\n}\nbody.theme-tide .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #fab797;\n}\nbody.theme-mint .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDateLabel {\n color: #d7e8fe;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n font-size: 14px;\n line-height: 20px;\n padding-bottom: 6px;\n}\n.measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-tide .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-tigerlily .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-crickets .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-honeycomb .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-mint .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-overcast .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\nbody.theme-quartz .measurementLightTableHeaderContainer .measurementLightTableHeader .studyDate {\n color: #fff;\n}\n.measurementLightTableLayoutChanger {\n margin: 0 auto;\n padding: 20px;\n text-align: center;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementEditDescription":{"measurementEditDescription.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementEditDescription/measuremen // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementEditDescription.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementEditDescription.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementEditDescription/template.measurementE // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementEditDescription"); Template["measurementEditDescription"] = new Template("Template.measurementEditDescription", (function() { var view = this; return Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("extend"), view.lookup("."), Spacebars.kw({ dialogClass: "modal-sm", api: Spacebars.dot(view.lookup("instance"), "api") })); }, function() { return Spacebars.include(view.lookupTemplate("dialogForm"), function() { return [ "\n ", Blaze._TemplateWith(function() { return { labelClass: Spacebars.call("form-group"), key: Spacebars.call("description"), hideSearch: Spacebars.call(true), options: Spacebars.call(Spacebars.dataMustache(view.lookup("clone"), Spacebars.kw({ placeholder: "Add a description" }))) }; }, function() { return Spacebars.include(view.lookupTemplate("inputText")); }), "\n " ]; }); }); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementEditDescription.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementEditDescription/measurementEditDescri // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); Template.measurementEditDescription.onRendered(function () { var instance = Template.instance(); var form = instance.$('form').data('component'); var measurementData = instance.data.measurementData; var collection = OHIF.viewer.measurementApi.tools[measurementData.toolType]; var currentMeasurement = collection.findOne({ _id: measurementData._id }); if (currentMeasurement.description) { form.value({ description: currentMeasurement.description }); } // Update the description after confirming the dialog data instance.data.promise.then(function (formData) { collection.update({ _id: measurementData._id }, { $set: { description: formData.description } }); }); }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementLightTableHeaderRow":{"measurementLightTableHeaderRow.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTableHeaderRow/measur // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementLightTableHeaderRow.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementLightTableHeaderRow.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableHeaderRow/template.measurem // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementLightTableHeaderRow"); Template["measurementLightTableHeaderRow"] = new Template("Template.measurementLightTableHeaderRow", (function() { var view = this; return HTML.DIV({ class: "measurementLightTableHeaderRow" }, "\n ", HTML.DIV({ class: "type" }, Blaze.View("lookup:toolGroup.name", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("toolGroup"), "name")); })), "\n ", HTML.DIV({ class: "numberOfMeasurements" }, Blaze.View("lookup:measurementRows.length", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("measurementRows"), "length")); })), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableHeaderRow.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTableHeaderRow/measur // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementLightTableHeaderRow.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableHeaderRow.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableHeaderRow/measurementLightT // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementLightTableHeaderRow {\n display: flex;\n height: 63px;\n line-height: 63px;\n margin-top: 2px;\n width: 100%;\n}\n.measurementLightTableHeaderRow {\n background-color: #151a1f;\n}\nbody.theme-tide .measurementLightTableHeaderRow {\n background-color: #151a1f;\n}\nbody.theme-tigerlily .measurementLightTableHeaderRow {\n background-color: #151a1f;\n}\nbody.theme-crickets .measurementLightTableHeaderRow {\n background-color: #231c1e;\n}\nbody.theme-honeycomb .measurementLightTableHeaderRow {\n background-color: #18161a;\n}\nbody.theme-mint .measurementLightTableHeaderRow {\n background-color: #15191e;\n}\nbody.theme-overcast .measurementLightTableHeaderRow {\n background-color: #15191e;\n}\nbody.theme-quartz .measurementLightTableHeaderRow {\n background-color: #151a1f;\n}\n.measurementLightTableHeaderRow {\n color: #91b9cd;\n}\nbody.theme-tide .measurementLightTableHeaderRow {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementLightTableHeaderRow {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementLightTableHeaderRow {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementLightTableHeaderRow {\n color: #fab797;\n}\nbody.theme-mint .measurementLightTableHeaderRow {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableHeaderRow {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementLightTableHeaderRow {\n color: #d7e8fe;\n}\n.measurementLightTableHeaderRow {\n fill: #91b9cd;\n}\nbody.theme-tide .measurementLightTableHeaderRow {\n fill: #91b9cd;\n}\nbody.theme-tigerlily .measurementLightTableHeaderRow {\n fill: #9ccdf8;\n}\nbody.theme-crickets .measurementLightTableHeaderRow {\n fill: #8be7b5;\n}\nbody.theme-honeycomb .measurementLightTableHeaderRow {\n fill: #fab797;\n}\nbody.theme-mint .measurementLightTableHeaderRow {\n fill: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableHeaderRow {\n fill: #73f2fc;\n}\nbody.theme-quartz .measurementLightTableHeaderRow {\n fill: #d7e8fe;\n}\n.measurementLightTableHeaderRow div {\n align-items: stretch;\n flex: 1;\n justify-content: space-around;\n text-align: center;\n}\n.measurementLightTableHeaderRow .type {\n font-size: 22px;\n font-weight: 300;\n line-height: 63px;\n padding: 0 10px;\n text-align: left;\n}\n.measurementLightTableHeaderRow .type {\n color: #91b9cd;\n}\nbody.theme-tide .measurementLightTableHeaderRow .type {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementLightTableHeaderRow .type {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementLightTableHeaderRow .type {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementLightTableHeaderRow .type {\n color: #fab797;\n}\nbody.theme-mint .measurementLightTableHeaderRow .type {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableHeaderRow .type {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementLightTableHeaderRow .type {\n color: #d7e8fe;\n}\n.measurementLightTableHeaderRow .numberOfMeasurements {\n float: right;\n font-weight: 300;\n font-size: 40px;\n max-width: 54px;\n height: 63px;\n line-height: 66px;\n}\n.measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-tide .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-tigerlily .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-crickets .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-honeycomb .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-mint .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-overcast .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-quartz .measurementLightTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementLightTableRow":{"measurementLightTableRow.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTableRow/measurementL // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementLightTableRow.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementLightTableRow.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableRow/template.measurementLig // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementLightTableRow"); Template["measurementLightTableRow"] = new Template("Template.measurementLightTableRow", (function() { var view = this; return HTML.DIV({ class: "measurementLightTableRow", "data-measurementid": function() { return Spacebars.mustache(view.lookup("_id")); } }, "\n ", HTML.DIV({ class: "measurementRowSidebar" }, "\n ", HTML.DIV({ class: "measurementNumber" }, "\n ", Blaze.View("lookup:rowItem.measurementNumber", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("rowItem"), "measurementNumber")); }), "\n "), "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("rowItem"), "responseStatus")); }, function() { return [ "\n ", HTML.DIV({ class: "response-status-icon" }, "\n ", Blaze.View("lookup:rowItem.responseStatus", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("rowItem"), "responseStatus")); }), "\n "), "\n " ]; }), "\n "), "\n ", HTML.DIV({ class: "measurementRowContent" }, "\n ", HTML.DIV({ class: "measurementDetails" }, "\n ", HTML.LABEL({ class: "location" }, "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("rowItem"), "location")); }, function() { return [ "\n ", Blaze.View("lookup:rowItem.location", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("rowItem"), "location")); }), "\n " ]; }, function() { return "\n (No Location)\n "; }), "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("rowItem"), "description")); }, function() { return [ "\n (", Blaze.View("lookup:rowItem.description", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("rowItem"), "description")); }), ")\n " ]; }), "\n "), "\n ", HTML.DIV({ class: "value" }, "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("displayData")); }, function() { return [ "\n ", Blaze.View("lookup:displayData", function() { return Spacebars.makeRaw(Spacebars.mustache(view.lookup("displayData"))); }), "\n " ]; }, function() { return "\n ...\n "; }), "\n "), "\n "), "\n ", HTML.DIV({ class: "rowOptions" }, "\n ", HTML.DIV({ class: "rowAction js-edit-label pull-left m-r-2", tabindex: "1" }, "\n ", HTML.SVG({ class: "edit-icon" }, "\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-measurements-additional"); } }), "\n "), "\n Relabel\n "), "\n ", HTML.DIV({ class: "rowAction js-edit-description pull-left m-r-2", tabindex: "1" }, "\n ", HTML.SVG({ class: "edit-icon" }, "\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-measurements-additional"); } }), "\n "), "\n Description\n "), "\n ", HTML.DIV({ class: "rowAction js-delete pull-left", tabindex: "1" }, "\n ", HTML.SVG({ class: "close-icon" }, "\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-ui-close"); } }), "\n "), "\n Delete\n "), "\n "), "\n "), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableRow.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableRow/measurementLightTableRo // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 4); var getPosition = function (event) { return { x: event.clientX, y: event.clientY }; }; Template.measurementLightTableRow.helpers({ displayData: function () { var instance = Template.instance(); var rowItem = instance.data.rowItem; var data = rowItem.entries[0]; var config = OHIF.measurements.MeasurementApi.getConfiguration(); var measurementTools = config.measurementTools; var toolGroup = measurementTools.find(function (toolGroup) { return toolGroup.id === rowItem.measurementTypeId; }); var tool = toolGroup.childTools.find(function (childTool) { return childTool.id === data.toolType; }); if (!tool) { return 'No measurement value'; } var displayFunction = tool.options.measurementTable.displayFunction; return displayFunction(data); } }); Template.measurementLightTableRow.events({ 'click .measurementLightTableRow': function (event, instance) { var $row = instance.$('.measurementLightTableRow'); var rowItem = instance.data.rowItem; var timepoints = instance.data.timepointApi.all(); $row.closest('.measurementLightTableView').find('.measurementLightTableRow').not($row).removeClass('active'); $row.toggleClass('active'); var childToolKey = $(event.target).attr('data-child'); OHIF.measurements.jumpToRowItem(rowItem, timepoints, childToolKey); }, 'click .js-edit-label': function (event, instance) { event.stopPropagation(); var rowItem = instance.data.rowItem; var entry = rowItem.entries[0]; // Show the measure flow for measurements OHIF.measurements.openLocationModal({ measurement: entry, element: document.body, measurementApi: instance.data.measurementApi, position: getPosition(event), autoClick: true }); }, 'click .js-edit-description': function (event, instance) { var rowItem = instance.data.rowItem; var entry = rowItem.entries[0]; OHIF.ui.showDialog('measurementEditDescription', { event: event, title: 'Edit Description', element: event.element, measurementData: entry }); }, 'click .js-delete': function (event, instance) { event.stopPropagation(); var dialogSettings = { "class": 'themed', title: 'Delete measurements', message: 'Are you sure you want to delete the measurement?', position: getPosition(event) }; OHIF.ui.showDialog('dialogConfirm', dialogSettings).then(function (formData) { var measurementTypeId = instance.data.rowItem.measurementTypeId; var measurement = instance.data.rowItem.entries[0]; var measurementNumber = measurement.measurementNumber; var _instance$data = instance.data, timepointApi = _instance$data.timepointApi, measurementApi = _instance$data.measurementApi; // Remove all the measurements with the given type and number measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber: measurementNumber }); // Sync the new measurement data with cornerstone tools var baseline = timepointApi.baseline(); measurementApi.sortMeasurements(baseline.timepointId); // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), function (element) { return cornerstone.updateImage(element); }); // Notify that viewer suffered changes OHIF.measurements.triggerTimepointUnsavedChanges('deleted'); }); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableRow.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTableRow/measurementL // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementLightTableRow.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableRow.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableRow/measurementLightTableRo // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementLightTableRow {\n display: flex;\n margin-left: -6px;\n margin-top: 2px;\n padding-left: 6px;\n opacity: 0.7;\n -webkit-transform: scale(1);\n -moz-transform: scale(1);\n -ms-transform: scale(1);\n -o-transform: scale(1);\n transform: scale(1);\n width: calc(100% + 6px);\n}\n.measurementLightTableRow:hover {\n opacity: 1;\n}\n.measurementLightTableRow.active {\n opacity: 1;\n}\n.measurementLightTableRow.active .measurementRowSidebar {\n color: #20a5d6;\n}\nbody.theme-tide .measurementLightTableRow.active .measurementRowSidebar {\n color: #20a5d6;\n}\nbody.theme-tigerlily .measurementLightTableRow.active .measurementRowSidebar {\n color: #fa8947;\n}\nbody.theme-crickets .measurementLightTableRow.active .measurementRowSidebar {\n color: #d4c3c1;\n}\nbody.theme-honeycomb .measurementLightTableRow.active .measurementRowSidebar {\n color: #cda56b;\n}\nbody.theme-mint .measurementLightTableRow.active .measurementRowSidebar {\n color: #31b166;\n}\nbody.theme-overcast .measurementLightTableRow.active .measurementRowSidebar {\n color: #507d80;\n}\nbody.theme-quartz .measurementLightTableRow.active .measurementRowSidebar {\n color: #7858ce;\n}\n.measurementLightTableRow.active .rowOptions {\n height: 35px;\n visibility: visible;\n}\n.measurementLightTableRow .rowOptions {\n height: 0;\n overflow: hidden;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n visibility: hidden;\n padding-left: 14px;\n}\n.measurementLightTableRow .rowOptions {\n background-color: #151a1f;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions {\n background-color: #151a1f;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions {\n background-color: #151a1f;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions {\n background-color: #231c1e;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions {\n background-color: #18161a;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions {\n background-color: #15191e;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions {\n background-color: #15191e;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions {\n background-color: #151a1f;\n}\n.measurementLightTableRow .rowOptions .rowAction {\n cursor: pointer;\n line-height: 35px;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementLightTableRow .rowOptions .rowAction {\n color: #9ccef9;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction {\n color: #9ccef9;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction {\n color: #9acffd;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction {\n color: #92c2da;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction {\n color: #b5b5b5;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction {\n color: #9cbecf;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction {\n color: #8ea2a4;\n}\n.measurementLightTableRow .rowOptions .rowAction:hover,\n.measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\n.measurementLightTableRow .rowOptions .rowAction:hover svg,\n.measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\n.measurementLightTableRow .rowOptions .rowAction:hover svg,\n.measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\n.measurementLightTableRow .rowOptions svg {\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementLightTableRow .rowOptions svg {\n fill: #9ccef9;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions svg {\n fill: #9ccef9;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions svg {\n fill: #9acffd;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions svg {\n fill: #92c2da;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions svg {\n fill: #b5b5b5;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions svg {\n fill: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions svg {\n fill: #9cbecf;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions svg {\n fill: #8ea2a4;\n}\n.measurementLightTableRow .rowOptions svg {\n stroke: #9ccef9;\n}\nbody.theme-tide .measurementLightTableRow .rowOptions svg {\n stroke: #9ccef9;\n}\nbody.theme-tigerlily .measurementLightTableRow .rowOptions svg {\n stroke: #9acffd;\n}\nbody.theme-crickets .measurementLightTableRow .rowOptions svg {\n stroke: #92c2da;\n}\nbody.theme-honeycomb .measurementLightTableRow .rowOptions svg {\n stroke: #b5b5b5;\n}\nbody.theme-mint .measurementLightTableRow .rowOptions svg {\n stroke: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableRow .rowOptions svg {\n stroke: #9cbecf;\n}\nbody.theme-quartz .measurementLightTableRow .rowOptions svg {\n stroke: #8ea2a4;\n}\n.measurementLightTableRow .rowOptions svg.edit-icon {\n width: 14px;\n height: 13px;\n}\n.measurementLightTableRow .rowOptions svg.close-icon {\n width: 11px;\n height: 11px;\n}\n.measurementLightTableRow .measurementRowSidebar {\n cursor: pointer;\n flex: 1;\n max-width: 30px;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-tide .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-tigerlily .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-crickets .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-honeycomb .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-mint .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-overcast .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-quartz .measurementLightTableRow .measurementRowSidebar {\n background: #263340;\n}\n.measurementLightTableRow .measurementRowSidebar {\n color: #91b9cd;\n}\nbody.theme-tide .measurementLightTableRow .measurementRowSidebar {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementLightTableRow .measurementRowSidebar {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementLightTableRow .measurementRowSidebar {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementLightTableRow .measurementRowSidebar {\n color: #fab797;\n}\nbody.theme-mint .measurementLightTableRow .measurementRowSidebar {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableRow .measurementRowSidebar {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementLightTableRow .measurementRowSidebar {\n color: #d7e8fe;\n}\n.measurementLightTableRow .measurementRowSidebar .measurementNumber {\n font-size: 14px;\n font-weight: 400;\n margin-right: 5px;\n padding-top: 10px;\n text-align: center;\n}\n.measurementLightTableRow .measurementRowContent {\n flex: 1;\n}\n.measurementLightTableRow .measurementDetails {\n padding: 5px 2px 0 14px;\n line-height: 30px;\n font-size: 14px;\n}\n.measurementLightTableRow .measurementDetails .location {\n font-weight: 400;\n margin-left: -2px;\n}\n.measurementLightTableRow .measurementDetails .location {\n color: #91b9cd;\n}\nbody.theme-tide .measurementLightTableRow .measurementDetails .location {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementLightTableRow .measurementDetails .location {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementLightTableRow .measurementDetails .location {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementLightTableRow .measurementDetails .location {\n color: #fab797;\n}\nbody.theme-mint .measurementLightTableRow .measurementDetails .location {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementLightTableRow .measurementDetails .location {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementLightTableRow .measurementDetails .location {\n color: #d7e8fe;\n}\n.measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-tide .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-tigerlily .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-crickets .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-honeycomb .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-mint .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-overcast .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\nbody.theme-quartz .measurementLightTableRow .measurementDetails .value {\n color: #fff;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementLightTableView":{"measurementLightTableView.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTableView/measurement // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementLightTableView.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementLightTableView.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableView/template.measurementLi // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementLightTableView"); Template["measurementLightTableView"] = new Template("Template.measurementLightTableView", (function() { var view = this; return [ Blaze.Let({ config: function() { return Spacebars.call(view.lookup("measurementConfiguration")); }, groups: function() { return Spacebars.call(Spacebars.dot(view.lookup("measurementGroups"), "get")); } }, function() { return [ "\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(view.lookup("groups")), _variable: "measurementGroup" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ toolGroup: Spacebars.dot(view.lookup("measurementGroup"), "toolGroup"), measurementRows: Spacebars.dot(view.lookup("measurementGroup"), "measurementRows") })); }, function() { return Spacebars.include(view.lookupTemplate("measurementLightTableHeaderRow")); }), "\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(Spacebars.dot(view.lookup("measurementGroup"), "measurementRows")), _variable: "rowItem" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ rowItem: view.lookup("rowItem") })); }, function() { return Spacebars.include(view.lookupTemplate("measurementLightTableRow")); }), "\n " ]; }), "\n " ]; }), "\n " ]; }), "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("hasAnyMeasurement")); }, function() { return [ "\n ", HTML.DIV({ class: "report-area" }, "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("saveEnabled")); }, function() { return [ "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("hasUnsavedChanges")); }, function() { return [ "\n ", HTML.DIV({ class: "unsaved-changes-alert" }, "\n You have unsaved changes\n "), "\n " ]; }), "\n " ]; }), "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("extend"), Spacebars.kw({ api: Spacebars.dot(view.lookup("instance"), "api") })); }, function() { return Spacebars.include(view.lookupTemplate("form"), function() { return [ "\n ", Blaze._TemplateWith(function() { return { class: Spacebars.call("btn p-x-2"), action: Spacebars.call("exportCSV") }; }, function() { return Spacebars.include(view.lookupTemplate("button"), function() { return "Export CSV"; }); }), "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("saveEnabled")); }, function() { return [ "\n ", Blaze._TemplateWith(function() { return { class: Spacebars.call("btn p-x-2"), action: Spacebars.call("save"), disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("not"), view.lookup("hasUnsavedChanges"))) }; }, function() { return Spacebars.include(view.lookupTemplate("button"), function() { return "Save to Archive"; }); }), "\n " ]; }), "\n " ]; }); }), "\n "), "\n " ]; }) ]; })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableView.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableView/measurementLightTableV // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); Template.measurementLightTableView.onCreated(function () { var instance = Template.instance(); var _instance$data = instance.data, measurementApi = _instance$data.measurementApi, timepointApi = _instance$data.timepointApi; instance.data.measurementGroups = new ReactiveVar(); instance.path = 'viewer.studyViewer.measurements'; instance.saveObserver = new Tracker.Dependency(); instance.api = { save: function () { var successHandler = function () { OHIF.ui.unsavedChanges.clear(instance.path + ".*"); instance.saveObserver.changed(); }; // Display the error messages var errorHandler = function (data) { OHIF.ui.showDialog('dialogInfo', Object.assign({ "class": 'themed' }, data)); }; var promise = instance.data.measurementApi.storeMeasurements(); promise.then(successHandler).catch(errorHandler); OHIF.ui.showDialog('dialogLoading', { promise: promise, text: 'Measurements saved.' }); return promise; }, exportCSV: function () { var _instance$data2 = instance.data, measurementApi = _instance$data2.measurementApi, timepointApi = _instance$data2.timepointApi; OHIF.measurements.exportCSV(measurementApi, timepointApi); } }; instance.autorun(function () { measurementApi.changeObserver.depend(); var data = OHIF.measurements.getMeasurementsGroupedByNumber(measurementApi, timepointApi); instance.data.measurementGroups.set(data); }); }); Template.measurementLightTableView.helpers({ hasUnsavedChanges: function () { var instance = Template.instance(); // Run this computation on save or every time any measurement / timepoint suffer changes OHIF.ui.unsavedChanges.depend(); instance.saveObserver.depend(); return OHIF.ui.unsavedChanges.probe('viewer.*') !== 0; }, hasAnyMeasurement: function () { var instance = Template.instance(); var groups = instance.data.measurementGroups.get(); if (!groups) { return false; } var group = groups.find(function (item) { return item.measurementRows.length > 0; }); return group; }, saveEnabled: function () { var server = OHIF.servers.getCurrentServer(); return server && server.type === 'dicomWeb'; } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableView.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementLightTableView/measurement // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementLightTableView.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementLightTableView.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementLightTableView/measurementLightTableV // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementLightTableView .report-area {\n margin-top: 2px;\n padding: 10px 0;\n text-align: center;\n}\n.measurementLightTableView .report-area {\n background-color: #151a1f;\n}\nbody.theme-tide .measurementLightTableView .report-area {\n background-color: #151a1f;\n}\nbody.theme-tigerlily .measurementLightTableView .report-area {\n background-color: #151a1f;\n}\nbody.theme-crickets .measurementLightTableView .report-area {\n background-color: #231c1e;\n}\nbody.theme-honeycomb .measurementLightTableView .report-area {\n background-color: #18161a;\n}\nbody.theme-mint .measurementLightTableView .report-area {\n background-color: #15191e;\n}\nbody.theme-overcast .measurementLightTableView .report-area {\n background-color: #15191e;\n}\nbody.theme-quartz .measurementLightTableView .report-area {\n background-color: #151a1f;\n}\n.measurementLightTableView .report-area .btn {\n color: #000;\n}\n.measurementLightTableView .report-area .btn {\n background-color: #20a5d6;\n}\nbody.theme-tide .measurementLightTableView .report-area .btn {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily .measurementLightTableView .report-area .btn {\n background-color: #fa8947;\n}\nbody.theme-crickets .measurementLightTableView .report-area .btn {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb .measurementLightTableView .report-area .btn {\n background-color: #cda56b;\n}\nbody.theme-mint .measurementLightTableView .report-area .btn {\n background-color: #31b166;\n}\nbody.theme-overcast .measurementLightTableView .report-area .btn {\n background-color: #507d80;\n}\nbody.theme-quartz .measurementLightTableView .report-area .btn {\n background-color: #7858ce;\n}\n.measurementLightTableView .report-area .btn {\n border: 1px solid #00a4d9;\n}\nbody.theme-tide .measurementLightTableView .report-area .btn {\n border: 1px solid #00a4d9;\n}\nbody.theme-tigerlily .measurementLightTableView .report-area .btn {\n border: 1px solid #ff8a3d;\n}\nbody.theme-crickets .measurementLightTableView .report-area .btn {\n border: 1px solid #d4aaa5;\n}\nbody.theme-honeycomb .measurementLightTableView .report-area .btn {\n border: 1px solid #ce9e59;\n}\nbody.theme-mint .measurementLightTableView .report-area .btn {\n border: 1px solid #23b15d;\n}\nbody.theme-overcast .measurementLightTableView .report-area .btn {\n border: 1px solid #467c80;\n}\nbody.theme-quartz .measurementLightTableView .report-area .btn {\n border: 1px solid #6843cc;\n}\n.measurementLightTableView .report-area .unsaved-changes-alert {\n padding-bottom: 10px;\n font-size: 11px;\n color: #ff0;\n font-weight: 100;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementRelabel":{"measurementRelabel.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementRelabel/measurementRelabel // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementRelabel.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementRelabel.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementRelabel/template.measurementRelabel.j // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementRelabel"); Template["measurementRelabel"] = new Template("Template.measurementRelabel", (function() { var view = this; return HTML.DIV({ class: function() { return [ "measurement-relabel ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("."), "threeColumns")); }, function() { return "tree-columns"; }), " ", Spacebars.mustache(Spacebars.dot(view.lookup("instance"), "state", "get")) ]; }, tabindex: "-1" }, "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementRelabel.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementRelabel/measurementRelabel.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Meteor; module.watch(require("meteor/meteor"), { Meteor: function (v) { Meteor = v; } }, 0); var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 1); var Blaze; module.watch(require("meteor/blaze"), { Blaze: function (v) { Blaze = v; } }, 2); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 3); var Tracker; module.watch(require("meteor/tracker"), { Tracker: function (v) { Tracker = v; } }, 4); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 5); var segmentedTerminologyList, segmentedTerminologyCommonList; module.watch(require("../../../lib/getLabelTerminologyList"), { segmentedTerminologyList: function (v) { segmentedTerminologyList = v; }, segmentedTerminologyCommonList: function (v) { segmentedTerminologyCommonList = v; } }, 6); Template.measurementRelabel.onCreated(function () { var instance = Template.instance(); instance.value = instance.data.currentValue || ''; instance.state = new ReactiveVar('closed'); instance.items = segmentedTerminologyList; instance.commonItems = segmentedTerminologyCommonList; }); Template.measurementRelabel.onRendered(function () { var instance = Template.instance(); var $measurementRelabel = instance.$('.measurement-relabel'); // Make the measure flow bounded by the window borders $measurementRelabel.bounded(); // Wait template rerender before rendering the selectTree Tracker.afterFlush(function () { // Get the click or rendering position var position = { left: event.clientX || instance.data.position.x, top: event.clientY || instance.data.position.y }; // Define the data for selectTreeComponent var data = { key: 'label', items: instance.items, commonItems: instance.commonItems, hideCommon: instance.data.hideCommon, label: 'Assign label', search: true, searchPlaceholder: 'Search labels', threeColumns: instance.data.threeColumns, position: position }; // Define in which element the selectTree will be rendered in var parentElement = $measurementRelabel[0]; // Render the selectTree element instance.selectTreeView = Blaze.renderWithData(Template.selectTree, data, parentElement); // Focus the measure flow to handle closing $measurementRelabel.focus(); }); }); Template.measurementRelabel.events({ 'click, mousedown, mouseup': function (event, instance) { event.stopPropagation(); }, 'click .tree-leaf input': function (event, instance) { var $target = $(event.currentTarget); var $measureFlow = instance.$('.measurement-relabel'); instance.state.set('selected'); instance.value = $target.data('component').value(); instance.data.updateCallback(instance.value); $measureFlow.trigger('close'); }, 'blur .measurement-relabel': function (event, instance) { var $measurementRelabel = $(event.currentTarget); var element = $measurementRelabel[0]; Meteor.defer(function () { var focused = $(':focus')[0]; if (element !== focused && !$.contains(element, focused)) { $measurementRelabel.trigger('close'); } }); }, 'mouseleave .measurement-relabel': function (event, instance) { var $measurementRelabel = $(event.currentTarget); var canClose = instance.state.get() === 'selected'; if (canClose && !$.contains($measurementRelabel[0], event.toElement)) { $measurementRelabel.trigger('close'); } }, 'mouseenter .measurement-relabel': function (event, instance) { // Prevent from closing if user go out and in too fast clearTimeout(instance.closingTimeout); $(event.currentTarget).off('animationend').removeClass('fadeOut'); }, 'close .measurement-relabel': function (event, instance) { // Clear the timeout to prevent executing the close process twice clearTimeout(instance.closingTimeout); instance.data.doneCallback(); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementRelabel.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementLightTable/measurementRelabel/measurementRelabel // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementRelabel.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementRelabel.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementLightTable/measurementRelabel/measurementRelabel.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurement-relabel {\n outline: none;\n position: fixed;\n z-index: 1;\n}\n.measurement-relabel.fadeOut {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: fadeOut;\n}\n.measurement-relabel .select-tree-root>.tree-content {\n width: 140px;\n}\n.measurement-relabel .select-tree-root>.tree-content>.tree-options {\n position: relative;\n z-index: 2;\n}\n.measurement-relabel .select-tree-root>.tree-content .tree-inputs {\n position: relative;\n}\n.measurement-relabel>.tree-leaf {\n position: relative;\n}\n.measurement-relabel>.tree-leaf .icon-check {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: zoomIn;\n left: -46px;\n position: absolute;\n top: 3px;\n}\n.measurement-relabel>.tree-leaf .icon-check {\n background-color: #20a5d6;\n}\nbody.theme-tide .measurement-relabel>.tree-leaf .icon-check {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily .measurement-relabel>.tree-leaf .icon-check {\n background-color: #fa8947;\n}\nbody.theme-crickets .measurement-relabel>.tree-leaf .icon-check {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb .measurement-relabel>.tree-leaf .icon-check {\n background-color: #cda56b;\n}\nbody.theme-mint .measurement-relabel>.tree-leaf .icon-check {\n background-color: #31b166;\n}\nbody.theme-overcast .measurement-relabel>.tree-leaf .icon-check {\n background-color: #507d80;\n}\nbody.theme-quartz .measurement-relabel>.tree-leaf .icon-check {\n background-color: #7858ce;\n}\n.measurement-relabel>.tree-leaf span {\n background: #fff;\n font-weight: normal;\n height: 46px;\n line-height: 46px;\n padding: 0 12px;\n}\n.measurement-relabel>.tree-leaf input,\n.measurement-relabel>.tree-leaf span {\n display: none;\n}\n.measurement-relabel>.tree-leaf .actions {\n padding-top: 16px;\n opacity: 0;\n}\n.measurement-relabel>.tree-leaf .actions:not(.fadeOut) {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: fadeIn;\n animation-delay: 0.3s;\n}\n.measurement-relabel>.tree-leaf .actions.fadeOut {\n animation-duration: 0.3s;\n animation-direction: alternate;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n animation-name: fadeOut;\n}\n.measurement-relabel.selected>.tree-leaf span {\n display: block;\n}\n.measurement-relabel.tree-columns .select-tree-root.navigated .select-tree-common .content {\n animation-name: none;\n}\n.measurement-relabel.tree-columns .select-tree-root.selected .select-tree-common .content {\n animation-name: selectTreeCommonCloseLeft;\n}\n.measurement-relabel.tree-columns .select-tree-root .select-tree-common {\n padding-left: 0;\n padding-right: 6px;\n right: auto;\n left: 0;\n width: 180px;\n}\n.measurement-relabel.tree-columns .select-tree-root>.tree-content {\n -webkit-transform-origin: 0% 50%;\n -moz-transform-origin: 0% 50%;\n -ms-transform-origin: 0% 50%;\n -o-transform-origin: 0% 50%;\n transform-origin: 0% 50%;\n width: 280px;\n}\n.measurement-relabel.tree-columns .select-tree-root .select-tree-common .content {\n right: -180px;\n}\n.measurement-relabel.tree-columns .select-tree-root.started .select-tree-common .content {\n right: 46px;\n}\n.measurement-relabel.tree-columns .select-tree-root.navigated .select-tree-common .content {\n animation-name: selectTreeCommonCloseRight;\n}\n.measurement-relabel.tree-columns .select-tree-root .tree-inputs>label {\n float: left;\n width: 50%;\n}\n@-moz-keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n@-webkit-keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n@-o-keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n@keyframes selectTreeCommonCloseRight {\n from {\n height: 37px;\n display: table;\n right: 6px;\n opacity: 1;\n visibility: visible;\n }\n to {\n height: 100%;\n right: -100%;\n opacity: 0;\n visibility: hidden;\n width: calc(100% - 6px);\n }\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"measurementTable":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTable.html")); module.watch(require("./measurementTable.styl")); module.watch(require("./measurementTable.js")); module.watch(require("./measurementTableView/measurementTableView.html")); module.watch(require("./measurementTableView/measurementTableView.styl")); module.watch(require("./measurementTableView/measurementTableView.js")); module.watch(require("./measurementTableHUD/measurementTableHUD.html")); module.watch(require("./measurementTableHUD/measurementTableHUD.styl")); module.watch(require("./measurementTableHUD/measurementTableHUD.js")); module.watch(require("./measurementTableRow/measurementTableRow.html")); module.watch(require("./measurementTableRow/measurementTableRow.styl")); module.watch(require("./measurementTableRow/measurementTableRow.js")); module.watch(require("./measurementTableHeaderRow/measurementTableHeaderRow.html")); module.watch(require("./measurementTableHeaderRow/measurementTableHeaderRow.styl")); module.watch(require("./measurementTableHeaderRow/measurementTableHeaderRow.js")); module.watch(require("./measurementTableTimepointCell/measurementTableTimepointCell.html")); module.watch(require("./measurementTableTimepointCell/measurementTableTimepointCell.styl")); module.watch(require("./measurementTableTimepointCell/measurementTableTimepointCell.js")); module.watch(require("./measurementTableTimepointHeader/measurementTableTimepointHeader.html")); module.watch(require("./measurementTableTimepointHeader/measurementTableTimepointHeader.styl")); module.watch(require("./measurementTableTimepointHeader/measurementTableTimepointHeader.js")); module.watch(require("./measurementTableWarnings/measurementTableWarningsDialog.html")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTable.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTable.html // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTable.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTable.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/template.measurementTable.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTable"); Template["measurementTable"] = new Template("Template.measurementTable", (function() { var view = this; return HTML.DIV({ id: "measurementTableContainer", class: "flex-v" }, "\n ", HTML.DIV({ class: "measurementTableHeader" }, "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("."), "timepoints", "get", "length")); }, function() { return [ "\n ", HTML.DIV({ class: "measurementTableLayoutChanger viewerRoundedButtonGroup" }, "\n ", Blaze._TemplateWith(function() { return Spacebars.call(view.lookup("buttonGroupData")); }, function() { return Spacebars.include(view.lookupTemplate("roundedButtonGroup")); }), "\n "), "\n " ]; }), "\n ", HTML.DIV({ class: "measurementTableTimepointHeaderRow" }, "\n ", HTML.DIV({ class: function() { return [ "warning-status ", Blaze.Unless(function() { return Spacebars.call(view.lookup("hasWarnings")); }, function() { return "hidden"; }) ]; } }, "\n ", HTML.SVG("\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-ui-warning"); } }), "\n "), "\n "), "\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(Spacebars.dot(view.lookup("."), "timepoints", "get")), _variable: "timepoint" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), view.lookup("timepoint")); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableTimepointHeader")); }), "\n " ]; }), "\n ", HTML.Raw(""), "\n "), "\n "), "\n ", Blaze._TemplateWith(function() { return { class: Spacebars.call("measurementTableView flex-grow fit"), scrollStep: Spacebars.call(63) }; }, function() { return Spacebars.include(view.lookupTemplate("scrollArea"), function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup(".")); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableView")); }), "\n " ]; }); }), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTable.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTable.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 1); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); Template.measurementTable.onCreated(function () { var instance = Template.instance(); instance.data.measurementTableLayout = new ReactiveVar('comparison'); instance.data.timepoints = new ReactiveVar([]); // Run this computation every time table layout changes instance.autorun(function () { // Get the current table layout var tableLayout = instance.data.measurementTableLayout.get(); var timepointApi = instance.data.timepointApi; var timepoints; if (!timepointApi) { timepoints = []; } else if (tableLayout === 'key') { timepoints = timepointApi.key(); } else { timepoints = timepointApi.comparison(); } // Return key timepoints instance.data.timepoints.set(timepoints); }); }); Template.measurementTable.onRendered(function () { var instance = Template.instance(); instance.autorun(function () { // Run this computation every time the lesion table layout is changed instance.data.measurementTableLayout.dep.depend(); if (instance.data.state.get('rightSidebar') !== 'measurements') { // Remove the amount attribute from sidebar element tag instance.$('#measurementTableContainer').closest('.sidebarMenu').removeAttr('data-timepoints'); return; } // Get the amount of timepoints being shown var timepointAmount = instance.data.timepoints.get().length; // Set the amount in an attribute on sidebar element tag instance.$('#measurementTableContainer').closest('.sidebarMenu').attr('data-timepoints', timepointAmount); }); }); Template.measurementTable.helpers({ hasWarnings: function () { return Template.instance().data.conformanceCriteria.nonconformities.get(); }, buttonGroupData: function () { var instance = Template.instance(); return { value: instance.data.measurementTableLayout, options: [{ value: 'comparison', text: 'Comparison' }, { value: 'key', text: 'Key Timepoints' }] }; } }); Template.measurementTable.events({ 'click .warning-status': function (event, instance) { var nonconformities = instance.data.conformanceCriteria.nonconformities.get(); var messages = []; _.each(nonconformities, function (nonconformity) { return messages.push(nonconformity.message); }); OHIF.ui.showDialog('measurementTableWarningsDialog', { messages: messages, position: { x: event.clientX, y: event.clientY } }); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTable.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTable.styl // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTable.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTable.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTable.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n#measurementTableContainer {\n height: 100%;\n width: 100%;\n}\n#measurementTableContainer {\n background-color: #000;\n}\nbody.theme-tide #measurementTableContainer {\n background-color: #000;\n}\nbody.theme-tigerlily #measurementTableContainer {\n background-color: #000;\n}\nbody.theme-crickets #measurementTableContainer {\n background-color: #000;\n}\nbody.theme-honeycomb #measurementTableContainer {\n background-color: #000;\n}\nbody.theme-mint #measurementTableContainer {\n background-color: #000;\n}\nbody.theme-overcast #measurementTableContainer {\n background-color: #000;\n}\nbody.theme-quartz #measurementTableContainer {\n background-color: #000;\n}\n.measurementTableTimepointHeaderRow {\n display: flex;\n padding: 0 2px 0 44px;\n position: relative;\n}\n.measurementTableTimepointHeaderRow .warning-status {\n -webkit-border-radius: 16px;\n -moz-border-radius: 16px;\n -ms-border-radius: 16px;\n -o-border-radius: 16px;\n border-radius: 16px;\n cursor: pointer;\n height: 32px;\n left: 0;\n margin: 4px 6px;\n padding-top: 1px;\n position: absolute;\n text-align: center;\n top: 0;\n -webkit-transition: border-color 0.3s ease;\n -moz-transition: border-color 0.3s ease;\n -ms-transition: border-color 0.3s ease;\n -o-transition: border-color 0.3s ease;\n transition: border-color 0.3s ease;\n width: 32px;\n}\n.measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-tide .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-tigerlily .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-crickets .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-honeycomb .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-mint .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-overcast .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\nbody.theme-quartz .measurementTableTimepointHeaderRow .warning-status {\n border: 2px solid #e29e4a;\n}\n.measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-tide .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-tigerlily .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-crickets .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-honeycomb .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-mint .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-overcast .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\nbody.theme-quartz .measurementTableTimepointHeaderRow .warning-status:hover {\n border-color: #fff;\n}\n.measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-tide .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-mint .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementTableTimepointHeaderRow .warning-status:hover svg {\n fill: #fff;\n}\n.measurementTableTimepointHeaderRow .warning-status svg {\n display: inline;\n height: 20px;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n width: 22px;\n}\n.measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-tide .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-tigerlily .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-crickets .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-honeycomb .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-mint .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-overcast .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\nbody.theme-quartz .measurementTableTimepointHeaderRow .warning-status svg {\n fill: #e29e4a;\n}\n.measurementTableLayoutChanger {\n margin: 0 auto;\n padding: 20px;\n text-align: center;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHUD":{"measurementTableHUD.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableHUD/measurementTableHUD.ht // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableHUD.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableHUD.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableHUD/template.measurementTableHUD.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableHUD"); Template["measurementTableHUD"] = new Template("Template.measurementTableHUD", (function() { var view = this; return HTML.DIV({ id: "measurementTableHUD", class: function() { return Spacebars.mustache(view.lookup("hudHidden")); } }, "\n ", HTML.DIV({ class: "flex-v full-height" }, "\n ", HTML.DIV({ class: "header" }, "\n ", HTML.Raw("Measurements"), "\n ", HTML.SVG({ class: "buttonClose" }, "\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-ui-close"); } }), "\n "), "\n "), "\n ", Blaze._TemplateWith(function() { return { class: Spacebars.call("measurementTableView flex-grow fit"), scrollStep: Spacebars.call(63) }; }, function() { return Spacebars.include(view.lookupTemplate("scrollArea"), function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ isHud: true })); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableView")); }), "\n " ]; }); }), "\n ", HTML.DIV({ class: "footer" }, "\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(view.lookup("toolbarButtons")), _variable: "toolbarButton" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.call(view.lookup("toolbarButton")); }, function() { return Spacebars.include(view.lookupTemplate("toolbarSectionButton")); }), "\n " ]; }), "\n "), "\n "), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHUD.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableHUD/measurementTableHUD.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var Session; module.watch(require("meteor/session"), { Session: function (v) { Session = v; } }, 1); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 2); Template.measurementTableHUD.onCreated(function () { var instance = Template.instance(); var timepointApi = instance.data.timepointApi; instance.isRemoved = true; if (timepointApi) { instance.data.timepoints = new ReactiveVar(timepointApi.currentAndPrior()); } }); Template.measurementTableHUD.onDestroyed(function () { var instance = Template.instance(); instance.isRemoved = true; Session.set('measurementTableHudOpen', false); }); Template.measurementTableHUD.onRendered(function () { var instance = Template.instance(); instance.$('#measurementTableHUD').resizable().draggable().bounded(); }); Template.measurementTableHUD.events({ 'click .buttonClose': function (event, instance) { Session.set('measurementTableHudOpen', false); } }); Template.measurementTableHUD.helpers({ hudHidden: function () { var instance = Template.instance(), isOpen = Session.get('measurementTableHudOpen'); if (isOpen) { instance.isRemoved = false; return 'dialog-animated dialog-open'; } return instance.isRemoved !== true ? 'dialog-animated dialog-closed' : 'hidden'; }, toolbarButtons: function () { var buttonData = []; buttonData.push({ id: 'bidirectional', title: 'Target', classes: 'imageViewerTool toolbarSectionButton', svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-target' }); buttonData.push({ id: 'nonTarget', title: 'Non-Target', classes: 'imageViewerTool toolbarSectionButton', svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-non-target' }); buttonData.push({ id: 'length', title: 'Temp', classes: 'imageViewerTool toolbarSectionButton', svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-temp' }); return buttonData; } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHUD.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableHUD/measurementTableHUD.st // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTableHUD.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHUD.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableHUD/measurementTableHUD.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n#measurementTableHUD {\n background: rgba(0,0,0,0.95);\n -webkit-border-radius: 8px;\n -moz-border-radius: 8px;\n -ms-border-radius: 8px;\n -o-border-radius: 8px;\n border-radius: 8px;\n border: solid 1px rgba(77,99,110,0.81);\n bottom: 3px;\n height: 326px;\n left: auto;\n overflow: hidden;\n position: absolute;\n right: 3px;\n top: auto;\n width: 318px;\n z-index: 1;\n}\n#measurementTableHUD .measurementTableView .scrollable {\n margin-left: 0;\n padding-left: 0;\n}\n#measurementTableHUD .header {\n border-bottom: 1px solid rgba(77,99,110,0.81);\n font-weight: 300;\n font-size: 20px;\n height: 55px;\n line-height: 55px;\n position: relative;\n text-align: center;\n width: 100%;\n}\n#measurementTableHUD .header {\n background: #14202a;\n}\nbody.theme-tide #measurementTableHUD .header {\n background: #14202a;\n}\nbody.theme-tigerlily #measurementTableHUD .header {\n background: #14191e;\n}\nbody.theme-crickets #measurementTableHUD .header {\n background: #14191e;\n}\nbody.theme-honeycomb #measurementTableHUD .header {\n background: #14191e;\n}\nbody.theme-mint #measurementTableHUD .header {\n background: #14191e;\n}\nbody.theme-overcast #measurementTableHUD .header {\n background: #14191e;\n}\nbody.theme-quartz #measurementTableHUD .header {\n background: #14191e;\n}\n#measurementTableHUD .header {\n color: #91b9cd;\n}\nbody.theme-tide #measurementTableHUD .header {\n color: #91b9cd;\n}\nbody.theme-tigerlily #measurementTableHUD .header {\n color: #9ccdf8;\n}\nbody.theme-crickets #measurementTableHUD .header {\n color: #8be7b5;\n}\nbody.theme-honeycomb #measurementTableHUD .header {\n color: #fab797;\n}\nbody.theme-mint #measurementTableHUD .header {\n color: #a7e9b3;\n}\nbody.theme-overcast #measurementTableHUD .header {\n color: #73f2fc;\n}\nbody.theme-quartz #measurementTableHUD .header {\n color: #d7e8fe;\n}\n#measurementTableHUD .header svg.buttonClose {\n cursor: pointer;\n height: 14px;\n position: absolute;\n right: 14px;\n top: 20px;\n width: 14px;\n}\n#measurementTableHUD .header svg.buttonClose {\n color: #9ccef9;\n}\nbody.theme-tide #measurementTableHUD .header svg.buttonClose {\n color: #9ccef9;\n}\nbody.theme-tigerlily #measurementTableHUD .header svg.buttonClose {\n color: #9acffd;\n}\nbody.theme-crickets #measurementTableHUD .header svg.buttonClose {\n color: #92c2da;\n}\nbody.theme-honeycomb #measurementTableHUD .header svg.buttonClose {\n color: #b5b5b5;\n}\nbody.theme-mint #measurementTableHUD .header svg.buttonClose {\n color: #a7e9b3;\n}\nbody.theme-overcast #measurementTableHUD .header svg.buttonClose {\n color: #9cbecf;\n}\nbody.theme-quartz #measurementTableHUD .header svg.buttonClose {\n color: #8ea2a4;\n}\n#measurementTableHUD .header svg.buttonClose {\n stroke: #9ccef9;\n}\nbody.theme-tide #measurementTableHUD .header svg.buttonClose {\n stroke: #9ccef9;\n}\nbody.theme-tigerlily #measurementTableHUD .header svg.buttonClose {\n stroke: #9acffd;\n}\nbody.theme-crickets #measurementTableHUD .header svg.buttonClose {\n stroke: #92c2da;\n}\nbody.theme-honeycomb #measurementTableHUD .header svg.buttonClose {\n stroke: #b5b5b5;\n}\nbody.theme-mint #measurementTableHUD .header svg.buttonClose {\n stroke: #a7e9b3;\n}\nbody.theme-overcast #measurementTableHUD .header svg.buttonClose {\n stroke: #9cbecf;\n}\nbody.theme-quartz #measurementTableHUD .header svg.buttonClose {\n stroke: #8ea2a4;\n}\n#measurementTableHUD .measurementTableView {\n height: calc(100% - 55px - 70px);\n padding-bottom: 20px;\n}\n#measurementTableHUD .footer {\n border-top: 1px solid rgba(77,99,110,0.81);\n height: 70px;\n padding: 10px;\n}\n#measurementTableHUD .footer {\n background: #14202a;\n}\nbody.theme-tide #measurementTableHUD .footer {\n background: #14202a;\n}\nbody.theme-tigerlily #measurementTableHUD .footer {\n background: #14191e;\n}\nbody.theme-crickets #measurementTableHUD .footer {\n background: #14191e;\n}\nbody.theme-honeycomb #measurementTableHUD .footer {\n background: #14191e;\n}\nbody.theme-mint #measurementTableHUD .footer {\n background: #14191e;\n}\nbody.theme-overcast #measurementTableHUD .footer {\n background: #14191e;\n}\nbody.theme-quartz #measurementTableHUD .footer {\n background: #14191e;\n}\n#measurementTableHUD .footer .toolbarSectionButton {\n display: inline-block;\n padding: 0 10px;\n height: 78px;\n min-width: 30px;\n cursor: pointer;\n text-align: center;\n}\n#measurementTableHUD .footer .toolbarSectionButton {\n color: #9ccef9;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton {\n color: #9ccef9;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton {\n color: #9acffd;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton {\n color: #92c2da;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton {\n color: #b5b5b5;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton {\n color: #a7e9b3;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton {\n color: #9cbecf;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton {\n color: #8ea2a4;\n}\n#measurementTableHUD .footer .toolbarSectionButton {\n fill: #9ccef9;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton {\n fill: #9ccef9;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton {\n fill: #9acffd;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton {\n fill: #92c2da;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton {\n fill: #b5b5b5;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton {\n fill: #a7e9b3;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton {\n fill: #9cbecf;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton {\n fill: #8ea2a4;\n}\n#measurementTableHUD .footer .toolbarSectionButton {\n stroke: #9ccef9;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #9ccef9;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #9acffd;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #92c2da;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #b5b5b5;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #a7e9b3;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #9cbecf;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton {\n stroke: #8ea2a4;\n}\n#measurementTableHUD .footer .toolbarSectionButton.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n#measurementTableHUD .footer .toolbarSectionButton .buttonLabel {\n font-size: 12px;\n}\n#measurementTableHUD .footer .toolbarSectionButton .svgContainer {\n margin: 0 auto;\n text-align: center;\n}\n#measurementTableHUD .footer .toolbarSectionButton svg {\n background-color: transparent;\n margin: 2px;\n width: 21px;\n height: 21px;\n}\n#measurementTableHUD .footer .toolbarSectionButton:active,\n#measurementTableHUD .footer .toolbarSectionButton.active {\n color: #20a5d6;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #20a5d6;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #20a5d6;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #fa8947;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #fa8947;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #d4c3c1;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #d4c3c1;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #cda56b;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #cda56b;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #31b166;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #31b166;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #507d80;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #507d80;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton:active {\n color: #7858ce;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton.active {\n color: #7858ce;\n}\n#measurementTableHUD .footer .toolbarSectionButton:active svg,\n#measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #20a5d6;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #20a5d6;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #20a5d6;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #fa8947;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #fa8947;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #d4c3c1;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #d4c3c1;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #cda56b;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #cda56b;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #31b166;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #31b166;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #507d80;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #507d80;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton:active svg {\n fill: #7858ce;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton.active svg {\n fill: #7858ce;\n}\n#measurementTableHUD .footer .toolbarSectionButton:active svg,\n#measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #20a5d6;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #20a5d6;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #20a5d6;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #fa8947;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #fa8947;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #d4c3c1;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #d4c3c1;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #cda56b;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #cda56b;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #31b166;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #31b166;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #507d80;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #507d80;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton:active svg {\n stroke: #7858ce;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton.active svg {\n stroke: #7858ce;\n}\n#measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton:hover {\n color: #fff;\n}\n#measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n fill: #fff;\n}\n#measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-tide #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-tigerlily #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-crickets #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-honeycomb #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-mint #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-overcast #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\nbody.theme-quartz #measurementTableHUD .footer .toolbarSectionButton:hover svg {\n stroke: #fff;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementTableHeaderRow":{"measurementTableHeaderRow.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableHeaderRow/measurementTable // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableHeaderRow.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableHeaderRow.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableHeaderRow/template.measurementTableHe // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableHeaderRow"); Template["measurementTableHeaderRow"] = new Template("Template.measurementTableHeaderRow", (function() { var view = this; return HTML.DIV({ class: "measurementTableHeaderRow" }, "\n ", HTML.DIV({ class: "type" }, Blaze.View("lookup:toolGroup.name", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("toolGroup"), "name")); })), "\n ", HTML.DIV({ class: function() { return [ "max ", Blaze.If(function() { return Spacebars.dataMustache(view.lookup("gt"), view.lookup("numberOfMeasurements"), view.lookup("maxNumMeasurements")); }, function() { return "warning"; }) ]; } }, "\n ", Blaze.If(function() { return Spacebars.dataMustache(view.lookup("getMax"), Spacebars.dot(view.lookup("toolGroup"), "id")); }, function() { return [ "\n ", HTML.P({ class: "maxNumMeasurements" }, "Max ", Blaze.View("lookup:getMax", function() { return Spacebars.mustache(view.lookup("getMax"), Spacebars.dot(view.lookup("toolGroup"), "id")); })), "\n " ]; }), "\n "), "\n ", HTML.DIV({ class: "numberOfMeasurements" }, Blaze.View("lookup:numberOfMeasurements", function() { return Spacebars.mustache(view.lookup("numberOfMeasurements"), Spacebars.dot(view.lookup("toolGroup"), "id")); })), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHeaderRow.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableHeaderRow/measurementTableHeaderRow.j // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); var Viewerbase; module.watch(require("meteor/ohif:viewerbase"), { Viewerbase: function (v) { Viewerbase = v; } }, 2); Template.measurementTableHeaderRow.helpers({ numberOfMeasurements: function (toolGroupId) { var _Template$instance$da = Template.instance().data, toolGroup = _Template$instance$da.toolGroup, measurementRows = _Template$instance$da.measurementRows; if (toolGroup.id === 'newTargets') { var result = 0; measurementRows.forEach(function (measurementRow) { var measurementData = measurementRow.entries[0]; if (measurementData.isSplitLesion) return; result++; }); return result; } return measurementRows.length ? measurementRows.length : null; }, getMax: function (toolGroupId) { var conformanceCriteria = Template.instance().data.conformanceCriteria; if (!conformanceCriteria) return; if (toolGroupId === 'targets') { return conformanceCriteria.maxTargets.get(); } else if (toolGroupId === 'newTargets') { return conformanceCriteria.maxNewTargets.get(); } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHeaderRow.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableHeaderRow/measurementTable // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTableHeaderRow.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableHeaderRow.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableHeaderRow/measurementTableHeaderRow.s // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementTableHeaderRow {\n display: flex;\n height: 63px;\n line-height: 63px;\n margin-top: 2px;\n width: 100%;\n}\n.measurementTableHeaderRow {\n background-color: #151a1f;\n}\nbody.theme-tide .measurementTableHeaderRow {\n background-color: #151a1f;\n}\nbody.theme-tigerlily .measurementTableHeaderRow {\n background-color: #151a1f;\n}\nbody.theme-crickets .measurementTableHeaderRow {\n background-color: #231c1e;\n}\nbody.theme-honeycomb .measurementTableHeaderRow {\n background-color: #18161a;\n}\nbody.theme-mint .measurementTableHeaderRow {\n background-color: #15191e;\n}\nbody.theme-overcast .measurementTableHeaderRow {\n background-color: #15191e;\n}\nbody.theme-quartz .measurementTableHeaderRow {\n background-color: #151a1f;\n}\n.measurementTableHeaderRow {\n color: #91b9cd;\n}\nbody.theme-tide .measurementTableHeaderRow {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableHeaderRow {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementTableHeaderRow {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableHeaderRow {\n color: #fab797;\n}\nbody.theme-mint .measurementTableHeaderRow {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableHeaderRow {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementTableHeaderRow {\n color: #d7e8fe;\n}\n.measurementTableHeaderRow {\n fill: #91b9cd;\n}\nbody.theme-tide .measurementTableHeaderRow {\n fill: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableHeaderRow {\n fill: #9ccdf8;\n}\nbody.theme-crickets .measurementTableHeaderRow {\n fill: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableHeaderRow {\n fill: #fab797;\n}\nbody.theme-mint .measurementTableHeaderRow {\n fill: #a7e9b3;\n}\nbody.theme-overcast .measurementTableHeaderRow {\n fill: #73f2fc;\n}\nbody.theme-quartz .measurementTableHeaderRow {\n fill: #d7e8fe;\n}\n.measurementTableHeaderRow.inactive .add {\n cursor: not-allowed;\n}\n.measurementTableHeaderRow.inactive .add svg {\n fill: #5a666d;\n}\n.measurementTableHeaderRow div {\n align-items: stretch;\n flex: 1;\n justify-content: space-around;\n text-align: center;\n}\n.measurementTableHeaderRow .add {\n cursor: pointer;\n max-width: 30px;\n padding-left: 2px;\n}\n.measurementTableHeaderRow .add svg {\n fill: #c1d8e3;\n height: 63px;\n max-width: 11px;\n}\n.measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-tide .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-mint .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementTableHeaderRow .add:hover svg {\n fill: #fff;\n}\n.measurementTableHeaderRow .add:active svg {\n fill: #20a5d6;\n}\nbody.theme-tide .measurementTableHeaderRow .add:active svg {\n fill: #20a5d6;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .add:active svg {\n fill: #fa8947;\n}\nbody.theme-crickets .measurementTableHeaderRow .add:active svg {\n fill: #d4c3c1;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .add:active svg {\n fill: #cda56b;\n}\nbody.theme-mint .measurementTableHeaderRow .add:active svg {\n fill: #31b166;\n}\nbody.theme-overcast .measurementTableHeaderRow .add:active svg {\n fill: #507d80;\n}\nbody.theme-quartz .measurementTableHeaderRow .add:active svg {\n fill: #7858ce;\n}\n.measurementTableHeaderRow .type {\n font-size: 22px;\n font-weight: 300;\n line-height: 63px;\n padding: 0 10px 0 20px;\n text-align: left;\n}\n.measurementTableHeaderRow .type {\n color: #91b9cd;\n}\nbody.theme-tide .measurementTableHeaderRow .type {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .type {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementTableHeaderRow .type {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .type {\n color: #fab797;\n}\nbody.theme-mint .measurementTableHeaderRow .type {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableHeaderRow .type {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementTableHeaderRow .type {\n color: #d7e8fe;\n}\n.measurementTableHeaderRow .numberOfMeasurements {\n float: right;\n font-weight: 300;\n font-size: 40px;\n max-width: 54px;\n height: 63px;\n line-height: 66px;\n}\n.measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-tide .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-crickets .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-mint .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-overcast .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\nbody.theme-quartz .measurementTableHeaderRow .numberOfMeasurements {\n color: #6fbde2;\n}\n.measurementTableHeaderRow .max {\n height: 63px;\n max-width: 64px;\n text-align: right;\n}\n.measurementTableHeaderRow .max .maxNumMeasurements {\n -webkit-border-radius: 3px;\n -moz-border-radius: 3px;\n -ms-border-radius: 3px;\n -o-border-radius: 3px;\n border-radius: 3px;\n color: #000;\n display: table;\n font-size: 12px;\n font-weight: 500;\n height: 19px;\n line-height: 17px;\n margin-left: auto;\n margin-top: 22px;\n padding: 2px 6px 0;\n text-transform: uppercase;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #91b9cd;\n}\nbody.theme-tide .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #9ccdf8;\n}\nbody.theme-crickets .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #fab797;\n}\nbody.theme-mint .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #73f2fc;\n}\nbody.theme-quartz .measurementTableHeaderRow .max .maxNumMeasurements {\n background-color: #d7e8fe;\n}\n.measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-tide .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-crickets .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-mint .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-overcast .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\nbody.theme-quartz .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n background-color: #e29e4a;\n}\n.measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-tide .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-crickets .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-mint .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-overcast .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\nbody.theme-quartz .measurementTableHeaderRow .max.warning .maxNumMeasurements {\n color: #fff;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementTableRow":{"measurementTableRow.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.ht // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableRow.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableRow.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableRow/template.measurementTableRow.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableRow"); Template["measurementTableRow"] = new Template("Template.measurementTableRow", (function() { var view = this; return HTML.DIV({ class: function() { return [ "measurementTableRow ", Blaze.If(function() { return Spacebars.call(view.lookup("hasWarnings")); }, function() { return "warning"; }), Blaze.If(function() { return Spacebars.call(view.lookup("responseStatus")); }, function() { return "response-status"; }) ]; }, "data-measurementid": function() { return Spacebars.mustache(view.lookup("_id")); } }, "\n ", HTML.DIV({ class: "measurementRowSidebar" }, "\n ", HTML.DIV({ class: "measurementNumber" }, "\n ", Blaze.View("lookup:rowItem.measurementNumber", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("rowItem"), "measurementNumber")); }), "\n "), "\n ", Blaze.If(function() { return Spacebars.call(view.lookup("hasWarnings")); }, function() { return [ "\n ", HTML.DIV({ class: "warning-icon" }, "\n ", HTML.SVG("\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-ui-warning"); } }), "\n "), "\n "), "\n " ]; }), "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("rowItem"), "responseStatus")); }, function() { return [ "\n ", HTML.DIV({ class: "response-status-icon" }, "\n ", Blaze.View("lookup:rowItem.responseStatus", function() { return Spacebars.mustache(Spacebars.dot(view.lookup("rowItem"), "responseStatus")); }), "\n "), "\n " ]; }), "\n "), "\n ", HTML.DIV({ class: "measurementDetails" }, "\n ", HTML.DIV({ class: "location" }, "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("rowItem"), "location")); }, function() { return [ "\n ", Blaze.View("lookup:getLocationLabel", function() { return Spacebars.mustache(view.lookup("getLocationLabel"), Spacebars.dot(view.lookup("rowItem"), "location")); }), "\n " ]; }, function() { return "\n (No description)\n "; }), "\n "), "\n ", HTML.DIV({ class: "timepointData" }, "\n ", HTML.Raw(""), "\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(Spacebars.dot(view.lookup("timepoints"), "get")), _variable: "timepoint" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), view.lookup("timepoint")); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableTimepointCell")); }), "\n " ]; }, function() { return [ "\n ", Spacebars.include(view.lookupTemplate("measurementTableTimepointCell")), "\n " ]; }), "\n "), "\n ", HTML.DIV({ class: "rowOptions" }, "\n ", HTML.DIV({ class: "rowAction js-rename pull-left m-r-2", tabindex: "1" }, "\n ", HTML.SVG({ class: "edit-icon" }, "\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-measurements-additional"); } }), "\n "), "\n Relabel\n "), "\n ", HTML.DIV({ class: "rowAction js-delete pull-left", tabindex: "1" }, "\n ", HTML.SVG({ class: "close-icon" }, "\n ", HTML.USE({ "xlink:href": function() { return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-ui-close"); } }), "\n "), "\n Delete\n "), "\n "), "\n "), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableRow.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 4); Template.measurementTableRow.onCreated(function () { var instance = Template.instance(); instance.getWarningMessages = function () { var measurementTypeId = instance.data.rowItem.measurementTypeId; var measurementNumber = instance.data.rowItem.measurementNumber; var groupedNonConformities = instance.data.conformanceCriteria.groupedNonConformities.get() || {}; var nonconformitiesByMeasurementTypeId = groupedNonConformities[measurementTypeId] || {}; var nonconformitiesByMeasurementNumbers = nonconformitiesByMeasurementTypeId.measurementNumbers || {}; var nonconformitiesByMeasurementNumber = nonconformitiesByMeasurementNumbers[measurementNumber] || {}; return _.uniq(nonconformitiesByMeasurementNumber.messages || []); }; }); Template.measurementTableRow.helpers({ hasWarnings: function () { return !!Template.instance().getWarningMessages().length; } }); Template.measurementTableRow.events({ 'click .measurementRowSidebar .warning-icon': function (event, instance) { event.stopPropagation(); OHIF.ui.showDialog('measurementTableWarningsDialog', { messages: instance.getWarningMessages(), position: { x: event.clientX, y: event.clientY } }); }, 'click .measurementRowSidebar': function (event, instance) { var $row = instance.$('.measurementTableRow'); var rowItem = instance.data.rowItem; var timepoints = instance.data.timepoints.get(); $row.closest('.measurementTableView').find('.measurementTableRow').not($row).removeClass('active'); $row.toggleClass('active'); var childToolKey = $(event.target).attr('data-child'); OHIF.measurements.jumpToRowItem(rowItem, timepoints, childToolKey); }, 'click .js-rename': function (event, instance) { var rowItem = instance.data.rowItem; var entry = rowItem.entries[0]; // Show the measure flow for targets OHIF.measurements.toggleLabelButton({ measurement: entry, element: document.body, measurementApi: instance.data.measurementApi, position: { x: event.clientX, y: event.clientY }, autoClick: true }); }, 'click .js-delete': function (event, instance) { var dialogSettings = { "class": 'themed', title: 'Delete measurements', message: 'Are you sure you want to delete the measurement across all timepoints?', position: { x: event.clientX, y: event.clientY } }; OHIF.ui.showDialog('dialogConfirm', dialogSettings).then(function (formData) { var measurementTypeId = instance.data.rowItem.measurementTypeId; var measurement = instance.data.rowItem.entries[0]; var measurementNumber = measurement.measurementNumber; var _instance$data = instance.data, timepointApi = _instance$data.timepointApi, measurementApi = _instance$data.measurementApi; // Remove all the measurements with the given type and number measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber: measurementNumber }); // Sync the new measurement data with cornerstone tools var baseline = timepointApi.baseline(); measurementApi.sortMeasurements(baseline.timepointId); // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), function (element) { return cornerstone.updateImage(element); }); // Notify that viewer suffered changes OHIF.measurements.triggerTimepointUnsavedChanges('deleted'); }); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableRow.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.st // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTableRow.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableRow.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableRow/measurementTableRow.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementTableRow {\n display: flex;\n margin-left: -6px;\n margin-top: 2px;\n padding-left: 6px;\n -webkit-transform: scale(1);\n -moz-transform: scale(1);\n -ms-transform: scale(1);\n -o-transform: scale(1);\n transform: scale(1);\n width: calc(100% + 6px);\n}\n.measurementTableRow.active .measurementRowSidebar {\n color: #20a5d6;\n}\nbody.theme-tide .measurementTableRow.active .measurementRowSidebar {\n color: #20a5d6;\n}\nbody.theme-tigerlily .measurementTableRow.active .measurementRowSidebar {\n color: #fa8947;\n}\nbody.theme-crickets .measurementTableRow.active .measurementRowSidebar {\n color: #d4c3c1;\n}\nbody.theme-honeycomb .measurementTableRow.active .measurementRowSidebar {\n color: #cda56b;\n}\nbody.theme-mint .measurementTableRow.active .measurementRowSidebar {\n color: #31b166;\n}\nbody.theme-overcast .measurementTableRow.active .measurementRowSidebar {\n color: #507d80;\n}\nbody.theme-quartz .measurementTableRow.active .measurementRowSidebar {\n color: #7858ce;\n}\n.measurementTableRow.active .rowOptions {\n height: 35px;\n visibility: visible;\n}\n.measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n -webkit-border-radius: 11px;\n -moz-border-radius: 11px;\n -ms-border-radius: 11px;\n -o-border-radius: 11px;\n border-radius: 11px;\n font-size: 12px;\n font-weight: 700;\n height: 21px;\n line-height: 22px;\n margin: 5px auto 0;\n text-align: center;\n width: 21px;\n}\n.measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #9ccef9;\n}\nbody.theme-tide .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #9ccef9;\n}\nbody.theme-tigerlily .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #9acffd;\n}\nbody.theme-crickets .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #92c2da;\n}\nbody.theme-honeycomb .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #b5b5b5;\n}\nbody.theme-mint .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #9cbecf;\n}\nbody.theme-quartz .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n background-color: #8ea2a4;\n}\n.measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-tide .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-tigerlily .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-crickets .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-honeycomb .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-mint .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-overcast .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\nbody.theme-quartz .measurementTableRow.response-status .measurementRowSidebar .response-status-icon {\n color: #263340;\n}\n.measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-tide .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-tigerlily .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-crickets .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-honeycomb .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-mint .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-overcast .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\nbody.theme-quartz .measurementTableRow.warning .measurementRowSidebar {\n background-color: #e29e4a;\n}\n.measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-tide .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-crickets .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-mint .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-overcast .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\nbody.theme-quartz .measurementTableRow.warning .measurementRowSidebar {\n color: #fff;\n}\n.measurementTableRow.warning .measurementRowSidebar .warning-icon,\n.measurementTableRow.warning .measurementRowSidebar svg {\n width: 22px;\n height: 20px;\n pointer-events: inherit;\n}\n.measurementTableRow.warning .measurementRowSidebar .warning-icon {\n margin: 7px auto 0;\n}\n.measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-tide .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-mint .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementTableRow.warning .measurementRowSidebar svg {\n fill: #fff;\n}\n.measurementTableRow .rowOptions {\n height: 0;\n overflow: hidden;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n visibility: hidden;\n}\n.measurementTableRow .rowOptions {\n background-color: #151a1f;\n}\nbody.theme-tide .measurementTableRow .rowOptions {\n background-color: #151a1f;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions {\n background-color: #151a1f;\n}\nbody.theme-crickets .measurementTableRow .rowOptions {\n background-color: #231c1e;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions {\n background-color: #18161a;\n}\nbody.theme-mint .measurementTableRow .rowOptions {\n background-color: #15191e;\n}\nbody.theme-overcast .measurementTableRow .rowOptions {\n background-color: #15191e;\n}\nbody.theme-quartz .measurementTableRow .rowOptions {\n background-color: #151a1f;\n}\n.measurementTableRow .rowOptions .rowAction {\n cursor: pointer;\n line-height: 35px;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementTableRow .rowOptions .rowAction {\n color: #9ccef9;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction {\n color: #9ccef9;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction {\n color: #9acffd;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction {\n color: #92c2da;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction {\n color: #b5b5b5;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction {\n color: #9cbecf;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction {\n color: #8ea2a4;\n}\n.measurementTableRow .rowOptions .rowAction:hover,\n.measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction:hover {\n color: #fff;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction:active {\n color: #fff;\n}\n.measurementTableRow .rowOptions .rowAction:hover svg,\n.measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction:hover svg {\n fill: #fff;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction:active svg {\n fill: #fff;\n}\n.measurementTableRow .rowOptions .rowAction:hover svg,\n.measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-tide .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-crickets .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-mint .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-overcast .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction:hover svg {\n stroke: #fff;\n}\nbody.theme-quartz .measurementTableRow .rowOptions .rowAction:active svg {\n stroke: #fff;\n}\n.measurementTableRow .rowOptions svg {\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementTableRow .rowOptions svg {\n fill: #9ccef9;\n}\nbody.theme-tide .measurementTableRow .rowOptions svg {\n fill: #9ccef9;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions svg {\n fill: #9acffd;\n}\nbody.theme-crickets .measurementTableRow .rowOptions svg {\n fill: #92c2da;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions svg {\n fill: #b5b5b5;\n}\nbody.theme-mint .measurementTableRow .rowOptions svg {\n fill: #a7e9b3;\n}\nbody.theme-overcast .measurementTableRow .rowOptions svg {\n fill: #9cbecf;\n}\nbody.theme-quartz .measurementTableRow .rowOptions svg {\n fill: #8ea2a4;\n}\n.measurementTableRow .rowOptions svg {\n stroke: #9ccef9;\n}\nbody.theme-tide .measurementTableRow .rowOptions svg {\n stroke: #9ccef9;\n}\nbody.theme-tigerlily .measurementTableRow .rowOptions svg {\n stroke: #9acffd;\n}\nbody.theme-crickets .measurementTableRow .rowOptions svg {\n stroke: #92c2da;\n}\nbody.theme-honeycomb .measurementTableRow .rowOptions svg {\n stroke: #b5b5b5;\n}\nbody.theme-mint .measurementTableRow .rowOptions svg {\n stroke: #a7e9b3;\n}\nbody.theme-overcast .measurementTableRow .rowOptions svg {\n stroke: #9cbecf;\n}\nbody.theme-quartz .measurementTableRow .rowOptions svg {\n stroke: #8ea2a4;\n}\n.measurementTableRow .rowOptions svg.edit-icon {\n width: 14px;\n height: 13px;\n}\n.measurementTableRow .rowOptions svg.close-icon {\n width: 11px;\n height: 11px;\n}\n.measurementTableRow .measurementRowSidebar {\n cursor: pointer;\n flex: 1;\n max-width: 30px;\n -webkit-transition: all 0.3s ease;\n -moz-transition: all 0.3s ease;\n -ms-transition: all 0.3s ease;\n -o-transition: all 0.3s ease;\n transition: all 0.3s ease;\n}\n.measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-tide .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-tigerlily .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-crickets .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-honeycomb .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-mint .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-overcast .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\nbody.theme-quartz .measurementTableRow .measurementRowSidebar {\n background: #263340;\n}\n.measurementTableRow .measurementRowSidebar {\n color: #91b9cd;\n}\nbody.theme-tide .measurementTableRow .measurementRowSidebar {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableRow .measurementRowSidebar {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementTableRow .measurementRowSidebar {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableRow .measurementRowSidebar {\n color: #fab797;\n}\nbody.theme-mint .measurementTableRow .measurementRowSidebar {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableRow .measurementRowSidebar {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementTableRow .measurementRowSidebar {\n color: #d7e8fe;\n}\n.measurementTableRow .measurementRowSidebar .measurementNumber {\n font-size: 14px;\n font-weight: 400;\n margin-right: 5px;\n padding-top: 10px;\n text-align: center;\n}\n.measurementTableRow .measurementDetails {\n flex: 1;\n padding: 5px 2px 0 0;\n}\n.measurementTableRow .measurementDetails>* {\n padding-left: 14px;\n}\n.measurementTableRow .measurementDetails .location {\n font-weight: 400;\n font-size: 14px;\n height: 30px;\n line-height: 30px;\n margin-left: -2px;\n width: 100%;\n}\n.measurementTableRow .measurementDetails .location {\n color: #91b9cd;\n}\nbody.theme-tide .measurementTableRow .measurementDetails .location {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableRow .measurementDetails .location {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementTableRow .measurementDetails .location {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableRow .measurementDetails .location {\n color: #fab797;\n}\nbody.theme-mint .measurementTableRow .measurementDetails .location {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableRow .measurementDetails .location {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementTableRow .measurementDetails .location {\n color: #d7e8fe;\n}\n.measurementTableRow .measurementDetails .timepointData {\n display: flex;\n min-height: 27px;\n margin-top: 1px;\n}\n.measurementTableRow .measurementDetails .timepointData div {\n flex: 1;\n font-size: 14px;\n font-weight: 400;\n justify-content: space-around;\n line-height: 18px;\n padding-bottom: 4px;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementTableTimepointCell":{"measurementTableTimepointCell.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableTimepointCell/measurementT // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableTimepointCell.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableTimepointCell.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableTimepointCell/template.measurementTab // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableTimepointCell"); Template["measurementTableTimepointCell"] = new Template("Template.measurementTableTimepointCell", (function() { var view = this; return Blaze.If(function() { return Spacebars.call(view.lookup("hasDataAtThisTimepoint")); }, function() { return [ "\n ", HTML.DIV({ class: function() { return [ "measurementTableTimepointCell noselect ", Blaze.If(function() { return Spacebars.call(view.lookup("isLoading")); }, function() { return "loading"; }) ]; }, tabindex: "1" }, "\n ", HTML.I({ class: "fa fa-spin fa-circle-o-notch fa-fw loading-spinner" }), "\n ", Blaze.View("lookup:displayData", function() { return Spacebars.makeRaw(Spacebars.mustache(view.lookup("displayData"))); }), "\n "), "\n " ]; }, function() { return [ "\n ", HTML.DIV({ class: "measurementTableTimepointCell noselect empty" }, "\n ...\n "), "\n " ]; }); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableTimepointCell.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableTimepointCell/measurementTableTimepoi // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 4); Template.measurementTableTimepointCell.helpers({ hasDataAtThisTimepoint: function () { // This simple function just checks whether or not timepoint data // exists for this Measurement at this Timepoint var instance = Template.instance(); var _instance$data = instance.data, rowItem = _instance$data.rowItem, timepointId = _instance$data.timepointId; if (timepointId) { var dataAtThisTimepoint = _.where(rowItem.entries, { timepointId: timepointId }); return dataAtThisTimepoint.length > 0; } else { return rowItem.entries.length > 0; } }, displayData: function () { var instance = Template.instance(); var _instance$data2 = instance.data, rowItem = _instance$data2.rowItem, timepointId = _instance$data2.timepointId; var data; if (timepointId) { var dataAtThisTimepoint = _.where(rowItem.entries, { timepointId: timepointId }); if (dataAtThisTimepoint.length > 1) { throw 'More than one measurement was found at the same timepoint with the same measurement number?'; } data = dataAtThisTimepoint[0]; } else { data = rowItem.entries[0]; } var config = OHIF.measurements.MeasurementApi.getConfiguration(); var measurementTools = config.measurementTools; var toolGroup = _.findWhere(measurementTools, { id: rowItem.measurementTypeId }); var tool = _.findWhere(toolGroup.childTools, { id: data.toolType }); if (!tool) { // TODO: Figure out what is going on here? OHIF.log.warn('Something went wrong?'); } var displayFunction = tool.options.measurementTable.displayFunction; return displayFunction(data); }, isLoading: function () { var instance = Template.instance(); var _instance$data3 = instance.data, rowItem = _instance$data3.rowItem, timepointId = _instance$data3.timepointId; var entries = rowItem.entries; var measurementData = timepointId ? _.findWhere(entries, { timepointId: timepointId }) : entries[0]; var studyInstanceUid = measurementData.studyInstanceUid; return OHIF.studies.loadingDict.get(studyInstanceUid) === 'loading'; } }); Template.measurementTableTimepointCell.events({ 'dblclick .measurementTableTimepointCell': function (event, instance) { var _instance$data4 = instance.data, rowItem = _instance$data4.rowItem, timepointId = _instance$data4.timepointId; if (!timepointId) return; var measurementData = _.findWhere(rowItem.entries, { timepointId: timepointId }); if (!measurementData || measurementData.toolType !== 'nonTarget') return; var viewportIndex = rowItem.entries.indexOf(measurementData); var $viewports = $('#viewer .imageViewerViewport'); var $element = $viewports.eq(viewportIndex); $element = $element.length ? $element : $viewports.eq(0); OHIF.ui.showDialog('dialogNonTargetMeasurement', { event: event, title: 'Change Lesion Location', element: $element[0], measurementData: measurementData, edit: true }); }, 'keydown .measurementTableTimepointCell': function (event, instance) { // Delete a lesion if Ctrl+D or DELETE is pressed while a lesion is selected var keys = { D: 68, DELETE: 46 }; var keyCode = event.which; if (keyCode === keys.DELETE || keyCode === keys.BACKSPACE || keyCode === keys.D && event.ctrlKey === true) { var timepointId = instance.data.timepointId; var offset = $(event.currentTarget).offset(); var dialogSettings = { "class": 'themed', title: 'Delete measurements', message: 'Are you sure you want to delete this measurement?', position: { x: offset.left, y: offset.top } }; OHIF.ui.showDialog('dialogConfirm', dialogSettings).then(function () { var measurementTypeId = instance.data.rowItem.measurementTypeId; var measurement = instance.data.rowItem.entries[0]; var measurementNumber = measurement.measurementNumber; var _instance$data5 = instance.data, timepointApi = _instance$data5.timepointApi, measurementApi = _instance$data5.measurementApi; // Remove all the measurements with the given type and number measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber: measurementNumber, timepointId: timepointId }); // Sync the new measurement data with cornerstone tools var baseline = timepointApi.baseline(); measurementApi.sortMeasurements(baseline.timepointId); // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), function (element) { return cornerstone.updateImage(element); }); }); } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableTimepointCell.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableTimepointCell/measurementT // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTableTimepointCell.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableTimepointCell.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableTimepointCell/measurementTableTimepoi // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementTableTimepointCell {\n cursor: pointer;\n padding: 0 10px;\n position: relative;\n}\n.measurementTableTimepointCell {\n border-left: 1px solid #44626f;\n}\nbody.theme-tide .measurementTableTimepointCell {\n border-left: 1px solid #44626f;\n}\nbody.theme-tigerlily .measurementTableTimepointCell {\n border-left: 1px solid #875a86;\n}\nbody.theme-crickets .measurementTableTimepointCell {\n border-left: 1px solid #537b76;\n}\nbody.theme-honeycomb .measurementTableTimepointCell {\n border-left: 1px solid #623337;\n}\nbody.theme-mint .measurementTableTimepointCell {\n border-left: 1px solid #214529;\n}\nbody.theme-overcast .measurementTableTimepointCell {\n border-left: 1px solid #404040;\n}\nbody.theme-quartz .measurementTableTimepointCell {\n border-left: 1px solid #885b86;\n}\n.measurementTableTimepointCell .loading-spinner {\n display: none;\n font-size: 16px;\n position: absolute;\n right: 5px;\n top: 3px;\n}\n.measurementTableTimepointCell span {\n display: block;\n}\n.measurementTableTimepointCell.loading .loading-spinner {\n display: block;\n}\n.measurementTableTimepointCell,\n.measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-tide .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-tide .measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-crickets .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-crickets .measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-mint .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-mint .measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-overcast .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-overcast .measurementTableTimepointCell span {\n color: #fff;\n}\nbody.theme-quartz .measurementTableTimepointCell {\n color: #fff;\n}\nbody.theme-quartz .measurementTableTimepointCell span {\n color: #fff;\n}\n.measurementTableTimepointCell:hover,\n.measurementTableTimepointCell span:hover {\n color: #20a5d6;\n}\nbody.theme-tide .measurementTableTimepointCell:hover {\n color: #20a5d6;\n}\nbody.theme-tide .measurementTableTimepointCell span:hover {\n color: #20a5d6;\n}\nbody.theme-tigerlily .measurementTableTimepointCell:hover {\n color: #fa8947;\n}\nbody.theme-tigerlily .measurementTableTimepointCell span:hover {\n color: #fa8947;\n}\nbody.theme-crickets .measurementTableTimepointCell:hover {\n color: #d4c3c1;\n}\nbody.theme-crickets .measurementTableTimepointCell span:hover {\n color: #d4c3c1;\n}\nbody.theme-honeycomb .measurementTableTimepointCell:hover {\n color: #cda56b;\n}\nbody.theme-honeycomb .measurementTableTimepointCell span:hover {\n color: #cda56b;\n}\nbody.theme-mint .measurementTableTimepointCell:hover {\n color: #31b166;\n}\nbody.theme-mint .measurementTableTimepointCell span:hover {\n color: #31b166;\n}\nbody.theme-overcast .measurementTableTimepointCell:hover {\n color: #507d80;\n}\nbody.theme-overcast .measurementTableTimepointCell span:hover {\n color: #507d80;\n}\nbody.theme-quartz .measurementTableTimepointCell:hover {\n color: #7858ce;\n}\nbody.theme-quartz .measurementTableTimepointCell span:hover {\n color: #7858ce;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementTableTimepointHeader":{"measurementTableTimepointHeader.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableTimepointHeader/measuremen // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableTimepointHeader.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableTimepointHeader.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableTimepointHeader/template.measurementT // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableTimepointHeader"); Template["measurementTableTimepointHeader"] = new Template("Template.measurementTableTimepointHeader", (function() { var view = this; return HTML.DIV({ class: "measurementTableTimepointHeader" }, "\n ", HTML.DIV({ class: "timepointName" }, "\n ", Blaze.View("lookup:timepointName", function() { return Spacebars.mustache(view.lookup("timepointName"), view.lookup(".")); }), "\n "), "\n ", HTML.DIV({ class: "timepointDate" }, "\n ", Blaze.View("lookup:formatDA", function() { return Spacebars.mustache(view.lookup("formatDA"), view.lookup("latestDate"), "DD-MMM-YY"); }), "\n "), "\n ", HTML.DIV({ class: "case-progress-container" }, "\n ", Spacebars.include(view.lookupTemplate("caseProgress")), "\n "), "\n "); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableTimepointHeader.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableTimepointHeader/measurementTableTimep // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); Template.measurementTableTimepointHeader.helpers({ timepointName: function (timepoint) { return Template.instance().data.timepointApi.name(timepoint); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableTimepointHeader.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableTimepointHeader/measuremen // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTableTimepointHeader.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableTimepointHeader.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableTimepointHeader/measurementTableTimep // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementTableTimepointHeader {\n flex: 1;\n justify-content: space-around;\n padding-top: 2px;\n position: relative;\n}\n.measurementTableTimepointHeader .timepointName,\n.measurementTableTimepointHeader .timepointDate {\n font-weight: 400;\n padding-left: 12px;\n text-align: left;\n}\n.measurementTableTimepointHeader .timepointName,\n.measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #44626f;\n}\nbody.theme-tide .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #44626f;\n}\nbody.theme-tide .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #44626f;\n}\nbody.theme-tigerlily .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #875a86;\n}\nbody.theme-tigerlily .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #875a86;\n}\nbody.theme-crickets .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #537b76;\n}\nbody.theme-crickets .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #537b76;\n}\nbody.theme-honeycomb .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #623337;\n}\nbody.theme-honeycomb .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #623337;\n}\nbody.theme-mint .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #214529;\n}\nbody.theme-mint .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #214529;\n}\nbody.theme-overcast .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #404040;\n}\nbody.theme-overcast .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #404040;\n}\nbody.theme-quartz .measurementTableTimepointHeader .timepointName {\n border-left: 1px solid #885b86;\n}\nbody.theme-quartz .measurementTableTimepointHeader .timepointDate {\n border-left: 1px solid #885b86;\n}\n.measurementTableTimepointHeader .timepointName {\n font-size: 12px;\n line-height: 12px;\n}\n.measurementTableTimepointHeader .timepointName {\n color: #91b9cd;\n}\nbody.theme-tide .measurementTableTimepointHeader .timepointName {\n color: #91b9cd;\n}\nbody.theme-tigerlily .measurementTableTimepointHeader .timepointName {\n color: #9ccdf8;\n}\nbody.theme-crickets .measurementTableTimepointHeader .timepointName {\n color: #8be7b5;\n}\nbody.theme-honeycomb .measurementTableTimepointHeader .timepointName {\n color: #fab797;\n}\nbody.theme-mint .measurementTableTimepointHeader .timepointName {\n color: #a7e9b3;\n}\nbody.theme-overcast .measurementTableTimepointHeader .timepointName {\n color: #73f2fc;\n}\nbody.theme-quartz .measurementTableTimepointHeader .timepointName {\n color: #d7e8fe;\n}\n.measurementTableTimepointHeader .timepointDate {\n font-size: 14px;\n line-height: 20px;\n padding-bottom: 6px;\n}\n.measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-tide .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-tigerlily .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-crickets .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-honeycomb .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-mint .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-overcast .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\nbody.theme-quartz .measurementTableTimepointHeader .timepointDate {\n color: #fff;\n}\n.measurementTableTimepointHeader .case-progress-container {\n position: absolute;\n right: 4px;\n top: 0;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementTableView":{"measurementTableView.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableView/measurementTableView. // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableView.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableView.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableView/template.measurementTableView.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableView"); Template["measurementTableView"] = new Template("Template.measurementTableView", (function() { var view = this; return [ Blaze.Let({ config: function() { return Spacebars.call(view.lookup("measurementConfiguration")); }, groups: function() { return Spacebars.call(Spacebars.dot(view.lookup("measurementGroups"), "get")); } }, function() { return [ "\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(view.lookup("groups")), _variable: "measurementGroup" }; }, function() { return [ "\n \n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ toolGroup: Spacebars.dot(view.lookup("measurementGroup"), "toolGroup"), measurementRows: Spacebars.dot(view.lookup("measurementGroup"), "measurementRows") })); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableHeaderRow")); }), "\n \n ", Blaze.Each(function() { return { _sequence: Spacebars.call(Spacebars.dot(view.lookup("measurementGroup"), "measurementRows")), _variable: "rowItem" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ rowItem: view.lookup("rowItem") })); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableRow")); }), "\n " ]; }), "\n " ]; }), "\n\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(Spacebars.dot(view.lookup("config"), "newLesions")), _variable: "newLesionGroup" }; }, function() { return [ "\n ", Blaze.Let({ toolGroup: function() { return Spacebars.call(Spacebars.dataMustache(view.lookup("getNewLesionsToolGroup"), view.lookup("newLesionGroup"))); } }, function() { return [ "\n ", Blaze.Let({ newMeasurements: function() { return Spacebars.call(Spacebars.dataMustache(view.lookup("newLesionsMeasurements"), view.lookup("toolGroup"))); } }, function() { return [ "\n ", Blaze.If(function() { return Spacebars.call(Spacebars.dot(view.lookup("newMeasurements"), "length")); }, function() { return [ "\n ", Blaze.Let({ collection: function() { return Spacebars.call(view.lookup("newMeasurements")); } }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ toolGroup: view.lookup("toolGroup"), measurementRows: view.lookup("collection") })); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableHeaderRow")); }), "\n\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(view.lookup("collection")), _variable: "entry" }; }, function() { return [ "\n ", Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({ rowItem: view.lookup("entry") })); }, function() { return Spacebars.include(view.lookupTemplate("measurementTableRow")); }), "\n " ]; }), "\n " ]; }), "\n " ]; }), "\n " ]; }), "\n " ]; }), "\n " ]; }), "\n " ]; }), "\n ", Blaze.Unless(function() { return Spacebars.call(Spacebars.dot(view.lookup("."), "isHud")); }, function() { return [ "\n ", Blaze.If(function() { return Spacebars.dataMustache(view.lookup("or"), Spacebars.dataMustache(view.lookup("hasMeasurements"), "targets"), Spacebars.dataMustache(view.lookup("hasMeasurements"), "nonTargets")); }, function() { return [ "\n ", HTML.DIV({ class: "report-area" }, "\n ", HTML.DIV({ class: "btn btn-sm js-pdf" }, "Generate Report"), "\n "), "\n " ]; }), "\n " ]; }) ]; })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableView.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableView/measurementTableView.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var Tracker; module.watch(require("meteor/tracker"), { Tracker: function (v) { Tracker = v; } }, 1); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 2); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 3); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 4); Template.measurementTableView.onCreated(function () { var instance = Template.instance(); var _instance$data = instance.data, measurementApi = _instance$data.measurementApi, timepointApi = _instance$data.timepointApi; instance.data.measurementGroups = new ReactiveVar(); Tracker.autorun(function () { measurementApi.changeObserver.depend(); var data = OHIF.measurements.getMeasurementsGroupedByNumber(measurementApi, timepointApi); instance.data.measurementGroups.set(data); }); }); Template.measurementTableView.events({ 'click .js-pdf': function (event, instance) { var _instance$data2 = instance.data, measurementApi = _instance$data2.measurementApi, timepointApi = _instance$data2.timepointApi; OHIF.measurements.exportPdf(measurementApi, timepointApi); } }); Template.measurementTableView.helpers({ hasMeasurements: function (toolGroupId) { var instance = Template.instance(); var groups = instance.data.measurementGroups.get(); if (!groups) { return false; } var group = _.find(groups, function (item) { return item.toolGroup.id === toolGroupId; }); return group && !!group.measurementRows.length; }, getNewLesionsToolGroup: function (newLesionGroup) { var configuration = OHIF.measurements.MeasurementApi.getConfiguration(); var toolGroup = _.findWhere(configuration.measurementTools, { id: newLesionGroup.toolGroupId }); return { id: newLesionGroup.id, name: newLesionGroup.name, childTools: toolGroup.childTools, measurementTypeId: toolGroup.id }; }, newLesionsMeasurements: function (toolGroup) { var _Template$instance$da = Template.instance().data, measurementApi = _Template$instance$da.measurementApi, timepointApi = _Template$instance$da.timepointApi; var current = timepointApi.current(); var baseline = timepointApi.baseline(); if (!measurementApi || !timepointApi || !current || !baseline) return; // If this is a baseline, stop here since there are no new measurements to display if (!current || current.timepointType === 'baseline') { OHIF.log.info('Skipping New Measurements section'); return; } // Retrieve all the data for this Measurement type (e.g. 'targets') // which was recorded at baseline. var measurementTypeId = toolGroup.measurementTypeId; var atBaseline = measurementApi.fetch(measurementTypeId, { timepointId: baseline.timepointId }); // Obtain a list of the Measurement Numbers from the // measurements which have baseline data var numbers = atBaseline.map(function (m) { return m.measurementNumber; }); // Retrieve all the data for this Measurement type which // do NOT match the Measurement Numbers obtained above var data = measurementApi.fetch(measurementTypeId, { measurementNumber: { $nin: numbers } }); // Group the Measurements by Measurement Number var groupObject = _.groupBy(data, function (entry) { return entry.measurementNumber; }); // Reformat the data for display in the table return Object.keys(groupObject).map(function (key) { return { measurementTypeId: measurementTypeId, measurementNumber: key, location: OHIF.measurements.getLocation(groupObject[key]), responseStatus: false, // TODO: Get the latest timepoint and determine the response status entries: groupObject[key] }; }); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableView.styl":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableView/measurementTableView. // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurementTableView.styl.css"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTableView.styl.css":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableView/measurementTableView.styl.css // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = require("meteor/modules").addStyles( ".theme-icon-crickets,\n.theme-icon-tide,\n.theme-icon-tigerlily,\n.theme-icon-quartz,\n.theme-icon-overcast,\n.theme-icon-mint,\n.theme-icon-honeycomb {\n display: inline-block;\n background: url(\"/packages/ohif_design/assets/theme-icons.png\") no-repeat;\n overflow: hidden;\n text-indent: -9999px;\n text-align: left;\n}\n.theme-icon-crickets {\n background-position: 0px 0px;\n width: 64px;\n height: 56px;\n}\n.theme-icon-tide {\n background-position: 0px -56px;\n width: 64px;\n height: 54px;\n}\n.theme-icon-tigerlily {\n background-position: 0px -110px;\n width: 62px;\n height: 61px;\n}\n.theme-icon-quartz {\n background-position: 0px -171px;\n width: 59px;\n height: 64px;\n}\n.theme-icon-overcast {\n background-position: 0px -235px;\n width: 58px;\n height: 37px;\n}\n.theme-icon-mint {\n background-position: 0px -272px;\n width: 57px;\n height: 61px;\n}\n.theme-icon-honeycomb {\n background-position: 0px -333px;\n width: 50px;\n height: 58px;\n}\n.measurementTableView .report-area {\n margin-top: 2px;\n padding: 10px 0;\n}\n.measurementTableView .report-area {\n background-color: #151a1f;\n}\nbody.theme-tide .measurementTableView .report-area {\n background-color: #151a1f;\n}\nbody.theme-tigerlily .measurementTableView .report-area {\n background-color: #151a1f;\n}\nbody.theme-crickets .measurementTableView .report-area {\n background-color: #231c1e;\n}\nbody.theme-honeycomb .measurementTableView .report-area {\n background-color: #18161a;\n}\nbody.theme-mint .measurementTableView .report-area {\n background-color: #15191e;\n}\nbody.theme-overcast .measurementTableView .report-area {\n background-color: #15191e;\n}\nbody.theme-quartz .measurementTableView .report-area {\n background-color: #151a1f;\n}\n.measurementTableView .report-area .btn.js-pdf {\n color: #000;\n display: table;\n margin: 0 auto;\n}\n.measurementTableView .report-area .btn.js-pdf {\n background-color: #20a5d6;\n}\nbody.theme-tide .measurementTableView .report-area .btn.js-pdf {\n background-color: #20a5d6;\n}\nbody.theme-tigerlily .measurementTableView .report-area .btn.js-pdf {\n background-color: #fa8947;\n}\nbody.theme-crickets .measurementTableView .report-area .btn.js-pdf {\n background-color: #d4c3c1;\n}\nbody.theme-honeycomb .measurementTableView .report-area .btn.js-pdf {\n background-color: #cda56b;\n}\nbody.theme-mint .measurementTableView .report-area .btn.js-pdf {\n background-color: #31b166;\n}\nbody.theme-overcast .measurementTableView .report-area .btn.js-pdf {\n background-color: #507d80;\n}\nbody.theme-quartz .measurementTableView .report-area .btn.js-pdf {\n background-color: #7858ce;\n}\n.measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #00a4d9;\n}\nbody.theme-tide .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #00a4d9;\n}\nbody.theme-tigerlily .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #ff8a3d;\n}\nbody.theme-crickets .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #d4aaa5;\n}\nbody.theme-honeycomb .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #ce9e59;\n}\nbody.theme-mint .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #23b15d;\n}\nbody.theme-overcast .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #467c80;\n}\nbody.theme-quartz .measurementTableView .report-area .btn.js-pdf {\n border: 1px solid #6843cc;\n}\n" ); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"measurementTableWarnings":{"measurementTableWarningsDialog.html":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/components/measurementTable/measurementTableWarnings/measurementTableW // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./template.measurementTableWarningsDialog.js"), { "*": module.makeNsSetter(true) }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"template.measurementTableWarningsDialog.js":function(){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/components/measurementTable/measurementTableWarnings/template.measurementTableWar // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Template.__checkName("measurementTableWarningsDialog"); Template["measurementTableWarningsDialog"] = new Template("Template.measurementTableWarningsDialog", (function() { var view = this; return Blaze._TemplateWith(function() { return Spacebars.dataMustache(view.lookup("extend"), view.lookup("."), Spacebars.kw({ class: "themed", dialogClass: "modal-sm", title: "Criteria nonconformities" })); }, function() { return Spacebars.include(view.lookupTemplate("dialogSimple"), function() { return [ "\n ", HTML.OL("\n ", Blaze.Each(function() { return { _sequence: Spacebars.call(Spacebars.dot(view.lookup("."), "messages")), _variable: "message" }; }, function() { return [ "\n ", HTML.LI(Blaze.View("lookup:message", function() { return Spacebars.mustache(view.lookup("message")); })), "\n " ]; }), "\n "), "\n " ]; }); }); })); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}}},"conformance":{"ConformanceCriteria.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/ConformanceCriteria.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var ReactiveVar; module.watch(require("meteor/reactive-var"), { ReactiveVar: function (v) { ReactiveVar = v; } }, 0); var Tracker; module.watch(require("meteor/tracker"), { Tracker: function (v) { Tracker = v; } }, 1); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); module.watch(require("meteor/ohif:viewerbase")); var CriteriaEvaluator; module.watch(require("./CriteriaEvaluator"), { CriteriaEvaluator: function (v) { CriteriaEvaluator = v; } }, 4); var evaluations; module.watch(require("./evaluations"), { "*": function (v) { evaluations = v; } }, 5); var ConformanceCriteria = /*#__PURE__*/ function () { function ConformanceCriteria(measurementApi, timepointApi) { var _this = this; this.measurementApi = measurementApi; this.timepointApi = timepointApi; this.nonconformities = new ReactiveVar(); this.groupedNonConformities = new ReactiveVar(); this.maxTargets = new ReactiveVar(null); this.maxNewTargets = new ReactiveVar(null); var validate = _.debounce(function (trialCriteriaType) { return _this.validate(trialCriteriaType); }, 300); Tracker.autorun(function () { var selectedType = OHIF.lesiontracker.TrialCriteriaTypes.findOne({ selected: true }); _this.measurementApi.changeObserver.depend(); validate(selectedType); }); } var _proto = ConformanceCriteria.prototype; _proto.validate = function () { function validate(trialCriteriaType) { var _this2 = this; return new Promise(function (resolve, reject) { var baselinePromise = _this2.getData('baseline'); var followupPromise = _this2.getData('followup'); Promise.all([baselinePromise, followupPromise]).then(function (values) { var _values = (0, _slicedToArray2.default)(values, 2), baselineData = _values[0], followupData = _values[1]; var mergedData = { targets: [], nonTargets: [] }; mergedData.targets = mergedData.targets.concat(baselineData.targets); mergedData.targets = mergedData.targets.concat(followupData.targets); mergedData.nonTargets = mergedData.nonTargets.concat(baselineData.nonTargets); mergedData.nonTargets = mergedData.nonTargets.concat(followupData.nonTargets); _this2.maxTargets.set(null); _this2.maxNewTargets.set(null); var resultBoth = _this2.validateTimepoint('both', trialCriteriaType, mergedData); var resultBaseline = _this2.validateTimepoint('baseline', trialCriteriaType, baselineData); var resultFollowup = _this2.validateTimepoint('followup', trialCriteriaType, followupData); var nonconformities = resultBaseline.concat(resultFollowup).concat(resultBoth); var groupedNonConformities = _this2.groupNonConformities(nonconformities); // Keep both? Group the data only on viewer/measurementTable views? // Work with not grouped data (worse lookup performance on measurementTableRow)? _this2.nonconformities.set(nonconformities); _this2.groupedNonConformities.set(groupedNonConformities); resolve(nonconformities); }); }); } return validate; }(); _proto.groupNonConformities = function () { function groupNonConformities(nonconformities) { var groups = {}; var toolsGroupsMap = this.measurementApi.toolsGroupsMap; nonconformities.forEach(function (nonConformity) { if (nonConformity.isGlobal) { groups.globals = groups.globals || { messages: [] }; groups.globals.messages.push(nonConformity.message); return; } nonConformity.measurements.forEach(function (measurement) { var groupName = toolsGroupsMap[measurement.toolType]; groups[groupName] = groups[groupName] || { measurementNumbers: {} }; var group = groups[groupName]; var measureNumber = measurement.measurementNumber; var measurementNumbers = group.measurementNumbers[measureNumber]; if (!measurementNumbers) { measurementNumbers = group.measurementNumbers[measureNumber] = { messages: [], measurements: [] }; } measurementNumbers.messages.push(nonConformity.message); measurementNumbers.measurements.push(measurement); }); }); return groups; } return groupNonConformities; }(); _proto.validateTimepoint = function () { function validateTimepoint(timepointId, trialCriteriaType, data) { var _this3 = this; var evaluators = this.getEvaluators(timepointId, trialCriteriaType); var nonconformities = []; evaluators.forEach(function (evaluator) { var maxTargets = evaluator.getMaxTargets(false); var maxNewTargets = evaluator.getMaxTargets(true); if (maxTargets) { _this3.maxTargets.set(maxTargets); } if (maxNewTargets) { _this3.maxNewTargets.set(maxNewTargets); } var result = evaluator.evaluate(data); nonconformities = nonconformities.concat(result); }); return nonconformities; } return validateTimepoint; }(); _proto.getEvaluators = function () { function getEvaluators(timepointId, trialCriteriaType) { var evaluators = []; var trialCriteriaTypeId = trialCriteriaType.id.toLowerCase(); var evaluation = evaluations[trialCriteriaTypeId]; if (evaluation) { var evaluationTimepoint = evaluation[timepointId]; if (evaluationTimepoint) { evaluators.push(new CriteriaEvaluator(evaluationTimepoint)); } } return evaluators; } return getEvaluators; }(); /* * Build the data that will be used to do the conformance criteria checks */ _proto.getData = function () { function getData(timepointType) { var _this4 = this; return new Promise(function (resolve, reject) { var data = { targets: [], nonTargets: [] }; var studyPromises = []; var fillData = function (measurementType) { var measurements = _this4.measurementApi.fetch(measurementType); measurements.forEach(function (measurement) { var studyInstanceUid = measurement.studyInstanceUid; var timepointId = measurement.timepointId; var timepoint = timepointId && _this4.timepointApi.timepoints.findOne({ timepointId: timepointId }); if (!timepoint || timepointType !== 'both' && timepoint.timepointType !== timepointType) { return; } var promise = OHIF.studies.loadStudy(studyInstanceUid); promise.then(function (study) { var studyMetadata = OHIF.viewerbase.getStudyMetadata(study); data[measurementType].push({ measurement: measurement, metadata: studyMetadata.getFirstInstance(), timepoint: timepoint }); }); studyPromises.push(promise); }); }; fillData('targets'); fillData('nonTargets'); Promise.all(studyPromises).then(function () { resolve(data); }).catch(reject); }); } return getData; }(); ConformanceCriteria.setEvaluationDefinitions = function () { function setEvaluationDefinitions(evaluationKey, evaluationDefinitions) { evaluations[evaluationKey] = evaluationDefinitions; } return setEvaluationDefinitions; }(); return ConformanceCriteria; }(); OHIF.measurements.ConformanceCriteria = ConformanceCriteria; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"CriteriaEvaluator.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/CriteriaEvaluator.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ CriteriaEvaluator: function () { return CriteriaEvaluator; } }); var BaseCriterion; module.watch(require("./criteria/BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 0); var Criteria; module.watch(require("./criteria"), { "*": function (v) { Criteria = v; } }, 1); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 2); var Ajv; module.watch(require("ajv"), { "default": function (v) { Ajv = v; } }, 3); var CriteriaEvaluator = /*#__PURE__*/ function () { function CriteriaEvaluator(criteriaObject) { var _this = this; var criteriaValidator = this.getCriteriaValidator(); this.criteria = []; if (!criteriaValidator(criteriaObject)) { var message = ''; _.each(criteriaValidator.errors, function (error) { message += "\noptions" + error.dataPath + " " + error.message; }); throw new Error(message); } _.each(criteriaObject, function (optionsObject, criterionkey) { var Criterion = Criteria[criterionkey + "Criterion"]; var optionsArray = optionsObject instanceof Array ? optionsObject : [optionsObject]; _.each(optionsArray, function (options) { return _this.criteria.push(new Criterion(options)); }); }); } var _proto = CriteriaEvaluator.prototype; _proto.getMaxTargets = function () { function getMaxTargets() { var newTarget = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var result = 0; _.each(this.criteria, function (criterion) { var newTargetMatch = newTarget === !!criterion.options.newTarget; if (criterion instanceof Criteria.MaxTargetsCriterion && newTargetMatch) { var limit = criterion.options.limit; if (limit > result) { result = limit; } } }); return result; } return getMaxTargets; }(); _proto.getCriteriaValidator = function () { function getCriteriaValidator() { if (CriteriaEvaluator.criteriaValidator) { return CriteriaEvaluator.criteriaValidator; } var schema = { properties: {}, definitions: {} }; _.each(Criteria, function (Criterion, key) { if (Criterion.prototype instanceof BaseCriterion) { var criterionkey = key.replace(/Criterion$/, ''); var criterionDefinition = "#/definitions/" + criterionkey; schema.definitions[criterionkey] = Criteria[criterionkey + "Schema"]; schema.properties[criterionkey] = { oneOf: [{ $ref: criterionDefinition }, { type: 'array', items: { $ref: criterionDefinition } }] }; } }); CriteriaEvaluator.criteriaValidator = new Ajv().compile(schema); return CriteriaEvaluator.criteriaValidator; } return getCriteriaValidator; }(); _proto.evaluate = function () { function evaluate(data) { var nonconformities = []; this.criteria.forEach(function (criterion) { var criterionResult = criterion.evaluate(data); if (!criterionResult.passed) { nonconformities.push(criterionResult); } }); return nonconformities; } return evaluate; }(); CriteriaEvaluator.setCriterion = function () { function setCriterion(criterionKey, criterionDefinitions) { Criteria[criterionKey] = criterionDefinitions; } return setCriterion; }(); return CriteriaEvaluator; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./ConformanceCriteria")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"criteria":{"BaseCriterion.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/BaseCriterion.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ BaseCriterion: function () { return BaseCriterion; } }); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var BaseCriterion = /*#__PURE__*/ function () { function BaseCriterion(options) { this.options = options; } var _proto = BaseCriterion.prototype; _proto.generateResponse = function () { function generateResponse(message, measurements) { var passed = !message; var isGlobal = !measurements || !measurements.length; return { passed: passed, isGlobal: isGlobal, message: message, measurements: measurements }; } return generateResponse; }(); _proto.getNewTargetNumbers = function () { function getNewTargetNumbers(data) { var options = this.options; var baselineMeasurementNumbers = []; var newTargetNumbers = new Set(); if (options.newTarget) { _.each(data.targets, function (target) { var measurementNumber = target.measurement.measurementNumber; if (target.timepoint.timepointType === 'baseline') { baselineMeasurementNumbers.push(measurementNumber); } }); _.each(data.targets, function (target) { var measurementNumber = target.measurement.measurementNumber; if (target.timepoint.timepointType === 'followup') { if (!_.contains(baselineMeasurementNumbers, measurementNumber)) { newTargetNumbers.add(measurementNumber); } } }); } return newTargetNumbers; } return getNewTargetNumbers; }(); return BaseCriterion; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"Location.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/Location.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ LocationSchema: function () { return LocationSchema; }, LocationCriterion: function () { return LocationCriterion; } }); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 0); var LocationSchema = { type: 'object' }; var LocationCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(LocationCriterion, _BaseCriterion); function LocationCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = LocationCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var items = data.targets.concat(data.nonTargets); var measurements = []; var message; items.forEach(function (item) { var measurement = item.measurement; if (!measurement.location) { measurements.push(measurement); } }); if (measurements.length) { message = 'All measurements should have a location'; } return this.generateResponse(message, measurements); } return evaluate; }(); return LocationCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"MaxTargets.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/MaxTargets.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ MaxTargetsSchema: function () { return MaxTargetsSchema; }, MaxTargetsCriterion: function () { return MaxTargetsCriterion; } }); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 1); var MaxTargetsSchema = { type: 'object', properties: { limit: { label: 'Max targets allowed in study', type: 'integer', minimum: 0 }, newTarget: { label: 'Flag to evaluate only new targets', type: 'boolean' }, locationIn: { label: 'Filter to evaluate only measurements with the specified locations', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true }, locationNotIn: { label: 'Filter to evaluate only measurements without the specified locations', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true } }, required: ['limit'] }; var MaxTargetsCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(MaxTargetsCriterion, _BaseCriterion); function MaxTargetsCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = MaxTargetsCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var options = this.options; var newTargetNumbers = this.getNewTargetNumbers(data); var measurementNumbers = []; _.each(data.targets, function (target) { var _target$measurement = target.measurement, location = _target$measurement.location, measurementNumber = _target$measurement.measurementNumber, isSplitLesion = _target$measurement.isSplitLesion; if (isSplitLesion) return; if (options.newTarget && !newTargetNumbers.has(measurementNumber)) return; if (options.locationIn && options.locationIn.indexOf(location) === -1) return; if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1) return; measurementNumbers.push(measurementNumber); }); var message; if (measurementNumbers.length > options.limit) { var increment = options.newTarget ? 'new ' : ''; var plural = options.limit === 1 ? '' : 's'; var amount = options.limit === 0 ? '' : "more than " + options.limit; message = options.message || "The study should not have " + amount + " " + increment + "target" + plural + "."; } return this.generateResponse(message); } return evaluate; }(); return MaxTargetsCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"MaxTargetsPerOrgan.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/MaxTargetsPerOrgan.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ MaxTargetsPerOrganSchema: function () { return MaxTargetsPerOrganSchema; }, MaxTargetsPerOrganCriterion: function () { return MaxTargetsPerOrganCriterion; } }); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 1); var MaxTargetsPerOrganSchema = { type: 'object', properties: { limit: { label: 'Max targets allowed per organ', type: 'integer', minimum: 1 }, newTarget: { label: 'Flag to evaluate only new targets', type: 'boolean' } }, required: ['limit'] }; var MaxTargetsPerOrganCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(MaxTargetsPerOrganCriterion, _BaseCriterion); function MaxTargetsPerOrganCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = MaxTargetsPerOrganCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var options = this.options; var targetsPerOrgan = {}; var measurements = []; var newTargetNumbers = this.getNewTargetNumbers(data); _.each(data.targets, function (target) { var measurement = target.measurement; var location = measurement.location, measurementNumber = measurement.measurementNumber, isSplitLesion = measurement.isSplitLesion; if (isSplitLesion) return; if (!targetsPerOrgan[location]) { targetsPerOrgan[location] = new Set(); } if (!options.newTarget || newTargetNumbers.has(measurementNumber)) { targetsPerOrgan[location].add(measurementNumber); } if (targetsPerOrgan[location].size > options.limit) { measurements.push(measurement); } }); var message; if (measurements.length) { var increment = options.newTarget ? 'new ' : ''; message = options.message || "Each organ should not have more than " + options.limit + " " + increment + "targets."; } return this.generateResponse(message, measurements); } return evaluate; }(); return MaxTargetsPerOrganCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"MeasurementsLength.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/MeasurementsLength.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ MeasurementsLengthSchema: function () { return MeasurementsLengthSchema; }, MeasurementsLengthCriterion: function () { return MeasurementsLengthCriterion; } }); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 0); var MeasurementsLengthSchema = { type: 'object', properties: { longAxis: { label: 'Minimum length of long axis', type: 'number', minimum: 0 }, shortAxis: { label: 'Minimum length of short axis', type: 'number', minimum: 0 }, longAxisSliceThicknessMultiplier: { label: 'Length of long axis multiplier', type: 'number', minimum: 0 }, shortAxisSliceThicknessMultiplier: { label: 'Length of short axis multiplier', type: 'number', minimum: 0 }, modalityIn: { label: 'Filter to evaluate only measurements with the specified modalities', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true }, modalityNotIn: { label: 'Filter to evaluate only measurements without the specified modalities', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true }, locationIn: { label: 'Filter to evaluate only measurements with the specified locations', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true }, locationNotIn: { label: 'Filter to evaluate only measurements without the specified locations', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true }, message: { label: 'Message to be displayed in case of nonconformity', type: 'string' } }, anyOf: [{ required: ['message', 'longAxis'] }, { required: ['message', 'shortAxis'] }, { required: ['message', 'longAxisSliceThicknessMultiplier'] }, { required: ['message', 'shortAxisSliceThicknessMultiplier'] }] }; var MeasurementsLengthCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(MeasurementsLengthCriterion, _BaseCriterion); function MeasurementsLengthCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = MeasurementsLengthCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var message; var measurements = []; var options = this.options; var longMultiplier = options.longAxisSliceThicknessMultiplier; var shortMultiplier = options.shortAxisSliceThicknessMultiplier; data.targets.forEach(function (item) { var metadata = item.metadata, measurement = item.measurement; var location = measurement.location; var longestDiameter = measurement.longestDiameter, shortestDiameter = measurement.shortestDiameter; if (measurement.childToolsCount) { var child = measurement.bidirectional; longestDiameter = child && child.longestDiameter || 0; shortestDiameter = child && child.shortestDiameter || 0; } var sliceThickness = metadata.sliceThickness; var modality = (metadata.getRawValue('x00080060') || '').toUpperCase(); // Stop here if the measurement does not match the modality and location filters if (options.locationIn && options.locationIn.indexOf(location) === -1) return; if (options.modalityIn && options.modalityIn.indexOf(modality) === -1) return; if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1) return; if (options.modalityNotIn && options.modalityNotIn.indexOf(modality) > -1) return; // Check the measurement length var failed = options.longAxis && longestDiameter < options.longAxis || options.shortAxis && shortestDiameter < options.shortAxis || longMultiplier && !isNaN(sliceThickness) && longestDiameter < longMultiplier * sliceThickness || shortMultiplier && !isNaN(sliceThickness) && shortestDiameter < shortMultiplier * sliceThickness; // Mark this measurement as invalid if some of the checks have failed if (failed) { measurements.push(measurement); } }); // Use the options' message if some measurement is invalid if (measurements.length) { message = options.message; } return this.generateResponse(message, measurements); } return evaluate; }(); return MeasurementsLengthCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"Modality.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/Modality.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ ModalitySchema: function () { return ModalitySchema; }, ModalityCriterion: function () { return ModalityCriterion; } }); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var ModalitySchema = { type: 'object', properties: { method: { label: 'Specify if it\'s goinig to "allow" or "deny" the modalities', type: 'string', "enum": ['allow', 'deny'] }, measurementTypes: { label: 'List of measurement types that will be evaluated', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true }, modalities: { label: 'List of allowed/denied modalities', type: 'array', items: { type: 'string' }, minItems: 1, uniqueItems: true } }, required: ['method', 'modalities'] }; var ModalityCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(ModalityCriterion, _BaseCriterion); function ModalityCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = ModalityCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var measurementTypes = this.options.measurementTypes || ['targets']; var modalitiesSet = new Set(this.options.modalities); var validationMethod = this.options.method; var measurements = []; var invalidModalities = []; var message; measurementTypes.forEach(function (measurementType) { var items = data[measurementType]; items.forEach(function (item) { var measurement = item.measurement, metadata = item.metadata; var modality = (metadata.getRawValue('x00080060') || '').toUpperCase(); if (validationMethod === 'allow' && !modalitiesSet.has(modality) || validationMethod === 'deny' && modalitiesSet.has(modality)) { measurements.push(measurement); invalidModalities.push(modality); } }); }); if (measurements.length) { var uniqueModalities = _.uniq(invalidModalities); var uniqueModalitiesText = uniqueModalities.join(', '); var modalityText = uniqueModalities.length > 1 ? 'modalities' : 'modality'; message = "The " + modalityText + " " + uniqueModalitiesText + " should not be used as a method of measurement"; } return this.generateResponse(message, measurements); } return evaluate; }(); return ModalityCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"NonTargetResponse.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/NonTargetResponse.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ NonTargetResponseSchema: function () { return NonTargetResponseSchema; }, NonTargetResponseCriterion: function () { return NonTargetResponseCriterion; } }); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 0); var NonTargetResponseSchema = { type: 'object' }; var NonTargetResponseCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(NonTargetResponseCriterion, _BaseCriterion); function NonTargetResponseCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = NonTargetResponseCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var items = data.nonTargets; var measurements = []; var message; items.forEach(function (item) { var measurement = item.measurement; var response = (measurement.response || '').toLowerCase(); if (response !== 'present') { measurements.push(measurement); } }); if (measurements.length) { message = 'Non-targets can only be assessed as "present"'; } return this.generateResponse(message, measurements); } return evaluate; }(); return NonTargetResponseCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"TargetType.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/TargetType.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ TargetTypeSchema: function () { return TargetTypeSchema; }, TargetTypeCriterion: function () { return TargetTypeCriterion; } }); var BaseCriterion; module.watch(require("./BaseCriterion"), { BaseCriterion: function (v) { BaseCriterion = v; } }, 0); var TargetTypeSchema = { type: 'object' }; var TargetTypeCriterion = /*#__PURE__*/ function (_BaseCriterion) { (0, _inheritsLoose2.default)(TargetTypeCriterion, _BaseCriterion); function TargetTypeCriterion(options) { return _BaseCriterion.call(this, options) || this; } var _proto = TargetTypeCriterion.prototype; _proto.evaluate = function () { function evaluate(data) { var items = data.targets; var measurements = []; var message; items.forEach(function (item) { var measurement = item.measurement; if (measurement.toolType !== 'bidirectional' && !measurement.bidirectional) { measurements.push(measurement); } }); if (measurements.length) { message = 'Target lesions must have measurements (cannot be assessed as CR, UN/NE, EX)'; } return this.generateResponse(message, measurements); } return evaluate; }(); return TargetTypeCriterion; }(BaseCriterion); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/criteria/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./Location"), { "*": module.makeNsSetter() }, 0); module.watch(require("./MaxTargetsPerOrgan"), { "*": module.makeNsSetter() }, 1); module.watch(require("./MaxTargets"), { "*": module.makeNsSetter() }, 2); module.watch(require("./MeasurementsLength"), { "*": module.makeNsSetter() }, 3); module.watch(require("./Modality"), { "*": module.makeNsSetter() }, 4); module.watch(require("./NonTargetResponse"), { "*": module.makeNsSetter() }, 5); module.watch(require("./TargetType"), { "*": module.makeNsSetter() }, 6); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"evaluations":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/conformance/evaluations/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ recist: function () { return recist; } }); var recistEvaluation; module.watch(require("./recist.json"), { "*": function (v) { recistEvaluation = v; } }, 0); var recist = recistEvaluation; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"recist.json":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/client/conformance/evaluations/recist.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exports = { "both": { "Location": {} }, "baseline": { "TargetType": {}, "MaxTargetsPerOrgan": { "limit": 2 }, "MaxTargets": { "limit": 5 }, "MeasurementsLength": [ { "longAxis": 10, "longAxisSliceThicknessMultiplier": 2, "modalityIn": [ "CT", "MR" ], "locationNotIn": [ "Lymph Node" ], "message": "Extranodal lesions must be >= 10mm long axis AND >= double the acquisition slice thickness by CT and MR" }, { "shortAxis": 20, "longAxis": 20, "modalityIn": [ "PX", "XA" ], "locationNotIn": [ "Lymph Node" ], "message": "Extranodal lesions must be >= 20mm on chest x-ray (although x-rays rarely used for clinical trial assessment)" }, { "shortAxis": 15, "shortAxisSliceThicknessMultiplier": 2, "modalityIn": [ "CT", "MR" ], "locationIn": [ "Lymph Node" ], "message": "Nodal lesions must be >= 15mm short axis AND >= double the acquisition slice thickness by CT and MR" } ] }, "followup": {} }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"helpers":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/helpers/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./measurements.js")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurements.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/helpers/measurements.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); // Get the current measurement API configuration with information about tools, data exchange // and data validation. Template.registerHelper('measurementConfiguration', function () { return OHIF.measurements.MeasurementApi.getConfiguration(); }); // Translates the location and return a string containing its label Template.registerHelper('getLocationLabel', function (label) { return OHIF.measurements.getLocationLabel(label); }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"lib":{"MeasurementManager.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementManager.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var MeasurementManager = /*#__PURE__*/ function () { function MeasurementManager() {} /** * If the current Measurements Number already exists * for any other timepoint, returns lesion locationUID * @param measurementData * @returns {number} - Measurement location ID */ MeasurementManager.getLocationIdIfMeasurementExists = function () { function getLocationIdIfMeasurementExists(measurementData, collection) { var measurement = collection.findOne({ measurementNumber: measurementData.measurementNumber }); if (!measurement) { return; } return measurement.locationId; } return getLocationIdIfMeasurementExists; }(); return MeasurementManager; }(); OHIF.measurements.MeasurementManager = MeasurementManager; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"activateMeasurements.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/activateMeasurements.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 0); var cornerstone, cornerstoneTools; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; }, cornerstoneTools: function (v) { cornerstoneTools = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); /** * Activates a specific tool data instance and deactivates all other * target and non-target measurement data * * @param element * @param measurementData */ function activateTool(measurementData) { var toolType = measurementData.toolType; var imageId = OHIF.viewerbase.getImageIdForImagePath(measurementData.imagePath); var toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState(); var imageToolState = toolState[imageId]; var toolData = imageToolState && imageToolState[toolType]; if (!toolData || !toolData.data || !toolData.data.length) { return; } // When a measurement is selected, it will be activated in Cornerstone's // tool data var tool = toolData.data.find(function (data) { return data._id === measurementData._id; }); if (tool) { tool.active = true; } cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(toolState); } /** * Switch to the image of the correct image index * Activate the selected measurement on the switched image (color to be green) * Deactivate all other measurements on the switched image (color to be white) */ OHIF.measurements.activateMeasurements = function (element, measurementData) { OHIF.log.info('activateMeasurements'); // If Cornerstone Viewport information was stored while the measurement was created, // we should re-apply this data when activating the measurement. var viewport = cornerstone.getViewport(element); // TODO: Make this an option somewhere? For now we only want to apply windowWidth and // windowCenter var viewportPropertiesToUpdate = ['voi']; // Check to make sure we actually stored viewport data before trying to apply it if (measurementData.viewport) { // For each property which is not undefined, update it's value from the stored // measurement data viewportPropertiesToUpdate.forEach(function (prop) { var storedPropertyValue = measurementData.viewport[prop]; if (storedPropertyValue === undefined) { return; } viewport[prop] = storedPropertyValue; }); // Apply the updated viewport parameters to the element cornerstone.setViewport(element, viewport); } // Activate the tool in the tool data activateTool(measurementData); var enabledElement = cornerstone.getEnabledElement(element); var currentImageId = enabledElement.image.imageId; var toolData = cornerstoneTools.getToolState(element, 'stack'); var imageId = OHIF.viewerbase.getImageIdForImagePath(measurementData.imagePath); var imageIdIndex = toolData.data[0].imageIds.indexOf(imageId); // If we aren't currently displaying the image that this tool is on, // scroll to it now. if (currentImageId !== imageId) { cornerstoneTools.scrollToIndex(element, imageIdIndex); } var $element = $(element); if (!$element.find('canvas').length) return; $element.trigger('ViewerMeasurementsActivated'); cornerstone.updateImage(element); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"clearCornerstoneToolState.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/clearCornerstoneToolState.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var cornerstoneTools; module.watch(require("meteor/ohif:cornerstone"), { cornerstoneTools: function (v) { cornerstoneTools = v; } }, 1); OHIF.measurements.clearCornerstoneToolState = function () { cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState({}); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"deactivateAllToolData.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/deactivateAllToolData.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Sets all tool data entries value for 'active' to false * This is used to remove the active color on entire sets of tools */ OHIF.measurements.deactivateAllToolData = function () { var toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState(); Object.keys(toolState).forEach(function (imageId) { var toolData = toolState[imageId]; Object.keys(toolData).forEach(function (toolType) { var specificToolData = toolData[toolType]; if (!specificToolData || !specificToolData.data || !specificToolData.data.length) { return; } specificToolData.data.forEach(function (data) { data.active = false; }); }); }); cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(toolState); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"exportPdf.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/exportPdf.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var MeasurementReport; module.watch(require("meteor/ohif:measurements/client/reports/measurement"), { MeasurementReport: function (v) { MeasurementReport = v; } }, 1); OHIF.measurements.exportPdf = function (measurementApi, timepointApi) { var currentTimepoint = timepointApi.current(); var timepointId = currentTimepoint.timepointId; var study = OHIF.viewer.Studies.findBy({ studyInstanceUid: currentTimepoint.studyInstanceUids[0] }); var report = new MeasurementReport({ header: { trial: 'RECIST 1.1', patientName: OHIF.viewerbase.helpers.formatPN(study.patientName), mrn: study.patientId, timepoint: timepointApi.name(currentTimepoint) } }); var printMeasurement = function (measurement, callback) { OHIF.measurements.getImageDataUrl({ measurement: measurement }).then(function (imageDataUrl) { var imageId = OHIF.viewerbase.getImageIdForImagePath(measurement.imagePath); var series = cornerstone.metaData.get('series', imageId); var instance = cornerstone.metaData.get('instance', imageId); var info = measurement.response; if (!info) { info = measurement.longestDiameter; if (measurement.shortestDiameter) { info += " \xD7 " + measurement.shortestDiameter; } info += ' mm'; } info += " (S:" + series.seriesNumber + ", I:" + instance.instanceNumber + ")"; var type = measurementApi.toolsGroupsMap[measurement.toolType]; type = type === 'targets' ? 'Target' : 'Non-target'; report.printMeasurement({ type: type, number: measurement.measurementNumber, location: OHIF.measurements.getLocationLabel(measurement.location) || '', info: info, image: imageDataUrl }); processMeasurements(callback); }); }; var processMeasurements = function (callback) { var current = iterator.next(); if (current.done) { callback(); return; } var measurement = current.value; printMeasurement(measurement, callback); }; var targets = measurementApi.fetch('targets', { timepointId: timepointId }); var nonTargets = measurementApi.fetch('nonTargets', { timepointId: timepointId }); var measurements = targets.concat(nonTargets); var iterator = measurements[Symbol.iterator](); processMeasurements(function () { return report.save('measurements.pdf'); }); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"exportToCsv.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/exportToCsv.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var getCSVMeasurementData; module.watch(require("../reports/reportMeasurementDataToCSV"), { getCSVMeasurementData: function (v) { getCSVMeasurementData = v; } }, 1); var downloadCSV = function (csvData) { var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var data, link; var filename = args.filename || 'export.csv'; if (csvData == null) return; if (!csvData.match(/^data:text\/csv/i)) { csvData = 'data:text/csv;charset=utf-8,' + csvData; } data = encodeURI(csvData); link = document.createElement('a'); link.setAttribute('href', data); link.setAttribute('download', filename); link.click(); }; OHIF.measurements.exportCSV = function () { function _callee(measurementApi, timepointApi) { var csvData; return _regenerator.default.async(function () { function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return _regenerator.default.awrap(getCSVMeasurementData(measurementApi, timepointApi)); case 2: csvData = _context.sent; downloadCSV(csvData); case 4: case "end": return _context.stop(); } } } return _callee$; }(), null, this); } return _callee; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"findAndRenderDisplaySet.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/findAndRenderDisplaySet.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); OHIF.measurements.findAndRenderDisplaySet = function (displaySets, viewportIndex, studyInstanceUid, seriesInstanceUid, sopInstanceUid, renderedCallback) { // Find the proper stack to display var stacksFromSeries = displaySets.filter(function (stack) { return stack.seriesInstanceUid === seriesInstanceUid; }); var stack = stacksFromSeries.find(function (stack) { var imageIndex = stack.images.findIndex(function (image) { return image.getSOPInstanceUID() === sopInstanceUid; }); return imageIndex > -1; }); // TODO: make this work for multi-frame instances var specificImageIndex = stack.images.findIndex(function (image) { return image.getSOPInstanceUID() === sopInstanceUid; }); var displaySetData = { studyInstanceUid: studyInstanceUid, seriesInstanceUid: seriesInstanceUid, displaySetInstanceUid: stack.displaySetInstanceUid, currentImageIdIndex: specificImageIndex }; // Add a renderedCallback to activate the measurements once it's if (renderedCallback) { displaySetData.renderedCallback = renderedCallback; } OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, displaySetData); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getActiveTimepoint.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getActiveTimepoint.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Session; module.watch(require("meteor/session"), { Session: function (v) { Session = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); /** * Extensible method to get the timepoint of the active viewport * * @returns {Object} - Timepoint data for the active viewport */ OHIF.measurements.getActiveTimepoint = function () { var activeViewportIndex = Session.get('activeViewport'); var studyInstanceUid = OHIF.viewerbase.layoutManager.viewportData[activeViewportIndex].studyInstanceUid; return OHIF.viewer.timepointApi.study(studyInstanceUid)[0]; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getImageDataUrl.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getImageDataUrl.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 1); var cornerstone, cornerstoneMath, cornerstoneTools; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; }, cornerstoneMath: function (v) { cornerstoneMath = v; }, cornerstoneTools: function (v) { cornerstoneTools = v; } }, 2); OHIF.measurements.getImageDataUrl = function (_ref) { var _ref$imageType = _ref.imageType, imageType = _ref$imageType === void 0 ? 'image/jpeg' : _ref$imageType, _ref$quality = _ref.quality, quality = _ref$quality === void 0 ? 1 : _ref$quality, _ref$width = _ref.width, width = _ref$width === void 0 ? 512 : _ref$width, _ref$height = _ref.height, height = _ref$height === void 0 ? 512 : _ref$height, _ref$cacheImage = _ref.cacheImage, cacheImage = _ref$cacheImage === void 0 ? true : _ref$cacheImage, imagePath = _ref.imagePath, measurement = _ref.measurement, _ref$alwaysVisibleTex = _ref.alwaysVisibleText, alwaysVisibleText = _ref$alwaysVisibleTex === void 0 ? true : _ref$alwaysVisibleTex, viewport = _ref.viewport; imagePath = imagePath || measurement.imagePath; var imageId = OHIF.viewerbase.getImageIdForImagePath(imagePath); // Create a deep copy of the measurement to prevent changing its original properties if (measurement) { measurement = $.extend(true, {}, measurement); } return new Promise(function (resolve, reject) { var loadMethod = cacheImage ? 'loadAndCacheImage' : 'loadImage'; cornerstone[loadMethod](imageId).then(function (image) { // Create a cornerstone enabled element to handle the image var enabledElement = createEnabledElement(width, height); var element = enabledElement.element; // Display the image on cornerstone's canvas cornerstone.displayImage(element, image); // Add the measurement state and enable the tool if a measurement was given if (measurement) { var state = Object.assign({}, measurement, { active: true }); Object.keys(measurement.handles).forEach(function (handleKey) { var handle = Object.assign({}, state.handles[handleKey]); handle.selected = false; handle.active = false; handle.moving = false; state.handles[handleKey] = handle; }); cornerstoneTools.addToolState(element, measurement.toolType, state); cornerstoneTools[measurement.toolType].enable(element); } // Set the viewport voi if present if (viewport && viewport.voi) { var csViewport = cornerstone.getViewport(element); Object.assign(csViewport, { voi: viewport.voi }); cornerstone.setViewport(element, csViewport); } // Resolve the current promise giving the dataUrl as parameter var renderedCallback = function () { var dataUrl = enabledElement.canvas.toDataURL(imageType, quality); // Disable the tool and clear the measurement state if a measurement was given if (measurement) { cornerstoneTools[measurement.toolType].disable(element); cornerstoneTools.clearToolState(element, measurement.toolType); } // Destroy the cornerstone enabled element, removing it from the DOM destroyEnabledElement(enabledElement); // Resolve the promise with the image's data URL resolve(dataUrl); }; // Wait for image rendering to get its data URL $(element).one('cornerstoneimagerendered', function () { if (measurement && alwaysVisibleText) { rearrangeTextBox(image, measurement, element).then(function () { return renderedCallback(); }); } else { renderedCallback(); } }); }); }); }; var getPoint = function (x, y) { return { x: x, y: y }; }; var lineRectangleIntersection = function (line, rect) { var intersection; Object.keys(rect).forEach(function (side) { if (intersection) return; var rectSegment = rect[side]; intersection = cornerstoneMath.lineSegment.intersectLine(line, rectSegment); }); return intersection; }; var rearrangeTextBox = function (image, measurement, element) { return new Promise(function (resolve, reject) { var handles = measurement && measurement.handles; if (!handles) return resolve(); var textBox = handles.textBox, start = handles.start, end = handles.end; if (!textBox || !textBox.boundingBox || !start || !end) return resolve(); // Build the dashed line segment var dashedLine = new cornerstoneMath.Line3(); var maxX = Math.max(start.x, end.x); var minX = Math.min(start.x, end.x); var maxY = Math.max(start.y, end.y); var minY = Math.min(start.y, end.y); dashedLine.start = getPoint(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2); dashedLine.end = getPoint(textBox.x, textBox.y); // Build the bounding rectangle var x0 = textBox.boundingBox.width / 2; var x1 = image.width - x0; var y0 = textBox.boundingBox.height / 2; var y1 = image.height - y0; var topLeft = getPoint(x0, y0); var topRight = getPoint(x1, y0); var bottomLeft = getPoint(x0, y1); var bottomRight = getPoint(x1, y1); var boundingRect = { top: new cornerstoneMath.Line3(topLeft, topRight), left: new cornerstoneMath.Line3(topLeft, bottomLeft), right: new cornerstoneMath.Line3(topRight, bottomRight), bottom: new cornerstoneMath.Line3(bottomLeft, bottomRight) }; // Check if the measurement center is outside the bounding rectangle var imageCenter = getPoint(image.width / 2, image.height / 2); var imageCenterToMeasurement = new cornerstoneMath.Line3(); imageCenterToMeasurement.start = imageCenter; imageCenterToMeasurement.end = dashedLine.start; if (lineRectangleIntersection(imageCenterToMeasurement, boundingRect)) { dashedLine = new cornerstoneMath.Line3(imageCenter, dashedLine.end); } // Check if the text box is outside the image area var intersection = lineRectangleIntersection(dashedLine, boundingRect); if (intersection) { textBox.boundingBox.left = intersection.x - x0; textBox.boundingBox.top = intersection.y - y0; Object.assign(textBox, intersection); cornerstone.updateImage(element); $(element).one('cornerstoneimagerendered', function () { return resolve(); }); } else { resolve(); } }); }; var createEnabledElement = function (width, height) { var $element = $('
').css({ height: height, left: 0, position: 'fixed', top: 0, visibility: 'hidden', width: width, 'z-index': -1 }); var element = $element[0]; $element.appendTo(document.body); cornerstone.enable(element, { renderer: OHIF.cornerstone.renderer }); var enabledElement = cornerstone.getEnabledElement(element); enabledElement.toolStateManager = cornerstoneTools.newImageIdSpecificToolStateManager(); return enabledElement; }; var destroyEnabledElement = function (enabledElement) { cornerstone.disable(enabledElement.element); $(enabledElement.element).remove(); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getLabelTerminologyList.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getLabelTerminologyList.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ segmentedTerminologyList: function () { return segmentedTerminologyList; }, segmentedTerminologyCommonList: function () { return segmentedTerminologyCommonList; } }); var segmentedTerminologyList = [{ label: 'Abdomen/Chest Wall', value: 'Abdomen/Chest Wall', segmentedPropCategory: 'T-D0080' }, { label: 'Adrenal', value: 'Adrenal', segmentedPropCategory: 'T-D0080' }, { label: 'Bladder', value: 'Bladder', segmentedPropCategory: 'T-D0080' }, { label: 'Bone', value: 'Bone', segmentedPropCategory: 'T-D0080' }, { label: 'Brain', value: 'Brain', segmentedPropCategory: 'T-D0080' }, { label: 'Breast', value: 'Breast', segmentedPropCategory: 'T-D0080' }, { label: 'Colon', value: 'Colon', segmentedPropCategory: 'T-D0080' }, { label: 'Esophagus', value: 'Esophagus', segmentedPropCategory: 'T-D0080' }, { label: 'Extremities', value: 'Extremities', segmentedPropCategory: 'T-D0080' }, { label: 'Gallbladder', value: 'Gallbladder', segmentedPropCategory: 'T-D0080' }, { label: 'Kidney', value: 'Kidney', segmentedPropCategory: 'T-D0080' }, { label: 'Liver', value: 'Liver', segmentedPropCategory: 'T-D0080' }, { label: 'Lung', value: 'Lung', segmentedPropCategory: 'T-D0080' }, { label: 'Lymph Node', value: 'Lymph Node', segmentedPropCategory: 'T-D0080' }, { label: 'Mediastinum/Hilum', value: 'Mediastinum/Hilum', segmentedPropCategory: 'T-D0080' }, { label: 'Muscle', value: 'Muscle', segmentedPropCategory: 'T-D0080' }, { label: 'Neck', value: 'Neck', segmentedPropCategory: 'T-D0080' }, { label: 'Other Soft Tissue', value: 'Other Soft Tissue', segmentedPropCategory: 'T-D0080' }, { label: 'Ovary', value: 'Ovary', segmentedPropCategory: 'T-D0080' }, { label: 'Pancreas', value: 'Pancreas', segmentedPropCategory: 'T-D0080' }, { label: 'Pelvis', value: 'Pelvis', segmentedPropCategory: 'T-D0080' }, { label: 'Peritoneum/Omentum', value: 'Peritoneum/Omentum', segmentedPropCategory: 'T-D0080' }, { label: 'Prostate', value: 'Prostate', segmentedPropCategory: 'T-D0080' }, { label: 'Retroperitoneum', value: 'Retroperitoneum', segmentedPropCategory: 'T-D0080' }, { label: 'Small Bowel', value: 'Small Bowel', segmentedPropCategory: 'T-D0080' }, { label: 'Spleen', value: 'Spleen', segmentedPropCategory: 'T-D0080' }, { label: 'Stomach', value: 'Stomach', segmentedPropCategory: 'T-D0080' }, { label: 'Subcutaneous', value: 'Subcutaneous', segmentedPropCategory: 'T-D0080' }]; var segmentedTerminologyCommonList = [{ label: 'Abdomen/Chest Wall', value: 'Abdomen/Chest Wall', segmentedPropCategory: 'T-D0080' }, { label: 'Liver', value: 'Liver', segmentedPropCategory: 'T-D0080' }, { label: 'Lung', value: 'Lung', segmentedPropCategory: 'T-D0080' }, { label: 'Lymph Node', value: 'Lymph Node', segmentedPropCategory: 'T-D0080' }, { label: 'Mediastinum/Hilum', value: 'Mediastinum/Hilum', segmentedPropCategory: 'T-D0080' }, { label: 'Pelvis', value: 'Pelvis', segmentedPropCategory: 'T-D0080' }, { label: 'Peritoneum/Omentum', value: 'Peritoneum/Omentum', segmentedPropCategory: 'T-D0080' }, { label: 'Retroperitoneum', value: 'Retroperitoneum', segmentedPropCategory: 'T-D0080' }]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getLocationLabel.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getLocationLabel.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Extensible method to translate the location and return a string containing its label * * @param location * @returns string - label for the given location */ OHIF.measurements.getLocationLabel = function (location) { return location; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getMeasurementsGroupedByNumber.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getMeasurementsGroupedByNumber.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); // TODO: change this to a const after refactoring newMeasurements code on measurementTableView.js OHIF.measurements.getLocation = function (collection) { for (var i = 0; i < collection.length; i++) { if (collection[i].location) { return collection[i].location; } } }; // TODO: change this to a const after refactoring newMeasurements code on measurementTableView.js OHIF.measurements.getDescription = function (collection) { for (var i = 0; i < collection.length; i++) { if (collection[i].description) { return collection[i].description; } } }; /** * Group all measurements by its tool group and measurement number. * * @param measurementApi * @param timepointApi * @returns {*} A list containing each toolGroup and an array containing the measurement rows */ OHIF.measurements.getMeasurementsGroupedByNumber = function (measurementApi, timepointApi) { var getPath = OHIF.utils.ObjectPath.get; var configuration = OHIF.measurements.MeasurementApi.getConfiguration(); if (!measurementApi || !timepointApi || !configuration) return; // Check which tools are going to be displayed var displayToolGroupMap = {}; var displayToolList = []; configuration.measurementTools.forEach(function (toolGroup) { displayToolGroupMap[toolGroup.id] = false; toolGroup.childTools.forEach(function (tool) { var willDisplay = !!getPath(tool, 'options.measurementTable.displayFunction'); if (willDisplay) { displayToolList.push(tool.id); displayToolGroupMap[toolGroup.id] = true; } }); }); // Create the result object var groupedMeasurements = []; var baseline = timepointApi.baseline(); if (!baseline) return; configuration.measurementTools.forEach(function (toolGroup) { // Skip this tool group if it should not be displayed if (!displayToolGroupMap[toolGroup.id]) return; // Retrieve all the data for this Measurement type (e.g. 'targets') // which was recorded at baseline. var atBaseline = measurementApi.fetch(toolGroup.id, { timepointId: baseline.timepointId }); // Obtain a list of the Measurement Numbers from the // measurements which have baseline data var numbers = atBaseline.map(function (m) { return m.measurementNumber; }); // Retrieve all the data for this Measurement type which // match the Measurement Numbers obtained above var data = measurementApi.fetch(toolGroup.id, { toolId: { $in: displayToolList }, measurementNumber: { $in: numbers } }); // Group the Measurements by Measurement Number var groupObject = _.groupBy(data, function (entry) { return entry.measurementNumber; }); // Reformat the data for display in the table var measurementRows = Object.keys(groupObject).map(function (key) { return { measurementTypeId: toolGroup.id, measurementNumber: key, location: OHIF.measurements.getLocation(groupObject[key]), description: OHIF.measurements.getDescription(groupObject[key]), responseStatus: false, // TODO: Get the latest timepoint and determine the response status entries: groupObject[key] }; }); // Add the group to the result groupedMeasurements.push({ toolGroup: toolGroup, measurementRows: measurementRows }); }); return groupedMeasurements; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getParentToolData.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getParentToolData.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Return the parent tool data if it's a child tool or the tool data itself if not * * @param measurementData measurement data that must contain the toolType and measurement's _id * @returns {Object} Parent measurement data */ OHIF.measurements.getParentToolData = function (measurementData) { var toolType = measurementData.toolType, _id = measurementData._id; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), tool = _OHIF$measurements$ge.tool; var parentToolType = tool.parentTool || toolType; var parentToolData = OHIF.viewer.measurementApi.tools[parentToolType].findOne(_id); return parentToolData; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getTimepointName.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getTimepointName.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Calculates a Timepoint's name based on how many timepoints exist between it * and the latest Baseline. Names returned are in the form of 'Baseline', or * 'Follow-up 1', 'Follow-up 2', and so on. * * @param timepoint * @returns {*} The timepoint name */ OHIF.measurements.getTimepointName = function (timepoint) { // Check if this is a Baseline timepoint, if it is, return 'Baseline' if (timepoint.timepointType === 'baseline') { return 'Baseline'; } else if (timepoint.visitNumber) { return 'Follow-up ' + timepoint.visitNumber; } // Retrieve all of the relevant follow-up timepoints for this patient var followupTimepoints = Timepoints.find({ patientId: timepoint.patientId, timepointType: timepoint.timepointType }, { sort: { latestDate: 1 } }); // Create an array of just timepointIds, so we can use indexOf // on it to find the current timepoint's relative position var followupTimepointIds = followupTimepoints.map(function (timepoint) { return timepoint.timepointId; }); // Calculate the index of the current timepoint in the array of all // relevant follow-up timepoints var index = followupTimepointIds.indexOf(timepoint.timepointId) + 1; // If index is 0, it means that the current timepoint was not in the list // Log a warning and return here if (!index) { OHIF.log.warn('Current follow-up was not in the list of relevant follow-ups?'); return; } // Return the timepoint name as 'Follow-up N' return 'Follow-up ' + index; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getToolConfiguration.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/getToolConfiguration.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); /** * Return the tool configuration of a given tool type * * @param {String} toolType The tool type of the desired configuration */ OHIF.measurements.getToolConfiguration = function (toolType) { var MeasurementApi = OHIF.measurements.MeasurementApi; var configuration = MeasurementApi.getConfiguration(); var toolsGroupsMap = MeasurementApi.getToolsGroupsMap(); var toolGroupId = toolsGroupsMap[toolType]; var toolGroup = _.findWhere(configuration.measurementTools, { id: toolGroupId }); var tool; if (toolGroup) { tool = _.findWhere(toolGroup.childTools, { id: toolType }); } return { toolGroupId: toolGroupId, toolGroup: toolGroup, tool: tool }; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"hangingProtocolCustomizations.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/hangingProtocolCustomizations.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Meteor; module.watch(require("meteor/meteor"), { Meteor: function (v) { Meteor = v; } }, 0); var Viewerbase; module.watch(require("meteor/ohif:viewerbase"), { Viewerbase: function (v) { Viewerbase = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var _Viewerbase$metadata = Viewerbase.metadata, InstanceMetadata = _Viewerbase$metadata.InstanceMetadata, StudySummary = _Viewerbase$metadata.StudySummary; // TODO: [LT-refactor] move this to ohif:hanging-protocols package /** * Get a timepoint type for a given study metadata * @param {StudyMetadata} study StudyMetadata instance * @return {String|undefined} Timepoint type if found or undefined if not found or any error/missing information */ var getTimepointType = function (study) { var timepointApi = OHIF.viewer.timepointApi; if (!timepointApi || !(study instanceof InstanceMetadata || study instanceof StudySummary)) { return; } var timepoint = timepointApi.study(study.getStudyInstanceUID()); if (!timepoint || !(timepoint instanceof Array) || timepoint.length < 1) { return; } return timepoint[0].timepointType; }; /** * Get the timpoint key (prior/current/baseline) for a given study metadata * @param {StudyMetadata} study StudyMetadata instance * @return {String|undefined} Timepoint key if found or undefined if not found or any error/missing information */ var getTimepointKey = function (study) { var timepointApi = OHIF.viewer.timepointApi; if (!timepointApi || !(study instanceof InstanceMetadata || study instanceof StudySummary)) { return; } var timepoint = timepointApi.study(study.getStudyInstanceUID()); if (!timepoint || !(timepoint instanceof Array) || timepoint.length < 1) { return; } var timepointId = timepoint[0]._id; if (timepointApi.current()._id === timepointId) { return 'current'; } else if (timepointApi.prior()._id === timepointId) { return 'prior'; } else if (timepointApi.baseline()._id === timepointId) { return 'baseline'; } }; Meteor.startup(function () { HP = HP || false; if (HP) { HP.addCustomAttribute('timepointType', 'Timepoint Type', getTimepointType); HP.addCustomAttribute('timepointKey', 'Timepoint Key', getTimepointKey); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./jumpToRowItem")); module.watch(require("./activateMeasurements")); module.watch(require("./clearCornerstoneToolState")); module.watch(require("./deactivateAllToolData")); module.watch(require("./exportPdf")); module.watch(require("./exportToCsv")); module.watch(require("./findAndRenderDisplaySet")); module.watch(require("./getActiveTimepoint")); module.watch(require("./getImageDataUrl")); module.watch(require("./getMeasurementsGroupedByNumber")); module.watch(require("./getLocationLabel")); module.watch(require("./getParentToolData")); module.watch(require("./getTimepointName")); module.watch(require("./getToolConfiguration")); module.watch(require("./hangingProtocolCustomizations")); module.watch(require("./isNewLesionsMeasurement")); module.watch(require("./MeasurementHandlers")); module.watch(require("./MeasurementManager")); module.watch(require("./navigateOverLesions")); module.watch(require("./saveMeasurements")); module.watch(require("./syncMeasurementAndToolData")); module.watch(require("./toggleLabelButton")); module.watch(require("./openLocationModal")); module.watch(require("./triggerTimepointUnsavedChanges")); module.watch(require("./updateMeasurementsDescription")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"isNewLesionsMeasurement.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/isNewLesionsMeasurement.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); /** * Check if the given measurement is a new lesion * * @param measurementData Measurement that will be checked * @returns {Boolean} Boolean value telling if the given measurement is a new lesion or not */ OHIF.measurements.isNewLesionsMeasurement = function (measurementData) { if (!measurementData) return; var toolConfig = OHIF.measurements.getToolConfiguration(measurementData.toolType); var toolType = toolConfig.tool.parentTool || measurementData.toolType; var _OHIF$viewer = OHIF.viewer, timepointApi = _OHIF$viewer.timepointApi, measurementApi = _OHIF$viewer.measurementApi; var currentMeasurement = measurementApi.tools[toolType].findOne(measurementData._id); var timepointId = currentMeasurement.timepointId, measurementNumber = currentMeasurement.measurementNumber; // Stop here if the needed information is not set if (!measurementApi || !timepointApi || !timepointId || !toolConfig) return; var toolGroupId = toolConfig.toolGroupId; var current = timepointApi.timepoints.findOne({ timepointId: timepointId }); var baseline = timepointApi.baseline(); // Stop here if there's no current or baseline timepoints, or if the current is the baseline if (!current || !baseline || current.timepointType === 'baseline') return false; // Retrieve all the data for the given tool group (e.g. 'targets') var atBaseline = measurementApi.fetch(toolGroupId, { timepointId: baseline.timepointId }); // Obtain a list of the Measurement Numbers from the measurements which have baseline data var numbers = atBaseline.map(function (m) { return m.measurementNumber; }); // Return true if the measurement number from follow-up is not present at baseline return !_.contains(numbers, measurementNumber); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"jumpToRowItem.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/jumpToRowItem.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 3); function renderIntoViewport(measurementData, enabledElement, viewportIndex) { var _OHIF$measurements = OHIF.measurements, activateMeasurements = _OHIF$measurements.activateMeasurements, findAndRenderDisplaySet = _OHIF$measurements.findAndRenderDisplaySet; var element = enabledElement.element; var studyInstanceUid = measurementData.studyInstanceUid, seriesInstanceUid = measurementData.seriesInstanceUid, sopInstanceUid = measurementData.sopInstanceUid; return new Promise(function (resolve, reject) { var renderedCallback = function (element) { activateMeasurements(element, measurementData); $(element).one('cornerstoneimagerendered', function () { return resolve(); }); }; // Find the study by studyInstanceUid and render the display set var findAndRender = function () { // @TypeSafeStudies var study = OHIF.viewer.Studies.findBy({ studyInstanceUid: studyInstanceUid }); // TODO: Support frames? e.g. for measurements on multi-frame instances findAndRenderDisplaySet(study.displaySets, viewportIndex, studyInstanceUid, seriesInstanceUid, sopInstanceUid, renderedCallback); }; // Check if the study / series we need is already the one in the viewport. // Otherwise, re-render the viewport with the required study/series, then add a rendered // callback to activate the measurements if (enabledElement && enabledElement.image) { var imageId = enabledElement.image.imageId; var series = cornerstone.metaData.get('series', imageId); var study = cornerstone.metaData.get('study', imageId); var isSameStudy = study.studyInstanceUid === measurementData.studyInstanceUid; var isSameSeries = series.seriesInstanceUid === measurementData.seriesInstanceUid; if (isSameStudy && isSameSeries) { // If it is, activate the measurements in this viewport and stop here OHIF.viewerbase.viewportUtils.resetViewport(viewportIndex); renderedCallback(element); } else { findAndRender(); } } else { findAndRender(); } }); } function syncViewports(viewportsIndexes) { var synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer; if (!synchronizer) { return; } var linkableViewports = synchronizer.getLinkableViewports(); if (linkableViewports.length) { var linkableViewportsIndexes = _.pluck(linkableViewports, 'index'); var indexes = _.intersection(linkableViewportsIndexes, viewportsIndexes); if (indexes.length) { OHIF.viewer.stackImagePositionOffsetSynchronizer.activateByViewportIndexes(indexes); } } } // Store the lastActivatedRowItem to cancel jumping if another rowItem was triggered during loading var lastActivatedRowItem; /** * Activates a set of lesions when lesion table row is clicked * * @param measurementId The unique key for a specific Measurement */ OHIF.measurements.jumpToRowItem = function (rowItem, timepoints, childToolKey) { var _OHIF$viewerbase$layo = OHIF.viewerbase.layoutManager, isZoomed = _OHIF$viewerbase$layo.isZoomed, zoomedViewportIndex = _OHIF$viewerbase$layo.zoomedViewportIndex; lastActivatedRowItem = rowItem; // Retrieve the list of available viewports var $viewports = $('.imageViewerViewport'); var numViewports = Math.max($viewports.length, 0); // Clone the timepoint list to prevent modifying the original object var timepointList; if (isZoomed) { timepointList = [timepoints[zoomedViewportIndex]]; } else { timepointList = _.clone(timepoints); } // Reverse the timepointList array if the flag is set if (OHIF.viewer.invertViewportTimepointsOrder) { timepointList.reverse(); } // Retrieve the timepoints that are currently being displayed in the Measurement Table var numTimepoints = Math.max(timepointList.length, 1); var numViewportsToUpdate = Math.min(numTimepoints, numViewports); // Retrieve the measurements data var measurementsData = []; var promises = new Set(); var _loop = function (i) { var timepointId = timepointList[i].timepointId; var dataAtThisTimepoint = _.where(rowItem.entries, { timepointId: timepointId }); if (!dataAtThisTimepoint || !dataAtThisTimepoint.length) { measurementsData.push(null); return "continue"; } var measurement = dataAtThisTimepoint[0]; var measurementData = measurement; var _measurementData = measurementData, toolType = _measurementData.toolType; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), tool = _OHIF$measurements$ge.tool; if (childToolKey) { measurementData = measurementData[childToolKey]; } else if (Array.isArray(tool.childTools)) { tool.childTools.every(function (key) { measurementData = measurementData[key]; return !measurementData; }); } measurementsData.push(measurementData); var promise = OHIF.studies.loadStudy(measurementData.studyInstanceUid); promise.then(function () { return OHIF.measurements.syncMeasurementAndToolData(measurement); }); promises.add(promise); }; for (var i = 0; i < numViewportsToUpdate; i++) { var _ret = _loop(i); if (_ret === "continue") continue; } // Wait for studies metadata to be retrieved before jumpint to the given row item Promise.all(promises).then(function () { // Stop here if another rowItem was activated during loading process if (rowItem !== lastActivatedRowItem) return; OHIF.measurements.deactivateAllToolData(); var activatedViewportIndexes = []; // Deactivate stack synchronizer because it will be re-activated later var synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer; if (synchronizer) { synchronizer.deactivate(); } var renderPromises = []; for (var viewportIndex = 0; viewportIndex < numViewportsToUpdate; viewportIndex++) { var measurementData = measurementsData[viewportIndex]; if (!measurementData) continue; activatedViewportIndexes.push(viewportIndex); var element = $viewports.get(viewportIndex); // TODO: Implement isEnabledElement in Cornerstone // or maybe just remove the 'error' this throws? var enabledElement = void 0; try { enabledElement = cornerstone.getEnabledElement(element); } catch (error) { continue; } var promise = renderIntoViewport(measurementData, enabledElement, viewportIndex); renderPromises.push(promise); } // Wait for all viewports to be rendered then sync them Promise.all(renderPromises).then(function () { return syncViewports(activatedViewportIndexes); }); }); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"navigateOverLesions.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/navigateOverLesions.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Method to go select the next or previous lesion on measurements table * * @param {Boolean} isNextLesion Determine if it will navigate to the next or previous lesion */ OHIF.measurements.navigateOverLesions = function (isNextLesion) { var $table = $('#measurementTableContainer'); if (!$table.length) return; var $lesions = $table.find('.measurementTableRow'); if (!$lesions.length) return; var $activeLesion = $lesions.filter('.active'); var activeIndex = $lesions.index($activeLesion); var step = isNextLesion ? 1 : -1; var newIndex = 0; if (activeIndex !== -1) { newIndex = activeIndex + step; if (newIndex >= $lesions.length) { newIndex = 0; } else if (newIndex < 0) { newIndex = $lesions.length - 1; } } $lesions.eq(newIndex).find('.measurementRowSidebar').trigger('click'); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"openLocationModal.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/openLocationModal.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var Blaze; module.watch(require("meteor/blaze"), { Blaze: function (v) { Blaze = v; } }, 1); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); OHIF.measurements.openLocationModal = function (options) { var toolType = options.measurement.toolType; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), tool = _OHIF$measurements$ge.tool; if (!tool) return; toolType = tool && tool.parentTool || toolType; var measurementId = options.measurement._id; var buttonView = null; var removeButtonView = function () { Blaze.remove(buttonView); buttonView = null; }; if (buttonView) { removeButtonView(); } var measurementApi = options.measurementApi; var toolCollection = measurementApi.tools[toolType]; var measurement = toolCollection.findOne(measurementId); var data = { measurement: measurement, position: options.position, direction: options.direction, threeColumns: true, hideCommon: true, autoClick: options.autoClick, doneCallback: removeButtonView, updateCallback: function (location) { var groupId = measurementApi.toolsGroupsMap[toolType]; var config = OHIF.measurements.MeasurementApi.getConfiguration(); var group = _.findWhere(config.measurementTools, { id: groupId }); group.childTools.forEach(function (tool) { measurementApi.tools[tool.id].update({ measurementNumber: measurement.measurementNumber, patientId: measurement.patientId }, { $set: { location: location } }, { multi: true }); }); options.measurement.location = location; // Notify that viewer suffered changes OHIF.measurements.triggerTimepointUnsavedChanges('relabel'); } }; buttonView = Blaze.renderWithData(Template.measurementRelabel, data, document.body); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"saveMeasurements.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/saveMeasurements.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); OHIF.measurements.saveMeasurements = function (measurementApi, timepointId) { var _OHIF$ui = OHIF.ui, unsavedChanges = _OHIF$ui.unsavedChanges, notifications = _OHIF$ui.notifications, showDialog = _OHIF$ui.showDialog; var basePath = "viewer.studyViewer.measurements." + timepointId; // Stop here if there are nonconformities in the timepoints var nonconformities = OHIF.viewer.conformanceCriteria.nonconformities.get(); if (nonconformities.length) return; // Stop here if there were no changes to the timepoint if (unsavedChanges.probe(basePath) === 0) return; // Clear unsaved changes state and display success message var successHandler = function () { unsavedChanges.clear(basePath, true); notifications.success({ text: 'The measurement data was successfully saved' }); }; // Display the error messages var errorHandler = function (data) { showDialog('dialogInfo', Object.assign({ "class": 'themed' }, data)); }; // Call the storage method and display a loading overlay var promise = measurementApi.storeMeasurements(timepointId); promise.then(successHandler).catch(errorHandler); showDialog('dialogLoading', { promise: promise, text: 'Saving measurement data' }); // Return the save promise return promise; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"syncMeasurementAndToolData.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/syncMeasurementAndToolData.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var cornerstoneTools; module.watch(require("meteor/ohif:cornerstone"), { cornerstoneTools: function (v) { cornerstoneTools = v; } }, 1); OHIF.measurements.syncMeasurementAndToolData = function (measurement) { OHIF.log.info('syncMeasurementAndToolData'); var toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState(); // Stop here if the metadata for the measurement's study is not loaded yet var studyInstanceUid = measurement.studyInstanceUid; var metadata = OHIF.viewer.StudyMetadataList.findBy({ "studyInstanceUID": studyInstanceUid }); if (!metadata) return; // Iterate each child tool if the current tool has children var getImageIdForImagePath = OHIF.viewerbase.getImageIdForImagePath; var toolType = measurement.toolType; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), tool = _OHIF$measurements$ge.tool; if (Array.isArray(tool.childTools)) { tool.childTools.forEach(function (childToolKey) { var childMeasurement = measurement[childToolKey]; if (!childMeasurement) return; childMeasurement._id = measurement._id; childMeasurement.measurementNumber = measurement.measurementNumber; OHIF.measurements.syncMeasurementAndToolData(childMeasurement); }); return; } var imageId = getImageIdForImagePath(measurement.imagePath); // If no tool state exists for this imageId, create an empty object to store it if (!toolState[imageId]) { toolState[imageId] = {}; } var currentToolState = toolState[imageId][toolType]; var toolData = currentToolState && currentToolState.data; // Check if we already have toolData for this imageId and toolType if (toolData && toolData.length) { // If we have toolData, we should search it for any data related to the current Measurement var _toolData = toolState[imageId][toolType].data; // Create a flag so we know if we've successfully updated the Measurement in the toolData var alreadyExists = false; // Loop through the toolData to search for this Measurement _toolData.forEach(function (tool) { // Break the loop if this isn't the Measurement we are looking for if (tool._id !== measurement._id) { return; } // If we have found the Measurement, set the flag to True alreadyExists = true; // Update the toolData from the Measurement data Object.assign(tool, measurement); return false; }); // If we have found the Measurement we intended to update, we can stop this function here if (alreadyExists === true) { return; } } else { // If no toolData exists for this toolType, create an empty array to hold some toolState[imageId][toolType] = { data: [] }; } // If we have reached this point, it means we haven't found the Measurement we are looking for // in the current toolData. This means we need to add it. // Add the MeasurementData into the toolData for this imageId toolState[imageId][toolType].data.push(measurement); cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(toolState); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"toggleLabelButton.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/toggleLabelButton.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Template; module.watch(require("meteor/templating"), { Template: function (v) { Template = v; } }, 0); var Blaze; module.watch(require("meteor/blaze"), { Blaze: function (v) { Blaze = v; } }, 1); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 2); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 3); OHIF.measurements.toggleLabelButton = function (options) { var toolType = options.measurement.toolType; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), tool = _OHIF$measurements$ge.tool; if (!tool) return; toolType = tool && tool.parentTool || toolType; var measurementId = options.measurement._id; var buttonView = null; var removeButtonView = function () { if (!buttonView) { return; } Blaze.remove(buttonView); buttonView = null; }; if (buttonView) { removeButtonView(); } var measurementApi = options.measurementApi; var toolCollection = measurementApi.tools[toolType]; var measurement = toolCollection.findOne(measurementId); var data = { measurement: measurement, position: options.position, direction: options.direction, threeColumns: true, hideCommon: true, autoClick: options.autoClick, doneCallback: removeButtonView, updateCallback: function (location, description) { var groupId = measurementApi.toolsGroupsMap[toolType]; var config = OHIF.measurements.MeasurementApi.getConfiguration(); var group = _.findWhere(config.measurementTools, { id: groupId }); group.childTools.forEach(function (tool) { measurementApi.tools[tool.id].update({ measurementNumber: measurement.measurementNumber, patientId: measurement.patientId }, { $set: { location: location, description: description } }, { multi: true }); }); options.measurement.location = location; options.measurement.description = description; // Notify that viewer suffered changes OHIF.measurements.triggerTimepointUnsavedChanges('relabel'); } }; buttonView = Blaze.renderWithData(Template.measureFlow, data, document.body); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"triggerTimepointUnsavedChanges.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/triggerTimepointUnsavedChanges.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Extensible method to trigger unsaved changes on the active timepoint * * @param {String} subpath - The unsaved changes subpath that will come after the timepoint ID */ OHIF.measurements.triggerTimepointUnsavedChanges = function () { var subpath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'changed'; var basePath = 'viewer.studyViewer.measurements'; var activeTimepoint = OHIF.measurements.getActiveTimepoint(); if (!activeTimepoint) return; var timepointId = activeTimepoint.timepointId; var timepointPath = timepointId ? "." + timepointId : ''; OHIF.ui.unsavedChanges.set("" + basePath + timepointPath + "." + subpath); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"updateMeasurementsDescription.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/updateMeasurementsDescription.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); /** * Updates the measurements' description for a measurement number across all timepoints * * @param measurementData base measurement data that must contain toolType and measurementNumber * @param description measurement description that will be used */ OHIF.measurements.updateMeasurementsDescription = function (measurementData, description) { var toolType = measurementData.toolType, measurementNumber = measurementData.measurementNumber; measurementData.description = description; var filter = { measurementNumber: measurementNumber }; var operator = { $set: { description: description } }; var options = { multi: true }; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), toolGroup = _OHIF$measurements$ge.toolGroup; toolGroup.childTools.forEach(function (childTool) { var collection = OHIF.viewer.measurementApi.tools[childTool.id]; collection.update(filter, operator, options); }); // Notify that viewer suffered changes OHIF.measurements.triggerTimepointUnsavedChanges('relabel'); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"MeasurementHandlers":{"MeasurementHandlers.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/MeasurementHandlers.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var handleSingleMeasurementAdded; module.watch(require("./handleSingleMeasurementAdded"), { "default": function (v) { handleSingleMeasurementAdded = v; } }, 1); var handleChildMeasurementAdded; module.watch(require("./handleChildMeasurementAdded"), { "default": function (v) { handleChildMeasurementAdded = v; } }, 2); var handleSingleMeasurementModified; module.watch(require("./handleSingleMeasurementModified"), { "default": function (v) { handleSingleMeasurementModified = v; } }, 3); var handleChildMeasurementModified; module.watch(require("./handleChildMeasurementModified"), { "default": function (v) { handleChildMeasurementModified = v; } }, 4); var handleSingleMeasurementRemoved; module.watch(require("./handleSingleMeasurementRemoved"), { "default": function (v) { handleSingleMeasurementRemoved = v; } }, 5); var handleChildMeasurementRemoved; module.watch(require("./handleChildMeasurementRemoved"), { "default": function (v) { handleChildMeasurementRemoved = v; } }, 6); var MeasurementHandlers = { handleSingleMeasurementAdded: handleSingleMeasurementAdded, handleChildMeasurementAdded: handleChildMeasurementAdded, handleSingleMeasurementModified: handleSingleMeasurementModified, handleChildMeasurementModified: handleChildMeasurementModified, handleSingleMeasurementRemoved: handleSingleMeasurementRemoved, handleChildMeasurementRemoved: handleChildMeasurementRemoved, onAdded: function (event, instance) { var eventData = event.detail; var toolType = eventData.toolType; var _OHIF$measurements$ge = OHIF.measurements.getToolConfiguration(toolType), toolGroupId = _OHIF$measurements$ge.toolGroupId, toolGroup = _OHIF$measurements$ge.toolGroup, tool = _OHIF$measurements$ge.tool; var params = { instance: instance, eventData: eventData, tool: tool, toolGroupId: toolGroupId, toolGroup: toolGroup }; if (!tool) return; if (tool.parentTool) { this.handleChildMeasurementAdded(params); } else { this.handleSingleMeasurementAdded(params); } }, onModified: function (event, instance) { var eventData = event.detail; var toolType = eventData.toolType; var _OHIF$measurements$ge2 = OHIF.measurements.getToolConfiguration(toolType), toolGroupId = _OHIF$measurements$ge2.toolGroupId, toolGroup = _OHIF$measurements$ge2.toolGroup, tool = _OHIF$measurements$ge2.tool; var params = { instance: instance, eventData: eventData, tool: tool, toolGroupId: toolGroupId, toolGroup: toolGroup }; if (!tool) return; if (tool.parentTool) { this.handleChildMeasurementModified(params); } else { this.handleSingleMeasurementModified(params); } }, onRemoved: function (e, instance) { var eventData = event.detail; var toolType = eventData.toolType; var _OHIF$measurements$ge3 = OHIF.measurements.getToolConfiguration(toolType), toolGroupId = _OHIF$measurements$ge3.toolGroupId, toolGroup = _OHIF$measurements$ge3.toolGroup, tool = _OHIF$measurements$ge3.tool; var params = { instance: instance, eventData: eventData, tool: tool, toolGroupId: toolGroupId, toolGroup: toolGroup }; if (!tool) return; if (tool.parentTool) { MeasurementHandlers.handleChildMeasurementRemoved(params); } else { MeasurementHandlers.handleSingleMeasurementRemoved(params); } } }; OHIF.measurements.MeasurementHandlers = MeasurementHandlers; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getImageAttributes.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/getImageAttributes.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 0); module.exportDefault(function (element) { // Get the Cornerstone imageId var enabledElement = cornerstone.getEnabledElement(element); var imageId = enabledElement.image.imageId; // Get studyInstanceUid & patientId var study = cornerstone.metaData.get('study', imageId); var studyInstanceUid = study.studyInstanceUid; var patientId = study.patientId; // Get seriesInstanceUid var series = cornerstone.metaData.get('series', imageId); var seriesInstanceUid = series.seriesInstanceUid; // Get sopInstanceUid var sopInstance = cornerstone.metaData.get('instance', imageId); var sopInstanceUid = sopInstance.sopInstanceUid; var frameIndex = sopInstance.frame || 0; var imagePath = [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join('_'); return { patientId: patientId, studyInstanceUid: studyInstanceUid, seriesInstanceUid: seriesInstanceUid, sopInstanceUid: sopInstanceUid, frameIndex: frameIndex, imagePath: imagePath }; }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleChildMeasurementAdded.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Meteor; module.watch(require("meteor/meteor"), { Meteor: function (v) { Meteor = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 3); var getImageAttributes; module.watch(require("./getImageAttributes"), { "default": function (v) { getImageAttributes = v; } }, 4); module.exportDefault(function (_ref) { var _Collection$findOne; var instance = _ref.instance, eventData = _ref.eventData, tool = _ref.tool, toolGroupId = _ref.toolGroupId, toolGroup = _ref.toolGroup; var measurementApi = instance.data.measurementApi; var measurementData = eventData.measurementData; var Collection = measurementApi.tools[tool.parentTool]; // Stop here if the tool data shall not be persisted (e.g. temp tools) if (!Collection) return; // Stop here if there's no measurement data or if it was cancelled if (!measurementData || measurementData.cancelled) return; OHIF.log.info('CornerstoneToolsMeasurementAdded'); var imageAttributes = getImageAttributes(eventData.element); var measurement = { toolType: tool.parentTool, measurementNumber: measurementData.measurementNumber, userId: Meteor.userId(), patientId: imageAttributes.patientId, studyInstanceUid: imageAttributes.studyInstanceUid }; var additionalProperties = _.extend(imageAttributes, { userId: Meteor.userId() }); var childMeasurement = _.extend({}, measurementData, additionalProperties); var parentMeasurement = Collection.findOne((_Collection$findOne = { toolType: tool.parentTool, patientId: imageAttributes.patientId }, _Collection$findOne[tool.attribute] = null, _Collection$findOne)); // Check if a measurement to fit this child tool already exists if (parentMeasurement) { var _$set; var key = tool.attribute; // Add the createdAt attribute childMeasurement.createdAt = new Date(); // Add the child measurement measurement[key] = childMeasurement; // Clean the measurement according to the Schema Collection._c2._simpleSchema.clean(measurement); // Update the measurement in the collection Collection.update(parentMeasurement._id, { $set: (_$set = {}, _$set[key] = measurement[key], _$set), $inc: { childToolsCount: 1 } }); // Update the measurementData ID and measurementNumber measurementData._id = parentMeasurement._id; measurementData.measurementNumber = parentMeasurement.measurementNumber; } else { measurement[tool.attribute] = _.extend({}, measurementData, additionalProperties); // Get the related timepoint by the measurement number and use its location if defined var relatedTimepoint = Collection.findOne({ measurementNumber: measurement.measurementNumber, toolType: tool.parentTool, patientId: imageAttributes.patientId }); // Use the related timepoint location if found and defined if (relatedTimepoint && relatedTimepoint.location) { measurement.location = relatedTimepoint.location; } // Use the related timepoint description if found and defined if (relatedTimepoint && relatedTimepoint.description) { measurement.description = relatedTimepoint.description; } // Clean the measurement according to the Schema Collection._c2._simpleSchema.clean(measurement); // Insert the new measurement into the collection measurementData._id = Collection.insert(measurement); // Get the updated measurement number after inserting Meteor.defer(function () { measurementData.measurementNumber = Collection.findOne(measurementData._id).measurementNumber; cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); }); } // Notify that viewer suffered changes if (tool.toolGroup !== 'temp') { OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleChildMeasurementModified.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 2); module.exportDefault(function (_ref) { var _$set; var instance = _ref.instance, eventData = _ref.eventData, tool = _ref.tool, toolGroupId = _ref.toolGroupId, toolGroup = _ref.toolGroup; var measurementApi = instance.data.measurementApi; var measurementData = eventData.measurementData; var Collection = measurementApi.tools[tool.parentTool]; // Stop here if the tool data shall not be persisted (e.g. temp tools) if (!Collection) return; OHIF.log.info('CornerstoneToolsMeasurementModified'); var measurement = Collection.findOne(measurementData._id); var childMeasurement = measurement && measurement[tool.attribute]; // Stop here if the measurement is already deleted if (!childMeasurement) return; // Update the collection data with the cornerstone measurement data var ignoredKeys = ['location', 'description', 'response']; Object.keys(measurementData).forEach(function (key) { if (_.contains(ignoredKeys, key)) return; childMeasurement[key] = measurementData[key]; }); // If the measurement configuration includes a value for Viewport, // we will populate this with the Cornerstone Viewport if (Collection._c2._simpleSchema.schema(tool.attribute + ".viewport")) { childMeasurement.viewport = cornerstone.getViewport(eventData.element); } // Update the measurement in the collection Collection.update(measurement._id, { $set: (_$set = {}, _$set[tool.attribute] = childMeasurement, _$set) }); // Notify that viewer suffered changes if (tool.toolGroup !== 'temp') { OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleChildMeasurementRemoved.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 3); module.exportDefault(function (_ref) { var instance = _ref.instance, eventData = _ref.eventData, tool = _ref.tool, toolGroupId = _ref.toolGroupId, toolGroup = _ref.toolGroup; OHIF.log.info('CornerstoneToolsMeasurementRemoved'); var measurementData = eventData.measurementData; var _instance$data = instance.data, measurementApi = _instance$data.measurementApi, timepointApi = _instance$data.timepointApi; var Collection = measurementApi.tools[tool.parentTool]; // Stop here if the tool data shall not be persisted (e.g. temp tools) if (!Collection) return; var measurement = Collection.findOne(measurementData._id); // Stop here if the measurement is already gone or never existed if (!measurement) return; if (measurement.childToolsCount === 1) { // Remove the measurement Collection.remove(measurement._id); // Sync the new measurement data with cornerstone tools var baseline = timepointApi.baseline(); measurementApi.sortMeasurements(baseline.timepointId); } else { var _$set; // Update the measurement in the collection Collection.update(measurement._id, { $set: (_$set = {}, _$set[tool.attribute] = null, _$set), $inc: { childToolsCount: -1 } }); } // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), function (element) { return cornerstone.updateImage(element); }); // Notify that viewer suffered changes if (tool.toolGroup !== 'temp') { OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleSingleMeasurementAdded.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var Meteor; module.watch(require("meteor/meteor"), { Meteor: function (v) { Meteor = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 3); var getImageAttributes; module.watch(require("./getImageAttributes"), { "default": function (v) { getImageAttributes = v; } }, 4); module.exportDefault(function (_ref) { var instance = _ref.instance, eventData = _ref.eventData, tool = _ref.tool; var measurementApi = instance.data.measurementApi; var measurementData = eventData.measurementData, toolType = eventData.toolType; var Collection = measurementApi.tools[toolType]; // Stop here if the tool data shall not be persisted (e.g. temp tools) if (!Collection) return; // Stop here if there's no measurement data or if it was cancelled if (!measurementData || measurementData.cancelled) return; OHIF.log.info('CornerstoneToolsMeasurementAdded'); var imageAttributes = getImageAttributes(eventData.element); var measurement = _.extend({}, measurementData, imageAttributes, { measurementNumber: measurementData.measurementNumber, userId: Meteor.userId() }); // Get the related timepoint by the measurement number and use its location if defined var relatedTimepoint = Collection.findOne({ measurementNumber: measurement.measurementNumber, toolType: measurementData.toolType, patientId: imageAttributes.patientId }); // Use the related timepoint location if found and defined if (relatedTimepoint && relatedTimepoint.location) { measurement.location = relatedTimepoint.location; } // Use the related timepoint description if found and defined if (relatedTimepoint && relatedTimepoint.description) { measurement.description = relatedTimepoint.description; } // Clean the measurement according to the Schema Collection._c2._simpleSchema.clean(measurement); // Insert the new measurement into the collection measurementData._id = Collection.insert(measurement); // Get the updated measurement number after inserting Meteor.defer(function () { measurementData.measurementNumber = Collection.findOne(measurementData._id).measurementNumber; cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); }); // Notify that viewer suffered changes if (tool.toolGroup !== 'temp') { OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleSingleMeasurementModified.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 2); module.exportDefault(function (_ref) { var instance = _ref.instance, eventData = _ref.eventData, tool = _ref.tool, toolGroupId = _ref.toolGroupId, toolGroup = _ref.toolGroup; var measurementApi = instance.data.measurementApi; var measurementData = eventData.measurementData, toolType = eventData.toolType; var Collection = measurementApi.tools[toolType]; // Stop here if the tool data shall not be persisted (e.g. temp tools) if (!Collection) return; OHIF.log.info('CornerstoneToolsMeasurementModified'); var measurement = Collection.findOne(measurementData._id); // Stop here if the measurement is already deleted if (!measurement) return; // Update the collection data with the cornerstone measurement data var ignoredKeys = ['location', 'description', 'response']; Object.keys(measurementData).forEach(function (key) { if (_.contains(ignoredKeys, key)) return; measurement[key] = measurementData[key]; }); var measurementId = measurement._id; delete measurement._id; // If the measurement configuration includes a value for Viewport, // we will populate this with the Cornerstone Viewport if (Collection._c2._simpleSchema.schema('viewport')) { measurement.viewport = cornerstone.getViewport(eventData.element); } // Update the measurement in the collection Collection.update(measurementId, { $set: measurement }); // Notify that viewer suffered changes if (tool.toolGroup !== 'temp') { OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleSingleMeasurementRemoved.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 0); var $; module.watch(require("meteor/jquery"), { $: function (v) { $ = v; } }, 1); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 2); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 3); module.exportDefault(function (_ref) { var instance = _ref.instance, eventData = _ref.eventData, tool = _ref.tool, toolGroupId = _ref.toolGroupId, toolGroup = _ref.toolGroup; OHIF.log.info('CornerstoneToolsMeasurementRemoved'); var measurementData = eventData.measurementData; var _instance$data = instance.data, measurementApi = _instance$data.measurementApi, timepointApi = _instance$data.timepointApi; var Collection = measurementApi.tools[eventData.toolType]; // Stop here if the tool data shall not be persisted (e.g. temp tools) if (!Collection) return; var measurementTypeId = measurementApi.toolsGroupsMap[eventData.toolType]; var measurement = Collection.findOne(measurementData._id); // Stop here if the measurement is already gone or never existed if (!measurement) return; // Remove all the measurements with the given type and number var measurementNumber = measurement.measurementNumber, timepointId = measurement.timepointId; measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber: measurementNumber, timepointId: timepointId }); // Sync the new measurement data with cornerstone tools var baseline = timepointApi.baseline(); measurementApi.sortMeasurements(baseline.timepointId); // Repaint the images on all viewports without the removed measurements _.each($('.imageViewerViewport'), function (element) { return cornerstone.updateImage(element); }); // Notify that viewer suffered changes if (tool.toolGroup !== 'temp') { OHIF.measurements.triggerTimepointUnsavedChanges(eventData.toolType); } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/lib/MeasurementHandlers/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.watch(require("./MeasurementHandlers")); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"reports":{"base.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/reports/base.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ BaseReport: function () { return BaseReport; } }); var jsPDF; module.watch(require("jspdf"), { "default": function (v) { jsPDF = v; } }, 0); var _; module.watch(require("meteor/underscore"), { _: function (v) { _ = v; } }, 1); var BaseReport = /*#__PURE__*/ function () { function BaseReport(options) { var defaultOptions = { width: 595.28, height: 841.89, marginTop: 30, marginLeft: 40, marginRight: 40, marginBottom: 30, showPageNumber: true }; this.options = _.extend(defaultOptions, options); this.init(); } var _proto = BaseReport.prototype; _proto.init = function () { function init() { this.doc = new jsPDF('portrait', 'pt', [this.options.width, this.options.height]); this.options.width = Math.floor(this.options.width); this.options.height = Math.floor(this.options.height); this.currentPage = 1; this.printStatic(); } return init; }(); _proto.printStatic = function () { function printStatic() { this.x = this.options.marginLeft; this.y = this.options.marginTop; this.printHeader(); if (this.options.showPageNumber) { this.printPageNumber(); } } return printStatic; }(); _proto.newPage = function () { function newPage() { this.doc.addPage(); this.currentPage++; this.printStatic(); } return newPage; }(); _proto.printHeader = function () { function printHeader() { var _this$options = this.options, marginLeft = _this$options.marginLeft, marginRight = _this$options.marginRight, width = _this$options.width; var doc = this.doc; var y = this.y; // Print the logo strokes doc.setDrawColor(0).setLineWidth(1); doc.roundedRect(marginLeft + 0.5, y + 0.5, 8, 8, 0.5, 0.5, 'D'); doc.roundedRect(marginLeft + 11, y + 0.5, 8, 8, 0.5, 0.5, 'D'); doc.roundedRect(marginLeft + 0.5, y + 11, 8, 8, 0.5, 0.5, 'D'); doc.roundedRect(marginLeft + 11, y + 11, 8, 8, 0.5, 0.5, 'D'); // Print the logo text doc.setFont('Serif').setFontSize(16).setFontStyle('normal').setTextColor(0); doc.text('Open Health Imaging Foundation', 66, y + 14); y += 24; // Print header horizontal line doc.setDrawColor(0).setLineWidth(0.5); doc.line(marginLeft, y, width - marginRight, y); y += 1; this.y = y; } return printHeader; }(); _proto.printPageNumber = function () { function printPageNumber() { var doc = this.doc; var _this$options2 = this.options, marginBottom = _this$options2.marginBottom, marginRight = _this$options2.marginRight, width = _this$options2.width, height = _this$options2.height; doc.setFont('Verdana'); doc.setFontSize(8); doc.setFontStyle('normal'); doc.setTextColor(0); var text = "PAGE " + this.currentPage; var size = doc.getTextDimensions(text); doc.text(text, width - marginRight - size.w, height - marginBottom + size.h / 2); } return printPageNumber; }(); _proto.save = function () { function save(fileName) { this.doc.save(fileName || 'report.pdf'); } return save; }(); return BaseReport; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurement.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/reports/measurement.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); module.export({ MeasurementReport: function () { return MeasurementReport; } }); var BaseReport; module.watch(require("./base"), { BaseReport: function (v) { BaseReport = v; } }, 0); var MeasurementReport = /*#__PURE__*/ function (_BaseReport) { (0, _inheritsLoose2.default)(MeasurementReport, _BaseReport); function MeasurementReport(options) { return _BaseReport.call(this, options) || this; } var _proto = MeasurementReport.prototype; _proto.printHeader = function () { function printHeader() { _BaseReport.prototype.printHeader.call(this); var _this$options = this.options, marginLeft = _this$options.marginLeft, marginRight = _this$options.marginRight, width = _this$options.width, header = _this$options.header; var doc = this.doc; var y = this.y; // don't print the header if not given if (!header) return; // Print trial label y += 10; doc.setFont('verdana'); doc.setFontSize(8); doc.setFontStyle('bold'); doc.setTextColor(255); doc.setFillColor(16); var trialLabel = header.trial; var trialLabelWidth = doc.getTextWidth(trialLabel) + 8; doc.roundedRect(marginLeft, y, trialLabelWidth, 15, 3, 3, 'F'); doc.text(trialLabel, marginLeft + 4, y + 10.5); // Print patient information doc.setFont('verdana'); doc.setFontSize(10); doc.setFontStyle('normal'); doc.setTextColor(0); doc.text(header.patientName + "\t" + header.mrn, marginLeft + trialLabelWidth + 10, y + 11); y += 25; // Print timepoint header doc.setFillColor(229); doc.rect(marginLeft, y, width - marginLeft - marginRight, 18, 'F'); doc.setFont('verdana'); doc.setFontSize(9); doc.setFontStyle('normal'); doc.setTextColor(0); doc.text(header.timepoint.toUpperCase(), marginLeft + 4, y + 12.5); y += 18; this.y = y; } return printHeader; }(); _proto.printMeasurement = function () { function printMeasurement(measurementData) { var _this$options2 = this.options, marginLeft = _this$options2.marginLeft, marginRight = _this$options2.marginRight, marginBottom = _this$options2.marginBottom, width = _this$options2.width, height = _this$options2.height; var infoHeight = 28; var rectSize = Math.round((width - marginLeft - marginRight - 3) / 2); var doc = this.doc; var x = this.x, y = this.y; var image = measurementData.image, location = measurementData.location, info = measurementData.info; var type = measurementData.type.toUpperCase(); var number = measurementData.number.toString(); if (y + rectSize + infoHeight > height - marginBottom) { this.newPage(); x = this.x; y = this.y; } // Print the image doc.setFillColor(0); doc.rect(x, y, rectSize, rectSize, 'F'); doc.addImage(image, 'JPEG', x + 1, y + 1, rectSize - 2, rectSize - 2); y += rectSize; // Print the measurement type doc.setFont('verdana').setFontSize(10).setFontStyle('bold').setTextColor(255); var typeWidth = Math.round(doc.getTextWidth(type)); var typeX = x + rectSize - typeWidth; doc.setFillColor(64); doc.rect(typeX - 8, y - 16, typeWidth + 8, 16, 'F'); doc.text(type, typeX - 4, y - 5); // Print the measurement number doc.setFillColor(224); doc.circle(x + 9, y - 10, 7, 'F'); doc.setFont('courier').setTextColor(0); var numberHalfWidth = doc.getTextWidth(number) / 2; doc.text(number, x + 9 - numberHalfWidth, y - 7); // Print the measurement location and info doc.setFillColor(240); doc.rect(x, y, rectSize, infoHeight, 'F'); doc.setFont('verdana').setFontSize(9); doc.text(location, x + 4, y + 11); doc.setFontStyle('normal'); doc.text(info, x + 4, y + 24); y += infoHeight; if (x === marginLeft) { this.x = width - marginRight - rectSize; } else { this.x = marginLeft; this.y = y; } } return printMeasurement; }(); return MeasurementReport; }(BaseReport); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"reportMeasurementData.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/reports/reportMeasurementData.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); module.export({ getExportMeasurementData: function () { return getExportMeasurementData; } }); var moment; module.watch(require("meteor/momentjs:moment"), { moment: function (v) { moment = v; } }, 0); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 1); var getExportMeasurementData = function () { function _callee2(measurementApi, timepointApi) { var currentTimepoint, timepointId, study, studyDescription, patientId, studyDate, patientName, measurementData, addNewMeasurement, allMeasurements, iterator, measurement, current; return _regenerator.default.async(function () { function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: currentTimepoint = timepointApi.current(); timepointId = currentTimepoint.timepointId; study = OHIF.viewer.Studies.findBy({ studyInstanceUid: currentTimepoint.studyInstanceUids[0] }); studyDescription = study.studyDescription, patientId = study.patientId, studyDate = study.studyDate; patientName = OHIF.viewerbase.helpers.formatPN(study.patientName); // All headers measurementData = { patientName: patientName, mrn: patientId, studyDate: moment(studyDate).format('MMM DD YYYY'), studyDescription: studyDescription, data: [] }; addNewMeasurement = function () { function _callee(measurement) { var imageId, _cornerstone$metaData, seriesDescription, seriesDate, modality, seriesInstanceUid, meanStdDev; return _regenerator.default.async(function () { function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: imageId = OHIF.viewerbase.getImageIdForImagePath(measurement.imagePath); _cornerstone$metaData = cornerstone.metaData.get('series', imageId), seriesDescription = _cornerstone$metaData.seriesDescription, seriesDate = _cornerstone$metaData.seriesDate, modality = _cornerstone$metaData.modality, seriesInstanceUid = _cornerstone$metaData.seriesInstanceUid; meanStdDev = measurement.meanStdDev || {}; measurementData.data.push({ seriesModality: modality, seriesDate: moment(seriesDate).format('MMM DD YYYY'), seriesDescription: seriesDescription, seriesInstanceUid: seriesInstanceUid, measurementTool: measurement.toolType, measurementDescription: OHIF.measurements.getLocationLabel(measurement.location) || 'No description', number: measurement.measurementNumber, length: measurement.length || '-', mean: meanStdDev.mean || '-', stdDev: meanStdDev.stdDev || '-', area: measurement.area || '-' }); case 4: case "end": return _context.stop(); } } } return _callee$; }(), null, this); } return _callee; }(); allMeasurements = []; Object.keys(measurementApi.toolGroups).forEach(function (toolGroup) { var measurements = measurementApi.fetch(toolGroup, { timepointId: timepointId }); allMeasurements = allMeasurements.concat(measurements); }); iterator = allMeasurements[Symbol.iterator](); current = iterator.next(); case 11: if (current.done) { _context2.next = 18; break; } measurement = current.value; _context2.next = 15; return _regenerator.default.awrap(addNewMeasurement(measurement)); case 15: current = iterator.next(); _context2.next = 11; break; case 18: return _context2.abrupt("return", measurementData); case 19: case "end": return _context2.stop(); } } } return _callee2$; }(), null, this); } return _callee2; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"reportMeasurementDataToCSV.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurements/client/reports/reportMeasurementDataToCSV.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); module.export({ getCSVMeasurementData: function () { return getCSVMeasurementData; } }); var getExportMeasurementData; module.watch(require("./reportMeasurementData"), { getExportMeasurementData: function (v) { getExportMeasurementData = v; } }, 0); var columnDelimiter = ','; var lineDelimiter = '\n'; var headers = { patientName: 'Patient Name', mrn: 'MRN', studyDate: 'Study Date', seriesModality: 'Series Modality', seriesDate: 'Series Date', seriesDescription: 'Series Description', seriesInstanceUid: 'Series InstanceUid', measurementTool: 'Measurement Tool', measurementDescription: 'Measurement Description', length: 'Length', mean: 'Mean', stdDev: 'stdDev', area: 'area' }; var getCSVMeasurementData = function () { function _callee(measurementApi, timepointApi) { var lineData, csvData, dataObject, _iterator, _isArray, _i; return _regenerator.default.async(function () { function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: lineData = []; csvData = ''; _context.next = 4; return _regenerator.default.awrap(getExportMeasurementData(measurementApi, timepointApi)); case 4: dataObject = _context.sent; for (header in meteorBabelHelpers.sanitizeForInObject(headers)) { lineData.push(headers[header]); } csvData += lineData.join(columnDelimiter) + lineDelimiter; _iterator = dataObject.data, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator](); case 8: if (!_isArray) { _context.next = 14; break; } if (!(_i >= _iterator.length)) { _context.next = 11; break; } return _context.abrupt("break", 22); case 11: measurementLine = _iterator[_i++]; _context.next = 18; break; case 14: _i = _iterator.next(); if (!_i.done) { _context.next = 17; break; } return _context.abrupt("break", 22); case 17: measurementLine = _i.value; case 18: lineData = [dataObject.patientName, dataObject.mrn, dataObject.studyDate, measurementLine.seriesModality, measurementLine.seriesDate, measurementLine.seriesDescription, measurementLine.seriesInstanceUid, measurementLine.measurementTool, measurementLine.measurementDescription, measurementLine.length, measurementLine.mean, measurementLine.stdDev, measurementLine.area]; csvData += lineData.join(columnDelimiter) + lineDelimiter; case 20: _context.next = 8; break; case 22: return _context.abrupt("return", csvData); case 23: case "end": return _context.stop(); } } } return _callee$; }(), null, this); } return _callee; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"node_modules":{"ajv":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "ajv"; exports.version = "4.10.4"; exports.main = "lib/ajv.js"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"lib":{"ajv.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/ajv.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; var compileSchema = require('./compile') , resolve = require('./compile/resolve') , Cache = require('./cache') , SchemaObject = require('./compile/schema_obj') , stableStringify = require('json-stable-stringify') , formats = require('./compile/formats') , rules = require('./compile/rules') , v5 = require('./v5') , util = require('./compile/util') , async = require('./async') , co = require('co'); module.exports = Ajv; Ajv.prototype.compileAsync = async.compile; var customKeyword = require('./keyword'); Ajv.prototype.addKeyword = customKeyword.add; Ajv.prototype.getKeyword = customKeyword.get; Ajv.prototype.removeKeyword = customKeyword.remove; Ajv.ValidationError = require('./compile/validation_error'); var META_SCHEMA_ID = 'http://json-schema.org/draft-04/schema'; var SCHEMA_URI_FORMAT = /^(?:(?:[a-z][a-z0-9+-.]*:)?\/\/)?[^\s]*$/i; function SCHEMA_URI_FORMAT_FUNC(str) { return SCHEMA_URI_FORMAT.test(str); } var META_IGNORE_OPTIONS = [ 'removeAdditional', 'useDefaults', 'coerceTypes' ]; /** * Creates validator instance. * Usage: `Ajv(opts)` * @param {Object} opts optional options * @return {Object} ajv instance */ function Ajv(opts) { if (!(this instanceof Ajv)) return new Ajv(opts); var self = this; opts = this._opts = util.copy(opts) || {}; this._schemas = {}; this._refs = {}; this._fragments = {}; this._formats = formats(opts.format); this._cache = opts.cache || new Cache; this._loadingSchemas = {}; this._compilations = []; this.RULES = rules(); // this is done on purpose, so that methods are bound to the instance // (without using bind) so that they can be used without the instance this.validate = validate; this.compile = compile; this.addSchema = addSchema; this.addMetaSchema = addMetaSchema; this.validateSchema = validateSchema; this.getSchema = getSchema; this.removeSchema = removeSchema; this.addFormat = addFormat; this.errorsText = errorsText; this._addSchema = _addSchema; this._compile = _compile; opts.loopRequired = opts.loopRequired || Infinity; if (opts.async || opts.transpile) async.setup(opts); if (opts.beautify === true) opts.beautify = { indent_size: 2 }; if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true; this._metaOpts = getMetaSchemaOptions(); if (opts.formats) addInitialFormats(); addDraft4MetaSchema(); if (opts.v5) v5.enable(this); if (typeof opts.meta == 'object') addMetaSchema(opts.meta); addInitialSchemas(); /** * Validate data using schema * Schema will be compiled and cached (using serialized JSON as key. [json-stable-stringify](https://github.com/substack/json-stable-stringify) is used to serialize. * @param {String|Object} schemaKeyRef key, ref or schema object * @param {Any} data to be validated * @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`). */ function validate(schemaKeyRef, data) { var v; if (typeof schemaKeyRef == 'string') { v = getSchema(schemaKeyRef); if (!v) throw new Error('no schema with key or ref "' + schemaKeyRef + '"'); } else { var schemaObj = _addSchema(schemaKeyRef); v = schemaObj.validate || _compile(schemaObj); } var valid = v(data); if (v.$async === true) return self._opts.async == '*' ? co(valid) : valid; self.errors = v.errors; return valid; } /** * Create validating function for passed schema. * @param {Object} schema schema object * @param {Boolean} _meta true if schema is a meta-schema. Used internally to compile meta schemas of custom keywords. * @return {Function} validating function */ function compile(schema, _meta) { var schemaObj = _addSchema(schema, undefined, _meta); return schemaObj.validate || _compile(schemaObj); } /** * Adds schema to the instance. * @param {Object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored. * @param {String} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`. * @param {Boolean} _skipValidation true to skip schema validation. Used internally, option validateSchema should be used instead. * @param {Boolean} _meta true if schema is a meta-schema. Used internally, addMetaSchema should be used instead. */ function addSchema(schema, key, _skipValidation, _meta) { if (Array.isArray(schema)){ for (var i=0; i} errors optional array of validation errors, if not passed errors from the instance are used. * @param {Object} options optional options with properties `separator` and `dataVar`. * @return {String} human readable string with all errors descriptions */ function errorsText(errors, options) { errors = errors || self.errors; if (!errors) return 'No errors'; options = options || {}; var separator = options.separator === undefined ? ', ' : options.separator; var dataVar = options.dataVar === undefined ? 'data' : options.dataVar; var text = ''; for (var i=0; i= 0) return { index: index, compiling: true }; index = this._compilations.length; this._compilations[index] = { schema: schema, root: root, baseId: baseId }; return { index: index, compiling: false }; } /** * Removes the schema from the currently compiled list * @this Ajv * @param {Object} schema schema to compile * @param {Object} root root object * @param {String} baseId base schema ID */ function endCompiling(schema, root, baseId) { /* jshint validthis: true */ var i = compIndex.call(this, schema, root, baseId); if (i >= 0) this._compilations.splice(i, 1); } /** * Index of schema compilation in the currently compiled list * @this Ajv * @param {Object} schema schema to compile * @param {Object} root root object * @param {String} baseId base schema ID * @return {Integer} compilation index */ function compIndex(schema, root, baseId) { /* jshint validthis: true */ for (var i=0; i= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl); return paths[lvl - up]; } if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl); data = 'data' + ((lvl - up) || ''); if (!jsonPointer) return data; } var expr = data; var segments = jsonPointer.split('/'); for (var i=0; i= 0xD800 && value <= 0xDBFF && pos < len) { // high surrogate, and there is a next character value = str.charCodeAt(pos); if ((value & 0xFC00) == 0xDC00) pos++; // low surrogate } } return length; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"schema_obj.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/compile/schema_obj.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; var util = require('./util'); module.exports = SchemaObject; function SchemaObject(obj) { util.copy(obj, this); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"validation_error.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/compile/validation_error.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = ValidationError; function ValidationError(errors) { this.message = 'validation failed'; this.errors = errors; this.ajv = this.validation = true; } ValidationError.prototype = Object.create(Error.prototype); ValidationError.prototype.constructor = ValidationError; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"formats.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/compile/formats.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; var util = require('./util'); var DATE = /^\d\d\d\d-(\d\d)-(\d\d)$/; var DAYS = [0,31,29,31,30,31,30,31,31,30,31,30,31]; var TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d:\d\d)?$/i; var HOSTNAME = /^[0-9a-z](?:(?:[-0-9a-z]{0,61})?[0-9a-z])?(\.[0-9a-z](?:(?:[-0-9a-z]{0,61})?[0-9a-z])?)*$/i; var URI = /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*)?$/i; var UUID = /^(?:urn\:uuid\:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i; var JSON_POINTER = /^(?:\/(?:[^~\/]|~0|~1)*)*$|^\#(?:\/(?:[a-z0-9_\-\.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i; var RELATIVE_JSON_POINTER = /^(?:0|[1-9][0-9]*)(?:\#|(?:\/(?:[^~\/]|~0|~1)*)*)$/; module.exports = formats; function formats(mode) { mode = mode == 'full' ? 'full' : 'fast'; var formatDefs = util.copy(formats[mode]); for (var fName in formats.compare) { formatDefs[fName] = { validate: formatDefs[fName], compare: formats.compare[fName] }; } return formatDefs; } formats.fast = { // date: http://tools.ietf.org/html/rfc3339#section-5.6 date: /^\d\d\d\d-[0-1]\d-[0-3]\d$/, // date-time: http://tools.ietf.org/html/rfc3339#section-5.6 time: /^[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i, 'date-time': /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:z|[+-]\d\d:\d\d)$/i, // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js uri: /^(?:[a-z][a-z0-9+-.]*)?(?:\:|\/)\/?[^\s]*$/i, // email (sources from jsen validator): // http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363 // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'willful violation') email: /^[a-z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i, hostname: HOSTNAME, // optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, // optimized http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i, regex: regex, // uuid: http://tools.ietf.org/html/rfc4122 uuid: UUID, // JSON-pointer: https://tools.ietf.org/html/rfc6901 // uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A 'json-pointer': JSON_POINTER, // relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00 'relative-json-pointer': RELATIVE_JSON_POINTER }; formats.full = { date: date, time: time, 'date-time': date_time, uri: uri, email: /^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&''*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i, hostname: hostname, ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i, regex: regex, uuid: UUID, 'json-pointer': JSON_POINTER, 'relative-json-pointer': RELATIVE_JSON_POINTER }; formats.compare = { date: compareDate, time: compareTime, 'date-time': compareDateTime }; function date(str) { // full-date from http://tools.ietf.org/html/rfc3339#section-5.6 var matches = str.match(DATE); if (!matches) return false; var month = +matches[1]; var day = +matches[2]; return month >= 1 && month <= 12 && day >= 1 && day <= DAYS[month]; } function time(str, full) { var matches = str.match(TIME); if (!matches) return false; var hour = matches[1]; var minute = matches[2]; var second = matches[3]; var timeZone = matches[5]; return hour <= 23 && minute <= 59 && second <= 59 && (!full || timeZone); } var DATE_TIME_SEPARATOR = /t|\s/i; function date_time(str) { // http://tools.ietf.org/html/rfc3339#section-5.6 var dateTime = str.split(DATE_TIME_SEPARATOR); return dateTime.length == 2 && date(dateTime[0]) && time(dateTime[1], true); } function hostname(str) { // https://tools.ietf.org/html/rfc1034#section-3.5 // https://tools.ietf.org/html/rfc1123#section-2 return str.length <= 255 && HOSTNAME.test(str); } var NOT_URI_FRAGMENT = /\/|\:/; function uri(str) { // http://jmrware.com/articles/2009/uri_regexp/URI_regex.html + optional protocol + required "." return NOT_URI_FRAGMENT.test(str) && URI.test(str); } function regex(str) { try { new RegExp(str); return true; } catch(e) { return false; } } function compareDate(d1, d2) { if (!(d1 && d2)) return; if (d1 > d2) return 1; if (d1 < d2) return -1; if (d1 === d2) return 0; } function compareTime(t1, t2) { if (!(t1 && t2)) return; t1 = t1.match(TIME); t2 = t2.match(TIME); if (!(t1 && t2)) return; t1 = t1[1] + t1[2] + t1[3] + (t1[4]||''); t2 = t2[1] + t2[2] + t2[3] + (t2[4]||''); if (t1 > t2) return 1; if (t1 < t2) return -1; if (t1 === t2) return 0; } function compareDateTime(dt1, dt2) { if (!(dt1 && dt2)) return; dt1 = dt1.split(DATE_TIME_SEPARATOR); dt2 = dt2.split(DATE_TIME_SEPARATOR); var res = compareDate(dt1[0], dt2[0]); if (res === undefined) return; return res || compareTime(dt1[1], dt2[1]); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"rules.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/compile/rules.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; var ruleModules = require('./_rules') , toHash = require('./util').toHash; module.exports = function rules() { var RULES = [ { type: 'number', rules: [ 'maximum', 'minimum', 'multipleOf'] }, { type: 'string', rules: [ 'maxLength', 'minLength', 'pattern', 'format' ] }, { type: 'array', rules: [ 'maxItems', 'minItems', 'uniqueItems', 'items' ] }, { type: 'object', rules: [ 'maxProperties', 'minProperties', 'required', 'dependencies', 'properties' ] }, { rules: [ '$ref', 'enum', 'not', 'anyOf', 'oneOf', 'allOf' ] } ]; var ALL = [ 'type', 'additionalProperties', 'patternProperties' ]; var KEYWORDS = [ 'additionalItems', '$schema', 'id', 'title', 'description', 'default' ]; var TYPES = [ 'number', 'integer', 'string', 'array', 'object', 'boolean', 'null' ]; RULES.all = toHash(ALL); RULES.forEach(function (group) { group.rules = group.rules.map(function (keyword) { ALL.push(keyword); var rule = RULES.all[keyword] = { keyword: keyword, code: ruleModules[keyword] }; return rule; }); }); RULES.keywords = toHash(ALL.concat(KEYWORDS)); RULES.types = toHash(TYPES); RULES.custom = {}; return RULES; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"_rules.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/compile/_rules.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; //all requires must be explicit because browserify won't work with dynamic requires module.exports = { '$ref': require('../dotjs/ref'), allOf: require('../dotjs/allOf'), anyOf: require('../dotjs/anyOf'), dependencies: require('../dotjs/dependencies'), 'enum': require('../dotjs/enum'), format: require('../dotjs/format'), items: require('../dotjs/items'), maximum: require('../dotjs/_limit'), minimum: require('../dotjs/_limit'), maxItems: require('../dotjs/_limitItems'), minItems: require('../dotjs/_limitItems'), maxLength: require('../dotjs/_limitLength'), minLength: require('../dotjs/_limitLength'), maxProperties: require('../dotjs/_limitProperties'), minProperties: require('../dotjs/_limitProperties'), multipleOf: require('../dotjs/multipleOf'), not: require('../dotjs/not'), oneOf: require('../dotjs/oneOf'), pattern: require('../dotjs/pattern'), properties: require('../dotjs/properties'), required: require('../dotjs/required'), uniqueItems: require('../dotjs/uniqueItems'), validate: require('../dotjs/validate') }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"async.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/async.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = { setup: setupAsync, compile: compileAsync }; var util = require('./compile/util'); var ASYNC = { '*': checkGenerators, 'co*': checkGenerators, 'es7': checkAsyncFunction }; var TRANSPILE = { 'nodent': getNodent, 'regenerator': getRegenerator }; var MODES = [ { async: 'co*' }, { async: 'es7', transpile: 'nodent' }, { async: 'co*', transpile: 'regenerator' } ]; var regenerator, nodent; function setupAsync(opts, required) { if (required !== false) required = true; var async = opts.async , transpile = opts.transpile , check; switch (typeof transpile) { case 'string': var get = TRANSPILE[transpile]; if (!get) throw new Error('bad transpiler: ' + transpile); return (opts._transpileFunc = get(opts, required)); case 'undefined': case 'boolean': if (typeof async == 'string') { check = ASYNC[async]; if (!check) throw new Error('bad async mode: ' + async); return (opts.transpile = check(opts, required)); } for (var i=0; i ' + ($i) + ') { '; var $passData = $data + '[' + $i + ']'; $it.schema = $sch; $it.schemaPath = $schemaPath + '[' + $i + ']'; $it.errSchemaPath = $errSchemaPath + '/' + $i; $it.errorPath = it.util.getPathExpr(it.errorPath, $i, it.opts.jsonPointers, true); $it.dataPathArr[$dataNxt] = $i; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } if (typeof $additionalItems == 'object' && it.util.schemaHasRules($additionalItems, it.RULES.all)) { $it.schema = $additionalItems; $it.schemaPath = it.schemaPath + '.additionalItems'; $it.errSchemaPath = it.errSchemaPath + '/additionalItems'; out += ' ' + ($nextValid) + ' = true; if (' + ($data) + '.length > ' + ($schema.length) + ') { for (var ' + ($idx) + ' = ' + ($schema.length) + '; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); var $passData = $data + '[' + $idx + ']'; $it.dataPathArr[$dataNxt] = $idx; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' } } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } else if (it.util.schemaHasRules($schema, it.RULES.all)) { $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; out += ' for (var ' + ($idx) + ' = ' + (0) + '; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); var $passData = $data + '[' + $idx + ']'; $it.dataPathArr[$dataNxt] = $idx; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } if ($breakOnError) { out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; } out = it.util.cleanUpCode(out); return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"_limit.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/_limit.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate__limit(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $isMax = $keyword == 'maximum', $exclusiveKeyword = $isMax ? 'exclusiveMaximum' : 'exclusiveMinimum', $schemaExcl = it.schema[$exclusiveKeyword], $isDataExcl = it.opts.v5 && $schemaExcl && $schemaExcl.$data, $op = $isMax ? '<' : '>', $notOp = $isMax ? '>' : '<'; if ($isDataExcl) { var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr), $exclusive = 'exclusive' + $lvl, $opExpr = 'op' + $lvl, $opStr = '\' + ' + $opExpr + ' + \''; out += ' var schemaExcl' + ($lvl) + ' = ' + ($schemaValueExcl) + '; '; $schemaValueExcl = 'schemaExcl' + $lvl; out += ' var exclusive' + ($lvl) + '; if (typeof ' + ($schemaValueExcl) + ' != \'boolean\' && typeof ' + ($schemaValueExcl) + ' != \'undefined\') { '; var $errorKeyword = $exclusiveKeyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_exclusiveLimit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'' + ($exclusiveKeyword) + ' should be boolean\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else if( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ((exclusive' + ($lvl) + ' = ' + ($schemaValueExcl) + ' === true) ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValue) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ') || ' + ($data) + ' !== ' + ($data) + ') { var op' + ($lvl) + ' = exclusive' + ($lvl) + ' ? \'' + ($op) + '\' : \'' + ($op) + '=\';'; } else { var $exclusive = $schemaExcl === true, $opStr = $op; if (!$exclusive) $opStr += '='; var $opExpr = '\'' + $opStr + '\''; out += ' if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ' + ($data) + ' ' + ($notOp); if ($exclusive) { out += '='; } out += ' ' + ($schemaValue) + ' || ' + ($data) + ' !== ' + ($data) + ') {'; } var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { comparison: ' + ($opExpr) + ', limit: ' + ($schemaValue) + ', exclusive: ' + ($exclusive) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be ' + ($opStr) + ' '; if ($isData) { out += '\' + ' + ($schemaValue); } else { out += '' + ($schema) + '\''; } } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($breakOnError) { out += ' else { '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"_limitItems.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/_limitItems.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate__limitItems(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $op = $keyword == 'maxItems' ? '>' : '<'; out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' ' + ($data) + '.length ' + ($op) + ' ' + ($schemaValue) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limitItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have '; if ($keyword == 'maxItems') { out += 'more'; } else { out += 'less'; } out += ' than '; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + ($schema); } out += ' items\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"_limitLength.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/_limitLength.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate__limitLength(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $op = $keyword == 'maxLength' ? '>' : '<'; out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } if (it.opts.unicode === false) { out += ' ' + ($data) + '.length '; } else { out += ' ucs2length(' + ($data) + ') '; } out += ' ' + ($op) + ' ' + ($schemaValue) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limitLength') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT be '; if ($keyword == 'maxLength') { out += 'longer'; } else { out += 'shorter'; } out += ' than '; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + ($schema); } out += ' characters\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"_limitProperties.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/_limitProperties.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate__limitProperties(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $op = $keyword == 'maxProperties' ? '>' : '<'; out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; } out += ' Object.keys(' + ($data) + ').length ' + ($op) + ' ' + ($schemaValue) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_limitProperties') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have '; if ($keyword == 'maxProperties') { out += 'more'; } else { out += 'less'; } out += ' than '; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + ($schema); } out += ' properties\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"multipleOf.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/multipleOf.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_multipleOf(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } out += 'var division' + ($lvl) + ';if ('; if ($isData) { out += ' ' + ($schemaValue) + ' !== undefined && ( typeof ' + ($schemaValue) + ' != \'number\' || '; } out += ' (division' + ($lvl) + ' = ' + ($data) + ' / ' + ($schemaValue) + ', '; if (it.opts.multipleOfPrecision) { out += ' Math.abs(Math.round(division' + ($lvl) + ') - division' + ($lvl) + ') > 1e-' + (it.opts.multipleOfPrecision) + ' '; } else { out += ' division' + ($lvl) + ' !== parseInt(division' + ($lvl) + ') '; } out += ' ) '; if ($isData) { out += ' ) '; } out += ' ) { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'multipleOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { multipleOf: ' + ($schemaValue) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be multiple of '; if ($isData) { out += '\' + ' + ($schemaValue); } else { out += '' + ($schema) + '\''; } } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"not.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/not.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_not(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); $it.level++; var $nextValid = 'valid' + $it.level; if (it.util.schemaHasRules($schema, it.RULES.all)) { $it.schema = $schema; $it.schemaPath = $schemaPath; $it.errSchemaPath = $errSchemaPath; out += ' var ' + ($errs) + ' = errors; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; $it.createErrors = false; var $allErrorsOption; if ($it.opts.allErrors) { $allErrorsOption = $it.opts.allErrors; $it.opts.allErrors = false; } out += ' ' + (it.validate($it)) + ' '; $it.createErrors = true; if ($allErrorsOption) $it.opts.allErrors = $allErrorsOption; it.compositeRule = $it.compositeRule = $wasComposite; out += ' if (' + ($nextValid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'not') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should NOT be valid\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; if (it.opts.allErrors) { out += ' } '; } } else { out += ' var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'not') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should NOT be valid\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; if ($breakOnError) { out += ' if (false) { '; } } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"oneOf.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/oneOf.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_oneOf(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; out += 'var ' + ($errs) + ' = errors;var prevValid' + ($lvl) + ' = false;var ' + ($valid) + ' = false;'; var $currentBaseId = $it.baseId; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; var arr1 = $schema; if (arr1) { var $sch, $i = -1, l1 = arr1.length - 1; while ($i < l1) { $sch = arr1[$i += 1]; if (it.util.schemaHasRules($sch, it.RULES.all)) { $it.schema = $sch; $it.schemaPath = $schemaPath + '[' + $i + ']'; $it.errSchemaPath = $errSchemaPath + '/' + $i; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; } else { out += ' var ' + ($nextValid) + ' = true; '; } if ($i) { out += ' if (' + ($nextValid) + ' && prevValid' + ($lvl) + ') ' + ($valid) + ' = false; else { '; $closingBraces += '}'; } out += ' if (' + ($nextValid) + ') ' + ($valid) + ' = prevValid' + ($lvl) + ' = true;'; } } it.compositeRule = $it.compositeRule = $wasComposite; out += '' + ($closingBraces) + 'if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'oneOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should match exactly one schema in oneOf\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; }'; if (it.opts.allErrors) { out += ' } '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"pattern.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/pattern.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_pattern(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $regexp = $isData ? '(new RegExp(' + $schemaValue + '))' : it.usePattern($schema); out += 'if ( '; if ($isData) { out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || '; } out += ' !' + ($regexp) + '.test(' + ($data) + ') ) { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'pattern') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { pattern: '; if ($isData) { out += '' + ($schemaValue); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' } '; if (it.opts.messages !== false) { out += ' , message: \'should match pattern "'; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + (it.util.escapeQuotes($schema)); } out += '"\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '} '; if ($breakOnError) { out += ' else { '; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"properties.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/properties.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_properties(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $key = 'key' + $lvl, $dataNxt = $it.dataLevel = it.dataLevel + 1, $nextData = 'data' + $dataNxt; var $schemaKeys = Object.keys($schema || {}), $pProperties = it.schema.patternProperties || {}, $pPropertyKeys = Object.keys($pProperties), $aProperties = it.schema.additionalProperties, $someProperties = $schemaKeys.length || $pPropertyKeys.length, $noAdditional = $aProperties === false, $additionalIsSchema = typeof $aProperties == 'object' && Object.keys($aProperties).length, $removeAdditional = it.opts.removeAdditional, $checkAdditional = $noAdditional || $additionalIsSchema || $removeAdditional, $ownProperties = it.opts.ownProperties, $currentBaseId = it.baseId; var $required = it.schema.required; if ($required && !(it.opts.v5 && $required.$data) && $required.length < it.opts.loopRequired) var $requiredHash = it.util.toHash($required); if (it.opts.v5) { var $pgProperties = it.schema.patternGroups || {}, $pgPropertyKeys = Object.keys($pgProperties); } out += 'var ' + ($errs) + ' = errors;var ' + ($nextValid) + ' = true;'; if ($checkAdditional) { out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; if ($ownProperties) { out += ' if (!Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($key) + ')) continue; '; } if ($someProperties) { out += ' var isAdditional' + ($lvl) + ' = !(false '; if ($schemaKeys.length) { if ($schemaKeys.length > 5) { out += ' || validate.schema' + ($schemaPath) + '[' + ($key) + '] '; } else { var arr1 = $schemaKeys; if (arr1) { var $propertyKey, i1 = -1, l1 = arr1.length - 1; while (i1 < l1) { $propertyKey = arr1[i1 += 1]; out += ' || ' + ($key) + ' == ' + (it.util.toQuotedString($propertyKey)) + ' '; } } } } if ($pPropertyKeys.length) { var arr2 = $pPropertyKeys; if (arr2) { var $pProperty, $i = -1, l2 = arr2.length - 1; while ($i < l2) { $pProperty = arr2[$i += 1]; out += ' || ' + (it.usePattern($pProperty)) + '.test(' + ($key) + ') '; } } } if (it.opts.v5 && $pgPropertyKeys && $pgPropertyKeys.length) { var arr3 = $pgPropertyKeys; if (arr3) { var $pgProperty, $i = -1, l3 = arr3.length - 1; while ($i < l3) { $pgProperty = arr3[$i += 1]; out += ' || ' + (it.usePattern($pgProperty)) + '.test(' + ($key) + ') '; } } } out += ' ); if (isAdditional' + ($lvl) + ') { '; } if ($removeAdditional == 'all') { out += ' delete ' + ($data) + '[' + ($key) + ']; '; } else { var $currentErrorPath = it.errorPath; var $additionalProperty = '\' + ' + $key + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); } if ($noAdditional) { if ($removeAdditional) { out += ' delete ' + ($data) + '[' + ($key) + ']; '; } else { out += ' ' + ($nextValid) + ' = false; '; var $currErrSchemaPath = $errSchemaPath; $errSchemaPath = it.errSchemaPath + '/additionalProperties'; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'additionalProperties') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { additionalProperty: \'' + ($additionalProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have additional properties\' '; } if (it.opts.verbose) { out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } $errSchemaPath = $currErrSchemaPath; if ($breakOnError) { out += ' break; '; } } } else if ($additionalIsSchema) { if ($removeAdditional == 'failing') { out += ' var ' + ($errs) + ' = errors; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; $it.schema = $aProperties; $it.schemaPath = it.schemaPath + '.additionalProperties'; $it.errSchemaPath = it.errSchemaPath + '/additionalProperties'; $it.errorPath = it.opts._errorDataPathProperty ? it.errorPath : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } out += ' if (!' + ($nextValid) + ') { errors = ' + ($errs) + '; if (validate.errors !== null) { if (errors) validate.errors.length = errors; else validate.errors = null; } delete ' + ($data) + '[' + ($key) + ']; } '; it.compositeRule = $it.compositeRule = $wasComposite; } else { $it.schema = $aProperties; $it.schemaPath = it.schemaPath + '.additionalProperties'; $it.errSchemaPath = it.errSchemaPath + '/additionalProperties'; $it.errorPath = it.opts._errorDataPathProperty ? it.errorPath : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } } } it.errorPath = $currentErrorPath; } if ($someProperties) { out += ' } '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } var $useDefaults = it.opts.useDefaults && !it.compositeRule; if ($schemaKeys.length) { var arr4 = $schemaKeys; if (arr4) { var $propertyKey, i4 = -1, l4 = arr4.length - 1; while (i4 < l4) { $propertyKey = arr4[i4 += 1]; var $sch = $schema[$propertyKey]; if (it.util.schemaHasRules($sch, it.RULES.all)) { var $prop = it.util.getProperty($propertyKey), $passData = $data + $prop, $hasDefault = $useDefaults && $sch.default !== undefined; $it.schema = $sch; $it.schemaPath = $schemaPath + $prop; $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($propertyKey); $it.errorPath = it.util.getPath(it.errorPath, $propertyKey, it.opts.jsonPointers); $it.dataPathArr[$dataNxt] = it.util.toQuotedString($propertyKey); var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { $code = it.util.varReplace($code, $nextData, $passData); var $useData = $passData; } else { var $useData = $nextData; out += ' var ' + ($nextData) + ' = ' + ($passData) + '; '; } if ($hasDefault) { out += ' ' + ($code) + ' '; } else { if ($requiredHash && $requiredHash[$propertyKey]) { out += ' if (' + ($useData) + ' === undefined) { ' + ($nextValid) + ' = false; '; var $currentErrorPath = it.errorPath, $currErrSchemaPath = $errSchemaPath, $missingProperty = it.util.escapeQuotes($propertyKey); if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers); } $errSchemaPath = it.errSchemaPath + '/required'; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } $errSchemaPath = $currErrSchemaPath; it.errorPath = $currentErrorPath; out += ' } else { '; } else { if ($breakOnError) { out += ' if (' + ($useData) + ' === undefined) { ' + ($nextValid) + ' = true; } else { '; } else { out += ' if (' + ($useData) + ' !== undefined) { '; } } out += ' ' + ($code) + ' } '; } } if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } var arr5 = $pPropertyKeys; if (arr5) { var $pProperty, i5 = -1, l5 = arr5.length - 1; while (i5 < l5) { $pProperty = arr5[i5 += 1]; var $sch = $pProperties[$pProperty]; if (it.util.schemaHasRules($sch, it.RULES.all)) { $it.schema = $sch; $it.schemaPath = it.schemaPath + '.patternProperties' + it.util.getProperty($pProperty); $it.errSchemaPath = it.errSchemaPath + '/patternProperties/' + it.util.escapeFragment($pProperty); out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; if ($ownProperties) { out += ' if (!Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($key) + ')) continue; '; } out += ' if (' + (it.usePattern($pProperty)) + '.test(' + ($key) + ')) { '; $it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' } '; if ($breakOnError) { out += ' else ' + ($nextValid) + ' = true; '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } } } } if (it.opts.v5) { var arr6 = $pgPropertyKeys; if (arr6) { var $pgProperty, i6 = -1, l6 = arr6.length - 1; while (i6 < l6) { $pgProperty = arr6[i6 += 1]; var $pgSchema = $pgProperties[$pgProperty], $sch = $pgSchema.schema; if (it.util.schemaHasRules($sch, it.RULES.all)) { $it.schema = $sch; $it.schemaPath = it.schemaPath + '.patternGroups' + it.util.getProperty($pgProperty) + '.schema'; $it.errSchemaPath = it.errSchemaPath + '/patternGroups/' + it.util.escapeFragment($pgProperty) + '/schema'; out += ' var pgPropCount' + ($lvl) + ' = 0; for (var ' + ($key) + ' in ' + ($data) + ') { '; if ($ownProperties) { out += ' if (!Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($key) + ')) continue; '; } out += ' if (' + (it.usePattern($pgProperty)) + '.test(' + ($key) + ')) { pgPropCount' + ($lvl) + '++; '; $it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); var $passData = $data + '[' + $key + ']'; $it.dataPathArr[$dataNxt] = $key; var $code = it.validate($it); $it.baseId = $currentBaseId; if (it.util.varOccurences($code, $nextData) < 2) { out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; } else { out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; } if ($breakOnError) { out += ' if (!' + ($nextValid) + ') break; '; } out += ' } '; if ($breakOnError) { out += ' else ' + ($nextValid) + ' = true; '; } out += ' } '; if ($breakOnError) { out += ' if (' + ($nextValid) + ') { '; $closingBraces += '}'; } var $pgMin = $pgSchema.minimum, $pgMax = $pgSchema.maximum; if ($pgMin !== undefined || $pgMax !== undefined) { out += ' var ' + ($valid) + ' = true; '; var $currErrSchemaPath = $errSchemaPath; if ($pgMin !== undefined) { var $limit = $pgMin, $reason = 'minimum', $moreOrLess = 'less'; out += ' ' + ($valid) + ' = pgPropCount' + ($lvl) + ' >= ' + ($pgMin) + '; '; $errSchemaPath = it.errSchemaPath + '/patternGroups/minimum'; out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'patternGroups') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { reason: \'' + ($reason) + '\', limit: ' + ($limit) + ', pattern: \'' + (it.util.escapeQuotes($pgProperty)) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have ' + ($moreOrLess) + ' than ' + ($limit) + ' properties matching pattern "' + (it.util.escapeQuotes($pgProperty)) + '"\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($pgMax !== undefined) { out += ' else '; } } if ($pgMax !== undefined) { var $limit = $pgMax, $reason = 'maximum', $moreOrLess = 'more'; out += ' ' + ($valid) + ' = pgPropCount' + ($lvl) + ' <= ' + ($pgMax) + '; '; $errSchemaPath = it.errSchemaPath + '/patternGroups/maximum'; out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'patternGroups') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { reason: \'' + ($reason) + '\', limit: ' + ($limit) + ', pattern: \'' + (it.util.escapeQuotes($pgProperty)) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have ' + ($moreOrLess) + ' than ' + ($limit) + ' properties matching pattern "' + (it.util.escapeQuotes($pgProperty)) + '"\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; } $errSchemaPath = $currErrSchemaPath; if ($breakOnError) { out += ' if (' + ($valid) + ') { '; $closingBraces += '}'; } } } } } } if ($breakOnError) { out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; } out = it.util.cleanUpCode(out); return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"required.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/required.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_required(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $vSchema = 'schema' + $lvl; if (!$isData) { if ($schema.length < it.opts.loopRequired && it.schema.properties && Object.keys(it.schema.properties).length) { var $required = []; var arr1 = $schema; if (arr1) { var $property, i1 = -1, l1 = arr1.length - 1; while (i1 < l1) { $property = arr1[i1 += 1]; var $propertySch = it.schema.properties[$property]; if (!($propertySch && it.util.schemaHasRules($propertySch, it.RULES.all))) { $required[$required.length] = $property; } } } } else { var $required = $schema; } } if ($isData || $required.length) { var $currentErrorPath = it.errorPath, $loopRequired = $isData || $required.length >= it.opts.loopRequired; if ($breakOnError) { out += ' var missing' + ($lvl) + '; '; if ($loopRequired) { if (!$isData) { out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; '; } var $i = 'i' + $lvl, $propertyPath = 'schema' + $lvl + '[' + $i + ']', $missingProperty = '\' + ' + $propertyPath + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers); } out += ' var ' + ($valid) + ' = true; '; if ($isData) { out += ' if (schema' + ($lvl) + ' === undefined) ' + ($valid) + ' = true; else if (!Array.isArray(schema' + ($lvl) + ')) ' + ($valid) + ' = false; else {'; } out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { ' + ($valid) + ' = ' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] !== undefined; if (!' + ($valid) + ') break; } '; if ($isData) { out += ' } '; } out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { '; } else { out += ' if ( '; var arr2 = $required; if (arr2) { var _$property, $i = -1, l2 = arr2.length - 1; while ($i < l2) { _$property = arr2[$i += 1]; if ($i) { out += ' || '; } var $prop = it.util.getProperty(_$property); out += ' ( ' + ($data) + ($prop) + ' === undefined && (missing' + ($lvl) + ' = ' + (it.util.toQuotedString(it.opts.jsonPointers ? _$property : $prop)) + ') ) '; } } out += ') { '; var $propertyPath = 'missing' + $lvl, $missingProperty = '\' + ' + $propertyPath + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.opts.jsonPointers ? it.util.getPathExpr($currentErrorPath, $propertyPath, true) : $currentErrorPath + ' + ' + $propertyPath; } var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } else { '; } } else { if ($loopRequired) { if (!$isData) { out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; '; } var $i = 'i' + $lvl, $propertyPath = 'schema' + $lvl + '[' + $i + ']', $missingProperty = '\' + ' + $propertyPath + ' + \''; if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers); } if ($isData) { out += ' if (' + ($vSchema) + ' && !Array.isArray(' + ($vSchema) + ')) { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else if (' + ($vSchema) + ' !== undefined) { '; } out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { if (' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] === undefined) { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } '; if ($isData) { out += ' } '; } } else { var arr3 = $required; if (arr3) { var $reqProperty, i3 = -1, l3 = arr3.length - 1; while (i3 < l3) { $reqProperty = arr3[i3 += 1]; var $prop = it.util.getProperty($reqProperty), $missingProperty = it.util.escapeQuotes($reqProperty); if (it.opts._errorDataPathProperty) { it.errorPath = it.util.getPath($currentErrorPath, $reqProperty, it.opts.jsonPointers); } out += ' if (' + ($data) + ($prop) + ' === undefined) { var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \''; if (it.opts._errorDataPathProperty) { out += 'is a required property'; } else { out += 'should have required property \\\'' + ($missingProperty) + '\\\''; } out += '\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } '; } } } } it.errorPath = $currentErrorPath; } else if ($breakOnError) { out += ' if (true) {'; } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"uniqueItems.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/uniqueItems.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_uniqueItems(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } if (($schema || $isData) && it.opts.uniqueItems !== false) { if ($isData) { out += ' var ' + ($valid) + '; if (' + ($schemaValue) + ' === false || ' + ($schemaValue) + ' === undefined) ' + ($valid) + ' = true; else if (typeof ' + ($schemaValue) + ' != \'boolean\') ' + ($valid) + ' = false; else { '; } out += ' var ' + ($valid) + ' = true; if (' + ($data) + '.length > 1) { var i = ' + ($data) + '.length, j; outer: for (;i--;) { for (j = i; j--;) { if (equal(' + ($data) + '[i], ' + ($data) + '[j])) { ' + ($valid) + ' = false; break outer; } } } } '; if ($isData) { out += ' } '; } out += ' if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'uniqueItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { i: i, j: j } '; if (it.opts.messages !== false) { out += ' , message: \'should NOT have duplicate items (items ## \' + j + \' and \' + i + \' are identical)\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + ($schema); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($breakOnError) { out += ' else { '; } } else { if ($breakOnError) { out += ' if (true) { '; } } return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"switch.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/switch.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_switch(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $errs = 'errs__' + $lvl; var $it = it.util.copy(it); var $closingBraces = ''; $it.level++; var $nextValid = 'valid' + $it.level; var $ifPassed = 'ifPassed' + it.level, $currentBaseId = $it.baseId, $shouldContinue; out += 'var ' + ($ifPassed) + ';'; var arr1 = $schema; if (arr1) { var $sch, $caseIndex = -1, l1 = arr1.length - 1; while ($caseIndex < l1) { $sch = arr1[$caseIndex += 1]; if ($caseIndex && !$shouldContinue) { out += ' if (!' + ($ifPassed) + ') { '; $closingBraces += '}'; } if ($sch.if && it.util.schemaHasRules($sch.if, it.RULES.all)) { out += ' var ' + ($errs) + ' = errors; '; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; $it.createErrors = false; $it.schema = $sch.if; $it.schemaPath = $schemaPath + '[' + $caseIndex + '].if'; $it.errSchemaPath = $errSchemaPath + '/' + $caseIndex + '/if'; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; $it.createErrors = true; it.compositeRule = $it.compositeRule = $wasComposite; out += ' ' + ($ifPassed) + ' = ' + ($nextValid) + '; if (' + ($ifPassed) + ') { '; if (typeof $sch.then == 'boolean') { if ($sch.then === false) { var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'switch') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { caseIndex: ' + ($caseIndex) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should pass "switch" keyword validation\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } } out += ' var ' + ($nextValid) + ' = ' + ($sch.then) + '; '; } else { $it.schema = $sch.then; $it.schemaPath = $schemaPath + '[' + $caseIndex + '].then'; $it.errSchemaPath = $errSchemaPath + '/' + $caseIndex + '/then'; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; } out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } } '; } else { out += ' ' + ($ifPassed) + ' = true; '; if (typeof $sch.then == 'boolean') { if ($sch.then === false) { var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'switch') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { caseIndex: ' + ($caseIndex) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should pass "switch" keyword validation\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } } out += ' var ' + ($nextValid) + ' = ' + ($sch.then) + '; '; } else { $it.schema = $sch.then; $it.schemaPath = $schemaPath + '[' + $caseIndex + '].then'; $it.errSchemaPath = $errSchemaPath + '/' + $caseIndex + '/then'; out += ' ' + (it.validate($it)) + ' '; $it.baseId = $currentBaseId; } } $shouldContinue = $sch.continue } } out += '' + ($closingBraces) + 'var ' + ($valid) + ' = ' + ($nextValid) + '; '; out = it.util.cleanUpCode(out); return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"constant.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/constant.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_constant(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } if (!$isData) { out += ' var schema' + ($lvl) + ' = validate.schema' + ($schemaPath) + ';'; } out += 'var ' + ($valid) + ' = equal(' + ($data) + ', schema' + ($lvl) + '); if (!' + ($valid) + ') { '; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'constant') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'should be equal to constant\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' }'; return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"_formatLimit.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/_formatLimit.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate__formatLimit(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; out += 'var ' + ($valid) + ' = undefined;'; if (it.opts.format === false) { out += ' ' + ($valid) + ' = true; '; return out; } var $schemaFormat = it.schema.format, $isDataFormat = it.opts.v5 && $schemaFormat.$data, $closingBraces = ''; if ($isDataFormat) { var $schemaValueFormat = it.util.getData($schemaFormat.$data, $dataLvl, it.dataPathArr), $format = 'format' + $lvl, $compare = 'compare' + $lvl; out += ' var ' + ($format) + ' = formats[' + ($schemaValueFormat) + '] , ' + ($compare) + ' = ' + ($format) + ' && ' + ($format) + '.compare;'; } else { var $format = it.formats[$schemaFormat]; if (!($format && $format.compare)) { out += ' ' + ($valid) + ' = true; '; return out; } var $compare = 'formats' + it.util.getProperty($schemaFormat) + '.compare'; } var $isMax = $keyword == 'formatMaximum', $exclusiveKeyword = 'formatExclusive' + ($isMax ? 'Maximum' : 'Minimum'), $schemaExcl = it.schema[$exclusiveKeyword], $isDataExcl = it.opts.v5 && $schemaExcl && $schemaExcl.$data, $op = $isMax ? '<' : '>', $result = 'result' + $lvl; var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } if ($isDataExcl) { var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr), $exclusive = 'exclusive' + $lvl, $opExpr = 'op' + $lvl, $opStr = '\' + ' + $opExpr + ' + \''; out += ' var schemaExcl' + ($lvl) + ' = ' + ($schemaValueExcl) + '; '; $schemaValueExcl = 'schemaExcl' + $lvl; out += ' if (typeof ' + ($schemaValueExcl) + ' != \'boolean\' && ' + ($schemaValueExcl) + ' !== undefined) { ' + ($valid) + ' = false; '; var $errorKeyword = $exclusiveKeyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_formatExclusiveLimit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; if (it.opts.messages !== false) { out += ' , message: \'' + ($exclusiveKeyword) + ' should be boolean\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += ' } '; if ($breakOnError) { $closingBraces += '}'; out += ' else { '; } if ($isData) { out += ' if (' + ($schemaValue) + ' === undefined) ' + ($valid) + ' = true; else if (typeof ' + ($schemaValue) + ' != \'string\') ' + ($valid) + ' = false; else { '; $closingBraces += '}'; } if ($isDataFormat) { out += ' if (!' + ($compare) + ') ' + ($valid) + ' = true; else { '; $closingBraces += '}'; } out += ' var ' + ($result) + ' = ' + ($compare) + '(' + ($data) + ', '; if ($isData) { out += '' + ($schemaValue); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' ); if (' + ($result) + ' === undefined) ' + ($valid) + ' = false; var ' + ($exclusive) + ' = ' + ($schemaValueExcl) + ' === true; if (' + ($valid) + ' === undefined) { ' + ($valid) + ' = ' + ($exclusive) + ' ? ' + ($result) + ' ' + ($op) + ' 0 : ' + ($result) + ' ' + ($op) + '= 0; } if (!' + ($valid) + ') var op' + ($lvl) + ' = ' + ($exclusive) + ' ? \'' + ($op) + '\' : \'' + ($op) + '=\';'; } else { var $exclusive = $schemaExcl === true, $opStr = $op; if (!$exclusive) $opStr += '='; var $opExpr = '\'' + $opStr + '\''; if ($isData) { out += ' if (' + ($schemaValue) + ' === undefined) ' + ($valid) + ' = true; else if (typeof ' + ($schemaValue) + ' != \'string\') ' + ($valid) + ' = false; else { '; $closingBraces += '}'; } if ($isDataFormat) { out += ' if (!' + ($compare) + ') ' + ($valid) + ' = true; else { '; $closingBraces += '}'; } out += ' var ' + ($result) + ' = ' + ($compare) + '(' + ($data) + ', '; if ($isData) { out += '' + ($schemaValue); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' ); if (' + ($result) + ' === undefined) ' + ($valid) + ' = false; if (' + ($valid) + ' === undefined) ' + ($valid) + ' = ' + ($result) + ' ' + ($op); if (!$exclusive) { out += '='; } out += ' 0;'; } out += '' + ($closingBraces) + 'if (!' + ($valid) + ') { '; var $errorKeyword = $keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || '_formatLimit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { comparison: ' + ($opExpr) + ', limit: '; if ($isData) { out += '' + ($schemaValue); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' , exclusive: ' + ($exclusive) + ' } '; if (it.opts.messages !== false) { out += ' , message: \'should be ' + ($opStr) + ' "'; if ($isData) { out += '\' + ' + ($schemaValue) + ' + \''; } else { out += '' + (it.util.escapeQuotes($schema)); } out += '"\' '; } if (it.opts.verbose) { out += ' , schema: '; if ($isData) { out += 'validate.schema' + ($schemaPath); } else { out += '' + (it.util.toQuotedString($schema)); } out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } out += '}'; return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"patternRequired.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/patternRequired.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_patternRequired(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $valid = 'valid' + $lvl; var $key = 'key' + $lvl, $matched = 'patternMatched' + $lvl, $closingBraces = '', $ownProperties = it.opts.ownProperties; out += 'var ' + ($valid) + ' = true;'; var arr1 = $schema; if (arr1) { var $pProperty, i1 = -1, l1 = arr1.length - 1; while (i1 < l1) { $pProperty = arr1[i1 += 1]; out += ' var ' + ($matched) + ' = false; for (var ' + ($key) + ' in ' + ($data) + ') { '; if ($ownProperties) { out += ' if (!Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($key) + ')) continue; '; } out += ' ' + ($matched) + ' = ' + (it.usePattern($pProperty)) + '.test(' + ($key) + '); if (' + ($matched) + ') break; } '; var $missingPattern = it.util.escapeQuotes($pProperty); out += ' if (!' + ($matched) + ') { ' + ($valid) + ' = false; var err = '; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'patternRequired') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingPattern: \'' + ($missingPattern) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should have property matching pattern \\\'' + ($missingPattern) + '\\\'\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } '; if ($breakOnError) { $closingBraces += '}'; out += ' else { '; } } } out += '' + ($closingBraces); return out; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"custom.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/ajv/lib/dotjs/custom.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = function generate_custom(it, $keyword) { var out = ' '; var $lvl = it.level; var $dataLvl = it.dataLevel; var $schema = it.schema[$keyword]; var $schemaPath = it.schemaPath + it.util.getProperty($keyword); var $errSchemaPath = it.errSchemaPath + '/' + $keyword; var $breakOnError = !it.opts.allErrors; var $errorKeyword; var $data = 'data' + ($dataLvl || ''); var $errs = 'errs__' + $lvl; var $isData = it.opts.v5 && $schema && $schema.$data, $schemaValue; if ($isData) { out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; $schemaValue = 'schema' + $lvl; } else { $schemaValue = $schema; } var $rule = this, $definition = 'definition' + $lvl, $rDef = $rule.definition, $validate = $rDef.validate, $compile, $inline, $macro, $ruleValidate, $validateCode; if ($isData && $rDef.$data) { $validateCode = 'keywordValidate' + $lvl; var $validateSchema = $rDef.validateSchema; out += ' var ' + ($definition) + ' = RULES.custom[\'' + ($keyword) + '\'].definition; var ' + ($validateCode) + ' = ' + ($definition) + '.validate;'; } else { $ruleValidate = it.useCustomRule($rule, $schema, it.schema, it); $schemaValue = 'validate.schema' + $schemaPath; $validateCode = $ruleValidate.code; $compile = $rDef.compile; $inline = $rDef.inline; $macro = $rDef.macro; } var $ruleErrs = $validateCode + '.errors', $i = 'i' + $lvl, $ruleErr = 'ruleErr' + $lvl, $asyncKeyword = $rDef.async; if ($asyncKeyword && !it.async) throw new Error('async keyword in sync schema'); if (!($inline || $macro)) { out += '' + ($ruleErrs) + ' = null;'; } out += 'var ' + ($errs) + ' = errors;var valid' + ($lvl) + ';'; if ($inline && $rDef.statements) { out += ' ' + ($ruleValidate.validate); } else if ($macro) { var $it = it.util.copy(it); $it.level++; var $nextValid = 'valid' + $it.level; $it.schema = $ruleValidate.validate; $it.schemaPath = ''; var $wasComposite = it.compositeRule; it.compositeRule = $it.compositeRule = true; var $code = it.validate($it).replace(/validate\.schema/g, $validateCode); it.compositeRule = $it.compositeRule = $wasComposite; out += ' ' + ($code); } else if (!$inline) { var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; out += ' ' + ($validateCode) + '.call( '; if (it.opts.passContext) { out += 'this'; } else { out += 'self'; } if ($compile || $rDef.schema === false) { out += ' , ' + ($data) + ' '; } else { out += ' , ' + ($schemaValue) + ' , ' + ($data) + ' , validate.schema' + (it.schemaPath) + ' '; } out += ' , (dataPath || \'\')'; if (it.errorPath != '""') { out += ' + ' + (it.errorPath); } if ($dataLvl) { out += ' , data' + (($dataLvl - 1) || '') + ' , ' + (it.dataPathArr[$dataLvl]) + ' '; } else { out += ' , parentData , parentDataProperty '; } out += ' , rootData ) '; var def_callRuleValidate = out; out = $$outStack.pop(); if ($rDef.errors !== false) { if ($asyncKeyword) { $ruleErrs = 'customErrors' + $lvl; out += ' var ' + ($ruleErrs) + ' = null; try { valid' + ($lvl) + ' = ' + (it.yieldAwait) + (def_callRuleValidate) + '; } catch (e) { valid' + ($lvl) + ' = false; if (e instanceof ValidationError) ' + ($ruleErrs) + ' = e.errors; else throw e; } '; } else { out += ' ' + ($validateCode) + '.errors = null; '; } } } out += 'if ('; if ($validateSchema) { out += ' !' + ($definition) + '.validateSchema(' + ($schemaValue) + ') || '; } out += ' ! '; if ($inline) { if ($rDef.statements) { out += ' valid' + ($lvl) + ' '; } else { out += ' (' + ($ruleValidate.validate) + ') '; } } else if ($macro) { out += ' ' + ($nextValid) + ' '; } else { if ($asyncKeyword) { if ($rDef.errors === false) { out += ' (' + (it.yieldAwait) + (def_callRuleValidate) + ') '; } else { out += ' valid' + ($lvl) + ' '; } } else { out += ' ' + (def_callRuleValidate) + ' '; } } out += ') { '; $errorKeyword = $rule.keyword; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; var $$outStack = $$outStack || []; $$outStack.push(out); out = ''; /* istanbul ignore else */ if (it.createErrors !== false) { out += ' { keyword: \'' + ($errorKeyword || 'custom') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { keyword: \'' + ($rule.keyword) + '\' } '; if (it.opts.messages !== false) { out += ' , message: \'should pass "' + ($rule.keyword) + '" keyword validation\' '; } if (it.opts.verbose) { out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; } out += ' } '; } else { out += ' {} '; } var __err = out; out = $$outStack.pop(); if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */ if (it.async) { out += ' throw new ValidationError([' + (__err) + ']); '; } else { out += ' validate.errors = [' + (__err) + ']; return false; '; } } else { out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; } var def_customError = out; out = $$outStack.pop(); if ($inline) { if ($rDef.errors) { if ($rDef.errors != 'full') { out += ' for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + '', '"', '`', ' ', '\r', '\n', '\t'], // RFC 2396: characters not allowed for various reasons. unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), // Allowed by RFCs, but cause of XSS attacks. Always escape these. autoEscape = ['\''].concat(unwise), // Characters that are never ever allowed in a hostname. // Note that any invalid chars are also handled, but these // are the ones that are *expected* to be seen, so we fast-path // them. nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), hostEndingChars = ['/', '?', '#'], hostnameMaxLen = 255, hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, // protocols that can allow "unsafe" and "unwise" chars. unsafeProtocol = { 'javascript': true, 'javascript:': true }, // protocols that never have a hostname. hostlessProtocol = { 'javascript': true, 'javascript:': true }, // protocols that always contain a // bit. slashedProtocol = { 'http': true, 'https': true, 'ftp': true, 'gopher': true, 'file': true, 'http:': true, 'https:': true, 'ftp:': true, 'gopher:': true, 'file:': true }, querystring = require('querystring'); function urlParse(url, parseQueryString, slashesDenoteHost) { if (url && util.isObject(url) && url instanceof Url) return url; var u = new Url; u.parse(url, parseQueryString, slashesDenoteHost); return u; } Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { if (!util.isString(url)) { throw new TypeError("Parameter 'url' must be a string, not " + typeof url); } // Copy chrome, IE, opera backslash-handling behavior. // Back slashes before the query string get converted to forward slashes // See: https://code.google.com/p/chromium/issues/detail?id=25916 var queryIndex = url.indexOf('?'), splitter = (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', uSplit = url.split(splitter), slashRegex = /\\/g; uSplit[0] = uSplit[0].replace(slashRegex, '/'); url = uSplit.join(splitter); var rest = url; // trim before proceeding. // This is to support parse stuff like " http://foo.com \n" rest = rest.trim(); if (!slashesDenoteHost && url.split('#').length === 1) { // Try fast path regexp var simplePath = simplePathPattern.exec(rest); if (simplePath) { this.path = rest; this.href = rest; this.pathname = simplePath[1]; if (simplePath[2]) { this.search = simplePath[2]; if (parseQueryString) { this.query = querystring.parse(this.search.substr(1)); } else { this.query = this.search.substr(1); } } else if (parseQueryString) { this.search = ''; this.query = {}; } return this; } } var proto = protocolPattern.exec(rest); if (proto) { proto = proto[0]; var lowerProto = proto.toLowerCase(); this.protocol = lowerProto; rest = rest.substr(proto.length); } // figure out if it's got a host // user@server is *always* interpreted as a hostname, and url // resolution will treat //foo/bar as host=foo,path=bar because that's // how the browser resolves relative URLs. if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { var slashes = rest.substr(0, 2) === '//'; if (slashes && !(proto && hostlessProtocol[proto])) { rest = rest.substr(2); this.slashes = true; } } if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) { // there's a hostname. // the first instance of /, ?, ;, or # ends the host. // // If there is an @ in the hostname, then non-host chars *are* allowed // to the left of the last @ sign, unless some host-ending character // comes *before* the @-sign. // URLs are obnoxious. // // ex: // http://a@b@c/ => user:a@b host:c // http://a@b?@c => user:a host:c path:/?@c // v0.12 TODO(isaacs): This is not quite how Chrome does things. // Review our test case against browsers more comprehensively. // find the first instance of any hostEndingChars var hostEnd = -1; for (var i = 0; i < hostEndingChars.length; i++) { var hec = rest.indexOf(hostEndingChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // at this point, either we have an explicit point where the // auth portion cannot go past, or the last @ char is the decider. var auth, atSign; if (hostEnd === -1) { // atSign can be anywhere. atSign = rest.lastIndexOf('@'); } else { // atSign must be in auth portion. // http://a@b/c@d => host:b auth:a path:/c@d atSign = rest.lastIndexOf('@', hostEnd); } // Now we have a portion which is definitely the auth. // Pull that off. if (atSign !== -1) { auth = rest.slice(0, atSign); rest = rest.slice(atSign + 1); this.auth = decodeURIComponent(auth); } // the host is the remaining to the left of the first non-host char hostEnd = -1; for (var i = 0; i < nonHostChars.length; i++) { var hec = rest.indexOf(nonHostChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // if we still have not hit it, then the entire thing is a host. if (hostEnd === -1) hostEnd = rest.length; this.host = rest.slice(0, hostEnd); rest = rest.slice(hostEnd); // pull out port. this.parseHost(); // we've indicated that there is a hostname, // so even if it's empty, it has to be present. this.hostname = this.hostname || ''; // if hostname begins with [ and ends with ] // assume that it's an IPv6 address. var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']'; // validate a little. if (!ipv6Hostname) { var hostparts = this.hostname.split(/\./); for (var i = 0, l = hostparts.length; i < l; i++) { var part = hostparts[i]; if (!part) continue; if (!part.match(hostnamePartPattern)) { var newpart = ''; for (var j = 0, k = part.length; j < k; j++) { if (part.charCodeAt(j) > 127) { // we replace non-ASCII char with a temporary placeholder // we need this to make sure size of hostname is not // broken by replacing non-ASCII by nothing newpart += 'x'; } else { newpart += part[j]; } } // we test again with ASCII char only if (!newpart.match(hostnamePartPattern)) { var validParts = hostparts.slice(0, i); var notHost = hostparts.slice(i + 1); var bit = part.match(hostnamePartStart); if (bit) { validParts.push(bit[1]); notHost.unshift(bit[2]); } if (notHost.length) { rest = '/' + notHost.join('.') + rest; } this.hostname = validParts.join('.'); break; } } } } if (this.hostname.length > hostnameMaxLen) { this.hostname = ''; } else { // hostnames are always lower case. this.hostname = this.hostname.toLowerCase(); } if (!ipv6Hostname) { // IDNA Support: Returns a punycoded representation of "domain". // It only converts parts of the domain name that // have non-ASCII characters, i.e. it doesn't matter if // you call it with a domain that already is ASCII-only. this.hostname = punycode.toASCII(this.hostname); } var p = this.port ? ':' + this.port : ''; var h = this.hostname || ''; this.host = h + p; this.href += this.host; // strip [ and ] from the hostname // the host field still retains them, though if (ipv6Hostname) { this.hostname = this.hostname.substr(1, this.hostname.length - 2); if (rest[0] !== '/') { rest = '/' + rest; } } } // now rest is set to the post-host stuff. // chop off any delim chars. if (!unsafeProtocol[lowerProto]) { // First, make 100% sure that any "autoEscape" chars get // escaped, even if encodeURIComponent doesn't think they // need to be. for (var i = 0, l = autoEscape.length; i < l; i++) { var ae = autoEscape[i]; if (rest.indexOf(ae) === -1) continue; var esc = encodeURIComponent(ae); if (esc === ae) { esc = escape(ae); } rest = rest.split(ae).join(esc); } } // chop off from the tail first. var hash = rest.indexOf('#'); if (hash !== -1) { // got a fragment string. this.hash = rest.substr(hash); rest = rest.slice(0, hash); } var qm = rest.indexOf('?'); if (qm !== -1) { this.search = rest.substr(qm); this.query = rest.substr(qm + 1); if (parseQueryString) { this.query = querystring.parse(this.query); } rest = rest.slice(0, qm); } else if (parseQueryString) { // no query string, but parseQueryString still requested this.search = ''; this.query = {}; } if (rest) this.pathname = rest; if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { this.pathname = '/'; } //to support http.request if (this.pathname || this.search) { var p = this.pathname || ''; var s = this.search || ''; this.path = p + s; } // finally, reconstruct the href based on what has been validated. this.href = this.format(); return this; }; // format a parsed object into a url string function urlFormat(obj) { // ensure it's an object, and not a string url. // If it's an obj, this is a no-op. // this way, you can call url_format() on strings // to clean up potentially wonky urls. if (util.isString(obj)) obj = urlParse(obj); if (!(obj instanceof Url)) return Url.prototype.format.call(obj); return obj.format(); } Url.prototype.format = function() { var auth = this.auth || ''; if (auth) { auth = encodeURIComponent(auth); auth = auth.replace(/%3A/i, ':'); auth += '@'; } var protocol = this.protocol || '', pathname = this.pathname || '', hash = this.hash || '', host = false, query = ''; if (this.host) { host = auth + this.host; } else if (this.hostname) { host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); if (this.port) { host += ':' + this.port; } } if (this.query && util.isObject(this.query) && Object.keys(this.query).length) { query = querystring.stringify(this.query); } var search = this.search || (query && ('?' + query)) || ''; if (protocol && protocol.substr(-1) !== ':') protocol += ':'; // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. // unless they had them to begin with. if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { host = '//' + (host || ''); if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; } else if (!host) { host = ''; } if (hash && hash.charAt(0) !== '#') hash = '#' + hash; if (search && search.charAt(0) !== '?') search = '?' + search; pathname = pathname.replace(/[?#]/g, function(match) { return encodeURIComponent(match); }); search = search.replace('#', '%23'); return protocol + host + pathname + search + hash; }; function urlResolve(source, relative) { return urlParse(source, false, true).resolve(relative); } Url.prototype.resolve = function(relative) { return this.resolveObject(urlParse(relative, false, true)).format(); }; function urlResolveObject(source, relative) { if (!source) return relative; return urlParse(source, false, true).resolveObject(relative); } Url.prototype.resolveObject = function(relative) { if (util.isString(relative)) { var rel = new Url(); rel.parse(relative, false, true); relative = rel; } var result = new Url(); var tkeys = Object.keys(this); for (var tk = 0; tk < tkeys.length; tk++) { var tkey = tkeys[tk]; result[tkey] = this[tkey]; } // hash is always overridden, no matter what. // even href="" will remove it. result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. if (relative.href === '') { result.href = result.format(); return result; } // hrefs like //foo/bar always cut to the protocol. if (relative.slashes && !relative.protocol) { // take everything except the protocol from relative var rkeys = Object.keys(relative); for (var rk = 0; rk < rkeys.length; rk++) { var rkey = rkeys[rk]; if (rkey !== 'protocol') result[rkey] = relative[rkey]; } //urlParse appends trailing / to urls like http://www.example.com if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { result.path = result.pathname = '/'; } result.href = result.format(); return result; } if (relative.protocol && relative.protocol !== result.protocol) { // if it's a known url protocol, then changing // the protocol does weird things // first, if it's not file:, then we MUST have a host, // and if there was a path // to begin with, then we MUST have a path. // if it is file:, then the host is dropped, // because that's known to be hostless. // anything else is assumed to be absolute. if (!slashedProtocol[relative.protocol]) { var keys = Object.keys(relative); for (var v = 0; v < keys.length; v++) { var k = keys[v]; result[k] = relative[k]; } result.href = result.format(); return result; } result.protocol = relative.protocol; if (!relative.host && !hostlessProtocol[relative.protocol]) { var relPath = (relative.pathname || '').split('/'); while (relPath.length && !(relative.host = relPath.shift())); if (!relative.host) relative.host = ''; if (!relative.hostname) relative.hostname = ''; if (relPath[0] !== '') relPath.unshift(''); if (relPath.length < 2) relPath.unshift(''); result.pathname = relPath.join('/'); } else { result.pathname = relative.pathname; } result.search = relative.search; result.query = relative.query; result.host = relative.host || ''; result.auth = relative.auth; result.hostname = relative.hostname || relative.host; result.port = relative.port; // to support http.request if (result.pathname || result.search) { var p = result.pathname || ''; var s = result.search || ''; result.path = p + s; } result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; } var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), isRelAbs = ( relative.host || relative.pathname && relative.pathname.charAt(0) === '/' ), mustEndAbs = (isRelAbs || isSourceAbs || (result.host && relative.pathname)), removeAllDots = mustEndAbs, srcPath = result.pathname && result.pathname.split('/') || [], relPath = relative.pathname && relative.pathname.split('/') || [], psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative // links like ../.. should be able // to crawl up to the hostname, as well. This is strange. // result.protocol has already been set by now. // Later on, put the first path part into the host field. if (psychotic) { result.hostname = ''; result.port = null; if (result.host) { if (srcPath[0] === '') srcPath[0] = result.host; else srcPath.unshift(result.host); } result.host = ''; if (relative.protocol) { relative.hostname = null; relative.port = null; if (relative.host) { if (relPath[0] === '') relPath[0] = relative.host; else relPath.unshift(relative.host); } relative.host = null; } mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); } if (isRelAbs) { // it's absolute. result.host = (relative.host || relative.host === '') ? relative.host : result.host; result.hostname = (relative.hostname || relative.hostname === '') ? relative.hostname : result.hostname; result.search = relative.search; result.query = relative.query; srcPath = relPath; // fall through to the dot-handling below. } else if (relPath.length) { // it's relative // throw away the existing file, and take the new path instead. if (!srcPath) srcPath = []; srcPath.pop(); srcPath = srcPath.concat(relPath); result.search = relative.search; result.query = relative.query; } else if (!util.isNullOrUndefined(relative.search)) { // just pull out the search. // like href='?foo'. // Put this after the other two cases because it simplifies the booleans if (psychotic) { result.hostname = result.host = srcPath.shift(); //occationaly the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } result.search = relative.search; result.query = relative.query; //to support http.request if (!util.isNull(result.pathname) || !util.isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.href = result.format(); return result; } if (!srcPath.length) { // no path at all. easy. // we've already handled the other stuff above. result.pathname = null; //to support http.request if (result.search) { result.path = '/' + result.search; } else { result.path = null; } result.href = result.format(); return result; } // if a url ENDs in . or .., then it must get a trailing slash. // however, if it ends in anything else non-slashy, // then it must NOT get a trailing slash. var last = srcPath.slice(-1)[0]; var hasTrailingSlash = ( (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''); // strip single dots, resolve double dots to parent dir // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = srcPath.length; i >= 0; i--) { last = srcPath[i]; if (last === '.') { srcPath.splice(i, 1); } else if (last === '..') { srcPath.splice(i, 1); up++; } else if (up) { srcPath.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (!mustEndAbs && !removeAllDots) { for (; up--; up) { srcPath.unshift('..'); } } if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { srcPath.unshift(''); } if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { srcPath.push(''); } var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/'); // put the host back if (psychotic) { result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; //occationaly the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } mustEndAbs = mustEndAbs || (result.host && srcPath.length); if (mustEndAbs && !isAbsolute) { srcPath.unshift(''); } if (!srcPath.length) { result.pathname = null; result.path = null; } else { result.pathname = srcPath.join('/'); } //to support request.http if (!util.isNull(result.pathname) || !util.isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.auth = relative.auth || result.auth; result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; }; Url.prototype.parseHost = function() { var host = this.host; var port = portPattern.exec(host); if (port) { port = port[0]; if (port !== ':') { this.port = port.substr(1); } host = host.substr(0, host.length - port.length); } if (host) this.hostname = host; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"util.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/url/util.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; module.exports = { isString: function(arg) { return typeof(arg) === 'string'; }, isObject: function(arg) { return typeof(arg) === 'object' && arg !== null; }, isNull: function(arg) { return arg === null; }, isNullOrUndefined: function(arg) { return arg == null; } }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"punycode":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/punycode/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "punycode"; exports.version = "1.3.2"; exports.main = "punycode.js"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"punycode.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/punycode/punycode.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // /*! https://mths.be/punycode v1.3.2 by @mathias */ ;(function(root) { /** Detect free variables */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; var freeModule = typeof module == 'object' && module && !module.nodeType && module; var freeGlobal = typeof global == 'object' && global; if ( freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal ) { root = freeGlobal; } /** * The `punycode` object. * @name punycode * @type Object */ var punycode, /** Highest positive signed 32-bit float value */ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700, initialBias = 72, initialN = 128, // 0x80 delimiter = '-', // '\x2D' /** Regular expressions */ regexPunycode = /^xn--/, regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators /** Error messages */ errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }, /** Convenience shortcuts */ baseMinusTMin = base - tMin, floor = Math.floor, stringFromCharCode = String.fromCharCode, /** Temporary variable */ key; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var length = array.length; var result = []; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // high surrogate, and there is a next character extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // low surrogate output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // unmatched surrogate; only append this code unit, in case the next // code unit is the high surrogate of a surrogate pair output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ function ucs2encode(array) { return map(array, function(value) { var output = ''; if (value > 0xFFFF) { value -= 0x10000; output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); value = 0xDC00 | value & 0x3FF; } output += stringFromCharCode(value); return output; }).join(''); } /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ function basicToDigit(codePoint) { if (codePoint - 48 < 10) { return codePoint - 22; } if (codePoint - 65 < 26) { return codePoint - 65; } if (codePoint - 97 < 26) { return codePoint - 97; } return base; } /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); } /** * Bias adaptation function as per section 3.4 of RFC 3492. * http://tools.ietf.org/html/rfc3492#section-3.4 * @private */ function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); } /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ function decode(input) { // Don't use UCS-2 var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t, /** Cached calculation results */ baseMinusT; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. for (oldi = i, w = 1, k = base; /* no condition */; k += base) { if (index >= inputLength) { error('invalid-input'); } digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error('overflow'); } i += digit * w; t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (digit < t) { break; } baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error('overflow'); } w *= baseMinusT; } out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output output.splice(i++, 0, n); } return ucs2encode(output); } /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ function encode(input) { var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [], /** `inputLength` will hold the number of code points in `input`. */ inputLength, /** Cached calculation results */ handledCPCountPlusOne, baseMinusT, qMinusT; // Convert the input in UCS-2 to Unicode input = ucs2decode(input); // Cache the length inputLength = input.length; // Initialize the state n = initialN; delta = 0; bias = initialBias; // Handle the basic code points for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < 0x80) { output.push(stringFromCharCode(currentValue)); } } handledCPCount = basicLength = output.length; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string - if it is not empty - with a delimiter if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: for (m = maxInt, j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < n && ++delta > maxInt) { error('overflow'); } if (currentValue == n) { // Represent delta as a generalized variable-length integer for (q = delta, k = base; /* no condition */; k += base) { t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (q < t) { break; } qMinusT = q - t; baseMinusT = base - t; output.push( stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) ); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(''); } /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ function toUnicode(input) { return mapDomain(input, function(string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); } /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ function toASCII(input) { return mapDomain(input, function(string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); } /*--------------------------------------------------------------------------*/ /** Define the public API */ punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '1.3.2', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** Expose `punycode` */ // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define('punycode', function() { return punycode; }); } else if (freeExports && freeModule) { if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ freeModule.exports = punycode; } else { // in Narwhal or RingoJS v0.7.0- for (key in punycode) { punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); } } } else { // in Rhino or a web browser root.punycode = punycode; } }(this)); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"querystring":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/querystring/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "querystring"; exports.version = "0.2.0"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/querystring/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"decode.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/querystring/decode.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. // See: https://github.com/joyent/node/issues/1707 function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } module.exports = function(qs, sep, eq, options) { sep = sep || '&'; eq = eq || '='; var obj = {}; if (typeof qs !== 'string' || qs.length === 0) { return obj; } var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; if (options && typeof options.maxKeys === 'number') { maxKeys = options.maxKeys; } var len = qs.length; // maxKeys <= 0 means that we should not limit keys count if (maxKeys > 0 && len > maxKeys) { len = maxKeys; } for (var i = 0; i < len; ++i) { var x = qs[i].replace(regexp, '%20'), idx = x.indexOf(eq), kstr, vstr, k, v; if (idx >= 0) { kstr = x.substr(0, idx); vstr = x.substr(idx + 1); } else { kstr = x; vstr = ''; } k = decodeURIComponent(kstr); v = decodeURIComponent(vstr); if (!hasOwnProperty(obj, k)) { obj[k] = v; } else if (Array.isArray(obj[k])) { obj[k].push(v); } else { obj[k] = [obj[k], v]; } } return obj; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"encode.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/querystring/encode.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var stringifyPrimitive = function(v) { switch (typeof v) { case 'string': return v; case 'boolean': return v ? 'true' : 'false'; case 'number': return isFinite(v) ? v : ''; default: return ''; } }; module.exports = function(obj, sep, eq, name) { sep = sep || '&'; eq = eq || '='; if (obj === null) { obj = undefined; } if (typeof obj === 'object') { return Object.keys(obj).map(function(k) { var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; if (Array.isArray(obj[k])) { return obj[k].map(function(v) { return ks + encodeURIComponent(stringifyPrimitive(v)); }).join(sep); } else { return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } }).join(sep); } if (!name) return ''; return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"json-stable-stringify":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/json-stable-stringify/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "json-stable-stringify"; exports.version = "1.0.1"; exports.main = "index.js"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/json-stable-stringify/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var json = typeof JSON !== 'undefined' ? JSON : require('jsonify'); module.exports = function (obj, opts) { if (!opts) opts = {}; if (typeof opts === 'function') opts = { cmp: opts }; var space = opts.space || ''; if (typeof space === 'number') space = Array(space+1).join(' '); var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; var replacer = opts.replacer || function(key, value) { return value; }; var cmp = opts.cmp && (function (f) { return function (node) { return function (a, b) { var aobj = { key: a, value: node[a] }; var bobj = { key: b, value: node[b] }; return f(aobj, bobj); }; }; })(opts.cmp); var seen = []; return (function stringify (parent, key, node, level) { var indent = space ? ('\n' + new Array(level + 1).join(space)) : ''; var colonSeparator = space ? ': ' : ':'; if (node && node.toJSON && typeof node.toJSON === 'function') { node = node.toJSON(); } node = replacer.call(parent, key, node); if (node === undefined) { return; } if (typeof node !== 'object' || node === null) { return json.stringify(node); } if (isArray(node)) { var out = []; for (var i = 0; i < node.length; i++) { var item = stringify(node, i, node[i], level+1) || json.stringify(null); out.push(indent + space + item); } return '[' + out.join(',') + indent + ']'; } else { if (seen.indexOf(node) !== -1) { if (cycles) return json.stringify('__cycle__'); throw new TypeError('Converting circular structure to JSON'); } else seen.push(node); var keys = objectKeys(node).sort(cmp && cmp(node)); var out = []; for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = stringify(node, key, node[key], level+1); if(!value) continue; var keyValue = json.stringify(key) + colonSeparator + value; ; out.push(indent + space + keyValue); } seen.splice(seen.indexOf(node), 1); return '{' + out.join(',') + indent + '}'; } })({ '': obj }, '', obj, 0); }; var isArray = Array.isArray || function (x) { return {}.toString.call(x) === '[object Array]'; }; var objectKeys = Object.keys || function (obj) { var has = Object.prototype.hasOwnProperty || function () { return true }; var keys = []; for (var key in obj) { if (has.call(obj, key)) keys.push(key); } return keys; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"jsonify":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/jsonify/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "jsonify"; exports.version = "0.0.0"; exports.main = "index.js"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/jsonify/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.parse = require('./lib/parse'); exports.stringify = require('./lib/stringify'); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"lib":{"parse.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/jsonify/lib/parse.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var at, // The index of the current character ch, // The current character escapee = { '"': '"', '\\': '\\', '/': '/', b: '\b', f: '\f', n: '\n', r: '\r', t: '\t' }, text, error = function (m) { // Call error when something is wrong. throw { name: 'SyntaxError', message: m, at: at, text: text }; }, next = function (c) { // If a c parameter is provided, verify that it matches the current character. if (c && c !== ch) { error("Expected '" + c + "' instead of '" + ch + "'"); } // Get the next character. When there are no more characters, // return the empty string. ch = text.charAt(at); at += 1; return ch; }, number = function () { // Parse a number value. var number, string = ''; if (ch === '-') { string = '-'; next('-'); } while (ch >= '0' && ch <= '9') { string += ch; next(); } if (ch === '.') { string += '.'; while (next() && ch >= '0' && ch <= '9') { string += ch; } } if (ch === 'e' || ch === 'E') { string += ch; next(); if (ch === '-' || ch === '+') { string += ch; next(); } while (ch >= '0' && ch <= '9') { string += ch; next(); } } number = +string; if (!isFinite(number)) { error("Bad number"); } else { return number; } }, string = function () { // Parse a string value. var hex, i, string = '', uffff; // When parsing for string values, we must look for " and \ characters. if (ch === '"') { while (next()) { if (ch === '"') { next(); return string; } else if (ch === '\\') { next(); if (ch === 'u') { uffff = 0; for (i = 0; i < 4; i += 1) { hex = parseInt(next(), 16); if (!isFinite(hex)) { break; } uffff = uffff * 16 + hex; } string += String.fromCharCode(uffff); } else if (typeof escapee[ch] === 'string') { string += escapee[ch]; } else { break; } } else { string += ch; } } } error("Bad string"); }, white = function () { // Skip whitespace. while (ch && ch <= ' ') { next(); } }, word = function () { // true, false, or null. switch (ch) { case 't': next('t'); next('r'); next('u'); next('e'); return true; case 'f': next('f'); next('a'); next('l'); next('s'); next('e'); return false; case 'n': next('n'); next('u'); next('l'); next('l'); return null; } error("Unexpected '" + ch + "'"); }, value, // Place holder for the value function. array = function () { // Parse an array value. var array = []; if (ch === '[') { next('['); white(); if (ch === ']') { next(']'); return array; // empty array } while (ch) { array.push(value()); white(); if (ch === ']') { next(']'); return array; } next(','); white(); } } error("Bad array"); }, object = function () { // Parse an object value. var key, object = {}; if (ch === '{') { next('{'); white(); if (ch === '}') { next('}'); return object; // empty object } while (ch) { key = string(); white(); next(':'); if (Object.hasOwnProperty.call(object, key)) { error('Duplicate key "' + key + '"'); } object[key] = value(); white(); if (ch === '}') { next('}'); return object; } next(','); white(); } } error("Bad object"); }; value = function () { // Parse a JSON value. It could be an object, an array, a string, a number, // or a word. white(); switch (ch) { case '{': return object(); case '[': return array(); case '"': return string(); case '-': return number(); default: return ch >= '0' && ch <= '9' ? number() : word(); } }; // Return the json_parse function. It will have access to all of the above // functions and variables. module.exports = function (source, reviver) { var result; text = source; at = 0; ch = ' '; result = value(); white(); if (ch) { error("Syntax error"); } // If there is a reviver function, we recursively walk the new structure, // passing each name/value pair to the reviver function for possible // transformation, starting with a temporary root object that holds the result // in an empty key. If there is not a reviver function, we simply return the // result. return typeof reviver === 'function' ? (function walk(holder, key) { var k, v, value = holder[key]; if (value && typeof value === 'object') { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } } } } return reviver.call(holder, key, value); }({'': result}, '')) : result; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"stringify.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/jsonify/lib/stringify.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { // table of character substitutions '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\' }, rep; function quote(string) { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { // Produce a string from holder[key]. var i, // The loop counter. k, // The member key. v, // The member value. length, mind = gap, partial, value = holder[key]; // If the value has a toJSON method, call it to obtain a replacement value. if (value && typeof value === 'object' && typeof value.toJSON === 'function') { value = value.toJSON(key); } // If we were called with a replacer function, then call the replacer to // obtain a replacement value. if (typeof rep === 'function') { value = rep.call(holder, key, value); } // What happens next depends on the value's type. switch (typeof value) { case 'string': return quote(value); case 'number': // JSON numbers must be finite. Encode non-finite numbers as null. return isFinite(value) ? String(value) : 'null'; case 'boolean': case 'null': // If the value is a boolean or null, convert it to a string. Note: // typeof null does not produce 'null'. The case is included here in // the remote chance that this gets fixed someday. return String(value); case 'object': if (!value) return 'null'; gap += indent; partial = []; // Array.isArray if (Object.prototype.toString.apply(value) === '[object Array]') { length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || 'null'; } // Join all of the elements together, separated with commas, and // wrap them in brackets. v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } // If the replacer is an array, use it to select the members to be // stringified. if (rep && typeof rep === 'object') { length = rep.length; for (i = 0; i < length; i += 1) { k = rep[i]; if (typeof k === 'string') { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { // Otherwise, iterate through all of the keys in the object. for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } // Join all of the member texts together, separated with commas, // and wrap them in braces. v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } module.exports = function (value, replacer, space) { var i; gap = ''; indent = ''; // If the space parameter is a number, make an indent string containing that // many spaces. if (typeof space === 'number') { for (i = 0; i < space; i += 1) { indent += ' '; } } // If the space parameter is a string, it will be used as the indent string. else if (typeof space === 'string') { indent = space; } // If there is a replacer, it must be a function or an array. // Otherwise, throw an error. rep = replacer; if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { throw new Error('JSON.stringify'); } // Make a fake root object containing our value under the key of ''. // Return the result of stringifying the value. return str('', {'': value}); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }}},"co":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/co/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "co"; exports.version = "4.6.0"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/co/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // /** * slice() reference. */ var slice = Array.prototype.slice; /** * Expose `co`. */ module.exports = co['default'] = co.co = co; /** * Wrap the given generator `fn` into a * function that returns a promise. * This is a separate function so that * every `co()` call doesn't create a new, * unnecessary closure. * * @param {GeneratorFunction} fn * @return {Function} * @api public */ co.wrap = function (fn) { createPromise.__generatorFunction__ = fn; return createPromise; function createPromise() { return co.call(this, fn.apply(this, arguments)); } }; /** * Execute the generator function or a generator * and return a promise. * * @param {Function} fn * @return {Promise} * @api public */ function co(gen) { var ctx = this; var args = slice.call(arguments, 1) // we wrap everything in a promise to avoid promise chaining, // which leads to memory leak errors. // see https://github.com/tj/co/issues/180 return new Promise(function(resolve, reject) { if (typeof gen === 'function') gen = gen.apply(ctx, args); if (!gen || typeof gen.next !== 'function') return resolve(gen); onFulfilled(); /** * @param {Mixed} res * @return {Promise} * @api private */ function onFulfilled(res) { var ret; try { ret = gen.next(res); } catch (e) { return reject(e); } next(ret); } /** * @param {Error} err * @return {Promise} * @api private */ function onRejected(err) { var ret; try { ret = gen.throw(err); } catch (e) { return reject(e); } next(ret); } /** * Get the next value in the generator, * return a promise. * * @param {Object} ret * @return {Promise} * @api private */ function next(ret) { if (ret.done) return resolve(ret.value); var value = toPromise.call(ctx, ret.value); if (value && isPromise(value)) return value.then(onFulfilled, onRejected); return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' + 'but the following object was passed: "' + String(ret.value) + '"')); } }); } /** * Convert a `yield`ed value into a promise. * * @param {Mixed} obj * @return {Promise} * @api private */ function toPromise(obj) { if (!obj) return obj; if (isPromise(obj)) return obj; if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); if ('function' == typeof obj) return thunkToPromise.call(this, obj); if (Array.isArray(obj)) return arrayToPromise.call(this, obj); if (isObject(obj)) return objectToPromise.call(this, obj); return obj; } /** * Convert a thunk to a promise. * * @param {Function} * @return {Promise} * @api private */ function thunkToPromise(fn) { var ctx = this; return new Promise(function (resolve, reject) { fn.call(ctx, function (err, res) { if (err) return reject(err); if (arguments.length > 2) res = slice.call(arguments, 1); resolve(res); }); }); } /** * Convert an array of "yieldables" to a promise. * Uses `Promise.all()` internally. * * @param {Array} obj * @return {Promise} * @api private */ function arrayToPromise(obj) { return Promise.all(obj.map(toPromise, this)); } /** * Convert an object of "yieldables" to a promise. * Uses `Promise.all()` internally. * * @param {Object} obj * @return {Promise} * @api private */ function objectToPromise(obj){ var results = new obj.constructor(); var keys = Object.keys(obj); var promises = []; for (var i = 0; i < keys.length; i++) { var key = keys[i]; var promise = toPromise.call(this, obj[key]); if (promise && isPromise(promise)) defer(promise, key); else results[key] = obj[key]; } return Promise.all(promises).then(function () { return results; }); function defer(promise, key) { // predefine the key in the result results[key] = undefined; promises.push(promise.then(function (res) { results[key] = res; })); } } /** * Check if `obj` is a promise. * * @param {Object} obj * @return {Boolean} * @api private */ function isPromise(obj) { return 'function' == typeof obj.then; } /** * Check if `obj` is a generator. * * @param {Mixed} obj * @return {Boolean} * @api private */ function isGenerator(obj) { return 'function' == typeof obj.next && 'function' == typeof obj.throw; } /** * Check if `obj` is a generator function. * * @param {Mixed} obj * @return {Boolean} * @api private */ function isGeneratorFunction(obj) { var constructor = obj.constructor; if (!constructor) return false; if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true; return isGenerator(constructor.prototype); } /** * Check for plain object. * * @param {Mixed} val * @return {Boolean} * @api private */ function isObject(val) { return Object == val.constructor; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"jspdf":{"package.json":function(require,exports){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/jspdf/package.json // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // exports.name = "jspdf"; exports.version = "1.3.3"; exports.main = "dist/jspdf.debug.js"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// },"dist":{"jspdf.debug.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // node_modules/meteor/ohif_measurements/node_modules/jspdf/dist/jspdf.debug.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.jspdf = factory()); }(this, (function () { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var asyncGenerator = function () { function AwaitValue(value) { this.value = value; } function AsyncGenerator(gen) { var front, back; function send(key, arg) { return new Promise(function (resolve, reject) { var request = { key: key, arg: arg, resolve: resolve, reject: reject, next: null }; if (back) { back = back.next = request; } else { front = back = request; resume(key, arg); } }); } function resume(key, arg) { try { var result = gen[key](arg); var value = result.value; if (value instanceof AwaitValue) { Promise.resolve(value.value).then(function (arg) { resume("next", arg); }, function (arg) { resume("throw", arg); }); } else { settle(result.done ? "return" : "normal", result.value); } } catch (err) { settle("throw", err); } } function settle(type, value) { switch (type) { case "return": front.resolve({ value: value, done: true }); break; case "throw": front.reject(value); break; default: front.resolve({ value: value, done: false }); break; } front = front.next; if (front) { resume(front.key, front.arg); } else { back = null; } } this._invoke = send; if (typeof gen.return !== "function") { this.return = undefined; } } if (typeof Symbol === "function" && Symbol.asyncIterator) { AsyncGenerator.prototype[Symbol.asyncIterator] = function () { return this; }; } AsyncGenerator.prototype.next = function (arg) { return this._invoke("next", arg); }; AsyncGenerator.prototype.throw = function (arg) { return this._invoke("throw", arg); }; AsyncGenerator.prototype.return = function (arg) { return this._invoke("return", arg); }; return { wrap: function (fn) { return function () { return new AsyncGenerator(fn.apply(this, arguments)); }; }, await: function (value) { return new AwaitValue(value); } }; }(); var get$1 = function get$1(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get$1(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var set$1 = function set$1(object, property, value, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent !== null) { set$1(parent, property, value, receiver); } } else if ("value" in desc && desc.writable) { desc.value = value; } else { var setter = desc.set; if (setter !== undefined) { setter.call(receiver, value); } } return value; }; /** @preserve * jsPDF - PDF Document creation from JavaScript * Version 1.3.3 Built on 2017-02-23T15:31:28.692Z * CommitID c2fa0d3c14 * * Copyright (c) 2010-2016 James Hall , https://github.com/MrRio/jsPDF * 2010 Aaron Spike, https://github.com/acspike * 2012 Willow Systems Corporation, willow-systems.com * 2012 Pablo Hess, https://github.com/pablohess * 2012 Florian Jenett, https://github.com/fjenett * 2013 Warren Weckesser, https://github.com/warrenweckesser * 2013 Youssef Beddad, https://github.com/lifof * 2013 Lee Driscoll, https://github.com/lsdriscoll * 2013 Stefan Slonevskiy, https://github.com/stefslon * 2013 Jeremy Morel, https://github.com/jmorel * 2013 Christoph Hartmann, https://github.com/chris-rock * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria * 2014 James Makes, https://github.com/dollaruw * 2014 Diego Casorran, https://github.com/diegocr * 2014 Steven Spungin, https://github.com/Flamenco * 2014 Kenneth Glassey, https://github.com/Gavvers * * Licensed under the MIT License * * Contributor(s): * siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango, * kim3er, mfo, alnorth, Flamenco */ /** * Creates new jsPDF document object instance. * * @class * @param orientation One of "portrait" or "landscape" (or shortcuts "p" (Default), "l") * @param unit Measurement unit to be used when coordinates are specified. * One of "pt" (points), "mm" (Default), "cm", "in" * @param format One of 'pageFormats' as shown below, default: a4 * @returns {jsPDF} * @name jsPDF */ var jsPDF = function (global) { 'use strict'; var pdfVersion = '1.3', pageFormats = { // Size in pt of various paper formats 'a0': [2383.94, 3370.39], 'a1': [1683.78, 2383.94], 'a2': [1190.55, 1683.78], 'a3': [841.89, 1190.55], 'a4': [595.28, 841.89], 'a5': [419.53, 595.28], 'a6': [297.64, 419.53], 'a7': [209.76, 297.64], 'a8': [147.40, 209.76], 'a9': [104.88, 147.40], 'a10': [73.70, 104.88], 'b0': [2834.65, 4008.19], 'b1': [2004.09, 2834.65], 'b2': [1417.32, 2004.09], 'b3': [1000.63, 1417.32], 'b4': [708.66, 1000.63], 'b5': [498.90, 708.66], 'b6': [354.33, 498.90], 'b7': [249.45, 354.33], 'b8': [175.75, 249.45], 'b9': [124.72, 175.75], 'b10': [87.87, 124.72], 'c0': [2599.37, 3676.54], 'c1': [1836.85, 2599.37], 'c2': [1298.27, 1836.85], 'c3': [918.43, 1298.27], 'c4': [649.13, 918.43], 'c5': [459.21, 649.13], 'c6': [323.15, 459.21], 'c7': [229.61, 323.15], 'c8': [161.57, 229.61], 'c9': [113.39, 161.57], 'c10': [79.37, 113.39], 'dl': [311.81, 623.62], 'letter': [612, 792], 'government-letter': [576, 756], 'legal': [612, 1008], 'junior-legal': [576, 360], 'ledger': [1224, 792], 'tabloid': [792, 1224], 'credit-card': [153, 243] }; /** * jsPDF's Internal PubSub Implementation. * See mrrio.github.io/jsPDF/doc/symbols/PubSub.html * Backward compatible rewritten on 2014 by * Diego Casorran, https://github.com/diegocr * * @class * @name PubSub * @ignore This should not be in the public docs. */ function PubSub(context) { var topics = {}; this.subscribe = function (topic, callback, once) { if (typeof callback !== 'function') { return false; } if (!topics.hasOwnProperty(topic)) { topics[topic] = {}; } var id = Math.random().toString(35); topics[topic][id] = [callback, !!once]; return id; }; this.unsubscribe = function (token) { for (var topic in topics) { if (topics[topic][token]) { delete topics[topic][token]; return true; } } return false; }; this.publish = function (topic) { if (topics.hasOwnProperty(topic)) { var args = Array.prototype.slice.call(arguments, 1), idr = []; for (var id in topics[topic]) { var sub = topics[topic][id]; try { sub[0].apply(context, args); } catch (ex) { if (global.console) { console.error('jsPDF PubSub Error', ex.message, ex); } } if (sub[1]) idr.push(id); } if (idr.length) idr.forEach(this.unsubscribe); } }; } /** * @constructor * @private */ function jsPDF(orientation, unit, format, compressPdf) { var options = {}; if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') { options = orientation; orientation = options.orientation; unit = options.unit || unit; format = options.format || format; compressPdf = options.compress || options.compressPdf || compressPdf; } // Default options unit = unit || 'mm'; format = format || 'a4'; orientation = ('' + (orientation || 'P')).toLowerCase(); var format_as_string = ('' + format).toLowerCase(), compress = !!compressPdf && typeof Uint8Array === 'function', textColor = options.textColor || '0 g', drawColor = options.drawColor || '0 G', activeFontSize = options.fontSize || 16, lineHeightProportion = options.lineHeight || 1.15, lineWidth = options.lineWidth || 0.200025, // 2mm objectNumber = 2, // 'n' Current object number outToPages = !1, // switches where out() prints. outToPages true = push to pages obj. outToPages false = doc builder content offsets = [], // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes. fonts = {}, // collection of font objects, where key is fontKey - a dynamically created label for a given font. fontmap = {}, // mapping structure fontName > fontStyle > font key - performance layer. See addFont() activeFontKey, // will be string representing the KEY of the font as combination of fontName + fontStyle k, // Scale factor tmp, page = 0, currentPage, pages = [], pagesContext = [], // same index as pages and pagedim pagedim = [], content = [], additionalObjects = [], lineCapID = 0, lineJoinID = 0, content_length = 0, pageWidth, pageHeight, pageMode, zoomMode, layoutMode, documentProperties = { 'title': '', 'subject': '', 'author': '', 'keywords': '', 'creator': '' }, API = {}, events = new PubSub(API), ///////////////////// // Private functions ///////////////////// f2 = function f2(number) { return number.toFixed(2); // Ie, %.2f }, f3 = function f3(number) { return number.toFixed(3); // Ie, %.3f }, padd2 = function padd2(number) { return ('0' + parseInt(number)).slice(-2); }, out = function out(string) { if (outToPages) { /* set by beginPage */ pages[currentPage].push(string); } else { // +1 for '\n' that will be used to join 'content' content_length += string.length + 1; content.push(string); } }, newObject = function newObject() { // Begin a new object objectNumber++; offsets[objectNumber] = content_length; out(objectNumber + ' 0 obj'); return objectNumber; }, // Does not output the object until after the pages have been output. // Returns an object containing the objectId and content. // All pages have been added so the object ID can be estimated to start right after. // This does not modify the current objectNumber; It must be updated after the newObjects are output. newAdditionalObject = function newAdditionalObject() { var objId = pages.length * 2 + 1; objId += additionalObjects.length; var obj = { objId: objId, content: '' }; additionalObjects.push(obj); return obj; }, // Does not output the object. The caller must call newObjectDeferredBegin(oid) before outputing any data newObjectDeferred = function newObjectDeferred() { objectNumber++; offsets[objectNumber] = function () { return content_length; }; return objectNumber; }, newObjectDeferredBegin = function newObjectDeferredBegin(oid) { offsets[oid] = content_length; }, putStream = function putStream(str) { out('stream'); out(str); out('endstream'); }, putPages = function putPages() { var n, p, arr, i, deflater, adler32, adler32cs, wPt, hPt, pageObjectNumbers = []; adler32cs = global.adler32cs || jsPDF.adler32cs; if (compress && typeof adler32cs === 'undefined') { compress = false; } // outToPages = false as set in endDocument(). out() writes to content. for (n = 1; n <= page; n++) { pageObjectNumbers.push(newObject()); wPt = (pageWidth = pagedim[n].width) * k; hPt = (pageHeight = pagedim[n].height) * k; out('<>'); out('endobj'); // Page content p = pages[n].join('\n'); newObject(); if (compress) { arr = []; i = p.length; while (i--) { arr[i] = p.charCodeAt(i); } adler32 = adler32cs.from(p); deflater = new Deflater(6); deflater.append(new Uint8Array(arr)); p = deflater.flush(); arr = new Uint8Array(p.length + 6); arr.set(new Uint8Array([120, 156])), arr.set(p, 2); arr.set(new Uint8Array([adler32 & 0xFF, adler32 >> 8 & 0xFF, adler32 >> 16 & 0xFF, adler32 >> 24 & 0xFF]), p.length + 2); p = String.fromCharCode.apply(null, arr); out('<>'); } else { out('<>'); } putStream(p); out('endobj'); } offsets[1] = content_length; out('1 0 obj'); out('<>'); out('endobj'); events.publish('postPutPages'); }, putFont = function putFont(font) { font.objectNumber = newObject(); out('<>'); out('endobj'); }, putFonts = function putFonts() { for (var fontKey in fonts) { if (fonts.hasOwnProperty(fontKey)) { putFont(fonts[fontKey]); } } }, putXobjectDict = function putXobjectDict() { // Loop through images, or other data objects events.publish('putXobjectDict'); }, putResourceDictionary = function putResourceDictionary() { out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); out('/Font <<'); // Do this for each font, the '1' bit is the index of the font for (var fontKey in fonts) { if (fonts.hasOwnProperty(fontKey)) { out('/' + fontKey + ' ' + fonts[fontKey].objectNumber + ' 0 R'); } } out('>>'); out('/XObject <<'); putXobjectDict(); out('>>'); }, putResources = function putResources() { putFonts(); events.publish('putResources'); // Resource dictionary offsets[2] = content_length; out('2 0 obj'); out('<<'); putResourceDictionary(); out('>>'); out('endobj'); events.publish('postPutResources'); }, putAdditionalObjects = function putAdditionalObjects() { events.publish('putAdditionalObjects'); for (var i = 0; i < additionalObjects.length; i++) { var obj = additionalObjects[i]; offsets[obj.objId] = content_length; out(obj.objId + ' 0 obj'); out(obj.content); out('endobj'); } objectNumber += additionalObjects.length; events.publish('postPutAdditionalObjects'); }, addToFontDictionary = function addToFontDictionary(fontKey, fontName, fontStyle) { // this is mapping structure for quick font key lookup. // returns the KEY of the font (ex: "F1") for a given // pair of font name and type (ex: "Arial". "Italic") if (!fontmap.hasOwnProperty(fontName)) { fontmap[fontName] = {}; } fontmap[fontName][fontStyle] = fontKey; }, /** * FontObject describes a particular font as member of an instnace of jsPDF * * It's a collection of properties like 'id' (to be used in PDF stream), * 'fontName' (font's family name), 'fontStyle' (font's style variant label) * * @class * @public * @property id {String} PDF-document-instance-specific label assinged to the font. * @property PostScriptName {String} PDF specification full name for the font * @property encoding {Object} Encoding_name-to-Font_metrics_object mapping. * @name FontObject * @ignore This should not be in the public docs. */ addFont = function addFont(PostScriptName, fontName, fontStyle, encoding) { var fontKey = 'F' + (Object.keys(fonts).length + 1).toString(10), // This is FontObject font = fonts[fontKey] = { 'id': fontKey, 'PostScriptName': PostScriptName, 'fontName': fontName, 'fontStyle': fontStyle, 'encoding': encoding, 'metadata': {} }; addToFontDictionary(fontKey, fontName, fontStyle); events.publish('addFont', font); return fontKey; }, addFonts = function addFonts() { var HELVETICA = "helvetica", TIMES = "times", COURIER = "courier", NORMAL = "normal", BOLD = "bold", ITALIC = "italic", BOLD_ITALIC = "bolditalic", encoding = 'StandardEncoding', ZAPF = "zapfdingbats", standardFonts = [['Helvetica', HELVETICA, NORMAL], ['Helvetica-Bold', HELVETICA, BOLD], ['Helvetica-Oblique', HELVETICA, ITALIC], ['Helvetica-BoldOblique', HELVETICA, BOLD_ITALIC], ['Courier', COURIER, NORMAL], ['Courier-Bold', COURIER, BOLD], ['Courier-Oblique', COURIER, ITALIC], ['Courier-BoldOblique', COURIER, BOLD_ITALIC], ['Times-Roman', TIMES, NORMAL], ['Times-Bold', TIMES, BOLD], ['Times-Italic', TIMES, ITALIC], ['Times-BoldItalic', TIMES, BOLD_ITALIC], ['ZapfDingbats', ZAPF]]; for (var i = 0, l = standardFonts.length; i < l; i++) { var fontKey = addFont(standardFonts[i][0], standardFonts[i][1], standardFonts[i][2], encoding); // adding aliases for standard fonts, this time matching the capitalization var parts = standardFonts[i][0].split('-'); addToFontDictionary(fontKey, parts[0], parts[1] || ''); } events.publish('addFonts', { fonts: fonts, dictionary: fontmap }); }, SAFE = function __safeCall(fn) { fn.foo = function __safeCallWrapper() { try { return fn.apply(this, arguments); } catch (e) { var stack = e.stack || ''; if (~stack.indexOf(' at ')) stack = stack.split(" at ")[1]; var m = "Error in function " + stack.split("\n")[0].split('<')[0] + ": " + e.message; if (global.console) { global.console.error(m, e); if (global.alert) alert(m); } else { throw new Error(m); } } }; fn.foo.bar = fn; return fn.foo; }, to8bitStream = function to8bitStream(text, flags) { /** * PDF 1.3 spec: * "For text strings encoded in Unicode, the first two bytes must be 254 followed by * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely * to be a meaningful beginning of a word or phrase.) The remainder of the * string consists of Unicode character codes, according to the UTF-16 encoding * specified in the Unicode standard, version 2.0. Commonly used Unicode values * are represented as 2 bytes per character, with the high-order byte appearing first * in the string." * * In other words, if there are chars in a string with char code above 255, we * recode the string to UCS2 BE - string doubles in length and BOM is prepended. * * HOWEVER! * Actual *content* (body) text (as opposed to strings used in document properties etc) * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID) * * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode * code page. There, however, all characters in the stream are treated as GIDs, * including BOM, which is the reason we need to skip BOM in content text (i.e. that * that is tied to a font). * * To signal this "special" PDFEscape / to8bitStream handling mode, * API.text() function sets (unless you overwrite it with manual values * given to API.text(.., flags) ) * flags.autoencode = true * flags.noBOM = true * * =================================================================================== * `flags` properties relied upon: * .sourceEncoding = string with encoding label. * "Unicode" by default. = encoding of the incoming text. * pass some non-existing encoding name * (ex: 'Do not touch my strings! I know what I am doing.') * to make encoding code skip the encoding step. * .outputEncoding = Either valid PDF encoding name * (must be supported by jsPDF font metrics, otherwise no encoding) * or a JS object, where key = sourceCharCode, value = outputCharCode * missing keys will be treated as: sourceCharCode === outputCharCode * .noBOM * See comment higher above for explanation for why this is important * .autoencode * See comment higher above for explanation for why this is important */ var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch; flags = flags || {}; sourceEncoding = flags.sourceEncoding || 'Unicode'; outputEncoding = flags.outputEncoding; // This 'encoding' section relies on font metrics format // attached to font objects by, among others, // "Willow Systems' standard_font_metrics plugin" // see jspdf.plugin.standard_font_metrics.js for format // of the font.metadata.encoding Object. // It should be something like // .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}} // .widths = {0:width, code:width, ..., 'fof':divisor} // .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...} if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) { encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding; // each font has default encoding. Some have it clearly defined. if (!outputEncoding && fonts[activeFontKey].encoding) { outputEncoding = fonts[activeFontKey].encoding; } // Hmmm, the above did not work? Let's try again, in different place. if (!outputEncoding && encodingBlock.codePages) { outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default } if (typeof outputEncoding === 'string') { outputEncoding = encodingBlock[outputEncoding]; } // we want output encoding to be a JS Object, where // key = sourceEncoding's character code and // value = outputEncoding's character code. if (outputEncoding) { isUnicode = false; newtext = []; for (i = 0, l = text.length; i < l; i++) { ch = outputEncoding[text.charCodeAt(i)]; if (ch) { newtext.push(String.fromCharCode(ch)); } else { newtext.push(text[i]); } // since we are looping over chars anyway, might as well // check for residual unicodeness if (newtext[i].charCodeAt(0) >> 8) { /* more than 255 */ isUnicode = true; } } text = newtext.join(''); } } i = text.length; // isUnicode may be set to false above. Hence the triple-equal to undefined while (isUnicode === undefined && i !== 0) { if (text.charCodeAt(i - 1) >> 8) { /* more than 255 */ isUnicode = true; } i--; } if (!isUnicode) { return text; } newtext = flags.noBOM ? [] : [254, 255]; for (i = 0, l = text.length; i < l; i++) { ch = text.charCodeAt(i); bch = ch >> 8; // divide by 256 if (bch >> 8) { /* something left after dividing by 256 second time */ throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE"); } newtext.push(bch); newtext.push(ch - (bch << 8)); } return String.fromCharCode.apply(undefined, newtext); }, pdfEscape = function pdfEscape(text, flags) { /** * Replace '/', '(', and ')' with pdf-safe versions * * Doing to8bitStream does NOT make this PDF display unicode text. For that * we also need to reference a unicode font and embed it - royal pain in the rear. * * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars, * which JavaScript Strings are happy to provide. So, while we still cannot display * 2-byte characters property, at least CONDITIONALLY converting (entire string containing) * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF * is still parseable. * This will allow immediate support for unicode in document properties strings. */ return to8bitStream(text, flags).replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)'); }, putInfo = function putInfo() { out('/Producer (jsPDF ' + jsPDF.version + ')'); for (var key in documentProperties) { if (documentProperties.hasOwnProperty(key) && documentProperties[key]) { out('/' + key.substr(0, 1).toUpperCase() + key.substr(1) + ' (' + pdfEscape(documentProperties[key]) + ')'); } } var created = new Date(), tzoffset = created.getTimezoneOffset(), tzsign = tzoffset < 0 ? '+' : '-', tzhour = Math.floor(Math.abs(tzoffset / 60)), tzmin = Math.abs(tzoffset % 60), tzstr = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join(''); out(['/CreationDate (D:', created.getFullYear(), padd2(created.getMonth() + 1), padd2(created.getDate()), padd2(created.getHours()), padd2(created.getMinutes()), padd2(created.getSeconds()), tzstr, ')'].join('')); }, putCatalog = function putCatalog() { out('/Type /Catalog'); out('/Pages 1 0 R'); // PDF13ref Section 7.2.1 if (!zoomMode) zoomMode = 'fullwidth'; switch (zoomMode) { case 'fullwidth': out('/OpenAction [3 0 R /FitH null]'); break; case 'fullheight': out('/OpenAction [3 0 R /FitV null]'); break; case 'fullpage': out('/OpenAction [3 0 R /Fit]'); break; case 'original': out('/OpenAction [3 0 R /XYZ null null 1]'); break; default: var pcn = '' + zoomMode; if (pcn.substr(pcn.length - 1) === '%') zoomMode = parseInt(zoomMode) / 100; if (typeof zoomMode === 'number') { out('/OpenAction [3 0 R /XYZ null null ' + f2(zoomMode) + ']'); } } if (!layoutMode) layoutMode = 'continuous'; switch (layoutMode) { case 'continuous': out('/PageLayout /OneColumn'); break; case 'single': out('/PageLayout /SinglePage'); break; case 'two': case 'twoleft': out('/PageLayout /TwoColumnLeft'); break; case 'tworight': out('/PageLayout /TwoColumnRight'); break; } if (pageMode) { /** * A name object specifying how the document should be displayed when opened: * UseNone : Neither document outline nor thumbnail images visible -- DEFAULT * UseOutlines : Document outline visible * UseThumbs : Thumbnail images visible * FullScreen : Full-screen mode, with no menu bar, window controls, or any other window visible */ out('/PageMode /' + pageMode); } events.publish('putCatalog'); }, putTrailer = function putTrailer() { out('/Size ' + (objectNumber + 1)); out('/Root ' + objectNumber + ' 0 R'); out('/Info ' + (objectNumber - 1) + ' 0 R'); }, beginPage = function beginPage(width, height) { // Dimensions are stored as user units and converted to points on output var orientation = typeof height === 'string' && height.toLowerCase(); if (typeof width === 'string') { var format = width.toLowerCase(); if (pageFormats.hasOwnProperty(format)) { width = pageFormats[format][0] / k; height = pageFormats[format][1] / k; } } if (Array.isArray(width)) { height = width[1]; width = width[0]; } if (orientation) { switch (orientation.substr(0, 1)) { case 'l': if (height > width) orientation = 's'; break; case 'p': if (width > height) orientation = 's'; break; } if (orientation === 's') { tmp = width; width = height; height = tmp; } } outToPages = true; pages[++page] = []; pagedim[page] = { width: Number(width) || pageWidth, height: Number(height) || pageHeight }; pagesContext[page] = {}; _setPage(page); }, _addPage = function _addPage() { beginPage.apply(this, arguments); // Set line width out(f2(lineWidth * k) + ' w'); // Set draw color out(drawColor); // resurrecting non-default line caps, joins if (lineCapID !== 0) { out(lineCapID + ' J'); } if (lineJoinID !== 0) { out(lineJoinID + ' j'); } events.publish('addPage', { pageNumber: page }); }, _deletePage = function _deletePage(n) { if (n > 0 && n <= page) { pages.splice(n, 1); pagedim.splice(n, 1); page--; if (currentPage > page) { currentPage = page; } this.setPage(currentPage); } }, _setPage = function _setPage(n) { if (n > 0 && n <= page) { currentPage = n; pageWidth = pagedim[n].width; pageHeight = pagedim[n].height; } }, /** * Returns a document-specific font key - a label assigned to a * font name + font type combination at the time the font was added * to the font inventory. * * Font key is used as label for the desired font for a block of text * to be added to the PDF document stream. * @private * @function * @param fontName {String} can be undefined on "falthy" to indicate "use current" * @param fontStyle {String} can be undefined on "falthy" to indicate "use current" * @returns {String} Font key. */ _getFont = function _getFont(fontName, fontStyle) { var key; fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName; fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle; if (fontName !== undefined) { fontName = fontName.toLowerCase(); } switch (fontName) { case 'sans-serif': case 'verdana': case 'arial': case 'helvetica': fontName = 'helvetica'; break; case 'fixed': case 'monospace': case 'terminal': case 'courier': fontName = 'courier'; break; case 'serif': case 'cursive': case 'fantasy': default: fontName = 'times'; break; } try { // get a string like 'F3' - the KEY corresponding tot he font + type combination. key = fontmap[fontName][fontStyle]; } catch (e) {} if (!key) { //throw new Error("Unable to look up font label for font '" + fontName + "', '" //+ fontStyle + "'. Refer to getFontList() for available fonts."); key = fontmap['times'][fontStyle]; if (key == null) { key = fontmap['times']['normal']; } } return key; }, buildDocument = function buildDocument() { outToPages = false; // switches out() to content objectNumber = 2; content_length = 0; content = []; offsets = []; additionalObjects = []; // Added for AcroForm events.publish('buildDocument'); // putHeader() out('%PDF-' + pdfVersion); putPages(); // Must happen after putPages // Modifies current object Id putAdditionalObjects(); putResources(); // Info newObject(); out('<<'); putInfo(); out('>>'); out('endobj'); // Catalog newObject(); out('<<'); putCatalog(); out('>>'); out('endobj'); // Cross-ref var o = content_length, i, p = "0000000000"; out('xref'); out('0 ' + (objectNumber + 1)); out(p + ' 65535 f '); for (i = 1; i <= objectNumber; i++) { var offset = offsets[i]; if (typeof offset === 'function') { out((p + offsets[i]()).slice(-10) + ' 00000 n '); } else { out((p + offsets[i]).slice(-10) + ' 00000 n '); } } // Trailer out('trailer'); out('<<'); putTrailer(); out('>>'); out('startxref'); out('' + o); out('%%EOF'); outToPages = true; return content.join('\n'); }, getStyle = function getStyle(style) { // see path-painting operators in PDF spec var op = 'S'; // stroke if (style === 'F') { op = 'f'; // fill } else if (style === 'FD' || style === 'DF') { op = 'B'; // both } else if (style === 'f' || style === 'f*' || style === 'B' || style === 'B*') { /* Allow direct use of these PDF path-painting operators: - f fill using nonzero winding number rule - f* fill using even-odd rule - B fill then stroke with fill using non-zero winding number rule - B* fill then stroke with fill using even-odd rule */ op = style; } return op; }, getArrayBuffer = function getArrayBuffer() { var data = buildDocument(), len = data.length, ab = new ArrayBuffer(len), u8 = new Uint8Array(ab); while (len--) { u8[len] = data.charCodeAt(len); }return ab; }, getBlob = function getBlob() { return new Blob([getArrayBuffer()], { type: "application/pdf" }); }, /** * Generates the PDF document. * * If `type` argument is undefined, output is raw body of resulting PDF returned as a string. * * @param {String} type A string identifying one of the possible output types. * @param {Object} options An object providing some additional signalling to PDF generator. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name output */ _output = SAFE(function (type, options) { var datauri = ('' + type).substr(0, 6) === 'dataur' ? 'data:application/pdf;base64,' + btoa(buildDocument()) : 0; switch (type) { case undefined: return buildDocument(); case 'save': if (navigator.getUserMedia) { if (global.URL === undefined || global.URL.createObjectURL === undefined) { return API.output('dataurlnewwindow'); } } saveAs(getBlob(), options); if (typeof saveAs.unload === 'function') { if (global.setTimeout) { setTimeout(saveAs.unload, 911); } } break; case 'arraybuffer': return getArrayBuffer(); case 'blob': return getBlob(); case 'bloburi': case 'bloburl': // User is responsible of calling revokeObjectURL return global.URL && global.URL.createObjectURL(getBlob()) || void 0; case 'datauristring': case 'dataurlstring': return datauri; case 'dataurlnewwindow': var nW = global.open(datauri); if (nW || typeof safari === "undefined") return nW; /* pass through */ case 'datauri': case 'dataurl': return global.document.location.href = datauri; default: throw new Error('Output type "' + type + '" is not supported.'); } // @TODO: Add different output options }); switch (unit) { case 'pt': k = 1; break; case 'mm': k = 72 / 25.4000508; break; case 'cm': k = 72 / 2.54000508; break; case 'in': k = 72; break; case 'px': k = 96 / 72; break; case 'pc': k = 12; break; case 'em': k = 12; break; case 'ex': k = 6; break; default: throw 'Invalid unit: ' + unit; } //--------------------------------------- // Public API /** * Object exposing internal API to plugins * @public */ API.internal = { 'pdfEscape': pdfEscape, 'getStyle': getStyle, /** * Returns {FontObject} describing a particular font. * @public * @function * @param fontName {String} (Optional) Font's family name * @param fontStyle {String} (Optional) Font's style variation name (Example:"Italic") * @returns {FontObject} */ 'getFont': function getFont() { return fonts[_getFont.apply(API, arguments)]; }, 'getFontSize': function getFontSize() { return activeFontSize; }, 'getLineHeight': function getLineHeight() { return activeFontSize * lineHeightProportion; }, 'write': function write(string1 /*, string2, string3, etc */) { out(arguments.length === 1 ? string1 : Array.prototype.join.call(arguments, ' ')); }, 'getCoordinateString': function getCoordinateString(value) { return f2(value * k); }, 'getVerticalCoordinateString': function getVerticalCoordinateString(value) { return f2((pageHeight - value) * k); }, 'collections': {}, 'newObject': newObject, 'newAdditionalObject': newAdditionalObject, 'newObjectDeferred': newObjectDeferred, 'newObjectDeferredBegin': newObjectDeferredBegin, 'putStream': putStream, 'events': events, // ratio that you use in multiplication of a given "size" number to arrive to 'point' // units of measurement. // scaleFactor is set at initialization of the document and calculated against the stated // default measurement units for the document. // If default is "mm", k is the number that will turn number in 'mm' into 'points' number. // through multiplication. 'scaleFactor': k, 'pageSize': { get width() { return pageWidth; }, get height() { return pageHeight; } }, 'output': function output(type, options) { return _output(type, options); }, 'getNumberOfPages': function getNumberOfPages() { return pages.length - 1; }, 'pages': pages, 'out': out, 'f2': f2, 'getPageInfo': function getPageInfo(pageNumberOneBased) { var objId = (pageNumberOneBased - 1) * 2 + 3; return { objId: objId, pageNumber: pageNumberOneBased, pageContext: pagesContext[pageNumberOneBased] }; }, 'getCurrentPageInfo': function getCurrentPageInfo() { var objId = (currentPage - 1) * 2 + 3; return { objId: objId, pageNumber: currentPage, pageContext: pagesContext[currentPage] }; }, 'getPDFVersion': function getPDFVersion() { return pdfVersion; } }; /** * Adds (and transfers the focus to) new page to the PDF document. * @function * @returns {jsPDF} * * @methodOf jsPDF# * @name addPage */ API.addPage = function () { _addPage.apply(this, arguments); return this; }; /** * Adds (and transfers the focus to) new page to the PDF document. * @function * @returns {jsPDF} * * @methodOf jsPDF# * @name setPage * @param {Number} page Switch the active page to the page number specified * @example * doc = jsPDF() * doc.addPage() * doc.addPage() * doc.text('I am on page 3', 10, 10) * doc.setPage(1) * doc.text('I am on page 1', 10, 10) */ API.setPage = function () { _setPage.apply(this, arguments); return this; }; API.insertPage = function (beforePage) { this.addPage(); this.movePage(currentPage, beforePage); return this; }; API.movePage = function (targetPage, beforePage) { if (targetPage > beforePage) { var tmpPages = pages[targetPage]; var tmpPagedim = pagedim[targetPage]; var tmpPagesContext = pagesContext[targetPage]; for (var i = targetPage; i > beforePage; i--) { pages[i] = pages[i - 1]; pagedim[i] = pagedim[i - 1]; pagesContext[i] = pagesContext[i - 1]; } pages[beforePage] = tmpPages; pagedim[beforePage] = tmpPagedim; pagesContext[beforePage] = tmpPagesContext; this.setPage(beforePage); } else if (targetPage < beforePage) { var tmpPages = pages[targetPage]; var tmpPagedim = pagedim[targetPage]; var tmpPagesContext = pagesContext[targetPage]; for (var i = targetPage; i < beforePage; i++) { pages[i] = pages[i + 1]; pagedim[i] = pagedim[i + 1]; pagesContext[i] = pagesContext[i + 1]; } pages[beforePage] = tmpPages; pagedim[beforePage] = tmpPagedim; pagesContext[beforePage] = tmpPagesContext; this.setPage(beforePage); } return this; }; API.deletePage = function () { _deletePage.apply(this, arguments); return this; }; /** * Set the display mode options of the page like zoom and layout. * * @param {integer|String} zoom You can pass an integer or percentage as * a string. 2 will scale the document up 2x, '200%' will scale up by the * same amount. You can also set it to 'fullwidth', 'fullheight', * 'fullpage', or 'original'. * * Only certain PDF readers support this, such as Adobe Acrobat * * @param {String} layout Layout mode can be: 'continuous' - this is the * default continuous scroll. 'single' - the single page mode only shows one * page at a time. 'twoleft' - two column left mode, first page starts on * the left, and 'tworight' - pages are laid out in two columns, with the * first page on the right. This would be used for books. * @param {String} pmode 'UseOutlines' - it shows the * outline of the document on the left. 'UseThumbs' - shows thumbnails along * the left. 'FullScreen' - prompts the user to enter fullscreen mode. * * @function * @returns {jsPDF} * @name setDisplayMode */ API.setDisplayMode = function (zoom, layout, pmode) { zoomMode = zoom; layoutMode = layout; pageMode = pmode; var validPageModes = [undefined, null, 'UseNone', 'UseOutlines', 'UseThumbs', 'FullScreen']; if (validPageModes.indexOf(pmode) == -1) { throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.'); } return this; }, /** * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings. * * @function * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call. * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Object} flags Collection of settings signalling how the text must be encoded. Defaults are sane. If you think you want to pass some flags, you likely can read the source. * @returns {jsPDF} * @methodOf jsPDF# * @name text */ API.text = function (text, x, y, flags, angle, align) { /** * Inserts something like this into PDF * BT * /F1 16 Tf % Font name + size * 16 TL % How many units down for next line in multiline text * 0 g % color * 28.35 813.54 Td % position * (line one) Tj * T* (line two) Tj * T* (line three) Tj * ET */ function ESC(s) { s = s.split("\t").join(Array(options.TabLen || 9).join(" ")); return pdfEscape(s, flags); } // Pre-August-2012 the order of arguments was function(x, y, text, flags) // in effort to make all calls have similar signature like // function(data, coordinates... , miscellaneous) // this method had its args flipped. // code below allows backward compatibility with old arg order. if (typeof text === 'number') { tmp = y; y = x; x = text; text = tmp; } // If there are any newlines in text, we assume // the user wanted to print multiple lines, so break the // text up into an array. If the text is already an array, // we assume the user knows what they are doing. // Convert text into an array anyway to simplify // later code. if (typeof text === 'string') { if (text.match(/[\n\r]/)) { text = text.split(/\r\n|\r|\n/g); } else { text = [text]; } } if (typeof angle === 'string') { align = angle; angle = null; } if (typeof flags === 'string') { align = flags; flags = null; } if (typeof flags === 'number') { angle = flags; flags = null; } var xtra = '', mode = 'Td', todo; if (angle) { angle *= Math.PI / 180; var c = Math.cos(angle), s = Math.sin(angle); xtra = [f2(c), f2(s), f2(s * -1), f2(c), ''].join(" "); mode = 'Tm'; } flags = flags || {}; if (!('noBOM' in flags)) flags.noBOM = true; if (!('autoencode' in flags)) flags.autoencode = true; var strokeOption = ''; var pageContext = this.internal.getCurrentPageInfo().pageContext; if (true === flags.stroke) { if (pageContext.lastTextWasStroke !== true) { strokeOption = '1 Tr\n'; pageContext.lastTextWasStroke = true; } } else { if (pageContext.lastTextWasStroke) { strokeOption = '0 Tr\n'; } pageContext.lastTextWasStroke = false; } if (typeof this._runningPageHeight === 'undefined') { this._runningPageHeight = 0; } if (typeof text === 'string') { text = ESC(text); } else if (Object.prototype.toString.call(text) === '[object Array]') { // we don't want to destroy original text array, so cloning it var sa = text.concat(), da = [], len = sa.length; // we do array.join('text that must not be PDFescaped") // thus, pdfEscape each component separately while (len--) { da.push(ESC(sa.shift())); } var linesLeft = Math.ceil((pageHeight - y - this._runningPageHeight) * k / (activeFontSize * lineHeightProportion)); if (0 <= linesLeft && linesLeft < da.length + 1) { //todo = da.splice(linesLeft-1); } if (align) { var left, prevX, maxLineLength, leading = activeFontSize * lineHeightProportion, lineWidths = text.map(function (v) { return this.getStringUnitWidth(v) * activeFontSize / k; }, this); maxLineLength = Math.max.apply(Math, lineWidths); // The first line uses the "main" Td setting, // and the subsequent lines are offset by the // previous line's x coordinate. if (align === "center") { // The passed in x coordinate defines // the center point. left = x - maxLineLength / 2; x -= lineWidths[0] / 2; } else if (align === "right") { // The passed in x coordinate defines the // rightmost point of the text. left = x - maxLineLength; x -= lineWidths[0]; } else { throw new Error('Unrecognized alignment option, use "center" or "right".'); } prevX = x; text = da[0]; for (var i = 1, len = da.length; i < len; i++) { var delta = maxLineLength - lineWidths[i]; if (align === "center") delta /= 2; // T* = x-offset leading Td ( text ) text += ") Tj\n" + (left - prevX + delta) + " -" + leading + " Td (" + da[i]; prevX = left + delta; } } else { text = da.join(") Tj\nT* ("); } } else { throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.'); } // Using "'" ("go next line and render text" mark) would save space but would complicate our rendering code, templates // BT .. ET does NOT have default settings for Tf. You must state that explicitely every time for BT .. ET // if you want text transformation matrix (+ multiline) to work reliably (which reads sizes of things from font declarations) // Thus, there is NO useful, *reliable* concept of "default" font for a page. // The fact that "default" (reuse font used before) font worked before in basic cases is an accident // - readers dealing smartly with brokenness of jsPDF's markup. var curY; if (todo) { //this.addPage(); //this._runningPageHeight += y - (activeFontSize * 1.7 / k); //curY = f2(pageHeight - activeFontSize * 1.7 /k); } else { curY = f2((pageHeight - y) * k); } //curY = f2((pageHeight - (y - this._runningPageHeight)) * k); // if (curY < 0){ // console.log('auto page break'); // this.addPage(); // this._runningPageHeight = y - (activeFontSize * 1.7 / k); // curY = f2(pageHeight - activeFontSize * 1.7 /k); // } out('BT\n/' + activeFontKey + ' ' + activeFontSize + ' Tf\n' + // font face, style, size activeFontSize * lineHeightProportion + ' TL\n' + // line spacing strokeOption + // stroke option textColor + '\n' + xtra + f2(x * k) + ' ' + curY + ' ' + mode + '\n(' + text + ') Tj\nET'); if (todo) { //this.text( todo, x, activeFontSize * 1.7 / k); //this.text( todo, x, this._runningPageHeight + (activeFontSize * 1.7 / k)); this.text(todo, x, y); // + (activeFontSize * 1.7 / k)); } return this; }; /** * Letter spacing method to print text with gaps * * @function * @param {String|Array} text String to be added to the page. * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} spacing Spacing (in units declared at inception) * @returns {jsPDF} * @methodOf jsPDF# * @name lstext * @deprecated We'll be removing this function. It doesn't take character width into account. */ API.lstext = function (text, x, y, spacing) { console.warn('jsPDF.lstext is deprecated'); for (var i = 0, len = text.length; i < len; i++, x += spacing) { this.text(text[i], x, y); }return this; }; API.line = function (x1, y1, x2, y2) { return this.lines([[x2 - x1, y2 - y1]], x1, y1); }; API.clip = function () { // By patrick-roberts, github.com/MrRio/jsPDF/issues/328 // Call .clip() after calling .rect() with a style argument of null out('W'); // clip out('S'); // stroke path; necessary for clip to work }; /** * This fixes the previous function clip(). Perhaps the 'stroke path' hack was due to the missing 'n' instruction? * We introduce the fixed version so as to not break API. * @param fillRule */ API.clip_fixed = function (fillRule) { // Call .clip() after calling drawing ops with a style argument of null // W is the PDF clipping op if ('evenodd' === fillRule) { out('W*'); } else { out('W'); } // End the path object without filling or stroking it. // This operator is a path-painting no-op, used primarily for the side effect of changing the current clipping path // (see Section 4.4.3, “Clipping Path Operators”) out('n'); }; /** * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates. * All data points in `lines` are relative to last line origin. * `x`, `y` become x1,y1 for first line / curve in the set. * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point. * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1. * * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, 10) // line, line, bezier curve, line * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves). * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction. * @param {String} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. * @param {Boolean} closed If true, the path is closed with a straight line from the end of the last curve to the starting point. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name lines */ API.lines = function (lines, x, y, scale, style, closed) { var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4; // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style) // in effort to make all calls have similar signature like // function(content, coordinateX, coordinateY , miscellaneous) // this method had its args flipped. // code below allows backward compatibility with old arg order. if (typeof lines === 'number') { tmp = y; y = x; x = lines; lines = tmp; } scale = scale || [1, 1]; // starting point out(f3(x * k) + ' ' + f3((pageHeight - y) * k) + ' m '); scalex = scale[0]; scaley = scale[1]; l = lines.length; //, x2, y2 // bezier only. In page default measurement "units", *after* scaling //, x3, y3 // bezier only. In page default measurement "units", *after* scaling // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling x4 = x; // last / ending point = starting point for first item. y4 = y; // last / ending point = starting point for first item. for (i = 0; i < l; i++) { leg = lines[i]; if (leg.length === 2) { // simple line x4 = leg[0] * scalex + x4; // here last x4 was prior ending point y4 = leg[1] * scaley + y4; // here last y4 was prior ending point out(f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' l'); } else { // bezier curve x2 = leg[0] * scalex + x4; // here last x4 is prior ending point y2 = leg[1] * scaley + y4; // here last y4 is prior ending point x3 = leg[2] * scalex + x4; // here last x4 is prior ending point y3 = leg[3] * scaley + y4; // here last y4 is prior ending point x4 = leg[4] * scalex + x4; // here last x4 was prior ending point y4 = leg[5] * scaley + y4; // here last y4 was prior ending point out(f3(x2 * k) + ' ' + f3((pageHeight - y2) * k) + ' ' + f3(x3 * k) + ' ' + f3((pageHeight - y3) * k) + ' ' + f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' c'); } } if (closed) { out(' h'); } // stroking / filling / both the path if (style !== null) { out(getStyle(style)); } return this; }; /** * Adds a rectangle to PDF * * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} w Width (in units declared at inception of PDF document) * @param {Number} h Height (in units declared at inception of PDF document) * @param {String} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name rect */ API.rect = function (x, y, w, h, style) { var op = getStyle(style); out([f2(x * k), f2((pageHeight - y) * k), f2(w * k), f2(-h * k), 're'].join(' ')); if (style !== null) { out(getStyle(style)); } return this; }; /** * Adds a triangle to PDF * * @param {Number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {String} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name triangle */ API.triangle = function (x1, y1, x2, y2, x3, y3, style) { this.lines([[x2 - x1, y2 - y1], // vector to point 2 [x3 - x2, y3 - y2], // vector to point 3 [x1 - x3, y1 - y3] // closing vector back to point 1 ], x1, y1, // start of path [1, 1], style, true); return this; }; /** * Adds a rectangle with rounded corners to PDF * * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} w Width (in units declared at inception of PDF document) * @param {Number} h Height (in units declared at inception of PDF document) * @param {Number} rx Radius along x axis (in units declared at inception of PDF document) * @param {Number} rx Radius along y axis (in units declared at inception of PDF document) * @param {String} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name roundedRect */ API.roundedRect = function (x, y, w, h, rx, ry, style) { var MyArc = 4 / 3 * (Math.SQRT2 - 1); this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path [1, 1], style); return this; }; /** * Adds an ellipse to PDF * * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} rx Radius along x axis (in units declared at inception of PDF document) * @param {Number} rx Radius along y axis (in units declared at inception of PDF document) * @param {String} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name ellipse */ API.ellipse = function (x, y, rx, ry, style) { var lx = 4 / 3 * (Math.SQRT2 - 1) * rx, ly = 4 / 3 * (Math.SQRT2 - 1) * ry; out([f2((x + rx) * k), f2((pageHeight - y) * k), 'm', f2((x + rx) * k), f2((pageHeight - (y - ly)) * k), f2((x + lx) * k), f2((pageHeight - (y - ry)) * k), f2(x * k), f2((pageHeight - (y - ry)) * k), 'c'].join(' ')); out([f2((x - lx) * k), f2((pageHeight - (y - ry)) * k), f2((x - rx) * k), f2((pageHeight - (y - ly)) * k), f2((x - rx) * k), f2((pageHeight - y) * k), 'c'].join(' ')); out([f2((x - rx) * k), f2((pageHeight - (y + ly)) * k), f2((x - lx) * k), f2((pageHeight - (y + ry)) * k), f2(x * k), f2((pageHeight - (y + ry)) * k), 'c'].join(' ')); out([f2((x + lx) * k), f2((pageHeight - (y + ry)) * k), f2((x + rx) * k), f2((pageHeight - (y + ly)) * k), f2((x + rx) * k), f2((pageHeight - y) * k), 'c'].join(' ')); if (style !== null) { out(getStyle(style)); } return this; }; /** * Adds an circle to PDF * * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page * @param {Number} r Radius (in units declared at inception of PDF document) * @param {String} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name circle */ API.circle = function (x, y, r, style) { return this.ellipse(x, y, r, r, style); }; /** * Adds a properties to the PDF document * * @param {Object} A property_name-to-property_value object structure. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setProperties */ API.setProperties = function (properties) { // copying only those properties we can render. for (var property in documentProperties) { if (documentProperties.hasOwnProperty(property) && properties[property]) { documentProperties[property] = properties[property]; } } return this; }; /** * Sets font size for upcoming text elements. * * @param {Number} size Font size in points. * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setFontSize */ API.setFontSize = function (size) { activeFontSize = size; return this; }; /** * Sets text font face, variant for upcoming text elements. * See output of jsPDF.getFontList() for possible font names, styles. * * @param {String} fontName Font name or family. Example: "times" * @param {String} fontStyle Font style or variant. Example: "italic" * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setFont */ API.setFont = function (fontName, fontStyle) { activeFontKey = _getFont(fontName, fontStyle); // if font is not found, the above line blows up and we never go further return this; }; /** * Switches font style or variant for upcoming text elements, * while keeping the font face or family same. * See output of jsPDF.getFontList() for possible font names, styles. * * @param {String} style Font style or variant. Example: "italic" * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setFontStyle */ API.setFontStyle = API.setFontType = function (style) { activeFontKey = _getFont(undefined, style); // if font is not found, the above line blows up and we never go further return this; }; /** * Returns an object - a tree of fontName to fontStyle relationships available to * active PDF document. * * @public * @function * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... } * @methodOf jsPDF# * @name getFontList */ API.getFontList = function () { // TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added. var list = {}, fontName, fontStyle, tmp; for (fontName in fontmap) { if (fontmap.hasOwnProperty(fontName)) { list[fontName] = tmp = []; for (fontStyle in fontmap[fontName]) { if (fontmap[fontName].hasOwnProperty(fontStyle)) { tmp.push(fontStyle); } } } } return list; }; /** * Add a custom font. * * @param {String} Postscript name of the Font. Example: "Menlo-Regular" * @param {String} Name of font-family from @font-face definition. Example: "Menlo Regular" * @param {String} Font style. Example: "normal" * @function * @returns the {fontKey} (same as the internal method) * @methodOf jsPDF# * @name addFont */ API.addFont = function (postScriptName, fontName, fontStyle) { addFont(postScriptName, fontName, fontStyle, 'StandardEncoding'); }; /** * Sets line width for upcoming lines. * * @param {Number} width Line width (in units declared at inception of PDF document) * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setLineWidth */ API.setLineWidth = function (width) { out((width * k).toFixed(2) + ' w'); return this; }; /** * Sets the stroke color for upcoming elements. * * Depending on the number of arguments given, Gray, RGB, or CMYK * color space is implied. * * When only ch1 is given, "Gray" color space is implied and it * must be a value in the range from 0.00 (solid black) to to 1.00 (white) * if values are communicated as String types, or in range from 0 (black) * to 255 (white) if communicated as Number type. * The RGB-like 0-255 range is provided for backward compatibility. * * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each * value must be in the range from 0.00 (minimum intensity) to to 1.00 * (max intensity) if values are communicated as String types, or * from 0 (min intensity) to to 255 (max intensity) if values are communicated * as Number types. * The RGB-like 0-255 range is provided for backward compatibility. * * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each * value must be a in the range from 0.00 (0% concentration) to to * 1.00 (100% concentration) * * Because JavaScript treats fixed point numbers badly (rounds to * floating point nearest to binary representation) it is highly advised to * communicate the fractional numbers as String types, not JavaScript Number type. * * @param {Number|String} ch1 Color channel value * @param {Number|String} ch2 Color channel value * @param {Number|String} ch3 Color channel value * @param {Number|String} ch4 Color channel value * * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setDrawColor */ API.setDrawColor = function (ch1, ch2, ch3, ch4) { var color; if (ch2 === undefined || ch4 === undefined && ch1 === ch2 === ch3) { // Gray color space. if (typeof ch1 === 'string') { color = ch1 + ' G'; } else { color = f2(ch1 / 255) + ' G'; } } else if (ch4 === undefined) { // RGB if (typeof ch1 === 'string') { color = [ch1, ch2, ch3, 'RG'].join(' '); } else { color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), 'RG'].join(' '); } } else { // CMYK if (typeof ch1 === 'string') { color = [ch1, ch2, ch3, ch4, 'K'].join(' '); } else { color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), 'K'].join(' '); } } out(color); return this; }; /** * Sets the fill color for upcoming elements. * * Depending on the number of arguments given, Gray, RGB, or CMYK * color space is implied. * * When only ch1 is given, "Gray" color space is implied and it * must be a value in the range from 0.00 (solid black) to to 1.00 (white) * if values are communicated as String types, or in range from 0 (black) * to 255 (white) if communicated as Number type. * The RGB-like 0-255 range is provided for backward compatibility. * * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each * value must be in the range from 0.00 (minimum intensity) to to 1.00 * (max intensity) if values are communicated as String types, or * from 0 (min intensity) to to 255 (max intensity) if values are communicated * as Number types. * The RGB-like 0-255 range is provided for backward compatibility. * * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each * value must be a in the range from 0.00 (0% concentration) to to * 1.00 (100% concentration) * * Because JavaScript treats fixed point numbers badly (rounds to * floating point nearest to binary representation) it is highly advised to * communicate the fractional numbers as String types, not JavaScript Number type. * * @param {Number|String} ch1 Color channel value * @param {Number|String} ch2 Color channel value * @param {Number|String} ch3 Color channel value * @param {Number|String} ch4 Color channel value * * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setFillColor */ API.setFillColor = function (ch1, ch2, ch3, ch4) { var color; if (ch2 === undefined || ch4 === undefined && ch1 === ch2 === ch3) { // Gray color space. if (typeof ch1 === 'string') { color = ch1 + ' g'; } else { color = f2(ch1 / 255) + ' g'; } } else if (ch4 === undefined || (typeof ch4 === 'undefined' ? 'undefined' : _typeof(ch4)) === 'object') { // RGB if (typeof ch1 === 'string') { color = [ch1, ch2, ch3, 'rg'].join(' '); } else { color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), 'rg'].join(' '); } if (ch4 && ch4.a === 0) { //TODO Implement transparency. //WORKAROUND use white for now color = ['255', '255', '255', 'rg'].join(' '); } } else { // CMYK if (typeof ch1 === 'string') { color = [ch1, ch2, ch3, ch4, 'k'].join(' '); } else { color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), 'k'].join(' '); } } out(color); return this; }; /** * Sets the text color for upcoming elements. * If only one, first argument is given, * treats the value as gray-scale color value. * * @param {Number} r Red channel color value in range 0-255 or {String} r color value in hexadecimal, example: '#FFFFFF' * @param {Number} g Green channel color value in range 0-255 * @param {Number} b Blue channel color value in range 0-255 * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setTextColor */ API.setTextColor = function (r, g, b) { if (typeof r === 'string' && /^#[0-9A-Fa-f]{6}$/.test(r)) { var hex = parseInt(r.substr(1), 16); r = hex >> 16 & 255; g = hex >> 8 & 255; b = hex & 255; } if (r === 0 && g === 0 && b === 0 || typeof g === 'undefined') { textColor = f3(r / 255) + ' g'; } else { textColor = [f3(r / 255), f3(g / 255), f3(b / 255), 'rg'].join(' '); } return this; }; /** * Is an Object providing a mapping from human-readable to * integer flag values designating the varieties of line cap * and join styles. * * @returns {Object} * @fieldOf jsPDF# * @name CapJoinStyles */ API.CapJoinStyles = { 0: 0, 'butt': 0, 'but': 0, 'miter': 0, 1: 1, 'round': 1, 'rounded': 1, 'circle': 1, 2: 2, 'projecting': 2, 'project': 2, 'square': 2, 'bevel': 2 }; /** * Sets the line cap styles * See {jsPDF.CapJoinStyles} for variants * * @param {String|Number} style A string or number identifying the type of line cap * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setLineCap */ API.setLineCap = function (style) { var id = this.CapJoinStyles[style]; if (id === undefined) { throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles"); } lineCapID = id; out(id + ' J'); return this; }; /** * Sets the line join styles * See {jsPDF.CapJoinStyles} for variants * * @param {String|Number} style A string or number identifying the type of line join * @function * @returns {jsPDF} * @methodOf jsPDF# * @name setLineJoin */ API.setLineJoin = function (style) { var id = this.CapJoinStyles[style]; if (id === undefined) { throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles"); } lineJoinID = id; out(id + ' j'); return this; }; // Output is both an internal (for plugins) and external function API.output = _output; /** * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf') * @param {String} filename The filename including extension. * * @function * @returns {jsPDF} * @methodOf jsPDF# * @name save */ API.save = function (filename) { API.output('save', filename); }; // applying plugins (more methods) ON TOP of built-in API. // this is intentional as we allow plugins to override // built-ins for (var plugin in jsPDF.API) { if (jsPDF.API.hasOwnProperty(plugin)) { if (plugin === 'events' && jsPDF.API.events.length) { (function (events, newEvents) { // jsPDF.API.events is a JS Array of Arrays // where each Array is a pair of event name, handler // Events were added by plugins to the jsPDF instantiator. // These are always added to the new instance and some ran // during instantiation. var eventname, handler_and_args, i; for (i = newEvents.length - 1; i !== -1; i--) { // subscribe takes 3 args: 'topic', function, runonce_flag // if undefined, runonce is false. // users can attach callback directly, // or they can attach an array with [callback, runonce_flag] // that's what the "apply" magic is for below. eventname = newEvents[i][0]; handler_and_args = newEvents[i][1]; events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === 'function' ? [handler_and_args] : handler_and_args)); } })(events, jsPDF.API.events); } else { API[plugin] = jsPDF.API[plugin]; } } } ////////////////////////////////////////////////////// // continuing initialization of jsPDF Document object ////////////////////////////////////////////////////// // Add the first page automatically addFonts(); activeFontKey = 'F1'; _addPage(format, orientation); events.publish('initialized'); return API; } /** * jsPDF.API is a STATIC property of jsPDF class. * jsPDF.API is an object you can add methods and properties to. * The methods / properties you add will show up in new jsPDF objects. * * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics, * callbacks to this object. These will be reassigned to all new instances of jsPDF. * Examples: * jsPDF.API.events['initialized'] = function(){ 'this' is API object } * jsPDF.API.events['addFont'] = function(added_font_object){ 'this' is API object } * * @static * @public * @memberOf jsPDF * @name API * * @example * jsPDF.API.mymethod = function(){ * // 'this' will be ref to internal API object. see jsPDF source * // , so you can refer to built-in methods like so: * // this.line(....) * // this.text(....) * } * var pdfdoc = new jsPDF() * pdfdoc.mymethod() // <- !!!!!! */ jsPDF.API = { events: [] }; jsPDF.version = "1.x-master"; if (typeof define === 'function' && define.amd) { define('jsPDF', function () { return jsPDF; }); } else if (typeof module !== 'undefined' && module.exports) { module.exports = jsPDF; } else { global.jsPDF = jsPDF; } return jsPDF; }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || undefined); /** * jsPDF AcroForm Plugin * Copyright (c) 2016 Alexander Weidt, https://github.com/BiggA94 * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ (window.AcroForm = function (jsPDFAPI) { 'use strict'; var AcroForm = window.AcroForm; AcroForm.scale = function (x) { return x * (acroformPlugin.internal.scaleFactor / 1); // 1 = (96 / 72) }; AcroForm.antiScale = function (x) { return 1 / acroformPlugin.internal.scaleFactor * x; }; var acroformPlugin = { fields: [], xForms: [], /** * acroFormDictionaryRoot contains information about the AcroForm Dictionary * 0: The Event-Token, the AcroFormDictionaryCallback has * 1: The Object ID of the Root */ acroFormDictionaryRoot: null, /** * After the PDF gets evaluated, the reference to the root has to be reset, * this indicates, whether the root has already been printed out */ printedOut: false, internal: null }; jsPDF.API.acroformPlugin = acroformPlugin; var annotReferenceCallback = function annotReferenceCallback() { for (var i in this.acroformPlugin.acroFormDictionaryRoot.Fields) { var formObject = this.acroformPlugin.acroFormDictionaryRoot.Fields[i]; // add Annot Reference! if (formObject.hasAnnotation) { // If theres an Annotation Widget in the Form Object, put the Reference in the /Annot array createAnnotationReference.call(this, formObject); } } }; var createAcroForm = function createAcroForm() { if (this.acroformPlugin.acroFormDictionaryRoot) { //return; throw new Error("Exception while creating AcroformDictionary"); } // The Object Number of the AcroForm Dictionary this.acroformPlugin.acroFormDictionaryRoot = new AcroForm.AcroFormDictionary(); this.acroformPlugin.internal = this.internal; // add Callback for creating the AcroForm Dictionary this.acroformPlugin.acroFormDictionaryRoot._eventID = this.internal.events.subscribe('postPutResources', AcroFormDictionaryCallback); this.internal.events.subscribe('buildDocument', annotReferenceCallback); //buildDocument // Register event, that is triggered when the DocumentCatalog is written, in order to add /AcroForm this.internal.events.subscribe('putCatalog', putCatalogCallback); // Register event, that creates all Fields this.internal.events.subscribe('postPutPages', createFieldCallback); }; /** * Create the Reference to the widgetAnnotation, so that it gets referenced in the Annot[] int the+ * (Requires the Annotation Plugin) */ var createAnnotationReference = function createAnnotationReference(object) { var options = { type: 'reference', object: object }; jsPDF.API.annotationPlugin.annotations[this.internal.getPageInfo(object.page).pageNumber].push(options); }; var putForm = function putForm(formObject) { if (this.acroformPlugin.printedOut) { this.acroformPlugin.printedOut = false; this.acroformPlugin.acroFormDictionaryRoot = null; } if (!this.acroformPlugin.acroFormDictionaryRoot) { createAcroForm.call(this); } this.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject); }; // Callbacks var putCatalogCallback = function putCatalogCallback() { //Put reference to AcroForm to DocumentCatalog if (typeof this.acroformPlugin.acroFormDictionaryRoot != 'undefined') { // for safety, shouldn't normally be the case this.internal.write('/AcroForm ' + this.acroformPlugin.acroFormDictionaryRoot.objId + ' ' + 0 + ' R'); } else { console.log('Root missing...'); } }; /** * Adds /Acroform X 0 R to Document Catalog, * and creates the AcroForm Dictionary */ var AcroFormDictionaryCallback = function AcroFormDictionaryCallback() { // Remove event this.internal.events.unsubscribe(this.acroformPlugin.acroFormDictionaryRoot._eventID); delete this.acroformPlugin.acroFormDictionaryRoot._eventID; this.acroformPlugin.printedOut = true; }; /** * Creates the single Fields and writes them into the Document * * If fieldArray is set, use the fields that are inside it instead of the fields from the AcroRoot * (for the FormXObjects...) */ var createFieldCallback = function createFieldCallback(fieldArray) { var standardFields = !fieldArray; if (!fieldArray) { // in case there is no fieldArray specified, we want to print out the Fields of the AcroForm // Print out Root this.internal.newObjectDeferredBegin(this.acroformPlugin.acroFormDictionaryRoot.objId); this.internal.out(this.acroformPlugin.acroFormDictionaryRoot.getString()); } var fieldArray = fieldArray || this.acroformPlugin.acroFormDictionaryRoot.Kids; for (var i in fieldArray) { var key = i; var form = fieldArray[i]; var oldRect = form.Rect; if (form.Rect) { form.Rect = AcroForm.internal.calculateCoordinates.call(this, form.Rect); } // Start Writing the Object this.internal.newObjectDeferredBegin(form.objId); var content = ""; content += form.objId + " 0 obj\n"; content += "<<\n" + form.getContent(); form.Rect = oldRect; if (form.hasAppearanceStream && !form.appearanceStreamContent) { // Calculate Appearance var appearance = AcroForm.internal.calculateAppearanceStream.call(this, form); content += "/AP << /N " + appearance + " >>\n"; this.acroformPlugin.xForms.push(appearance); } // Assume AppearanceStreamContent is a Array with N,R,D (at least one of them!) if (form.appearanceStreamContent) { content += "/AP << "; // Iterate over N,R and D for (var k in form.appearanceStreamContent) { var value = form.appearanceStreamContent[k]; content += "/" + k + " "; content += "<< "; if (Object.keys(value).length >= 1 || Array.isArray(value)) { // appearanceStream is an Array or Object! for (var i in value) { var obj = value[i]; if (typeof obj === 'function') { // if Function is referenced, call it in order to get the FormXObject obj = obj.call(this, form); } content += "/" + i + " " + obj + " "; // In case the XForm is already used, e.g. OffState of CheckBoxes, don't add it if (!(this.acroformPlugin.xForms.indexOf(obj) >= 0)) this.acroformPlugin.xForms.push(obj); } } else { var obj = value; if (typeof obj === 'function') { // if Function is referenced, call it in order to get the FormXObject obj = obj.call(this, form); } content += "/" + i + " " + obj + " \n"; if (!(this.acroformPlugin.xForms.indexOf(obj) >= 0)) this.acroformPlugin.xForms.push(obj); } content += " >>\n"; } // appearance stream is a normal Object.. content += ">>\n"; } content += ">>\nendobj\n"; this.internal.out(content); } if (standardFields) { createXFormObjectCallback.call(this, this.acroformPlugin.xForms); } }; var createXFormObjectCallback = function createXFormObjectCallback(fieldArray) { for (var i in fieldArray) { var key = i; var form = fieldArray[i]; // Start Writing the Object this.internal.newObjectDeferredBegin(form && form.objId); var content = ""; content += form ? form.getString() : ''; this.internal.out(content); delete fieldArray[key]; } }; // Public: jsPDFAPI.addField = function (fieldObject) { //var opt = parseOptions(fieldObject); if (fieldObject instanceof AcroForm.TextField) { addTextField.call(this, fieldObject); } else if (fieldObject instanceof AcroForm.ChoiceField) { addChoiceField.call(this, fieldObject); } else if (fieldObject instanceof AcroForm.Button) { addButton.call(this, fieldObject); } else if (fieldObject instanceof AcroForm.ChildClass) { putForm.call(this, fieldObject); } else if (fieldObject) { // try to put.. putForm.call(this, fieldObject); } fieldObject.page = this.acroformPlugin.internal.getCurrentPageInfo().pageNumber; return this; }; // ############### sort in: /** * Button * FT = Btn */ var addButton = function addButton(options) { var options = options || new AcroForm.Field(); options.FT = '/Btn'; /** * Calculating the Ff entry: * * The Ff entry contains flags, that have to be set bitwise * In the Following the number in the Comment is the BitPosition */ var flags = options.Ff || 0; // 17, Pushbutton if (options.pushbutton) { // Options.pushbutton should be 1 or 0 flags = AcroForm.internal.setBitPosition(flags, 17); delete options.pushbutton; } //16, Radio if (options.radio) { //flags = options.Ff | options.radio << 15; flags = AcroForm.internal.setBitPosition(flags, 16); delete options.radio; } // 15, NoToggleToOff (Radio buttons only if (options.noToggleToOff) { //flags = options.Ff | options.noToggleToOff << 14; flags = AcroForm.internal.setBitPosition(flags, 15); //delete options.noToggleToOff; } // In case, there is no Flag set, it is a check-box options.Ff = flags; putForm.call(this, options); }; var addTextField = function addTextField(options) { var options = options || new AcroForm.Field(); options.FT = '/Tx'; /** * Calculating the Ff entry: * * The Ff entry contains flags, that have to be set bitwise * In the Following the number in the Comment is the BitPosition */ var flags = options.Ff || 0; // 13, multiline if (options.multiline) { // Set Flag flags = flags | 1 << 12; // Remove multiline from FieldObject //delete options.multiline; } // 14, Password if (options.password) { flags = flags | 1 << 13; //delete options.password; } // 21, FileSelect, PDF 1.4... if (options.fileSelect) { flags = flags | 1 << 20; //delete options.fileSelect; } // 23, DoNotSpellCheck, PDF 1.4... if (options.doNotSpellCheck) { flags = flags | 1 << 22; //delete options.doNotSpellCheck; } // 24, DoNotScroll, PDF 1.4... if (options.doNotScroll) { flags = flags | 1 << 23; //delete options.doNotScroll; } options.Ff = options.Ff || flags; // Add field putForm.call(this, options); }; var addChoiceField = function addChoiceField(opt) { var options = opt || new AcroForm.Field(); options.FT = '/Ch'; /** * Calculating the Ff entry: * * The Ff entry contains flags, that have to be set bitwise * In the Following the number in the Comment is the BitPosition */ var flags = options.Ff || 0; // 18, Combo (If not set, the choiceField is a listBox!!) if (options.combo) { // Set Flag flags = AcroForm.internal.setBitPosition(flags, 18); // Remove combo from FieldObject delete options.combo; } // 19, Edit if (options.edit) { flags = AcroForm.internal.setBitPosition(flags, 19); delete options.edit; } // 20, Sort if (options.sort) { flags = AcroForm.internal.setBitPosition(flags, 20); delete options.sort; } // 22, MultiSelect (PDF 1.4) if (options.multiSelect && this.internal.getPDFVersion() >= 1.4) { flags = AcroForm.internal.setBitPosition(flags, 22); delete options.multiSelect; } // 23, DoNotSpellCheck (PDF 1.4) if (options.doNotSpellCheck && this.internal.getPDFVersion() >= 1.4) { flags = AcroForm.internal.setBitPosition(flags, 23); delete options.doNotSpellCheck; } options.Ff = flags; //options.hasAnnotation = true; // Add field putForm.call(this, options); }; })(jsPDF.API); var AcroForm = window.AcroForm; AcroForm.internal = {}; AcroForm.createFormXObject = function (formObject) { var xobj = new AcroForm.FormXObject(); var height = AcroForm.Appearance.internal.getHeight(formObject) || 0; var width = AcroForm.Appearance.internal.getWidth(formObject) || 0; xobj.BBox = [0, 0, width, height]; return xobj; }; // Contains Methods for creating standard appearances AcroForm.Appearance = { CheckBox: { createAppearanceStream: function createAppearanceStream() { var appearance = { N: { On: AcroForm.Appearance.CheckBox.YesNormal }, D: { On: AcroForm.Appearance.CheckBox.YesPushDown, Off: AcroForm.Appearance.CheckBox.OffPushDown } }; return appearance; }, /** * If any other icons are needed, the number between the brackets can be changed * @returns {string} */ createMK: function createMK() { // 3-> Hook return "<< /CA (3)>>"; }, /** * Returns the standard On Appearance for a CheckBox * @returns {AcroForm.FormXObject} */ YesPushDown: function YesPushDown(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; // F13 is ZapfDingbats (Symbolic) formObject.Q = 1; // set text-alignment as centered var calcRes = AcroForm.internal.calculateX(formObject, "3", "ZapfDingbats", 50); stream += "0.749023 g\n\ 0 0 " + AcroForm.Appearance.internal.getWidth(formObject) + " " + AcroForm.Appearance.internal.getHeight(formObject) + " re\n\ f\n\ BMC\n\ q\n\ 0 0 1 rg\n\ /F13 " + calcRes.fontSize + " Tf 0 g\n\ BT\n"; stream += calcRes.text; stream += "ET\n\ Q\n\ EMC\n"; xobj.stream = stream; return xobj; }, YesNormal: function YesNormal(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; formObject.Q = 1; // set text-alignment as centered var calcRes = AcroForm.internal.calculateX(formObject, "3", "ZapfDingbats", AcroForm.Appearance.internal.getHeight(formObject) * 0.9); stream += "1 g\n\ 0 0 " + AcroForm.Appearance.internal.getWidth(formObject) + " " + AcroForm.Appearance.internal.getHeight(formObject) + " re\n\ f\n\ q\n\ 0 0 1 rg\n\ 0 0 " + (AcroForm.Appearance.internal.getWidth(formObject) - 1) + " " + (AcroForm.Appearance.internal.getHeight(formObject) - 1) + " re\n\ W\n\ n\n\ 0 g\n\ BT\n\ /F13 " + calcRes.fontSize + " Tf 0 g\n"; stream += calcRes.text; stream += "ET\n\ Q\n"; xobj.stream = stream; return xobj; }, /** * Returns the standard Off Appearance for a CheckBox * @returns {AcroForm.FormXObject} */ OffPushDown: function OffPushDown(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; stream += "0.749023 g\n\ 0 0 " + AcroForm.Appearance.internal.getWidth(formObject) + " " + AcroForm.Appearance.internal.getHeight(formObject) + " re\n\ f\n"; xobj.stream = stream; return xobj; } }, RadioButton: { Circle: { createAppearanceStream: function createAppearanceStream(name) { var appearanceStreamContent = { D: { 'Off': AcroForm.Appearance.RadioButton.Circle.OffPushDown }, N: {} }; appearanceStreamContent.N[name] = AcroForm.Appearance.RadioButton.Circle.YesNormal; appearanceStreamContent.D[name] = AcroForm.Appearance.RadioButton.Circle.YesPushDown; return appearanceStreamContent; }, createMK: function createMK() { return "<< /CA (l)>>"; }, YesNormal: function YesNormal(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; // Make the Radius of the Circle relative to min(height, width) of formObject var DotRadius = AcroForm.Appearance.internal.getWidth(formObject) <= AcroForm.Appearance.internal.getHeight(formObject) ? AcroForm.Appearance.internal.getWidth(formObject) / 4 : AcroForm.Appearance.internal.getHeight(formObject) / 4; // The Borderpadding... DotRadius *= 0.9; var c = AcroForm.Appearance.internal.Bezier_C; /* The Following is a Circle created with Bezier-Curves. */ stream += "q\n\ 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ " + DotRadius + " 0 m\n\ " + DotRadius + " " + DotRadius * c + " " + DotRadius * c + " " + DotRadius + " 0 " + DotRadius + " c\n\ -" + DotRadius * c + " " + DotRadius + " -" + DotRadius + " " + DotRadius * c + " -" + DotRadius + " 0 c\n\ -" + DotRadius + " -" + DotRadius * c + " -" + DotRadius * c + " -" + DotRadius + " 0 -" + DotRadius + " c\n\ " + DotRadius * c + " -" + DotRadius + " " + DotRadius + " -" + DotRadius * c + " " + DotRadius + " 0 c\n\ f\n\ Q\n"; xobj.stream = stream; return xobj; }, YesPushDown: function YesPushDown(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; var DotRadius = AcroForm.Appearance.internal.getWidth(formObject) <= AcroForm.Appearance.internal.getHeight(formObject) ? AcroForm.Appearance.internal.getWidth(formObject) / 4 : AcroForm.Appearance.internal.getHeight(formObject) / 4; // The Borderpadding... DotRadius *= 0.9; // Save results for later use; no need to waste processor ticks on doing math var k = DotRadius * 2; // var c = AcroForm.Appearance.internal.Bezier_C; var kc = k * AcroForm.Appearance.internal.Bezier_C; var dc = DotRadius * AcroForm.Appearance.internal.Bezier_C; // stream += "0.749023 g\n\ // q\n\ // 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ // " + DotRadius * 2 + " 0 m\n\ // " + DotRadius * 2 + " " + DotRadius * 2 * c + " " + DotRadius * 2 * c + " " + DotRadius * 2 + " 0 " + DotRadius * 2 + " c\n\ // -" + DotRadius * 2 * c + " " + DotRadius * 2 + " -" + DotRadius * 2 + " " + DotRadius * 2 * c + " -" + DotRadius * 2 + " 0 c\n\ // -" + DotRadius * 2 + " -" + DotRadius * 2 * c + " -" + DotRadius * 2 * c + " -" + DotRadius * 2 + " 0 -" + DotRadius * 2 + " c\n\ // " + DotRadius * 2 * c + " -" + DotRadius * 2 + " " + DotRadius * 2 + " -" + DotRadius * 2 * c + " " + DotRadius * 2 + " 0 c\n\ // f\n\ // Q\n\ // 0 g\n\ // q\n\ // 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ // " + DotRadius + " 0 m\n\ // " + DotRadius + " " + DotRadius * c + " " + DotRadius * c + " " + DotRadius + " 0 " + DotRadius + " c\n\ // -" + DotRadius * c + " " + DotRadius + " -" + DotRadius + " " + DotRadius * c + " -" + DotRadius + " 0 c\n\ // -" + DotRadius + " -" + DotRadius * c + " -" + DotRadius * c + " -" + DotRadius + " 0 -" + DotRadius + " c\n\ // " + DotRadius * c + " -" + DotRadius + " " + DotRadius + " -" + DotRadius * c + " " + DotRadius + " 0 c\n\ // f\n\ // Q\n"; // FASTER VERSION with less processor ticks spent on math operations stream += "0.749023 g\n\ q\n\ 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ " + k + " 0 m\n\ " + k + " " + kc + " " + kc + " " + k + " 0 " + k + " c\n\ -" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c\n\ -" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c\n\ " + kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c\n\ f\n\ Q\n\ 0 g\n\ q\n\ 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ " + DotRadius + " 0 m\n\ " + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c\n\ -" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c\n\ -" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c\n\ " + dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c\n\ f\n\ Q\n"; xobj.stream = stream; return xobj; }, OffPushDown: function OffPushDown(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; var DotRadius = AcroForm.Appearance.internal.getWidth(formObject) <= AcroForm.Appearance.internal.getHeight(formObject) ? AcroForm.Appearance.internal.getWidth(formObject) / 4 : AcroForm.Appearance.internal.getHeight(formObject) / 4; // The Borderpadding... DotRadius *= 0.9; // Save results for later use; no need to waste processor ticks on doing math var k = DotRadius * 2; // var c = AcroForm.Appearance.internal.Bezier_C; var kc = k * AcroForm.Appearance.internal.Bezier_C; // stream += "0.749023 g\n\ // q\n\ // 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ // " + DotRadius * 2 + " 0 m\n\ // " + DotRadius * 2 + " " + DotRadius * 2 * c + " " + DotRadius * 2 * c + " " + DotRadius * 2 + " 0 " + DotRadius * 2 + " c\n\ // -" + DotRadius * 2 * c + " " + DotRadius * 2 + " -" + DotRadius * 2 + " " + DotRadius * 2 * c + " -" + DotRadius * 2 + " 0 c\n\ // -" + DotRadius * 2 + " -" + DotRadius * 2 * c + " -" + DotRadius * 2 * c + " -" + DotRadius * 2 + " 0 -" + DotRadius * 2 + " c\n\ // " + DotRadius * 2 * c + " -" + DotRadius * 2 + " " + DotRadius * 2 + " -" + DotRadius * 2 * c + " " + DotRadius * 2 + " 0 c\n\ // f\n\ // Q\n"; // FASTER VERSION with less processor ticks spent on math operations stream += "0.749023 g\n\ q\n\ 1 0 0 1 " + AcroForm.Appearance.internal.getWidth(formObject) / 2 + " " + AcroForm.Appearance.internal.getHeight(formObject) / 2 + " cm\n\ " + k + " 0 m\n\ " + k + " " + kc + " " + kc + " " + k + " 0 " + k + " c\n\ -" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c\n\ -" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c\n\ " + kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c\n\ f\n\ Q\n"; xobj.stream = stream; return xobj; } }, Cross: { /** * Creates the Actual AppearanceDictionary-References * @param name * @returns */ createAppearanceStream: function createAppearanceStream(name) { var appearanceStreamContent = { D: { 'Off': AcroForm.Appearance.RadioButton.Cross.OffPushDown }, N: {} }; appearanceStreamContent.N[name] = AcroForm.Appearance.RadioButton.Cross.YesNormal; appearanceStreamContent.D[name] = AcroForm.Appearance.RadioButton.Cross.YesPushDown; return appearanceStreamContent; }, createMK: function createMK() { return "<< /CA (8)>>"; }, YesNormal: function YesNormal(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; var cross = AcroForm.Appearance.internal.calculateCross(formObject); stream += "q\n\ 1 1 " + (AcroForm.Appearance.internal.getWidth(formObject) - 2) + " " + (AcroForm.Appearance.internal.getHeight(formObject) - 2) + " re\n\ W\n\ n\n\ " + cross.x1.x + " " + cross.x1.y + " m\n\ " + cross.x2.x + " " + cross.x2.y + " l\n\ " + cross.x4.x + " " + cross.x4.y + " m\n\ " + cross.x3.x + " " + cross.x3.y + " l\n\ s\n\ Q\n"; xobj.stream = stream; return xobj; }, YesPushDown: function YesPushDown(formObject) { var xobj = AcroForm.createFormXObject(formObject); var cross = AcroForm.Appearance.internal.calculateCross(formObject); var stream = ""; stream += "0.749023 g\n\ 0 0 " + AcroForm.Appearance.internal.getWidth(formObject) + " " + AcroForm.Appearance.internal.getHeight(formObject) + " re\n\ f\n\ q\n\ 1 1 " + (AcroForm.Appearance.internal.getWidth(formObject) - 2) + " " + (AcroForm.Appearance.internal.getHeight(formObject) - 2) + " re\n\ W\n\ n\n\ " + cross.x1.x + " " + cross.x1.y + " m\n\ " + cross.x2.x + " " + cross.x2.y + " l\n\ " + cross.x4.x + " " + cross.x4.y + " m\n\ " + cross.x3.x + " " + cross.x3.y + " l\n\ s\n\ Q\n"; xobj.stream = stream; return xobj; }, OffPushDown: function OffPushDown(formObject) { var xobj = AcroForm.createFormXObject(formObject); var stream = ""; stream += "0.749023 g\n\ 0 0 " + AcroForm.Appearance.internal.getWidth(formObject) + " " + AcroForm.Appearance.internal.getHeight(formObject) + " re\n\ f\n"; xobj.stream = stream; return xobj; } } }, /** * Returns the standard Appearance * @returns {AcroForm.FormXObject} */ createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) { var stream = ""; // Set Helvetica to Standard Font (size: auto) // Color: Black stream += "/Helv 0 Tf 0 g"; return stream; } }; AcroForm.Appearance.internal = { Bezier_C: 0.551915024494, calculateCross: function calculateCross(formObject) { var min = function min(x, y) { return x > y ? y : x; }; var width = AcroForm.Appearance.internal.getWidth(formObject); var height = AcroForm.Appearance.internal.getHeight(formObject); var a = min(width, height); var crossSize = a; var borderPadding = 2; // The Padding in px var cross = { x1: { // upperLeft x: (width - a) / 2, y: (height - a) / 2 + a }, x2: { // lowerRight x: (width - a) / 2 + a, y: (height - a) / 2 //borderPadding }, x3: { // lowerLeft x: (width - a) / 2, y: (height - a) / 2 //borderPadding }, x4: { // upperRight x: (width - a) / 2 + a, y: (height - a) / 2 + a } }; return cross; } }; AcroForm.Appearance.internal.getWidth = function (formObject) { return formObject.Rect[2]; //(formObject.Rect[2] - formObject.Rect[0]) || 0; }; AcroForm.Appearance.internal.getHeight = function (formObject) { return formObject.Rect[3]; //(formObject.Rect[1] - formObject.Rect[3]) || 0; }; // ########################## //### For inheritance: AcroForm.internal.inherit = function (child, parent) { var ObjectCreate = Object.create || function (o) { var F = function F() {}; F.prototype = o; return new F(); }; child.prototype = Object.create(parent.prototype); child.prototype.constructor = child; }; // ### Handy Functions: AcroForm.internal.arrayToPdfArray = function (array) { if (Array.isArray(array)) { var content = ' ['; for (var i in array) { var element = array[i].toString(); content += element; content += i < array.length - 1 ? ' ' : ''; } content += ']'; return content; } }; AcroForm.internal.toPdfString = function (string) { string = string || ""; // put Bracket at the Beginning of the String if (string.indexOf('(') !== 0) { string = '(' + string; } if (string.substring(string.length - 1) != ')') { string += '('; } return string; }; // ########################## // Classes // ########################## AcroForm.PDFObject = function () { // The Object ID in the PDF Object Model // todo var _objId; Object.defineProperty(this, 'objId', { get: function get() { if (!_objId) { if (this.internal) { _objId = this.internal.newObjectDeferred(); } else if (jsPDF.API.acroformPlugin.internal) { // todo - find better option, that doesn't rely on a Global Static var _objId = jsPDF.API.acroformPlugin.internal.newObjectDeferred(); } } if (!_objId) { console.log("Couldn't create Object ID"); } return _objId; }, configurable: false }); }; AcroForm.PDFObject.prototype.toString = function () { return this.objId + " 0 R"; }; AcroForm.PDFObject.prototype.getString = function () { var res = this.objId + " 0 obj\n<<"; var content = this.getContent(); res += content + ">>\n"; if (this.stream) { res += "stream\n"; res += this.stream; res += "endstream\n"; } res += "endobj\n"; return res; }; AcroForm.PDFObject.prototype.getContent = function () { /** * Prints out all enumerable Variables from the Object * @param fieldObject * @returns {string} */ var createContentFromFieldObject = function createContentFromFieldObject(fieldObject) { var content = ''; var keys = Object.keys(fieldObject).filter(function (key) { return key != 'content' && key != 'appearanceStreamContent' && key.substring(0, 1) != "_"; }); for (var i in keys) { var key = keys[i]; var value = fieldObject[key]; /*if (key == 'Rect' && value) { value = AcroForm.internal.calculateCoordinates.call(jsPDF.API.acroformPlugin.internal, value); }*/ if (value) { if (Array.isArray(value)) { content += '/' + key + ' ' + AcroForm.internal.arrayToPdfArray(value) + "\n"; } else if (value instanceof AcroForm.PDFObject) { // In case it is a reference to another PDFObject, take the referennce number content += '/' + key + ' ' + value.objId + " 0 R" + "\n"; } else { content += '/' + key + ' ' + value + '\n'; } } } return content; }; var object = ""; object += createContentFromFieldObject(this); return object; }; AcroForm.FormXObject = function () { AcroForm.PDFObject.call(this); this.Type = "/XObject"; this.Subtype = "/Form"; this.FormType = 1; this.BBox; this.Matrix; this.Resources = "2 0 R"; this.PieceInfo; var _stream; Object.defineProperty(this, 'Length', { enumerable: true, get: function get() { return _stream !== undefined ? _stream.length : 0; } }); Object.defineProperty(this, 'stream', { enumerable: false, set: function set(val) { _stream = val; }, get: function get() { if (_stream) { return _stream; } else { return null; } } }); }; AcroForm.internal.inherit(AcroForm.FormXObject, AcroForm.PDFObject); AcroForm.AcroFormDictionary = function () { AcroForm.PDFObject.call(this); var _Kids = []; Object.defineProperty(this, 'Kids', { enumerable: false, configurable: true, get: function get() { if (_Kids.length > 0) { return _Kids; } else { return; } } }); Object.defineProperty(this, 'Fields', { enumerable: true, configurable: true, get: function get() { return _Kids; } }); // Default Appearance this.DA; }; AcroForm.internal.inherit(AcroForm.AcroFormDictionary, AcroForm.PDFObject); // ##### The Objects, the User can Create: // The Field Object contains the Variables, that every Field needs // Rectangle for Appearance: lower_left_X, lower_left_Y, width, height AcroForm.Field = function () { 'use strict'; AcroForm.PDFObject.call(this); var _Rect; Object.defineProperty(this, 'Rect', { enumerable: true, configurable: false, get: function get() { if (!_Rect) { return; } var tmp = _Rect; //var calculatedRes = AcroForm.internal.calculateCoordinates(_Rect); // do later! return tmp; }, set: function set(val) { _Rect = val; } }); var _FT = ""; Object.defineProperty(this, 'FT', { enumerable: true, set: function set(val) { _FT = val; }, get: function get() { return _FT; } }); /** * The Partial name of the Field Object. * It has to be unique. */ var _T; Object.defineProperty(this, 'T', { enumerable: true, configurable: false, set: function set(val) { _T = val; }, get: function get() { if (!_T || _T.length < 1) { if (this instanceof AcroForm.ChildClass) { // In case of a Child from a Radio´Group, you don't need a FieldName!!! return; } return "(FieldObject" + AcroForm.Field.FieldNum++ + ")"; } if (_T.substring(0, 1) == "(" && _T.substring(_T.length - 1)) { return _T; } return "(" + _T + ")"; } }); var _DA; // Defines the default appearance (Needed for variable Text) Object.defineProperty(this, 'DA', { enumerable: true, get: function get() { if (!_DA) { return; } return '(' + _DA + ')'; }, set: function set(val) { _DA = val; } }); var _DV; // Defines the default value Object.defineProperty(this, 'DV', { enumerable: true, configurable: true, get: function get() { if (!_DV) { return; } return _DV; }, set: function set(val) { _DV = val; } }); //this.Type = "/Annot"; //this.Subtype = "/Widget"; Object.defineProperty(this, 'Type', { enumerable: true, get: function get() { return this.hasAnnotation ? "/Annot" : null; } }); Object.defineProperty(this, 'Subtype', { enumerable: true, get: function get() { return this.hasAnnotation ? "/Widget" : null; } }); /** * * @type {Array} */ this.BG; Object.defineProperty(this, 'hasAnnotation', { enumerable: false, get: function get() { if (this.Rect || this.BC || this.BG) { return true; } return false; } }); Object.defineProperty(this, 'hasAppearanceStream', { enumerable: false, configurable: true, writable: true }); Object.defineProperty(this, 'page', { enumerable: false, configurable: true, writable: true }); }; AcroForm.Field.FieldNum = 0; AcroForm.internal.inherit(AcroForm.Field, AcroForm.PDFObject); AcroForm.ChoiceField = function () { AcroForm.Field.call(this); // Field Type = Choice Field this.FT = "/Ch"; // options this.Opt = []; this.V = '()'; // Top Index this.TI = 0; /** * Defines, whether the * @type {boolean} */ this.combo = false; /** * Defines, whether the Choice Field is an Edit Field. * An Edit Field is automatically an Combo Field. */ Object.defineProperty(this, 'edit', { enumerable: true, set: function set(val) { if (val == true) { this._edit = true; // ComboBox has to be true this.combo = true; } else { this._edit = false; } }, get: function get() { if (!this._edit) { return false; } return this._edit; }, configurable: false }); this.hasAppearanceStream = true; Object.defineProperty(this, 'V', { get: function get() { AcroForm.internal.toPdfString(); } }); }; AcroForm.internal.inherit(AcroForm.ChoiceField, AcroForm.Field); window["ChoiceField"] = AcroForm.ChoiceField; AcroForm.ListBox = function () { AcroForm.ChoiceField.call(this); //var combo = true; }; AcroForm.internal.inherit(AcroForm.ListBox, AcroForm.ChoiceField); window["ListBox"] = AcroForm.ListBox; AcroForm.ComboBox = function () { AcroForm.ListBox.call(this); this.combo = true; }; AcroForm.internal.inherit(AcroForm.ComboBox, AcroForm.ListBox); window["ComboBox"] = AcroForm.ComboBox; AcroForm.EditBox = function () { AcroForm.ComboBox.call(this); this.edit = true; }; AcroForm.internal.inherit(AcroForm.EditBox, AcroForm.ComboBox); window["EditBox"] = AcroForm.EditBox; AcroForm.Button = function () { AcroForm.Field.call(this); this.FT = "/Btn"; //this.hasAnnotation = true; }; AcroForm.internal.inherit(AcroForm.Button, AcroForm.Field); window["Button"] = AcroForm.Button; AcroForm.PushButton = function () { AcroForm.Button.call(this); this.pushbutton = true; }; AcroForm.internal.inherit(AcroForm.PushButton, AcroForm.Button); window["PushButton"] = AcroForm.PushButton; AcroForm.RadioButton = function () { AcroForm.Button.call(this); this.radio = true; var _Kids = []; Object.defineProperty(this, 'Kids', { enumerable: true, get: function get() { if (_Kids.length > 0) { return _Kids; } } }); Object.defineProperty(this, '__Kids', { get: function get() { return _Kids; } }); var _noToggleToOff; Object.defineProperty(this, 'noToggleToOff', { enumerable: false, get: function get() { return _noToggleToOff; }, set: function set(val) { _noToggleToOff = val; } }); //this.hasAnnotation = false; }; AcroForm.internal.inherit(AcroForm.RadioButton, AcroForm.Button); window["RadioButton"] = AcroForm.RadioButton; /* * The Child classs of a RadioButton (the radioGroup) * -> The single Buttons */ AcroForm.ChildClass = function (parent, name) { AcroForm.Field.call(this); this.Parent = parent; // todo: set AppearanceType as variable that can be set from the outside... this._AppearanceType = AcroForm.Appearance.RadioButton.Circle; // The Default appearanceType is the Circle this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(name); // Set Print in the Annot Flag this.F = AcroForm.internal.setBitPosition(this.F, 3, 1); // Set AppearanceCharacteristicsDictionary with default appearance if field is not interacting with user this.MK = this._AppearanceType.createMK(); // (8) -> Cross, (1)-> Circle, ()-> nothing // Default Appearance is Off this.AS = "/Off"; // + name; this._Name = name; }; AcroForm.internal.inherit(AcroForm.ChildClass, AcroForm.Field); AcroForm.RadioButton.prototype.setAppearance = function (appearance) { if (!('createAppearanceStream' in appearance && 'createMK' in appearance)) { console.log("Couldn't assign Appearance to RadioButton. Appearance was Invalid!"); return; } for (var i in this.__Kids) { var child = this.__Kids[i]; child.appearanceStreamContent = appearance.createAppearanceStream(child._Name); child.MK = appearance.createMK(); } }; AcroForm.RadioButton.prototype.createOption = function (name) { var parent = this; var kidCount = this.__Kids.length; // Create new Child for RadioGroup var child = new AcroForm.ChildClass(parent, name); // Add to Parent this.__Kids.push(child); jsPDF.API.addField(child); return child; }; AcroForm.CheckBox = function () { Button.call(this); this.appearanceStreamContent = AcroForm.Appearance.CheckBox.createAppearanceStream(); this.MK = AcroForm.Appearance.CheckBox.createMK(); this.AS = "/On"; this.V = "/On"; }; AcroForm.internal.inherit(AcroForm.CheckBox, AcroForm.Button); window["CheckBox"] = AcroForm.CheckBox; AcroForm.TextField = function () { AcroForm.Field.call(this); this.DA = AcroForm.Appearance.createDefaultAppearanceStream(); this.F = 4; var _V; Object.defineProperty(this, 'V', { get: function get() { if (_V) { return "(" + _V + ")"; } else { return _V; } }, enumerable: true, set: function set(val) { _V = val; } }); var _DV; Object.defineProperty(this, 'DV', { get: function get() { if (_DV) { return "(" + _DV + ")"; } else { return _DV; } }, enumerable: true, set: function set(val) { _DV = val; } }); var _multiline = false; Object.defineProperty(this, 'multiline', { enumerable: false, get: function get() { return _multiline; }, set: function set(val) { _multiline = val; } }); //this.multiline = false; //this.password = false; /** * For PDF 1.4 * @type {boolean} */ //this.fileSelect = false; /** * For PDF 1.4 * @type {boolean} */ //this.doNotSpellCheck = false; /** * For PDF 1.4 * @type {boolean} */ //this.doNotScroll = false; var _MaxLen = false; Object.defineProperty(this, 'MaxLen', { enumerable: true, get: function get() { return _MaxLen; }, set: function set(val) { _MaxLen = val; } }); Object.defineProperty(this, 'hasAppearanceStream', { enumerable: false, get: function get() { return this.V || this.DV; } }); }; AcroForm.internal.inherit(AcroForm.TextField, AcroForm.Field); window["TextField"] = AcroForm.TextField; AcroForm.PasswordField = function () { TextField.call(this); Object.defineProperty(this, 'password', { value: true, enumerable: false, configurable: false, writable: false }); }; AcroForm.internal.inherit(AcroForm.PasswordField, AcroForm.TextField); window["PasswordField"] = AcroForm.PasswordField; // ############ internal functions /* * small workaround for calculating the TextMetric approximately * @param text * @param fontsize * @returns {TextMetrics} (Has Height and Width) */ AcroForm.internal.calculateFontSpace = function (text, fontsize, fonttype) { var fonttype = fonttype || "helvetica"; //re-use canvas object for speed improvements var canvas = AcroForm.internal.calculateFontSpace.canvas || (AcroForm.internal.calculateFontSpace.canvas = document.createElement('canvas')); var context = canvas.getContext('2d'); context.save(); var newFont = fontsize + " " + fonttype; context.font = newFont; var res = context.measureText(text); context.fontcolor = 'black'; // Calculate height: var context = canvas.getContext('2d'); res.height = context.measureText("3").width * 1.5; // 3 because in ZapfDingbats its a Hook and a 3 in normal fonts context.restore(); var width = res.width; return res; }; AcroForm.internal.calculateX = function (formObject, text, font, maxFontSize) { var maxFontSize = maxFontSize || 12; var font = font || "helvetica"; var returnValue = { text: "", fontSize: "" }; // Remove Brackets text = text.substr(0, 1) == '(' ? text.substr(1) : text; text = text.substr(text.length - 1) == ')' ? text.substr(0, text.length - 1) : text; // split into array of words var textSplit = text.split(' '); /** * the color could be ((alpha)||(r,g,b)||(c,m,y,k)) * @type {string} */ var color = "0 g\n"; var fontSize = maxFontSize; // The Starting fontSize (The Maximum) var lineSpacing = 2; var borderPadding = 2; var height = AcroForm.Appearance.internal.getHeight(formObject) || 0; height = height < 0 ? -height : height; var width = AcroForm.Appearance.internal.getWidth(formObject) || 0; width = width < 0 ? -width : width; var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) { if (i + 1 < textSplit.length) { var tmp = lastLine + " " + textSplit[i + 1]; var TextWidth = AcroForm.internal.calculateFontSpace(tmp, fontSize + "px", font).width; var FieldWidth = width - 2 * borderPadding; return TextWidth <= FieldWidth; } else { return false; } }; fontSize++; FontSize: while (true) { var text = ""; fontSize--; var textHeight = AcroForm.internal.calculateFontSpace("3", fontSize + "px", font).height; var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2; startY += lineSpacing; var startX = -borderPadding; var lastX = startX, lastY = startY; var firstWordInLine = 0, lastWordInLine = 0; var lastLength = 0; var y = 0; if (fontSize == 0) { // In case, the Text doesn't fit at all fontSize = 12; text = "(...) Tj\n"; text += "% Width of Text: " + AcroForm.internal.calculateFontSpace(text, "1px").width + ", FieldWidth:" + width + "\n"; break; } lastLength = AcroForm.internal.calculateFontSpace(textSplit[0] + " ", fontSize + "px", font).width; var lastLine = ""; var lineCount = 0; Line: for (var i in textSplit) { lastLine += textSplit[i] + " "; // Remove last blank lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine; var key = parseInt(i); lastLength = AcroForm.internal.calculateFontSpace(lastLine + " ", fontSize + "px", font).width; var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize); var isLastWord = i >= textSplit.length - 1; if (nextLineIsSmaller && !isLastWord) { lastLine += " "; continue; // Line } else if (!nextLineIsSmaller && !isLastWord) { if (!formObject.multiline) { continue FontSize; } else { if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) { // If the Text is higher than the FieldObject continue FontSize; } lastWordInLine = key; // go on } } else if (isLastWord) { lastWordInLine = key; } else { if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) { // If the Text is higher than the FieldObject continue FontSize; } } var line = ''; for (var x = firstWordInLine; x <= lastWordInLine; x++) { line += textSplit[x] + ' '; } // Remove last blank line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line; //lastLength -= blankSpace.width; lastLength = AcroForm.internal.calculateFontSpace(line, fontSize + "px", font).width; // Calculate startX switch (formObject.Q) { case 2: // Right justified startX = width - lastLength - borderPadding; break; case 1: // Q = 1 := Text-Alignment: Center startX = (width - lastLength) / 2; break; case 0: default: startX = borderPadding; break; } text += startX + ' ' + lastY + ' Td\n'; text += '(' + line + ') Tj\n'; // reset X in PDF text += -startX + ' 0 Td\n'; // After a Line, adjust y position lastY = -(fontSize + lineSpacing); lastX = startX; // Reset for next iteration step lastLength = 0; firstWordInLine = lastWordInLine + 1; lineCount++; lastLine = ""; continue Line; } break; } returnValue.text = text; returnValue.fontSize = fontSize; return returnValue; }; AcroForm.internal.calculateAppearanceStream = function (formObject) { if (formObject.appearanceStreamContent) { // If appearanceStream is already set, use it return formObject.appearanceStreamContent; } if (!formObject.V && !formObject.DV) { return; } // else calculate it var stream = ''; var text = formObject.V || formObject.DV; var calcRes = AcroForm.internal.calculateX(formObject, text); stream += '/Tx BMC\n' + 'q\n' + //color + '\n' + '/F1 ' + calcRes.fontSize + ' Tf\n' + // Text Matrix '1 0 0 1 0 0 Tm\n'; // Begin Text stream += 'BT\n'; stream += calcRes.text; // End Text stream += 'ET\n'; stream += 'Q\n' + 'EMC\n'; var appearanceStreamContent = new AcroForm.createFormXObject(formObject); appearanceStreamContent.stream = stream; var appearance = { N: { 'Normal': appearanceStreamContent } }; return appearanceStreamContent; }; /* * Converts the Parameters from x,y,w,h to lowerLeftX, lowerLeftY, upperRightX, upperRightY * @param x * @param y * @param w * @param h * @returns {*[]} */ AcroForm.internal.calculateCoordinates = function (x, y, w, h) { var coordinates = {}; if (this.internal) { var mmtopx = function mmtopx(x) { return x * this.internal.scaleFactor; }; if (Array.isArray(x)) { x[0] = AcroForm.scale(x[0]); x[1] = AcroForm.scale(x[1]); x[2] = AcroForm.scale(x[2]); x[3] = AcroForm.scale(x[3]); coordinates.lowerLeft_X = x[0] || 0; coordinates.lowerLeft_Y = mmtopx.call(this, this.internal.pageSize.height) - x[3] - x[1] || 0; coordinates.upperRight_X = x[0] + x[2] || 0; coordinates.upperRight_Y = mmtopx.call(this, this.internal.pageSize.height) - x[1] || 0; } else { x = AcroForm.scale(x); y = AcroForm.scale(y); w = AcroForm.scale(w); h = AcroForm.scale(h); coordinates.lowerLeft_X = x || 0; coordinates.lowerLeft_Y = this.internal.pageSize.height - y || 0; coordinates.upperRight_X = x + w || 0; coordinates.upperRight_Y = this.internal.pageSize.height - y + h || 0; } } else { // old method, that is fallback, if we can't get the pageheight, the coordinate-system starts from lower left if (Array.isArray(x)) { coordinates.lowerLeft_X = x[0] || 0; coordinates.lowerLeft_Y = x[1] || 0; coordinates.upperRight_X = x[0] + x[2] || 0; coordinates.upperRight_Y = x[1] + x[3] || 0; } else { coordinates.lowerLeft_X = x || 0; coordinates.lowerLeft_Y = y || 0; coordinates.upperRight_X = x + w || 0; coordinates.upperRight_Y = y + h || 0; } } return [coordinates.lowerLeft_X, coordinates.lowerLeft_Y, coordinates.upperRight_X, coordinates.upperRight_Y]; }; AcroForm.internal.calculateColor = function (r, g, b) { var color = new Array(3); color.r = r | 0; color.g = g | 0; color.b = b | 0; return color; }; AcroForm.internal.getBitPosition = function (variable, position) { variable = variable || 0; var bitMask = 1; bitMask = bitMask << position - 1; return variable | bitMask; }; AcroForm.internal.setBitPosition = function (variable, position, value) { variable = variable || 0; value = value || 1; var bitMask = 1; bitMask = bitMask << position - 1; if (value == 1) { // Set the Bit to 1 var variable = variable | bitMask; } else { // Set the Bit to 0 var variable = variable & ~bitMask; } return variable; }; /** * jsPDF addHTML PlugIn * Copyright (c) 2014 Diego Casorran * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ (function (jsPDFAPI) { 'use strict'; /** * Renders an HTML element to canvas object which added to the PDF * * This feature requires [html2canvas](https://github.com/niklasvh/html2canvas) * or [rasterizeHTML](https://github.com/cburgmer/rasterizeHTML.js) * * @returns {jsPDF} * @name addHTML * @param element {Mixed} HTML Element, or anything supported by html2canvas. * @param x {Number} starting X coordinate in jsPDF instance's declared units. * @param y {Number} starting Y coordinate in jsPDF instance's declared units. * @param options {Object} Additional options, check the code below. * @param callback {Function} to call when the rendering has finished. * NOTE: Every parameter is optional except 'element' and 'callback', in such * case the image is positioned at 0x0 covering the whole PDF document * size. Ie, to easily take screenshots of webpages saving them to PDF. * @deprecated This is being replace with a vector-supporting API. See * [this link](https://cdn.rawgit.com/MrRio/jsPDF/master/examples/html2pdf/showcase_supported_html.html) */ jsPDFAPI.addHTML = function (element, x, y, options, callback) { 'use strict'; if (typeof html2canvas === 'undefined' && typeof rasterizeHTML === 'undefined') throw new Error('You need either ' + 'https://github.com/niklasvh/html2canvas' + ' or https://github.com/cburgmer/rasterizeHTML.js'); if (typeof x !== 'number') { options = x; callback = y; } if (typeof options === 'function') { callback = options; options = null; } var I = this.internal, K = I.scaleFactor, W = I.pageSize.width, H = I.pageSize.height; options = options || {}; options.onrendered = function (obj) { x = parseInt(x) || 0; y = parseInt(y) || 0; var dim = options.dim || {}; var h = dim.h || 0; var w = dim.w || Math.min(W, obj.width / K) - x; var format = 'JPEG'; if (options.format) format = options.format; if (obj.height > H && options.pagesplit) { var crop = function () { var cy = 0; while (1) { var canvas = document.createElement('canvas'); canvas.width = Math.min(W * K, obj.width); canvas.height = Math.min(H * K, obj.height - cy); var ctx = canvas.getContext('2d'); ctx.drawImage(obj, 0, cy, obj.width, canvas.height, 0, 0, canvas.width, canvas.height); var args = [canvas, x, cy ? 0 : y, canvas.width / K, canvas.height / K, format, null, 'SLOW']; this.addImage.apply(this, args); cy += canvas.height; if (cy >= obj.height) break; this.addPage(); } callback(w, cy, null, args); }.bind(this); if (obj.nodeName === 'CANVAS') { var img = new Image(); img.onload = crop; img.src = obj.toDataURL("image/png"); obj = img; } else { crop(); } } else { var alias = Math.random().toString(35); var args = [obj, x, y, w, h, format, alias, 'SLOW']; this.addImage.apply(this, args); callback(w, h, alias, args); } }.bind(this); if (typeof html2canvas !== 'undefined' && !options.rstz) { return html2canvas(element, options); } if (typeof rasterizeHTML !== 'undefined') { var meth = 'drawDocument'; if (typeof element === 'string') { meth = /^http/.test(element) ? 'drawURL' : 'drawHTML'; } options.width = options.width || W * K; return rasterizeHTML[meth](element, void 0, options).then(function (r) { options.onrendered(r.image); }, function (e) { callback(null, e); }); } return null; }; })(jsPDF.API); /** @preserve * jsPDF addImage plugin * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/ * 2013 Chris Dowling, https://github.com/gingerchris * 2013 Trinh Ho, https://github.com/ineedfat * 2013 Edwin Alejandro Perez, https://github.com/eaparango * 2013 Norah Smith, https://github.com/burnburnrocket * 2014 Diego Casorran, https://github.com/diegocr * 2014 James Robb, https://github.com/jamesbrobb * * */ (function (jsPDFAPI) { 'use strict'; var namespace = 'addImage_', supported_image_types = ['jpeg', 'jpg', 'png']; // Image functionality ported from pdf.js var putImage = function putImage(img) { var objectNumber = this.internal.newObject(), out = this.internal.write, putStream = this.internal.putStream; img['n'] = objectNumber; out('<>'); } if ('trns' in img && img['trns'].constructor == Array) { var trns = '', i = 0, len = img['trns'].length; for (; i < len; i++) { trns += img['trns'][i] + ' ' + img['trns'][i] + ' '; }out('/Mask [' + trns + ']'); } if ('smask' in img) { out('/SMask ' + (objectNumber + 1) + ' 0 R'); } out('/Length ' + img['data'].length + '>>'); putStream(img['data']); out('endobj'); // Soft mask if ('smask' in img) { var dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w']; var smask = { 'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': img['bpc'], 'dp': dp, 'data': img['smask'] }; if ('f' in img) smask.f = img['f']; putImage.call(this, smask); } //Palette if (img['cs'] === this.color_spaces.INDEXED) { this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>'); //putStream(zlib.compress(img['pal'])); out('<< /Length ' + img['pal'].length + '>>'); putStream(this.arrayBufferToBinaryString(new Uint8Array(img['pal']))); out('endobj'); } }, putResourcesCallback = function putResourcesCallback() { var images = this.internal.collections[namespace + 'images']; for (var i in images) { putImage.call(this, images[i]); } }, putXObjectsDictCallback = function putXObjectsDictCallback() { var images = this.internal.collections[namespace + 'images'], out = this.internal.write, image; for (var i in images) { image = images[i]; out('/I' + image['i'], image['n'], '0', 'R'); } }, checkCompressValue = function checkCompressValue(value) { if (value && typeof value === 'string') value = value.toUpperCase(); return value in jsPDFAPI.image_compression ? value : jsPDFAPI.image_compression.NONE; }, getImages = function getImages() { var images = this.internal.collections[namespace + 'images']; //first run, so initialise stuff if (!images) { this.internal.collections[namespace + 'images'] = images = {}; this.internal.events.subscribe('putResources', putResourcesCallback); this.internal.events.subscribe('putXobjectDict', putXObjectsDictCallback); } return images; }, getImageIndex = function getImageIndex(images) { var imageIndex = 0; if (images) { // this is NOT the first time this method is ran on this instance of jsPDF object. imageIndex = Object.keys ? Object.keys(images).length : function (o) { var i = 0; for (var e in o) { if (o.hasOwnProperty(e)) { i++; } } return i; }(images); } return imageIndex; }, notDefined = function notDefined(value) { return typeof value === 'undefined' || value === null; }, generateAliasFromData = function generateAliasFromData(data) { return typeof data === 'string' && jsPDFAPI.sHashCode(data); }, doesNotSupportImageType = function doesNotSupportImageType(type) { return supported_image_types.indexOf(type) === -1; }, processMethodNotEnabled = function processMethodNotEnabled(type) { return typeof jsPDFAPI['process' + type.toUpperCase()] !== 'function'; }, isDOMElement = function isDOMElement(object) { return (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && object.nodeType === 1; }, createDataURIFromElement = function createDataURIFromElement(element, format, angle) { //if element is an image which uses data url definition, just return the dataurl if (element.nodeName === 'IMG' && element.hasAttribute('src')) { var src = '' + element.getAttribute('src'); if (!angle && src.indexOf('data:image/') === 0) return src; // only if the user doesn't care about a format if (!format && /\.png(?:[?#].*)?$/i.test(src)) format = 'png'; } if (element.nodeName === 'CANVAS') { var canvas = element; } else { var canvas = document.createElement('canvas'); canvas.width = element.clientWidth || element.width; canvas.height = element.clientHeight || element.height; var ctx = canvas.getContext('2d'); if (!ctx) { throw 'addImage requires canvas to be supported by browser.'; } if (angle) { var x, y, b, c, s, w, h, to_radians = Math.PI / 180, angleInRadians; if ((typeof angle === 'undefined' ? 'undefined' : _typeof(angle)) === 'object') { x = angle.x; y = angle.y; b = angle.bg; angle = angle.angle; } angleInRadians = angle * to_radians; c = Math.abs(Math.cos(angleInRadians)); s = Math.abs(Math.sin(angleInRadians)); w = canvas.width; h = canvas.height; canvas.width = h * s + w * c; canvas.height = h * c + w * s; if (isNaN(x)) x = canvas.width / 2; if (isNaN(y)) y = canvas.height / 2; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = b || 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.save(); ctx.translate(x, y); ctx.rotate(angleInRadians); ctx.drawImage(element, -(w / 2), -(h / 2)); ctx.rotate(-angleInRadians); ctx.translate(-x, -y); ctx.restore(); } else { ctx.drawImage(element, 0, 0, canvas.width, canvas.height); } } return canvas.toDataURL(('' + format).toLowerCase() == 'png' ? 'image/png' : 'image/jpeg'); }, checkImagesForAlias = function checkImagesForAlias(alias, images) { var cached_info; if (images) { for (var e in images) { if (alias === images[e].alias) { cached_info = images[e]; break; } } } return cached_info; }, determineWidthAndHeight = function determineWidthAndHeight(w, h, info) { if (!w && !h) { w = -96; h = -96; } if (w < 0) { w = -1 * info['w'] * 72 / w / this.internal.scaleFactor; } if (h < 0) { h = -1 * info['h'] * 72 / h / this.internal.scaleFactor; } if (w === 0) { w = h * info['w'] / info['h']; } if (h === 0) { h = w * info['h'] / info['w']; } return [w, h]; }, writeImageToPDF = function writeImageToPDF(x, y, w, h, info, index, images) { var dims = determineWidthAndHeight.call(this, w, h, info), coord = this.internal.getCoordinateString, vcoord = this.internal.getVerticalCoordinateString; w = dims[0]; h = dims[1]; images[index] = info; this.internal.write('q', coord(w), '0 0', coord(h) // TODO: check if this should be shifted by vcoord , coord(x), vcoord(y + h), 'cm /I' + info['i'], 'Do Q'); }; /** * COLOR SPACES */ jsPDFAPI.color_spaces = { DEVICE_RGB: 'DeviceRGB', DEVICE_GRAY: 'DeviceGray', DEVICE_CMYK: 'DeviceCMYK', CAL_GREY: 'CalGray', CAL_RGB: 'CalRGB', LAB: 'Lab', ICC_BASED: 'ICCBased', INDEXED: 'Indexed', PATTERN: 'Pattern', SEPARATION: 'Separation', DEVICE_N: 'DeviceN' }; /** * DECODE METHODS */ jsPDFAPI.decode = { DCT_DECODE: 'DCTDecode', FLATE_DECODE: 'FlateDecode', LZW_DECODE: 'LZWDecode', JPX_DECODE: 'JPXDecode', JBIG2_DECODE: 'JBIG2Decode', ASCII85_DECODE: 'ASCII85Decode', ASCII_HEX_DECODE: 'ASCIIHexDecode', RUN_LENGTH_DECODE: 'RunLengthDecode', CCITT_FAX_DECODE: 'CCITTFaxDecode' }; /** * IMAGE COMPRESSION TYPES */ jsPDFAPI.image_compression = { NONE: 'NONE', FAST: 'FAST', MEDIUM: 'MEDIUM', SLOW: 'SLOW' }; jsPDFAPI.sHashCode = function (str) { return Array.prototype.reduce && str.split("").reduce(function (a, b) { a = (a << 5) - a + b.charCodeAt(0);return a & a; }, 0); }; jsPDFAPI.isString = function (object) { return typeof object === 'string'; }; /** * Strips out and returns info from a valid base64 data URI * @param {String[dataURI]} a valid data URI of format 'data:[][;base64],' * @returns an Array containing the following * [0] the complete data URI * [1] * [2] format - the second part of the mime-type i.e 'png' in 'image/png' * [4] */ jsPDFAPI.extractInfoFromBase64DataURI = function (dataURI) { return (/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(dataURI) ); }; /** * Check to see if ArrayBuffer is supported */ jsPDFAPI.supportsArrayBuffer = function () { return typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined'; }; /** * Tests supplied object to determine if ArrayBuffer * @param {Object[object]} */ jsPDFAPI.isArrayBuffer = function (object) { if (!this.supportsArrayBuffer()) return false; return object instanceof ArrayBuffer; }; /** * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface * @param {Object[object]} */ jsPDFAPI.isArrayBufferView = function (object) { if (!this.supportsArrayBuffer()) return false; if (typeof Uint32Array === 'undefined') return false; return object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== 'undefined' && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array; }; /** * Exactly what it says on the tin */ jsPDFAPI.binaryStringToUint8Array = function (binary_string) { /* * not sure how efficient this will be will bigger files. Is there a native method? */ var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes; }; /** * @see this discussion * http://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers * * As stated, i imagine the method below is highly inefficent for large files. * * Also of note from Mozilla, * * "However, this is slow and error-prone, due to the need for multiple conversions (especially if the binary data is not actually byte-format data, but, for example, 32-bit integers or floats)." * * https://developer.mozilla.org/en-US/Add-ons/Code_snippets/StringView * * Although i'm strugglig to see how StringView solves this issue? Doesn't appear to be a direct method for conversion? * * Async method using Blob and FileReader could be best, but i'm not sure how to fit it into the flow? */ jsPDFAPI.arrayBufferToBinaryString = function (buffer) { /*if('TextDecoder' in window){ var decoder = new TextDecoder('ascii'); return decoder.decode(buffer); }*/ if (this.isArrayBuffer(buffer)) buffer = new Uint8Array(buffer); var binary_string = ''; var len = buffer.byteLength; for (var i = 0; i < len; i++) { binary_string += String.fromCharCode(buffer[i]); } return binary_string; /* * Another solution is the method below - convert array buffer straight to base64 and then use atob */ //return atob(this.arrayBufferToBase64(buffer)); }; /** * Converts an ArrayBuffer directly to base64 * * Taken from here * * http://jsperf.com/encoding-xhr-image-data/31 * * Need to test if this is a better solution for larger files * */ jsPDFAPI.arrayBufferToBase64 = function (arrayBuffer) { var base64 = ''; var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; var bytes = new Uint8Array(arrayBuffer); var byteLength = bytes.byteLength; var byteRemainder = byteLength % 3; var mainLength = byteLength - byteRemainder; var a, b, c, d; var chunk; // Main loop deals with bytes in chunks of 3 for (var i = 0; i < mainLength; i = i + 3) { // Combine the three bytes into a single integer chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2]; // Use bitmasks to extract 6-bit segments from the triplet a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18 b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12 c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6 d = chunk & 63; // 63 = 2^6 - 1 // Convert the raw binary segments to the appropriate ASCII encoding base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; } // Deal with the remaining bytes and padding if (byteRemainder == 1) { chunk = bytes[mainLength]; a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2 // Set the 4 least significant bits to zero b = (chunk & 3) << 4; // 3 = 2^2 - 1 base64 += encodings[a] + encodings[b] + '=='; } else if (byteRemainder == 2) { chunk = bytes[mainLength] << 8 | bytes[mainLength + 1]; a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10 b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4 // Set the 2 least significant bits to zero c = (chunk & 15) << 2; // 15 = 2^4 - 1 base64 += encodings[a] + encodings[b] + encodings[c] + '='; } return base64; }; jsPDFAPI.createImageInfo = function (data, wd, ht, cs, bpc, f, imageIndex, alias, dp, trns, pal, smask, p) { var info = { alias: alias, w: wd, h: ht, cs: cs, bpc: bpc, i: imageIndex, data: data // n: objectNumber will be added by putImage code }; if (f) info.f = f; if (dp) info.dp = dp; if (trns) info.trns = trns; if (pal) info.pal = pal; if (smask) info.smask = smask; if (p) info.p = p; // predictor parameter for PNG compression return info; }; jsPDFAPI.addImage = function (imageData, format, x, y, w, h, alias, compression, rotation) { 'use strict'; if (typeof format !== 'string') { var tmp = h; h = w; w = y; y = x; x = format; format = tmp; } if ((typeof imageData === 'undefined' ? 'undefined' : _typeof(imageData)) === 'object' && !isDOMElement(imageData) && "imageData" in imageData) { var options = imageData; imageData = options.imageData; format = options.format || format; x = options.x || x || 0; y = options.y || y || 0; w = options.w || w; h = options.h || h; alias = options.alias || alias; compression = options.compression || compression; rotation = options.rotation || options.angle || rotation; } if (isNaN(x) || isNaN(y)) { console.error('jsPDF.addImage: Invalid coordinates', arguments); throw new Error('Invalid coordinates passed to jsPDF.addImage'); } var images = getImages.call(this), info; if (!(info = checkImagesForAlias(imageData, images))) { var dataAsBinaryString; if (isDOMElement(imageData)) imageData = createDataURIFromElement(imageData, format, rotation); if (notDefined(alias)) alias = generateAliasFromData(imageData); if (!(info = checkImagesForAlias(alias, images))) { if (this.isString(imageData)) { var base64Info = this.extractInfoFromBase64DataURI(imageData); if (base64Info) { format = base64Info[2]; imageData = atob(base64Info[3]); //convert to binary string } else { if (imageData.charCodeAt(0) === 0x89 && imageData.charCodeAt(1) === 0x50 && imageData.charCodeAt(2) === 0x4e && imageData.charCodeAt(3) === 0x47) format = 'png'; } } format = (format || 'JPEG').toLowerCase(); if (doesNotSupportImageType(format)) throw new Error('addImage currently only supports formats ' + supported_image_types + ', not \'' + format + '\''); if (processMethodNotEnabled(format)) throw new Error('please ensure that the plugin for \'' + format + '\' support is added'); /** * need to test if it's more efficient to convert all binary strings * to TypedArray - or should we just leave and process as string? */ if (this.supportsArrayBuffer()) { // no need to convert if imageData is already uint8array if (!(imageData instanceof Uint8Array)) { dataAsBinaryString = imageData; imageData = this.binaryStringToUint8Array(imageData); } } info = this['process' + format.toUpperCase()](imageData, getImageIndex(images), alias, checkCompressValue(compression), dataAsBinaryString); if (!info) throw new Error('An unkwown error occurred whilst processing the image'); } } writeImageToPDF.call(this, x, y, w, h, info, info.i, images); return this; }; /** * JPEG SUPPORT **/ //takes a string imgData containing the raw bytes of //a jpeg image and returns [width, height] //Algorithm from: http://www.64lines.com/jpeg-width-height var getJpegSize = function getJpegSize(imgData) { 'use strict'; var width, height, numcomponents; // Verify we have a valid jpeg header 0xff,0xd8,0xff,0xe0,?,?,'J','F','I','F',0x00 if (!imgData.charCodeAt(0) === 0xff || !imgData.charCodeAt(1) === 0xd8 || !imgData.charCodeAt(2) === 0xff || !imgData.charCodeAt(3) === 0xe0 || !imgData.charCodeAt(6) === 'J'.charCodeAt(0) || !imgData.charCodeAt(7) === 'F'.charCodeAt(0) || !imgData.charCodeAt(8) === 'I'.charCodeAt(0) || !imgData.charCodeAt(9) === 'F'.charCodeAt(0) || !imgData.charCodeAt(10) === 0x00) { throw new Error('getJpegSize requires a binary string jpeg file'); } var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5); var i = 4, len = imgData.length; while (i < len) { i += blockLength; if (imgData.charCodeAt(i) !== 0xff) { throw new Error('getJpegSize could not find the size of the image'); } if (imgData.charCodeAt(i + 1) === 0xc0 || //(SOF) Huffman - Baseline DCT imgData.charCodeAt(i + 1) === 0xc1 || //(SOF) Huffman - Extended sequential DCT imgData.charCodeAt(i + 1) === 0xc2 || // Progressive DCT (SOF2) imgData.charCodeAt(i + 1) === 0xc3 || // Spatial (sequential) lossless (SOF3) imgData.charCodeAt(i + 1) === 0xc4 || // Differential sequential DCT (SOF5) imgData.charCodeAt(i + 1) === 0xc5 || // Differential progressive DCT (SOF6) imgData.charCodeAt(i + 1) === 0xc6 || // Differential spatial (SOF7) imgData.charCodeAt(i + 1) === 0xc7) { height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6); width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8); numcomponents = imgData.charCodeAt(i + 9); return [width, height, numcomponents]; } else { i += 2; blockLength = imgData.charCodeAt(i) * 256 + imgData.charCodeAt(i + 1); } } }, getJpegSizeFromBytes = function getJpegSizeFromBytes(data) { var hdr = data[0] << 8 | data[1]; if (hdr !== 0xFFD8) throw new Error('Supplied data is not a JPEG'); var len = data.length, block = (data[4] << 8) + data[5], pos = 4, bytes, width, height, numcomponents; while (pos < len) { pos += block; bytes = readBytes(data, pos); block = (bytes[2] << 8) + bytes[3]; if ((bytes[1] === 0xC0 || bytes[1] === 0xC2) && bytes[0] === 0xFF && block > 7) { bytes = readBytes(data, pos + 5); width = (bytes[2] << 8) + bytes[3]; height = (bytes[0] << 8) + bytes[1]; numcomponents = bytes[4]; return { width: width, height: height, numcomponents: numcomponents }; } pos += 2; } throw new Error('getJpegSizeFromBytes could not find the size of the image'); }, readBytes = function readBytes(data, offset) { return data.subarray(offset, offset + 5); }; jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString) { 'use strict'; var colorSpace = this.color_spaces.DEVICE_RGB, filter = this.decode.DCT_DECODE, bpc = 8, dims; if (this.isString(data)) { dims = getJpegSize(data); return this.createImageInfo(data, dims[0], dims[1], dims[3] == 1 ? this.color_spaces.DEVICE_GRAY : colorSpace, bpc, filter, index, alias); } if (this.isArrayBuffer(data)) data = new Uint8Array(data); if (this.isArrayBufferView(data)) { dims = getJpegSizeFromBytes(data); // if we already have a stored binary string rep use that data = dataAsBinaryString || this.arrayBufferToBinaryString(data); return this.createImageInfo(data, dims.width, dims.height, dims.numcomponents == 1 ? this.color_spaces.DEVICE_GRAY : colorSpace, bpc, filter, index, alias); } return null; }; jsPDFAPI.processJPG = function () /*data, index, alias, compression, dataAsBinaryString*/{ return this.processJPEG.apply(this, arguments); }; })(jsPDF.API); /** * jsPDF Annotations PlugIn * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ /** * There are many types of annotations in a PDF document. Annotations are placed * on a page at a particular location. They are not 'attached' to an object. *
* This plugin current supports
*
  • Goto Page (set pageNumber and top in options) *
  • Goto Name (set name and top in options) *
  • Goto URL (set url in options) *

    * The destination magnification factor can also be specified when goto is a page number or a named destination. (see documentation below) * (set magFactor in options). XYZ is the default. *

    *

    * Links, Text, Popup, and FreeText are supported. *

    *

    * Options In PDF spec Not Implemented Yet *

  • link border *
  • named target *
  • page coordinates *
  • destination page scaling and layout *
  • actions other than URL and GotoPage *
  • background / hover actions *

    */ /* Destination Magnification Factors See PDF 1.3 Page 386 for meanings and options [supported] XYZ (options; left top zoom) Fit (no options) FitH (options: top) FitV (options: left) [not supported] FitR FitB FitBH FitBV */ (function (jsPDFAPI) { 'use strict'; var annotationPlugin = { /** * An array of arrays, indexed by pageNumber. */ annotations: [], f2: function f2(number) { return number.toFixed(2); }, notEmpty: function notEmpty(obj) { if (typeof obj != 'undefined') { if (obj != '') { return true; } } } }; jsPDF.API.annotationPlugin = annotationPlugin; jsPDF.API.events.push(['addPage', function (info) { this.annotationPlugin.annotations[info.pageNumber] = []; }]); jsPDFAPI.events.push(['putPage', function (info) { //TODO store annotations in pageContext so reorder/remove will not affect them. var pageAnnos = this.annotationPlugin.annotations[info.pageNumber]; var found = false; for (var a = 0; a < pageAnnos.length && !found; a++) { var anno = pageAnnos[a]; switch (anno.type) { case 'link': if (annotationPlugin.notEmpty(anno.options.url) || annotationPlugin.notEmpty(anno.options.pageNumber)) { found = true; break; } case 'reference': case 'text': case 'freetext': found = true; break; } } if (found == false) { return; } this.internal.write("/Annots ["); var f2 = this.annotationPlugin.f2; var k = this.internal.scaleFactor; var pageHeight = this.internal.pageSize.height; var pageInfo = this.internal.getPageInfo(info.pageNumber); for (var a = 0; a < pageAnnos.length; a++) { var anno = pageAnnos[a]; switch (anno.type) { case 'reference': // References to Widget Anotations (for AcroForm Fields) this.internal.write(' ' + anno.object.objId + ' 0 R '); break; case 'text': // Create a an object for both the text and the popup var objText = this.internal.newAdditionalObject(); var objPopup = this.internal.newAdditionalObject(); var title = anno.title || 'Note'; var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] "; line = '<>'; objText.content = line; var parent = objText.objId + ' 0 R'; var popoff = 30; var rect = "/Rect [" + f2((anno.bounds.x + popoff) * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w + popoff) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] "; //var rect2 = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] "; line = '<>'; } else if (anno.options.pageNumber) { // first page is 0 var info = this.internal.getPageInfo(anno.options.pageNumber); line = '< pageNumber or url [required] *

    If pageNumber is specified, top and zoom may also be specified

    */ jsPDFAPI.link = function (x, y, w, h, options) { 'use strict'; this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({ x: x, y: y, w: w, h: h, options: options, type: 'link' }); }; /** * valid options *
  • pageNumber or url [required] *

    If pageNumber is specified, top and zoom may also be specified

    */ jsPDFAPI.link = function (x, y, w, h, options) { 'use strict'; this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({ x: x, y: y, w: w, h: h, options: options, type: 'link' }); }; /** * Currently only supports single line text. * Returns the width of the text/link */ jsPDFAPI.textWithLink = function (text, x, y, options) { 'use strict'; var width = this.getTextWidth(text); var height = this.internal.getLineHeight(); this.text(text, x, y); //TODO We really need the text baseline height to do this correctly. // Or ability to draw text on top, bottom, center, or baseline. y += height * .2; this.link(x, y - height, width, height, options); return width; }; //TODO move into external library jsPDFAPI.getTextWidth = function (text) { 'use strict'; var fontSize = this.internal.getFontSize(); var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor; return txtWidth; }; //TODO move into external library jsPDFAPI.getLineHeight = function () { return this.internal.getLineHeight(); }; return this; })(jsPDF.API); /** * jsPDF Autoprint Plugin * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ /** * Makes the PDF automatically print. This works in Chrome, Firefox, Acrobat * Reader. * * @returns {jsPDF} * @name autoPrint * @example * var doc = new jsPDF() * doc.text(10, 10, 'This is a test') * doc.autoPrint() * doc.save('autoprint.pdf') */ (function (jsPDFAPI) { 'use strict'; jsPDFAPI.autoPrint = function () { 'use strict'; var refAutoPrintTag; this.internal.events.subscribe('postPutResources', function () { refAutoPrintTag = this.internal.newObject(); this.internal.write("<< /S/Named /Type/Action /N/Print >>", "endobj"); }); this.internal.events.subscribe("putCatalog", function () { this.internal.write("/OpenAction " + refAutoPrintTag + " 0" + " R"); }); return this; }; })(jsPDF.API); /** * jsPDF Canvas PlugIn * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ /** * This plugin mimics the HTML5 Canvas * * The goal is to provide a way for current canvas users to print directly to a PDF. */ (function (jsPDFAPI) { 'use strict'; jsPDFAPI.events.push(['initialized', function () { this.canvas.pdf = this; }]); jsPDFAPI.canvas = { getContext: function getContext(name) { this.pdf.context2d._canvas = this; return this.pdf.context2d; }, style: {} }; Object.defineProperty(jsPDFAPI.canvas, 'width', { get: function get() { return this._width; }, set: function set(value) { this._width = value; this.getContext('2d').pageWrapX = value + 1; } }); Object.defineProperty(jsPDFAPI.canvas, 'height', { get: function get() { return this._height; }, set: function set(value) { this._height = value; this.getContext('2d').pageWrapY = value + 1; } }); return this; })(jsPDF.API); /** ==================================================================== * jsPDF Cell plugin * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com * 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br * 2013 Lee Driscoll, https://github.com/lsdriscoll * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria * 2014 James Hall, james@parall.ax * 2014 Diego Casorran, https://github.com/diegocr * * * ==================================================================== */ (function (jsPDFAPI) { 'use strict'; /*jslint browser:true */ /*global document: false, jsPDF */ var fontName, fontSize, fontStyle, padding = 3, margin = 13, headerFunction, lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }, pages = 1, setLastCellPosition = function setLastCellPosition(x, y, w, h, ln) { lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln }; }, getLastCellPosition = function getLastCellPosition() { return lastCellPos; }, NO_MARGINS = { left: 0, top: 0, bottom: 0 }; jsPDFAPI.setHeaderFunction = function (func) { headerFunction = func; }; jsPDFAPI.getTextDimensions = function (txt) { fontName = this.internal.getFont().fontName; fontSize = this.table_font_size || this.internal.getFontSize(); fontStyle = this.internal.getFont().fontStyle; // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point var px2pt = 0.264583 * 72 / 25.4, dimensions, text; text = document.createElement('font'); text.id = "jsPDFCell"; try { text.style.fontStyle = fontStyle; } catch (e) { text.style.fontWeight = fontStyle; } text.style.fontName = fontName; text.style.fontSize = fontSize + 'pt'; try { text.textContent = txt; } catch (e) { text.innerText = txt; } document.body.appendChild(text); dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt }; document.body.removeChild(text); return dimensions; }; jsPDFAPI.cellAddPage = function () { var margins = this.margins || NO_MARGINS; this.addPage(); setLastCellPosition(margins.left, margins.top, undefined, undefined); //setLastCellPosition(undefined, undefined, undefined, undefined, undefined); pages += 1; }; jsPDFAPI.cellInitialize = function () { lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }; pages = 1; }; jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) { var curCell = getLastCellPosition(); var pgAdded = false; // If this is not the first cell, we must change its position if (curCell.ln !== undefined) { if (curCell.ln === ln) { //Same line x = curCell.x + curCell.w; y = curCell.y; } else { //New line var margins = this.margins || NO_MARGINS; if (curCell.y + curCell.h + h + margin >= this.internal.pageSize.height - margins.bottom) { this.cellAddPage(); pgAdded = true; if (this.printHeaders && this.tableHeaderRow) { this.printHeaderRow(ln, true); } } //We ignore the passed y: the lines may have different heights y = getLastCellPosition().y + getLastCellPosition().h; if (pgAdded) y = margin + 10; } } if (txt[0] !== undefined) { if (this.printingHeaderRow) { this.rect(x, y, w, h, 'FD'); } else { this.rect(x, y, w, h); } if (align === 'right') { if (!(txt instanceof Array)) { txt = [txt]; } for (var i = 0; i < txt.length; i++) { var currentLine = txt[i]; var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize(); this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight() * (i + 1)); } } else { this.text(txt, x + padding, y + this.internal.getLineHeight()); } } setLastCellPosition(x, y, w, h, ln); return this; }; /** * Return the maximum value from an array * @param array * @param comparisonFn * @returns {*} */ jsPDFAPI.arrayMax = function (array, comparisonFn) { var max = array[0], i, ln, item; for (i = 0, ln = array.length; i < ln; i += 1) { item = array[i]; if (comparisonFn) { if (comparisonFn(max, item) === -1) { max = item; } } else { if (item > max) { max = item; } } } return max; }; /** * Create a table from a set of data. * @param {Integer} [x] : left-position for top-left corner of table * @param {Integer} [y] top-position for top-left corner of table * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data. * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost * @param {Object} [config.printHeaders] True to print column headers at the top of every page * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value * @param {Object} [config.margins] margin values for left, top, bottom, and width * @param {Object} [config.fontSize] Integer fontSize to use (optional) */ jsPDFAPI.table = function (x, y, data, headers, config) { if (!data) { throw 'No data for PDF table'; } var headerNames = [], headerPrompts = [], header, i, ln, cln, columnMatrix = {}, columnWidths = {}, columnData, column, columnMinWidths = [], j, tableHeaderConfigs = [], model, jln, func, //set up defaults. If a value is provided in config, defaults will be overwritten: autoSize = false, printHeaders = true, fontSize = 12, margins = NO_MARGINS; margins.width = this.internal.pageSize.width; if (config) { //override config defaults if the user has specified non-default behavior: if (config.autoSize === true) { autoSize = true; } if (config.printHeaders === false) { printHeaders = false; } if (config.fontSize) { fontSize = config.fontSize; } if (config.css && typeof config.css['font-size'] !== "undefined") { fontSize = config.css['font-size'] * 16; } if (config.margins) { margins = config.margins; } } /** * @property {Number} lnMod * Keep track of the current line number modifier used when creating cells */ this.lnMod = 0; lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }, pages = 1; this.printHeaders = printHeaders; this.margins = margins; this.setFontSize(fontSize); this.table_font_size = fontSize; // Set header values if (headers === undefined || headers === null) { // No headers defined so we derive from data headerNames = Object.keys(data[0]); } else if (headers[0] && typeof headers[0] !== 'string') { var px2pt = 0.264583 * 72 / 25.4; // Split header configs into names and prompts for (i = 0, ln = headers.length; i < ln; i += 1) { header = headers[i]; headerNames.push(header.name); headerPrompts.push(header.prompt); columnWidths[header.name] = header.width * px2pt; } } else { headerNames = headers; } if (autoSize) { // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]} func = function func(rec) { return rec[header]; }; for (i = 0, ln = headerNames.length; i < ln; i += 1) { header = headerNames[i]; columnMatrix[header] = data.map(func); // get header width columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w); column = columnMatrix[header]; // get cell widths for (j = 0, cln = column.length; j < cln; j += 1) { columnData = column[j]; columnMinWidths.push(this.getTextDimensions(columnData).w); } // get final column width columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths); //have to reset columnMinWidths = []; } } // -- Construct the table if (printHeaders) { var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length ? headerPrompts : headerNames); // Construct the header row for (i = 0, ln = headerNames.length; i < ln; i += 1) { header = headerNames[i]; tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]); } // Store the table header config this.setTableHeaderRow(tableHeaderConfigs); // Print the header for the start of the table this.printHeaderRow(1, false); } // Construct the data rows for (i = 0, ln = data.length; i < ln; i += 1) { var lineHeight; model = data[i]; lineHeight = this.calculateLineHeight(headerNames, columnWidths, model); for (j = 0, jln = headerNames.length; j < jln; j += 1) { header = headerNames[j]; this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align); } } this.lastCellPos = lastCellPos; this.table_x = x; this.table_y = y; return this; }; /** * Calculate the height for containing the highest column * @param {String[]} headerNames is the header, used as keys to the data * @param {Integer[]} columnWidths is size of each column * @param {Object[]} model is the line of data we want to calculate the height of */ jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) { var header, lineHeight = 0; for (var j = 0; j < headerNames.length; j++) { header = headerNames[j]; model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding); var h = this.internal.getLineHeight() * model[header].length + padding; if (h > lineHeight) lineHeight = h; } return lineHeight; }; /** * Store the config for outputting a table header * @param {Object[]} config * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell * except the ln parameter is excluded */ jsPDFAPI.setTableHeaderRow = function (config) { this.tableHeaderRow = config; }; /** * Output the store header row * @param lineNumber The line number to output the header at */ jsPDFAPI.printHeaderRow = function (lineNumber, new_page) { if (!this.tableHeaderRow) { throw 'Property tableHeaderRow does not exist.'; } var tableHeaderCell, tmpArray, i, ln; this.printingHeaderRow = true; if (headerFunction !== undefined) { var position = headerFunction(this, pages); setLastCellPosition(position[0], position[1], position[2], position[3], -1); } this.setFontStyle('bold'); var tempHeaderConf = []; for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) { this.setFillColor(200, 200, 200); tableHeaderCell = this.tableHeaderRow[i]; if (new_page) { this.margins.top = margin; tableHeaderCell[1] = this.margins && this.margins.top || 0; tempHeaderConf.push(tableHeaderCell); } tmpArray = [].concat(tableHeaderCell); this.cell.apply(this, tmpArray.concat(lineNumber)); } if (tempHeaderConf.length > 0) { this.setTableHeaderRow(tempHeaderConf); } this.setFontStyle('normal'); this.printingHeaderRow = false; }; })(jsPDF.API); /** * jsPDF Context2D PlugIn Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv * * Licensed under the MIT License. http://opensource.org/licenses/mit-license */ /** * This plugin mimics the HTML5 Canvas's context2d. * * The goal is to provide a way for current canvas implementations to print directly to a PDF. */ /** * TODO implement stroke opacity (refactor from fill() method ) * TODO transform angle and radii parameters */ /** * require('jspdf.js'); require('lib/css_colors.js'); */ (function (jsPDFAPI) { 'use strict'; jsPDFAPI.events.push(['initialized', function () { this.context2d.pdf = this; this.context2d.internal.pdf = this; this.context2d.ctx = new context(); this.context2d.ctxStack = []; this.context2d.path = []; }]); jsPDFAPI.context2d = { pageWrapXEnabled: false, pageWrapYEnabled: false, pageWrapX: 9999999, pageWrapY: 9999999, ctx: new context(), f2: function f2(number) { return number.toFixed(2); }, fillRect: function fillRect(x, y, w, h) { if (this._isFillTransparent()) { return; } x = this._wrapX(x); y = this._wrapY(y); var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h }); this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f"); }, strokeRect: function strokeRect(x, y, w, h) { if (this._isStrokeTransparent()) { return; } x = this._wrapX(x); y = this._wrapY(y); var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h }); this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "s"); }, /** * We cannot clear PDF commands that were already written to PDF, so we use white instead.
    * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set. * This results in all calls to clearRect() to do nothing, and keep the canvas transparent. * This flag is stored in the save/restore context and is managed the same way as other drawing states. * @param x * @param y * @param w * @param h */ clearRect: function clearRect(x, y, w, h) { if (this.ctx.ignoreClearRect) { return; } x = this._wrapX(x); y = this._wrapY(y); var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h }); this.save(); this.setFillStyle('#ffffff'); //TODO This is hack to fill with white. this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f"); this.restore(); }, save: function save() { this.ctx._fontSize = this.pdf.internal.getFontSize(); var ctx = new context(); ctx.copy(this.ctx); this.ctxStack.push(this.ctx); this.ctx = ctx; }, restore: function restore() { this.ctx = this.ctxStack.pop(); this.setFillStyle(this.ctx.fillStyle); this.setStrokeStyle(this.ctx.strokeStyle); this.setFont(this.ctx.font); this.pdf.setFontSize(this.ctx._fontSize); this.setLineCap(this.ctx.lineCap); this.setLineWidth(this.ctx.lineWidth); this.setLineJoin(this.ctx.lineJoin); }, rect: function rect(x, y, w, h) { this.moveTo(x, y); this.lineTo(x + w, y); this.lineTo(x + w, y + h); this.lineTo(x, y + h); this.lineTo(x, y); //TODO not needed this.closePath(); }, beginPath: function beginPath() { this.path = []; }, closePath: function closePath() { this.path.push({ type: 'close' }); }, _getRgba: function _getRgba(style) { // get the decimal values of r, g, and b; var rgba = {}; if (this.internal.rxTransparent.test(style)) { rgba.r = 0; rgba.g = 0; rgba.b = 0; rgba.a = 0; } else { var m = this.internal.rxRgb.exec(style); if (m != null) { rgba.r = parseInt(m[1]); rgba.g = parseInt(m[2]); rgba.b = parseInt(m[3]); rgba.a = 1; } else { m = this.internal.rxRgba.exec(style); if (m != null) { rgba.r = parseInt(m[1]); rgba.g = parseInt(m[2]); rgba.b = parseInt(m[3]); rgba.a = parseFloat(m[4]); } else { rgba.a = 1; if (style.charAt(0) != '#') { style = CssColors.colorNameToHex(style); if (!style) { style = '#000000'; } } else {} if (style.length === 4) { rgba.r = style.substring(1, 2); rgba.r += r; rgba.g = style.substring(2, 3); rgba.g += g; rgba.b = style.substring(3, 4); rgba.b += b; } else { rgba.r = style.substring(1, 3); rgba.g = style.substring(3, 5); rgba.b = style.substring(5, 7); } rgba.r = parseInt(rgba.r, 16); rgba.g = parseInt(rgba.g, 16); rgba.b = parseInt(rgba.b, 16); } } } rgba.style = style; return rgba; }, setFillStyle: function setFillStyle(style) { // get the decimal values of r, g, and b; var r, g, b, a; if (this.internal.rxTransparent.test(style)) { r = 0; g = 0; b = 0; a = 0; } else { var m = this.internal.rxRgb.exec(style); if (m != null) { r = parseInt(m[1]); g = parseInt(m[2]); b = parseInt(m[3]); a = 1; } else { m = this.internal.rxRgba.exec(style); if (m != null) { r = parseInt(m[1]); g = parseInt(m[2]); b = parseInt(m[3]); a = parseFloat(m[4]); } else { a = 1; if (style.charAt(0) != '#') { style = CssColors.colorNameToHex(style); if (!style) { style = '#000000'; } } else {} if (style.length === 4) { r = style.substring(1, 2); r += r; g = style.substring(2, 3); g += g; b = style.substring(3, 4); b += b; } else { r = style.substring(1, 3); g = style.substring(3, 5); b = style.substring(5, 7); } r = parseInt(r, 16); g = parseInt(g, 16); b = parseInt(b, 16); } } } this.ctx.fillStyle = style; this.ctx._isFillTransparent = a == 0; this.ctx._fillOpacity = a; this.pdf.setFillColor(r, g, b, { a: a }); this.pdf.setTextColor(r, g, b, { a: a }); }, setStrokeStyle: function setStrokeStyle(style) { var rgba = this._getRgba(style); this.ctx.strokeStyle = rgba.style; this.ctx._isStrokeTransparent = rgba.a == 0; this.ctx._strokeOpacity = rgba.a; //TODO jsPDF to handle rgba if (rgba.a === 0) { this.pdf.setDrawColor(255, 255, 255); } else if (rgba.a === 1) { this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b); } else { //this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b, {a: rgba.a}); this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b); } }, fillText: function fillText(text, x, y, maxWidth) { if (this._isFillTransparent()) { return; } x = this._wrapX(x); y = this._wrapY(y); var xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; var rads = this._matrix_rotation(this.ctx._transform); var degs = rads * 57.2958; //TODO only push the clip if it has not been applied to the current PDF context if (this.ctx._clip_path.length > 0) { var lines; if (window.outIntercept) { lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept; } else { lines = this.internal.getCurrentPage(); } lines.push("q"); var origPath = this.path; this.path = this.ctx._clip_path; this.ctx._clip_path = []; this._fill(null, true); this.ctx._clip_path = this.path; this.path = origPath; } var scale; if (this.pdf.hotfix && this.pdf.hotfix.scale_text) { scale = this._getTransform()[0]; } else { scale = 1; } // In some cases the transform was very small (5.715760606202283e-17). Most likely a canvg rounding error. if (scale < .01) { this.pdf.text(text, x, this._getBaseline(y), null, degs); } else { var oldSize = this.pdf.internal.getFontSize(); this.pdf.setFontSize(oldSize * scale); this.pdf.text(text, x, this._getBaseline(y), null, degs); this.pdf.setFontSize(oldSize); } if (this.ctx._clip_path.length > 0) { lines.push('Q'); } }, strokeText: function strokeText(text, x, y, maxWidth) { if (this._isStrokeTransparent()) { return; } x = this._wrapX(x); y = this._wrapY(y); var xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; var rads = this._matrix_rotation(this.ctx._transform); var degs = rads * 57.2958; //TODO only push the clip if it has not been applied to the current PDF context if (this.ctx._clip_path.length > 0) { var lines; if (window.outIntercept) { lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept; } else { lines = this.internal.getCurrentPage(); } lines.push("q"); var origPath = this.path; this.path = this.ctx._clip_path; this.ctx._clip_path = []; this._fill(null, true); this.ctx._clip_path = this.path; this.path = origPath; } var scale; if (this.pdf.hotfix && this.pdf.hotfix.scale_text) { scale = this._getTransform()[0]; } else { scale = 1; } if (scale === 1) { this.pdf.text(text, x, this._getBaseline(y), { stroke: true }, degs); } else { var oldSize = this.pdf.internal.getFontSize(); this.pdf.setFontSize(oldSize * scale); this.pdf.text(text, x, this._getBaseline(y), { stroke: true }, degs); this.pdf.setFontSize(oldSize); } if (this.ctx._clip_path.length > 0) { lines.push('Q'); } }, setFont: function setFont(font) { this.ctx.font = font; //var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+["']?(\w+)['"]?/; var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+(.*)?/; m = rx.exec(font); if (m != null) { var fontStyle = m[1]; var fontVariant = m[2]; var fontWeight = m[3]; var fontSize = m[4]; var fontSizeUnit = m[5]; var fontFamily = m[6]; if ('px' === fontSizeUnit) { fontSize = Math.floor(parseFloat(fontSize)); // fontSize = fontSize * 1.25; } else if ('em' === fontSizeUnit) { fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize()); } else { fontSize = Math.floor(parseFloat(fontSize)); } this.pdf.setFontSize(fontSize); if (fontWeight === 'bold' || fontWeight === '700') { this.pdf.setFontStyle('bold'); } else { if (fontStyle === 'italic') { this.pdf.setFontStyle('italic'); } else { this.pdf.setFontStyle('normal'); } } var name = fontFamily; var parts = name.toLowerCase().split(/\s*,\s*/); var jsPdfFontName; if (parts.indexOf('arial') != -1) { jsPdfFontName = 'Arial'; } else if (parts.indexOf('verdana') != -1) { jsPdfFontName = 'Verdana'; } else if (parts.indexOf('helvetica') != -1) { jsPdfFontName = 'Helvetica'; } else if (parts.indexOf('sans-serif') != -1) { jsPdfFontName = 'sans-serif'; } else if (parts.indexOf('fixed') != -1) { jsPdfFontName = 'Fixed'; } else if (parts.indexOf('monospace') != -1) { jsPdfFontName = 'Monospace'; } else if (parts.indexOf('terminal') != -1) { jsPdfFontName = 'Terminal'; } else if (parts.indexOf('courier') != -1) { jsPdfFontName = 'Courier'; } else if (parts.indexOf('times') != -1) { jsPdfFontName = 'Times'; } else if (parts.indexOf('cursive') != -1) { jsPdfFontName = 'Cursive'; } else if (parts.indexOf('fantasy') != -1) { jsPdfFontName = 'Fantasy'; } else if (parts.indexOf('serif') != -1) { jsPdfFontName = 'Serif'; } else { jsPdfFontName = 'Serif'; } //TODO check more cases var style; if ('bold' === fontWeight) { style = 'bold'; } else { style = 'normal'; } this.pdf.setFont(jsPdfFontName, style); } else { var rx = /(\d+)(pt|px|em)\s+(\w+)\s*(\w+)?/; var m = rx.exec(font); if (m != null) { var size = m[1]; var unit = m[2]; var name = m[3]; var style = m[4]; if (!style) { style = 'normal'; } if ('em' === fontSizeUnit) { size = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize()); } else { size = Math.floor(parseFloat(size)); } this.pdf.setFontSize(size); this.pdf.setFont(name, style); } } }, setTextBaseline: function setTextBaseline(baseline) { this.ctx.textBaseline = baseline; }, getTextBaseline: function getTextBaseline() { return this.ctx.textBaseline; }, //TODO implement textAlign setTextAlign: function setTextAlign(align) { this.ctx.textAlign = align; }, getTextAlign: function getTextAlign() { return this.ctx.textAlign; }, setLineWidth: function setLineWidth(width) { this.ctx.lineWidth = width; this.pdf.setLineWidth(width); }, setLineCap: function setLineCap(style) { this.ctx.lineCap = style; this.pdf.setLineCap(style); }, setLineJoin: function setLineJoin(style) { this.ctx.lineJoin = style; this.pdf.setLineJoin(style); }, moveTo: function moveTo(x, y) { x = this._wrapX(x); y = this._wrapY(y); var xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; var obj = { type: 'mt', x: x, y: y }; this.path.push(obj); }, _wrapX: function _wrapX(x) { if (this.pageWrapXEnabled) { return x % this.pageWrapX; } else { return x; } }, _wrapY: function _wrapY(y) { if (this.pageWrapYEnabled) { this._gotoPage(this._page(y)); return (y - this.lastBreak) % this.pageWrapY; } else { return y; } }, transform: function transform(a, b, c, d, e, f) { //TODO apply to current transformation instead of replacing this.ctx._transform = [a, b, c, d, e, f]; }, setTransform: function setTransform(a, b, c, d, e, f) { this.ctx._transform = [a, b, c, d, e, f]; }, _getTransform: function _getTransform() { return this.ctx._transform; }, lastBreak: 0, // Y Position of page breaks. pageBreaks: [], // returns: One-based Page Number // Should only be used if pageWrapYEnabled is true _page: function _page(y) { if (this.pageWrapYEnabled) { this.lastBreak = 0; var manualBreaks = 0; var autoBreaks = 0; for (var i = 0; i < this.pageBreaks.length; i++) { if (y >= this.pageBreaks[i]) { manualBreaks++; if (this.lastBreak === 0) { autoBreaks++; } var spaceBetweenLastBreak = this.pageBreaks[i] - this.lastBreak; this.lastBreak = this.pageBreaks[i]; var pagesSinceLastBreak = Math.floor(spaceBetweenLastBreak / this.pageWrapY); autoBreaks += pagesSinceLastBreak; } } if (this.lastBreak === 0) { var pagesSinceLastBreak = Math.floor(y / this.pageWrapY) + 1; autoBreaks += pagesSinceLastBreak; } return autoBreaks + manualBreaks; } else { return this.pdf.internal.getCurrentPageInfo().pageNumber; } }, _gotoPage: function _gotoPage(pageOneBased) { // This is a stub to be overriden if needed }, lineTo: function lineTo(x, y) { x = this._wrapX(x); y = this._wrapY(y); var xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; var obj = { type: 'lt', x: x, y: y }; this.path.push(obj); }, bezierCurveTo: function bezierCurveTo(x1, y1, x2, y2, x, y) { x1 = this._wrapX(x1); y1 = this._wrapY(y1); x2 = this._wrapX(x2); y2 = this._wrapY(y2); x = this._wrapX(x); y = this._wrapY(y); var xpt; xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]); x1 = xpt[0]; y1 = xpt[1]; xpt = this._matrix_map_point(this.ctx._transform, [x2, y2]); x2 = xpt[0]; y2 = xpt[1]; var obj = { type: 'bct', x1: x1, y1: y1, x2: x2, y2: y2, x: x, y: y }; this.path.push(obj); }, quadraticCurveTo: function quadraticCurveTo(x1, y1, x, y) { x1 = this._wrapX(x1); y1 = this._wrapY(y1); x = this._wrapX(x); y = this._wrapY(y); var xpt; xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]); x1 = xpt[0]; y1 = xpt[1]; var obj = { type: 'qct', x1: x1, y1: y1, x: x, y: y }; this.path.push(obj); }, arc: function arc(x, y, radius, startAngle, endAngle, anticlockwise) { x = this._wrapX(x); y = this._wrapY(y); if (!this._matrix_is_identity(this.ctx._transform)) { var xpt = this._matrix_map_point(this.ctx._transform, [x, y]); x = xpt[0]; y = xpt[1]; var x_radPt0 = this._matrix_map_point(this.ctx._transform, [0, 0]); var x_radPt = this._matrix_map_point(this.ctx._transform, [0, radius]); radius = Math.sqrt(Math.pow(x_radPt[0] - x_radPt0[0], 2) + Math.pow(x_radPt[1] - x_radPt0[1], 2)); //TODO angles need to be transformed } var obj = { type: 'arc', x: x, y: y, radius: radius, startAngle: startAngle, endAngle: endAngle, anticlockwise: anticlockwise }; this.path.push(obj); }, drawImage: function drawImage(img, x, y, w, h, x2, y2, w2, h2) { if (x2 !== undefined) { x = x2; y = y2; w = w2; h = h2; } x = this._wrapX(x); y = this._wrapY(y); var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h }); var xRect2 = this._matrix_map_rect(this.ctx._transform, { x: x2, y: y2, w: w2, h: h2 }); // TODO implement source clipping and image scaling var format; var rx = /data:image\/(\w+).*/i; var m = rx.exec(img); if (m != null) { format = m[1]; } else { // format = "jpeg"; format = "png"; } this.pdf.addImage(img, format, xRect.x, xRect.y, xRect.w, xRect.h); }, /** * Multiply the first matrix by the second * @param m1 * @param m2 * @returns {*[]} * @private */ _matrix_multiply: function _matrix_multiply(m2, m1) { var sx = m1[0]; var shy = m1[1]; var shx = m1[2]; var sy = m1[3]; var tx = m1[4]; var ty = m1[5]; var t0 = sx * m2[0] + shy * m2[2]; var t2 = shx * m2[0] + sy * m2[2]; var t4 = tx * m2[0] + ty * m2[2] + m2[4]; shy = sx * m2[1] + shy * m2[3]; sy = shx * m2[1] + sy * m2[3]; ty = tx * m2[1] + ty * m2[3] + m2[5]; sx = t0; shx = t2; tx = t4; return [sx, shy, shx, sy, tx, ty]; }, _matrix_rotation: function _matrix_rotation(m) { return Math.atan2(m[2], m[0]); }, _matrix_decompose: function _matrix_decompose(matrix) { var a = matrix[0]; var b = matrix[1]; var c = matrix[2]; var d = matrix[3]; var scaleX = Math.sqrt(a * a + b * b); a /= scaleX; b /= scaleX; var shear = a * c + b * d; c -= a * shear; d -= b * shear; var scaleY = Math.sqrt(c * c + d * d); c /= scaleY; d /= scaleY; shear /= scaleY; if (a * d < b * c) { a = -a; b = -b; shear = -shear; scaleX = -scaleX; } return { scale: [scaleX, 0, 0, scaleY, 0, 0], translate: [1, 0, 0, 1, matrix[4], matrix[5]], rotate: [a, b, -b, a, 0, 0], skew: [1, 0, shear, 1, 0, 0] }; }, _matrix_map_point: function _matrix_map_point(m1, pt) { var sx = m1[0]; var shy = m1[1]; var shx = m1[2]; var sy = m1[3]; var tx = m1[4]; var ty = m1[5]; var px = pt[0]; var py = pt[1]; var x = px * sx + py * shx + tx; var y = px * shy + py * sy + ty; return [x, y]; }, _matrix_map_point_obj: function _matrix_map_point_obj(m1, pt) { var xpt = this._matrix_map_point(m1, [pt.x, pt.y]); return { x: xpt[0], y: xpt[1] }; }, _matrix_map_rect: function _matrix_map_rect(m1, rect) { var p1 = this._matrix_map_point(m1, [rect.x, rect.y]); var p2 = this._matrix_map_point(m1, [rect.x + rect.w, rect.y + rect.h]); return { x: p1[0], y: p1[1], w: p2[0] - p1[0], h: p2[1] - p1[1] }; }, _matrix_is_identity: function _matrix_is_identity(m1) { if (m1[0] != 1) { return false; } if (m1[1] != 0) { return false; } if (m1[2] != 0) { return false; } if (m1[3] != 1) { return false; } if (m1[4] != 0) { return false; } if (m1[5] != 0) { return false; } return true; }, rotate: function rotate(angle) { var matrix = [Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0]; this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix); }, scale: function scale(sx, sy) { var matrix = [sx, 0.0, 0.0, sy, 0.0, 0.0]; this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix); }, translate: function translate(x, y) { var matrix = [1.0, 0.0, 0.0, 1.0, x, y]; this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix); }, stroke: function stroke() { if (this.ctx._clip_path.length > 0) { var lines; if (window.outIntercept) { lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept; } else { lines = this.internal.getCurrentPage(); } lines.push("q"); var origPath = this.path; this.path = this.ctx._clip_path; this.ctx._clip_path = []; this._stroke(true); this.ctx._clip_path = this.path; this.path = origPath; this._stroke(false); lines.push("Q"); } else { this._stroke(false); } }, _stroke: function _stroke(isClip) { if (!isClip && this._isStrokeTransparent()) { return; } //TODO opacity var moves = []; var closed = false; var xPath = this.path; for (var i = 0; i < xPath.length; i++) { var pt = xPath[i]; switch (pt.type) { case 'mt': moves.push({ start: pt, deltas: [], abs: [] }); break; case 'lt': var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y]; moves[moves.length - 1].deltas.push(delta); moves[moves.length - 1].abs.push(pt); break; case 'bct': var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y]; moves[moves.length - 1].deltas.push(delta); break; case 'qct': // convert to bezier var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x); var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y); var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x); var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y); var x3 = pt.x; var y3 = pt.y; var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y]; moves[moves.length - 1].deltas.push(delta); break; case 'arc': //TODO this was hack to avoid out-of-bounds issue // No move-to before drawing the arc if (moves.length == 0) { moves.push({ start: { x: 0, y: 0 }, deltas: [], abs: [] }); } moves[moves.length - 1].arc = true; moves[moves.length - 1].abs.push(pt); break; case 'close': closed = true; break; } } for (var i = 0; i < moves.length; i++) { var style; if (i == moves.length - 1) { style = 's'; } else { style = null; } if (moves[i].arc) { var arcs = moves[i].abs; for (var ii = 0; ii < arcs.length; ii++) { var arc = arcs[ii]; var start = arc.startAngle * 360 / (2 * Math.PI); var end = arc.endAngle * 360 / (2 * Math.PI); var x = arc.x; var y = arc.y; this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, style, isClip); } } else { var x = moves[i].start.x; var y = moves[i].start.y; if (!isClip) { this.pdf.lines(moves[i].deltas, x, y, null, style); } else { this.pdf.lines(moves[i].deltas, x, y, null, null); this.pdf.clip_fixed(); } } } }, _isFillTransparent: function _isFillTransparent() { return this.ctx._isFillTransparent || this.globalAlpha == 0; }, _isStrokeTransparent: function _isStrokeTransparent() { return this.ctx._isStrokeTransparent || this.globalAlpha == 0; }, fill: function fill(fillRule) { //evenodd or nonzero (default) if (this.ctx._clip_path.length > 0) { var lines; if (window.outIntercept) { lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept; } else { lines = this.internal.getCurrentPage(); } lines.push("q"); var origPath = this.path; this.path = this.ctx._clip_path; this.ctx._clip_path = []; this._fill(fillRule, true); this.ctx._clip_path = this.path; this.path = origPath; this._fill(fillRule, false); lines.push('Q'); } else { this._fill(fillRule, false); } }, _fill: function _fill(fillRule, isClip) { if (this._isFillTransparent()) { return; } var v2Support = typeof this.pdf.internal.newObject2 === 'function'; var lines; if (window.outIntercept) { lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept; } else { lines = this.internal.getCurrentPage(); } // if (this.ctx._clip_path.length > 0) { // lines.push('q'); // var oldPath = this.path; // this.path = this.ctx._clip_path; // this.ctx._clip_path = []; // this._fill(fillRule, true); // this.ctx._clip_path = this.path; // this.path = oldPath; // } var moves = []; var outInterceptOld = window.outIntercept; if (v2Support) { // Blend and Mask switch (this.ctx.globalCompositeOperation) { case 'normal': case 'source-over': break; case 'destination-in': case 'destination-out': //TODO this need to be added to the current group or page // define a mask stream var obj = this.pdf.internal.newStreamObject(); // define a mask state var obj2 = this.pdf.internal.newObject2(); obj2.push('<>'); // /S /Luminosity will need to define color space obj2.push('>>'); // add mask to page resources var gsName = 'MASK' + obj2.objId; this.pdf.internal.addGraphicsState(gsName, obj2.objId); var instruction = '/' + gsName + ' gs'; // add mask to page, group, or stream lines.splice(0, 0, 'q'); lines.splice(1, 0, instruction); lines.push('Q'); window.outIntercept = obj; break; default: var dictionaryEntry = '/' + this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()]; if (dictionaryEntry) { this.pdf.internal.out(dictionaryEntry + ' gs'); } break; } } var alpha = this.ctx.globalAlpha; if (this.ctx._fillOpacity < 1) { // TODO combine this with global opacity alpha = this.ctx._fillOpacity; } //TODO check for an opacity graphics state that was already created //TODO do not set opacity if current value is already active if (v2Support) { var objOpac = this.pdf.internal.newObject2(); objOpac.push('<>'); var gsName = 'GS_O_' + objOpac.objId; this.pdf.internal.addGraphicsState(gsName, objOpac.objId); this.pdf.internal.out('/' + gsName + ' gs'); } var xPath = this.path; for (var i = 0; i < xPath.length; i++) { var pt = xPath[i]; switch (pt.type) { case 'mt': moves.push({ start: pt, deltas: [], abs: [] }); break; case 'lt': var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y]; moves[moves.length - 1].deltas.push(delta); moves[moves.length - 1].abs.push(pt); break; case 'bct': var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y]; moves[moves.length - 1].deltas.push(delta); break; case 'qct': // convert to bezier var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x); var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y); var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x); var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y); var x3 = pt.x; var y3 = pt.y; var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y]; moves[moves.length - 1].deltas.push(delta); break; case 'arc': //TODO this was hack to avoid out-of-bounds issue when drawing circle // No move-to before drawing the arc if (moves.length === 0) { moves.push({ deltas: [], abs: [] }); } moves[moves.length - 1].arc = true; moves[moves.length - 1].abs.push(pt); break; case 'close': moves.push({ close: true }); break; } } for (var i = 0; i < moves.length; i++) { var style; if (i == moves.length - 1) { style = 'f'; if (fillRule === 'evenodd') { style += '*'; } } else { style = null; } if (moves[i].close) { this.pdf.internal.out('h'); this.pdf.internal.out('f'); } else if (moves[i].arc) { if (moves[i].start) { this.internal.move2(this, moves[i].start.x, moves[i].start.y); } var arcs = moves[i].abs; for (var ii = 0; ii < arcs.length; ii++) { var arc = arcs[ii]; //TODO lines deltas were getting in here if (typeof arc.startAngle !== 'undefined') { var start = arc.startAngle * 360 / (2 * Math.PI); var end = arc.endAngle * 360 / (2 * Math.PI); var x = arc.x; var y = arc.y; if (ii === 0) { this.internal.move2(this, x, y); } this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, null, isClip); if (ii === arcs.length - 1) { // The original arc move did not occur because of the algorithm if (moves[i].start) { var x = moves[i].start.x; var y = moves[i].start.y; this.internal.line2(c2d, x, y); } } } else { this.internal.line2(c2d, arc.x, arc.y); } } } else { var x = moves[i].start.x; var y = moves[i].start.y; if (!isClip) { this.pdf.lines(moves[i].deltas, x, y, null, style); } else { this.pdf.lines(moves[i].deltas, x, y, null, null); this.pdf.clip_fixed(); } } } window.outIntercept = outInterceptOld; // if (this.ctx._clip_path.length > 0) { // lines.push('Q'); // } }, pushMask: function pushMask() { var v2Support = typeof this.pdf.internal.newObject2 === 'function'; if (!v2Support) { console.log('jsPDF v2 not enabled'); return; } // define a mask stream var obj = this.pdf.internal.newStreamObject(); // define a mask state var obj2 = this.pdf.internal.newObject2(); obj2.push('<>'); // /S /Luminosity will need to define color space obj2.push('>>'); // add mask to page resources var gsName = 'MASK' + obj2.objId; this.pdf.internal.addGraphicsState(gsName, obj2.objId); var instruction = '/' + gsName + ' gs'; this.pdf.internal.out(instruction); }, clip: function clip() { //TODO do we reset the path, or just copy it? if (this.ctx._clip_path.length > 0) { for (var i = 0; i < this.path.length; i++) { this.ctx._clip_path.push(this.path[i]); } } else { this.ctx._clip_path = this.path; } this.path = []; }, measureText: function measureText(text) { var pdf = this.pdf; return { getWidth: function getWidth() { var fontSize = pdf.internal.getFontSize(); var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor; // Convert points to pixels txtWidth *= 1.3333; return txtWidth; }, get width() { return this.getWidth(text); } }; }, _getBaseline: function _getBaseline(y) { var height = parseInt(this.pdf.internal.getFontSize()); // TODO Get descent from font descriptor var descent = height * .25; switch (this.ctx.textBaseline) { case 'bottom': return y - descent; case 'top': return y + height; case 'hanging': return y + height - descent; case 'middle': return y + height / 2 - descent; case 'ideographic': // TODO not implemented return y; case 'alphabetic': default: return y; } } }; var c2d = jsPDFAPI.context2d; // accessor methods Object.defineProperty(c2d, 'fillStyle', { set: function set(value) { this.setFillStyle(value); }, get: function get() { return this.ctx.fillStyle; } }); Object.defineProperty(c2d, 'strokeStyle', { set: function set(value) { this.setStrokeStyle(value); }, get: function get() { return this.ctx.strokeStyle; } }); Object.defineProperty(c2d, 'lineWidth', { set: function set(value) { this.setLineWidth(value); }, get: function get() { return this.ctx.lineWidth; } }); Object.defineProperty(c2d, 'lineCap', { set: function set(val) { this.setLineCap(val); }, get: function get() { return this.ctx.lineCap; } }); Object.defineProperty(c2d, 'lineJoin', { set: function set(val) { this.setLineJoin(val); }, get: function get() { return this.ctx.lineJoin; } }); Object.defineProperty(c2d, 'miterLimit', { set: function set(val) { this.ctx.miterLimit = val; }, get: function get() { return this.ctx.miterLimit; } }); Object.defineProperty(c2d, 'textBaseline', { set: function set(value) { this.setTextBaseline(value); }, get: function get() { return this.getTextBaseline(); } }); Object.defineProperty(c2d, 'textAlign', { set: function set(value) { this.setTextAlign(value); }, get: function get() { return this.getTextAlign(); } }); Object.defineProperty(c2d, 'font', { set: function set(value) { this.setFont(value); }, get: function get() { return this.ctx.font; } }); Object.defineProperty(c2d, 'globalCompositeOperation', { set: function set(value) { this.ctx.globalCompositeOperation = value; }, get: function get() { return this.ctx.globalCompositeOperation; } }); Object.defineProperty(c2d, 'globalAlpha', { set: function set(value) { this.ctx.globalAlpha = value; }, get: function get() { return this.ctx.globalAlpha; } }); // Not HTML API Object.defineProperty(c2d, 'ignoreClearRect', { set: function set(value) { this.ctx.ignoreClearRect = value; }, get: function get() { return this.ctx.ignoreClearRect; } }); // End Not HTML API c2d.internal = {}; c2d.internal.rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/; c2d.internal.rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/; c2d.internal.rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/; // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html c2d.internal.arc = function (c2d, xc, yc, r, a1, a2, anticlockwise, style) { var includeMove = true; var k = this.pdf.internal.scaleFactor; var pageHeight = this.pdf.internal.pageSize.height; var f2 = this.pdf.internal.f2; var a1r = a1 * (Math.PI / 180); var a2r = a2 * (Math.PI / 180); var curves = this.createArc(r, a1r, a2r, anticlockwise); var pathData = null; for (var i = 0; i < curves.length; i++) { var curve = curves[i]; if (includeMove && i === 0) { this.pdf.internal.out([f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' ')); } else { this.pdf.internal.out([f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' ')); } //c2d._lastPoint = {x: curve.x1 + xc, y: curve.y1 + yc}; c2d._lastPoint = { x: xc, y: yc }; // f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c' } if (style !== null) { this.pdf.internal.out(this.pdf.internal.getStyle(style)); } }; /** * * @param x Edge point X * @param y Edge point Y * @param r Radius * @param a1 start angle * @param a2 end angle * @param anticlockwise * @param style * @param isClip */ c2d.internal.arc2 = function (c2d, x, y, r, a1, a2, anticlockwise, style, isClip) { // we need to convert from cartesian to polar here methinks. var centerX = x; // + r; var centerY = y; if (!isClip) { this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, style); } else { this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, null); this.pdf.clip_fixed(); } }; c2d.internal.move2 = function (c2d, x, y) { var k = this.pdf.internal.scaleFactor; var pageHeight = this.pdf.internal.pageSize.height; var f2 = this.pdf.internal.f2; this.pdf.internal.out([f2(x * k), f2((pageHeight - y) * k), 'm'].join(' ')); c2d._lastPoint = { x: x, y: y }; }; c2d.internal.line2 = function (c2d, dx, dy) { var k = this.pdf.internal.scaleFactor; var pageHeight = this.pdf.internal.pageSize.height; var f2 = this.pdf.internal.f2; //var pt = {x: c2d._lastPoint.x + dx, y: c2d._lastPoint.y + dy}; var pt = { x: dx, y: dy }; this.pdf.internal.out([f2(pt.x * k), f2((pageHeight - pt.y) * k), 'l'].join(' ')); //this.pdf.internal.out('f'); c2d._lastPoint = pt; }; /** * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius. * * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points. */ c2d.internal.createArc = function (radius, startAngle, endAngle, anticlockwise) { var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below var twoPI = Math.PI * 2; var piOverTwo = Math.PI / 2.0; // normalize startAngle, endAngle to [0, 2PI] var startAngleN = startAngle; if (startAngleN < twoPI || startAngleN > twoPI) { startAngleN = startAngleN % twoPI; } if (startAngleN < 0) { startAngleN = twoPI + startAngleN; } while (startAngle > endAngle) { startAngle = startAngle - twoPI; } var totalAngle = Math.abs(endAngle - startAngle); if (totalAngle < twoPI) { if (anticlockwise) { totalAngle = twoPI - totalAngle; } } // Compute the sequence of arc curves, up to PI/2 at a time. var curves = []; var sgn = anticlockwise ? -1 : +1; var a1 = startAngleN; for (; totalAngle > EPSILON;) { var remain = sgn * Math.min(totalAngle, piOverTwo); var a2 = a1 + remain; curves.push(this.createSmallArc(radius, a1, a2)); totalAngle -= Math.abs(a2 - a1); a1 = a2; } return curves; }; c2d.internal.getCurrentPage = function () { return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber]; }; /** * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r. * * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points. * * This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378. */ c2d.internal.createSmallArc = function (r, a1, a2) { // Compute all four points for an arc that subtends the same total angle // but is centered on the X-axis var a = (a2 - a1) / 2.0; var x4 = r * Math.cos(a); var y4 = r * Math.sin(a); var x1 = x4; var y1 = -y4; var q1 = x1 * x1 + y1 * y1; var q2 = q1 + x1 * x4 + y1 * y4; var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4); var x2 = x1 - k2 * y1; var y2 = y1 + k2 * x1; var x3 = x2; var y3 = -y2; // Find the arc points' actual locations by computing x1,y1 and x4,y4 // and rotating the control points by a + a1 var ar = a + a1; var cos_ar = Math.cos(ar); var sin_ar = Math.sin(ar); return { x1: r * Math.cos(a1), y1: r * Math.sin(a1), x2: x2 * cos_ar - y2 * sin_ar, y2: x2 * sin_ar + y2 * cos_ar, x3: x3 * cos_ar - y3 * sin_ar, y3: x3 * sin_ar + y3 * cos_ar, x4: r * Math.cos(a2), y4: r * Math.sin(a2) }; }; function context() { this._isStrokeTransparent = false; this._strokeOpacity = 1; this.strokeStyle = '#000000'; this.fillStyle = '#000000'; this._isFillTransparent = false; this._fillOpacity = 1; this.font = "12pt times"; this.textBaseline = 'alphabetic'; // top,bottom,middle,ideographic,alphabetic,hanging this.textAlign = 'start'; this.lineWidth = 1; this.lineJoin = 'miter'; // round, bevel, miter this.lineCap = 'butt'; // butt, round, square this._transform = [1, 0, 0, 1, 0, 0]; // sx, shy, shx, sy, tx, ty this.globalCompositeOperation = 'normal'; this.globalAlpha = 1.0; this._clip_path = []; // TODO miter limit //default 10 // Not HTML API this.ignoreClearRect = false; this.copy = function (ctx) { this._isStrokeTransparent = ctx._isStrokeTransparent; this._strokeOpacity = ctx._strokeOpacity; this.strokeStyle = ctx.strokeStyle; this._isFillTransparent = ctx._isFillTransparent; this._fillOpacity = ctx._fillOpacity; this.fillStyle = ctx.fillStyle; this.font = ctx.font; this.lineWidth = ctx.lineWidth; this.lineJoin = ctx.lineJoin; this.lineCap = ctx.lineCap; this.textBaseline = ctx.textBaseline; this.textAlign = ctx.textAlign; this._fontSize = ctx._fontSize; this._transform = ctx._transform.slice(0); this.globalCompositeOperation = ctx.globalCompositeOperation; this.globalAlpha = ctx.globalAlpha; this._clip_path = ctx._clip_path.slice(0); //TODO deep copy? // Not HTML API this.ignoreClearRect = ctx.ignoreClearRect; }; } return this; })(jsPDF.API); /** @preserve * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria * 2014 Diego Casorran, https://github.com/diegocr * 2014 Daniel Husar, https://github.com/danielhusar * 2014 Wolfgang Gassler, https://github.com/woolfg * 2014 Steven Spungin, https://github.com/flamenco * * * ==================================================================== */ (function (jsPDFAPI) { var clone, _DrillForContent, FontNameDB, FontStyleMap, TextAlignMap, FontWeightMap, FloatMap, ClearMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, checkForFooter, process, tableToJson; clone = function () { return function (obj) { Clone.prototype = obj; return new Clone(); }; function Clone() {} }(); PurgeWhiteSpace = function PurgeWhiteSpace(array) { var fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace; i = 0; l = array.length; fragment = void 0; lTrimmed = false; rTrimmed = false; while (!lTrimmed && i !== l) { fragment = array[i] = array[i].trimLeft(); if (fragment) { lTrimmed = true; } i++; } i = l - 1; while (l && !rTrimmed && i !== -1) { fragment = array[i] = array[i].trimRight(); if (fragment) { rTrimmed = true; } i--; } r = /\s+$/g; trailingSpace = true; i = 0; while (i !== l) { // Leave the line breaks intact if (array[i] != "\u2028") { fragment = array[i].replace(/\s+/g, " "); if (trailingSpace) { fragment = fragment.trimLeft(); } if (fragment) { trailingSpace = r.test(fragment); } array[i] = fragment; } i++; } return array; }; Renderer = function Renderer(pdf, x, y, settings) { this.pdf = pdf; this.x = x; this.y = y; this.settings = settings; //list of functions which are called after each element-rendering process this.watchFunctions = []; this.init(); return this; }; ResolveFont = function ResolveFont(css_font_family_string) { var name, part, parts; name = void 0; parts = css_font_family_string.split(","); part = parts.shift(); while (!name && part) { name = FontNameDB[part.trim().toLowerCase()]; part = parts.shift(); } return name; }; ResolveUnitedNumber = function ResolveUnitedNumber(css_line_height_string) { //IE8 issues css_line_height_string = css_line_height_string === "auto" ? "0px" : css_line_height_string; if (css_line_height_string.indexOf("em") > -1 && !isNaN(Number(css_line_height_string.replace("em", "")))) { css_line_height_string = Number(css_line_height_string.replace("em", "")) * 18.719 + "px"; } if (css_line_height_string.indexOf("pt") > -1 && !isNaN(Number(css_line_height_string.replace("pt", "")))) { css_line_height_string = Number(css_line_height_string.replace("pt", "")) * 1.333 + "px"; } var normal, undef, value; undef = void 0; normal = 16.00; value = UnitedNumberMap[css_line_height_string]; if (value) { return value; } value = { "xx-small": 9, "x-small": 11, small: 13, medium: 16, large: 19, "x-large": 23, "xx-large": 28, auto: 0 }[{ css_line_height_string: css_line_height_string }]; if (value !== undef) { return UnitedNumberMap[css_line_height_string] = value / normal; } if (value = parseFloat(css_line_height_string)) { return UnitedNumberMap[css_line_height_string] = value / normal; } value = css_line_height_string.match(/([\d\.]+)(px)/); if (value.length === 3) { return UnitedNumberMap[css_line_height_string] = parseFloat(value[1]) / normal; } return UnitedNumberMap[css_line_height_string] = 1; }; GetCSS = function GetCSS(element) { var css, tmp, computedCSSElement; computedCSSElement = function (el) { var compCSS; compCSS = function (el) { if (document.defaultView && document.defaultView.getComputedStyle) { return document.defaultView.getComputedStyle(el, null); } else if (el.currentStyle) { return el.currentStyle; } else { return el.style; } }(el); return function (prop) { prop = prop.replace(/-\D/g, function (match) { return match.charAt(1).toUpperCase(); }); return compCSS[prop]; }; }(element); css = {}; tmp = void 0; css["font-family"] = ResolveFont(computedCSSElement("font-family")) || "times"; css["font-style"] = FontStyleMap[computedCSSElement("font-style")] || "normal"; css["text-align"] = TextAlignMap[computedCSSElement("text-align")] || "left"; tmp = FontWeightMap[computedCSSElement("font-weight")] || "normal"; if (tmp === "bold") { if (css["font-style"] === "normal") { css["font-style"] = tmp; } else { css["font-style"] = tmp + css["font-style"]; } } css["font-size"] = ResolveUnitedNumber(computedCSSElement("font-size")) || 1; css["line-height"] = ResolveUnitedNumber(computedCSSElement("line-height")) || 1; css["display"] = computedCSSElement("display") === "inline" ? "inline" : "block"; tmp = css["display"] === "block"; css["margin-top"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-top")) || 0; css["margin-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-bottom")) || 0; css["padding-top"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-top")) || 0; css["padding-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-bottom")) || 0; css["margin-left"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-left")) || 0; css["margin-right"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-right")) || 0; css["padding-left"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-left")) || 0; css["padding-right"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-right")) || 0; css["page-break-before"] = computedCSSElement("page-break-before") || "auto"; //float and clearing of floats css["float"] = FloatMap[computedCSSElement("cssFloat")] || "none"; css["clear"] = ClearMap[computedCSSElement("clear")] || "none"; css["color"] = computedCSSElement("color"); return css; }; elementHandledElsewhere = function elementHandledElsewhere(element, renderer, elementHandlers) { var handlers, i, isHandledElsewhere, l, t; isHandledElsewhere = false; i = void 0; l = void 0; t = void 0; handlers = elementHandlers["#" + element.id]; if (handlers) { if (typeof handlers === "function") { isHandledElsewhere = handlers(element, renderer); } else { i = 0; l = handlers.length; while (!isHandledElsewhere && i !== l) { isHandledElsewhere = handlers[i](element, renderer); i++; } } } handlers = elementHandlers[element.nodeName]; if (!isHandledElsewhere && handlers) { if (typeof handlers === "function") { isHandledElsewhere = handlers(element, renderer); } else { i = 0; l = handlers.length; while (!isHandledElsewhere && i !== l) { isHandledElsewhere = handlers[i](element, renderer); i++; } } } return isHandledElsewhere; }; tableToJson = function tableToJson(table, renderer) { var data, headers, i, j, rowData, tableRow, table_obj, table_with, cell, l; data = []; headers = []; i = 0; l = table.rows[0].cells.length; table_with = table.clientWidth; while (i < l) { cell = table.rows[0].cells[i]; headers[i] = { name: cell.textContent.toLowerCase().replace(/\s+/g, ''), prompt: cell.textContent.replace(/\r?\n/g, ''), width: cell.clientWidth / table_with * renderer.pdf.internal.pageSize.width }; i++; } i = 1; while (i < table.rows.length) { tableRow = table.rows[i]; rowData = {}; j = 0; while (j < tableRow.cells.length) { rowData[headers[j].name] = tableRow.cells[j].textContent.replace(/\r?\n/g, ''); j++; } data.push(rowData); i++; } return table_obj = { rows: data, headers: headers }; }; var SkipNode = { SCRIPT: 1, STYLE: 1, NOSCRIPT: 1, OBJECT: 1, EMBED: 1, SELECT: 1 }; var listCount = 1; _DrillForContent = function DrillForContent(element, renderer, elementHandlers) { var cn, cns, fragmentCSS, i, isBlock, l, px2pt, table2json, cb; cns = element.childNodes; cn = void 0; fragmentCSS = GetCSS(element); isBlock = fragmentCSS.display === "block"; if (isBlock) { renderer.setBlockBoundary(); renderer.setBlockStyle(fragmentCSS); } px2pt = 0.264583 * 72 / 25.4; i = 0; l = cns.length; while (i < l) { cn = cns[i]; if ((typeof cn === "undefined" ? "undefined" : _typeof(cn)) === "object") { //execute all watcher functions to e.g. reset floating renderer.executeWatchFunctions(cn); /*** HEADER rendering **/ if (cn.nodeType === 1 && cn.nodeName === 'HEADER') { var header = cn; //store old top margin var oldMarginTop = renderer.pdf.margins_doc.top; //subscribe for new page event and render header first on every page renderer.pdf.internal.events.subscribe('addPage', function (pageInfo) { //set current y position to old margin renderer.y = oldMarginTop; //render all child nodes of the header element _DrillForContent(header, renderer, elementHandlers); //set margin to old margin + rendered header + 10 space to prevent overlapping //important for other plugins (e.g. table) to start rendering at correct position after header renderer.pdf.margins_doc.top = renderer.y + 10; renderer.y += 10; }, false); } if (cn.nodeType === 8 && cn.nodeName === "#comment") { if (~cn.textContent.indexOf("ADD_PAGE")) { renderer.pdf.addPage(); renderer.y = renderer.pdf.margins_doc.top; } } else if (cn.nodeType === 1 && !SkipNode[cn.nodeName]) { /*** IMAGE RENDERING ***/ var cached_image; if (cn.nodeName === "IMG") { var url = cn.getAttribute("src"); cached_image = images[renderer.pdf.sHashCode(url) || url]; } if (cached_image) { if (renderer.pdf.internal.pageSize.height - renderer.pdf.margins_doc.bottom < renderer.y + cn.height && renderer.y > renderer.pdf.margins_doc.top) { renderer.pdf.addPage(); renderer.y = renderer.pdf.margins_doc.top; //check if we have to set back some values due to e.g. header rendering for new page renderer.executeWatchFunctions(cn); } var imagesCSS = GetCSS(cn); var imageX = renderer.x; var fontToUnitRatio = 12 / renderer.pdf.internal.scaleFactor; //define additional paddings, margins which have to be taken into account for margin calculations var additionalSpaceLeft = (imagesCSS["margin-left"] + imagesCSS["padding-left"]) * fontToUnitRatio; var additionalSpaceRight = (imagesCSS["margin-right"] + imagesCSS["padding-right"]) * fontToUnitRatio; var additionalSpaceTop = (imagesCSS["margin-top"] + imagesCSS["padding-top"]) * fontToUnitRatio; var additionalSpaceBottom = (imagesCSS["margin-bottom"] + imagesCSS["padding-bottom"]) * fontToUnitRatio; //if float is set to right, move the image to the right border //add space if margin is set if (imagesCSS['float'] !== undefined && imagesCSS['float'] === 'right') { imageX += renderer.settings.width - cn.width - additionalSpaceRight; } else { imageX += additionalSpaceLeft; } renderer.pdf.addImage(cached_image, imageX, renderer.y + additionalSpaceTop, cn.width, cn.height); cached_image = undefined; //if the float prop is specified we have to float the text around the image if (imagesCSS['float'] === 'right' || imagesCSS['float'] === 'left') { //add functiont to set back coordinates after image rendering renderer.watchFunctions.push(function (diffX, thresholdY, diffWidth, el) { //undo drawing box adaptions which were set by floating if (renderer.y >= thresholdY) { renderer.x += diffX; renderer.settings.width += diffWidth; return true; } else if (el && el.nodeType === 1 && !SkipNode[el.nodeName] && renderer.x + el.width > renderer.pdf.margins_doc.left + renderer.pdf.margins_doc.width) { renderer.x += diffX; renderer.y = thresholdY; renderer.settings.width += diffWidth; return true; } else { return false; } }.bind(this, imagesCSS['float'] === 'left' ? -cn.width - additionalSpaceLeft - additionalSpaceRight : 0, renderer.y + cn.height + additionalSpaceTop + additionalSpaceBottom, cn.width)); //reset floating by clear:both divs //just set cursorY after the floating element renderer.watchFunctions.push(function (yPositionAfterFloating, pages, el) { if (renderer.y < yPositionAfterFloating && pages === renderer.pdf.internal.getNumberOfPages()) { if (el.nodeType === 1 && GetCSS(el).clear === 'both') { renderer.y = yPositionAfterFloating; return true; } else { return false; } } else { return true; } }.bind(this, renderer.y + cn.height, renderer.pdf.internal.getNumberOfPages())); //if floating is set we decrease the available width by the image width renderer.settings.width -= cn.width + additionalSpaceLeft + additionalSpaceRight; //if left just add the image width to the X coordinate if (imagesCSS['float'] === 'left') { renderer.x += cn.width + additionalSpaceLeft + additionalSpaceRight; } } else { //if no floating is set, move the rendering cursor after the image height renderer.y += cn.height + additionalSpaceTop + additionalSpaceBottom; } /*** TABLE RENDERING ***/ } else if (cn.nodeName === "TABLE") { table2json = tableToJson(cn, renderer); renderer.y += 10; renderer.pdf.table(renderer.x, renderer.y, table2json.rows, table2json.headers, { autoSize: false, printHeaders: elementHandlers.printHeaders, margins: renderer.pdf.margins_doc, css: GetCSS(cn) }); renderer.y = renderer.pdf.lastCellPos.y + renderer.pdf.lastCellPos.h + 20; } else if (cn.nodeName === "OL" || cn.nodeName === "UL") { listCount = 1; if (!elementHandledElsewhere(cn, renderer, elementHandlers)) { _DrillForContent(cn, renderer, elementHandlers); } renderer.y += 10; } else if (cn.nodeName === "LI") { var temp = renderer.x; renderer.x += 20 / renderer.pdf.internal.scaleFactor; renderer.y += 3; if (!elementHandledElsewhere(cn, renderer, elementHandlers)) { _DrillForContent(cn, renderer, elementHandlers); } renderer.x = temp; } else if (cn.nodeName === "BR") { renderer.y += fragmentCSS["font-size"] * renderer.pdf.internal.scaleFactor; renderer.addText("\u2028", clone(fragmentCSS)); } else { if (!elementHandledElsewhere(cn, renderer, elementHandlers)) { _DrillForContent(cn, renderer, elementHandlers); } } } else if (cn.nodeType === 3) { var value = cn.nodeValue; if (cn.nodeValue && cn.parentNode.nodeName === "LI") { if (cn.parentNode.parentNode.nodeName === "OL") { value = listCount++ + '. ' + value; } else { var fontSize = fragmentCSS["font-size"]; var offsetX = (3 - fontSize * 0.75) * renderer.pdf.internal.scaleFactor; var offsetY = fontSize * 0.75 * renderer.pdf.internal.scaleFactor; var radius = fontSize * 1.74 / renderer.pdf.internal.scaleFactor; cb = function cb(x, y) { this.pdf.circle(x + offsetX, y + offsetY, radius, 'FD'); }; } } // Only add the text if the text node is in the body element // Add compatibility with IE11 if (!!(cn.ownerDocument.body.compareDocumentPosition(cn) & 16)) { renderer.addText(value, fragmentCSS); } } else if (typeof cn === "string") { renderer.addText(cn, fragmentCSS); } } i++; } elementHandlers.outY = renderer.y; if (isBlock) { return renderer.setBlockBoundary(cb); } }; images = {}; loadImgs = function loadImgs(element, renderer, elementHandlers, cb) { var imgs = element.getElementsByTagName('img'), l = imgs.length, found_images, x = 0; function done() { renderer.pdf.internal.events.publish('imagesLoaded'); cb(found_images); } function loadImage(url, width, height) { if (!url) return; var img = new Image(); found_images = ++x; img.crossOrigin = ''; img.onerror = img.onload = function () { if (img.complete) { //to support data urls in images, set width and height //as those values are not recognized automatically if (img.src.indexOf('data:image/') === 0) { img.width = width || img.width || 0; img.height = height || img.height || 0; } //if valid image add to known images array if (img.width + img.height) { var hash = renderer.pdf.sHashCode(url) || url; images[hash] = images[hash] || img; } } if (! --x) { done(); } }; img.src = url; } while (l--) { loadImage(imgs[l].getAttribute("src"), imgs[l].width, imgs[l].height); }return x || done(); }; checkForFooter = function checkForFooter(elem, renderer, elementHandlers) { //check if we can found a