You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2405 lines
66 KiB
2405 lines
66 KiB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.DxfParser = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ |
|
/** |
|
* AutoCad files sometimes use an indexed color value between 1 and 255 inclusive. |
|
* Each value corresponds to a color. index 1 is red, that is 16711680 or 0xFF0000. |
|
* index 0 and 256, while included in this array, are actually reserved for inheritance |
|
* values in AutoCad so they should not be used for index color lookups. |
|
*/ |
|
|
|
module.exports = [ |
|
0, |
|
16711680, |
|
16776960, |
|
65280, |
|
65535, |
|
255, |
|
16711935, |
|
16777215, |
|
8421504, |
|
12632256, |
|
16711680, |
|
16744319, |
|
13369344, |
|
13395558, |
|
10027008, |
|
10046540, |
|
8323072, |
|
8339263, |
|
4980736, |
|
4990502, |
|
16727808, |
|
16752511, |
|
13382400, |
|
13401958, |
|
10036736, |
|
10051404, |
|
8331008, |
|
8343359, |
|
4985600, |
|
4992806, |
|
16744192, |
|
16760703, |
|
13395456, |
|
13408614, |
|
10046464, |
|
10056268, |
|
8339200, |
|
8347455, |
|
4990464, |
|
4995366, |
|
16760576, |
|
16768895, |
|
13408512, |
|
13415014, |
|
10056192, |
|
10061132, |
|
8347392, |
|
8351551, |
|
4995328, |
|
4997670, |
|
16776960, |
|
16777087, |
|
13421568, |
|
13421670, |
|
10000384, |
|
10000460, |
|
8355584, |
|
8355647, |
|
5000192, |
|
5000230, |
|
12582656, |
|
14679935, |
|
10079232, |
|
11717734, |
|
7510016, |
|
8755276, |
|
6258432, |
|
7307071, |
|
3755008, |
|
4344870, |
|
8388352, |
|
12582783, |
|
6736896, |
|
10079334, |
|
5019648, |
|
7510092, |
|
4161280, |
|
6258495, |
|
2509824, |
|
3755046, |
|
4194048, |
|
10485631, |
|
3394560, |
|
8375398, |
|
2529280, |
|
6264908, |
|
2064128, |
|
5209919, |
|
1264640, |
|
3099686, |
|
65280, |
|
8388479, |
|
52224, |
|
6736998, |
|
38912, |
|
5019724, |
|
32512, |
|
4161343, |
|
19456, |
|
2509862, |
|
65343, |
|
8388511, |
|
52275, |
|
6737023, |
|
38950, |
|
5019743, |
|
32543, |
|
4161359, |
|
19475, |
|
2509871, |
|
65407, |
|
8388543, |
|
52326, |
|
6737049, |
|
38988, |
|
5019762, |
|
32575, |
|
4161375, |
|
19494, |
|
2509881, |
|
65471, |
|
8388575, |
|
52377, |
|
6737074, |
|
39026, |
|
5019781, |
|
32607, |
|
4161391, |
|
19513, |
|
2509890, |
|
65535, |
|
8388607, |
|
52428, |
|
6737100, |
|
39064, |
|
5019800, |
|
32639, |
|
4161407, |
|
19532, |
|
2509900, |
|
49151, |
|
8380415, |
|
39372, |
|
6730444, |
|
29336, |
|
5014936, |
|
24447, |
|
4157311, |
|
14668, |
|
2507340, |
|
32767, |
|
8372223, |
|
26316, |
|
6724044, |
|
19608, |
|
5010072, |
|
16255, |
|
4153215, |
|
9804, |
|
2505036, |
|
16383, |
|
8364031, |
|
13260, |
|
6717388, |
|
9880, |
|
5005208, |
|
8063, |
|
4149119, |
|
4940, |
|
2502476, |
|
255, |
|
8355839, |
|
204, |
|
6710988, |
|
152, |
|
5000344, |
|
127, |
|
4145023, |
|
76, |
|
2500172, |
|
4129023, |
|
10452991, |
|
3342540, |
|
8349388, |
|
2490520, |
|
6245528, |
|
2031743, |
|
5193599, |
|
1245260, |
|
3089996, |
|
8323327, |
|
12550143, |
|
6684876, |
|
10053324, |
|
4980888, |
|
7490712, |
|
4128895, |
|
6242175, |
|
2490444, |
|
3745356, |
|
12517631, |
|
14647295, |
|
10027212, |
|
11691724, |
|
7471256, |
|
8735896, |
|
6226047, |
|
7290751, |
|
3735628, |
|
4335180, |
|
16711935, |
|
16744447, |
|
13369548, |
|
13395660, |
|
9961624, |
|
9981080, |
|
8323199, |
|
8339327, |
|
4980812, |
|
4990540, |
|
16711871, |
|
16744415, |
|
13369497, |
|
13395634, |
|
9961586, |
|
9981061, |
|
8323167, |
|
8339311, |
|
4980793, |
|
4990530, |
|
16711807, |
|
16744383, |
|
13369446, |
|
13395609, |
|
9961548, |
|
9981042, |
|
8323135, |
|
8339295, |
|
4980774, |
|
4990521, |
|
16711743, |
|
16744351, |
|
13369395, |
|
13395583, |
|
9961510, |
|
9981023, |
|
8323103, |
|
8339279, |
|
4980755, |
|
4990511, |
|
3355443, |
|
5987163, |
|
8684676, |
|
11382189, |
|
14079702, |
|
16777215 |
|
]; |
|
},{}],2:[function(require,module,exports){ |
|
/** |
|
* DxfArrayScanner |
|
* |
|
* Based off the AutoCad 2012 DXF Reference |
|
* http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf |
|
* |
|
* Reads through an array representing lines of a dxf file. Takes an array and |
|
* provides an easy interface to extract group code and value pairs. |
|
* @param data - an array where each element represents a line in the dxf file |
|
* @constructor |
|
*/ |
|
function DxfArrayScanner(data) { |
|
this._pointer = 0; |
|
this._data = data; |
|
this._eof = false; |
|
} |
|
|
|
/** |
|
* Gets the next group (code, value) from the array. A group is two consecutive elements |
|
* in the array. The first is the code, the second is the value. |
|
* @returns {{code: Number}|*} |
|
*/ |
|
DxfArrayScanner.prototype.next = function() { |
|
var group; |
|
if(!this.hasNext()) { |
|
if(!this._eof) |
|
throw new Error('Unexpected end of input: EOF group not read before end of file. Ended on code ' + this._data[this._pointer]); |
|
else |
|
throw new Error('Cannot call \'next\' after EOF group has been read'); |
|
} |
|
|
|
group = { |
|
code: parseInt(this._data[this._pointer]) |
|
}; |
|
|
|
this._pointer++; |
|
|
|
group.value = parseGroupValue(group.code, this._data[this._pointer].trim()); |
|
|
|
this._pointer++; |
|
|
|
if(group.code === 0 && group.value === 'EOF') this._eof = true; |
|
|
|
this.lastReadGroup = group; |
|
|
|
return group; |
|
}; |
|
|
|
DxfArrayScanner.prototype.peek = function() { |
|
if(!this.hasNext()) { |
|
if(!this._eof) |
|
throw new Error('Unexpected end of input: EOF group not read before end of file. Ended on code ' + this._data[this._pointer]); |
|
else |
|
throw new Error('Cannot call \'next\' after EOF group has been read'); |
|
} |
|
|
|
var group = { |
|
code: parseInt(this._data[this._pointer]) |
|
}; |
|
|
|
group.value = parseGroupValue(group.code, this._data[this._pointer + 1].trim()); |
|
|
|
return group; |
|
}; |
|
|
|
|
|
DxfArrayScanner.prototype.rewind = function(numberOfGroups) { |
|
numberOfGroups = numberOfGroups || 1; |
|
this._pointer = this._pointer - numberOfGroups * 2; |
|
}; |
|
|
|
/** |
|
* Returns true if there is another code/value pair (2 elements in the array). |
|
* @returns {boolean} |
|
*/ |
|
DxfArrayScanner.prototype.hasNext = function() { |
|
// Check if we have read EOF group code |
|
if(this._eof) { |
|
return false; |
|
} |
|
|
|
// We need to be sure there are two lines available |
|
if(this._pointer > this._data.length - 2) { |
|
return false; |
|
} |
|
return true; |
|
}; |
|
|
|
/** |
|
* Returns true if the scanner is at the end of the array |
|
* @returns {boolean} |
|
*/ |
|
DxfArrayScanner.prototype.isEOF = function() { |
|
return this._eof; |
|
}; |
|
|
|
/** |
|
* Parse a value to its proper type. |
|
* See pages 3 - 10 of the AutoCad DXF 2012 reference given at the top of this file |
|
* |
|
* @param code |
|
* @param value |
|
* @returns {*} |
|
*/ |
|
function parseGroupValue(code, value) { |
|
if(code <= 9) return value; |
|
if(code >= 10 && code <= 59) return parseFloat(value); |
|
if(code >= 60 && code <= 99) return parseInt(value); |
|
if(code >= 100 && code <= 109) return value; |
|
if(code >= 110 && code <= 149) return parseFloat(value); |
|
if(code >= 160 && code <= 179) return parseInt(value); |
|
if(code >= 210 && code <= 239) return parseFloat(value); |
|
if(code >= 270 && code <= 289) return parseInt(value); |
|
if(code >= 290 && code <= 299) return parseBoolean(value); |
|
if(code >= 300 && code <= 369) return value; |
|
if(code >= 370 && code <= 389) return parseInt(value); |
|
if(code >= 390 && code <= 399) return value; |
|
if(code >= 400 && code <= 409) return parseInt(value); |
|
if(code >= 410 && code <= 419) return value; |
|
if(code >= 420 && code <= 429) return parseInt(value); |
|
if(code >= 430 && code <= 439) return value; |
|
if(code >= 440 && code <= 459) return parseInt(value); |
|
if(code >= 460 && code <= 469) return parseFloat(value); |
|
if(code >= 470 && code <= 481) return value; |
|
if(code === 999) return value; |
|
if(code >= 1000 && code <= 1009) return value; |
|
if(code >= 1010 && code <= 1059) return parseFloat(value); |
|
if(code >= 1060 && code <= 1071) return parseInt(value); |
|
|
|
console.log('WARNING: Group code does not have a defined type: %j', { code: code, value: value }); |
|
return value; |
|
} |
|
|
|
/** |
|
* Parse a boolean according to a 1 or 0 value |
|
* @param str |
|
* @returns {boolean} |
|
*/ |
|
function parseBoolean(str) { |
|
if(str === '0') return false; |
|
if(str === '1') return true; |
|
throw TypeError('String \'' + str + '\' cannot be cast to Boolean type'); |
|
} |
|
|
|
module.exports = DxfArrayScanner; |
|
},{}],3:[function(require,module,exports){ |
|
var DxfArrayScanner = require('./DxfArrayScanner.js'), |
|
AUTO_CAD_COLOR_INDEX = require('./AutoCadColorIndex'); |
|
|
|
var log = require('loglevel'); |
|
|
|
//log.setLevel('trace'); |
|
//log.setLevel('debug'); |
|
//log.setLevel('info'); |
|
//log.setLevel('warn'); |
|
log.setLevel('error'); |
|
//log.setLevel('silent'); |
|
|
|
function registerDefaultEntityHandlers(dxfParser) { |
|
// Supported entities here (some entity code is still being refactored into this flow) |
|
dxfParser.registerEntityHandler(require('./entities/3dface')); |
|
dxfParser.registerEntityHandler(require('./entities/arc')); |
|
dxfParser.registerEntityHandler(require('./entities/attdef')); |
|
dxfParser.registerEntityHandler(require('./entities/circle')); |
|
dxfParser.registerEntityHandler(require('./entities/dimension')); |
|
dxfParser.registerEntityHandler(require('./entities/ellipse')); |
|
dxfParser.registerEntityHandler(require('./entities/insert')); |
|
dxfParser.registerEntityHandler(require('./entities/line')); |
|
dxfParser.registerEntityHandler(require('./entities/lwpolyline')); |
|
dxfParser.registerEntityHandler(require('./entities/mtext')); |
|
dxfParser.registerEntityHandler(require('./entities/point')); |
|
dxfParser.registerEntityHandler(require('./entities/polyline')); |
|
dxfParser.registerEntityHandler(require('./entities/solid')); |
|
dxfParser.registerEntityHandler(require('./entities/spline')); |
|
dxfParser.registerEntityHandler(require('./entities/text')); |
|
//dxfParser.registerEntityHandler(require('./entities/vertex')); |
|
} |
|
|
|
function DxfParser() { |
|
this._entityHandlers = {}; |
|
|
|
registerDefaultEntityHandlers(this); |
|
} |
|
|
|
DxfParser.prototype.parse = function(source, done) { |
|
throw new Error("read() not implemented. Use readSync()"); |
|
}; |
|
|
|
DxfParser.prototype.registerEntityHandler = function(handlerType) { |
|
var instance = new handlerType(); |
|
this._entityHandlers[handlerType.ForEntityName] = instance; |
|
} |
|
|
|
DxfParser.prototype.parseSync = function(source) { |
|
if(typeof(source) === 'string') { |
|
return this._parse(source); |
|
}else { |
|
console.error('Cannot read dxf source of type `' + typeof(source)); |
|
return null; |
|
} |
|
}; |
|
|
|
DxfParser.prototype.parseStream = function(stream, done) { |
|
|
|
var dxfString = ""; |
|
var self = this; |
|
|
|
stream.on('data', onData); |
|
stream.on('end', onEnd); |
|
stream.on('error', onError); |
|
|
|
function onData(chunk) { |
|
dxfString += chunk; |
|
} |
|
|
|
function onEnd() { |
|
try { |
|
var dxf = self._parse(dxfString); |
|
}catch(err) { |
|
return done(err); |
|
} |
|
done(null, dxf); |
|
} |
|
|
|
function onError(err) { |
|
done(err); |
|
} |
|
}; |
|
|
|
DxfParser.prototype._parse = function(dxfString) { |
|
var scanner, curr, dxf = {}, lastHandle = 0; |
|
var dxfLinesArray = dxfString.split(/\r\n|\r|\n/g); |
|
|
|
scanner = new DxfArrayScanner(dxfLinesArray); |
|
if(!scanner.hasNext()) throw Error('Empty file'); |
|
|
|
var self = this; |
|
|
|
var parseAll = function() { |
|
curr = scanner.next(); |
|
while(!scanner.isEOF()) { |
|
if(curr.code === 0 && curr.value === 'SECTION') { |
|
curr = scanner.next(); |
|
|
|
// Be sure we are reading a section code |
|
if (curr.code !== 2) { |
|
console.error('Unexpected code %s after 0:SECTION', debugCode(curr)); |
|
curr = scanner.next(); |
|
continue; |
|
} |
|
|
|
if (curr.value === 'HEADER') { |
|
log.debug('> HEADER'); |
|
dxf.header = parseHeader(); |
|
log.debug('<'); |
|
} else if (curr.value === 'BLOCKS') { |
|
log.debug('> BLOCKS'); |
|
dxf.blocks = parseBlocks(); |
|
log.debug('<'); |
|
} else if(curr.value === 'ENTITIES') { |
|
log.debug('> ENTITIES'); |
|
dxf.entities = parseEntities(false); |
|
log.debug('<'); |
|
} else if(curr.value === 'TABLES') { |
|
log.debug('> TABLES'); |
|
dxf.tables = parseTables(); |
|
log.debug('<'); |
|
} else if(curr.value === 'EOF') { |
|
log.debug('EOF'); |
|
} else { |
|
log.warn('Skipping section \'%s\'', curr.value); |
|
} |
|
} else { |
|
curr = scanner.next(); |
|
} |
|
// If is a new section |
|
} |
|
}; |
|
|
|
var groupIs = function(code, value) { |
|
return curr.code === code && curr.value === value; |
|
}; |
|
|
|
/** |
|
* |
|
* @return {object} header |
|
*/ |
|
var parseHeader = function() { |
|
// interesting variables: |
|
// $ACADVER, $VIEWDIR, $VIEWSIZE, $VIEWCTR, $TDCREATE, $TDUPDATE |
|
// http://www.autodesk.com/techpubs/autocad/acadr14/dxf/header_section_al_u05_c.htm |
|
// Also see VPORT table entries |
|
var currVarName = null, currVarValue = null; |
|
var header = {}; |
|
// loop through header variables |
|
curr = scanner.next(); |
|
|
|
while(true) { |
|
if(groupIs(0, 'ENDSEC')) { |
|
if(currVarName) header[currVarName] = currVarValue; |
|
break; |
|
} else if(curr.code === 9) { |
|
if(currVarName) header[currVarName] = currVarValue; |
|
currVarName = curr.value; |
|
// Filter here for particular variables we are interested in |
|
} else { |
|
if(curr.code === 10) { |
|
currVarValue = { x: curr.value }; |
|
} else if(curr.code === 20) { |
|
currVarValue.y = curr.value; |
|
} else if(curr.code === 30) { |
|
currVarValue.z = curr.value; |
|
} else { |
|
currVarValue = curr.value; |
|
} |
|
} |
|
curr = scanner.next(); |
|
} |
|
// console.log(util.inspect(header, { colors: true, depth: null })); |
|
curr = scanner.next(); // swallow up ENDSEC |
|
return header; |
|
}; |
|
|
|
|
|
/** |
|
* |
|
*/ |
|
var parseBlocks = function() { |
|
var blocks = {}, block; |
|
|
|
curr = scanner.next(); |
|
|
|
while(curr.value !== 'EOF') { |
|
if(groupIs(0, 'ENDSEC')) { |
|
break; |
|
} |
|
|
|
if(groupIs(0, 'BLOCK')) { |
|
log.debug('block {'); |
|
block = parseBlock(); |
|
log.debug('}'); |
|
ensureHandle(block); |
|
if(!block.name) |
|
log.error('block with handle "' + block.handle + '" is missing a name.'); |
|
else |
|
blocks[block.name] = block; |
|
} else { |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
} |
|
} |
|
return blocks; |
|
}; |
|
|
|
var parseBlock = function() { |
|
var block = {}; |
|
curr = scanner.next(); |
|
|
|
while(curr.value !== 'EOF') { |
|
switch(curr.code) { |
|
case 1: |
|
block.xrefPath = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 2: |
|
block.name = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 3: |
|
block.name2 = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 5: |
|
block.handle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 8: |
|
block.layer = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 10: |
|
block.position = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 67: |
|
block.paperSpace = (curr.value && curr.value == 1) ? true : false; |
|
curr = scanner.next(); |
|
break; |
|
case 70: |
|
if (curr.value != 0) { |
|
//if(curr.value & BLOCK_ANONYMOUS_FLAG) console.log(' Anonymous block'); |
|
//if(curr.value & BLOCK_NON_CONSTANT_FLAG) console.log(' Non-constant attributes'); |
|
//if(curr.value & BLOCK_XREF_FLAG) console.log(' Is xref'); |
|
//if(curr.value & BLOCK_XREF_OVERLAY_FLAG) console.log(' Is xref overlay'); |
|
//if(curr.value & BLOCK_EXTERNALLY_DEPENDENT_FLAG) console.log(' Is externally dependent'); |
|
//if(curr.value & BLOCK_RESOLVED_OR_DEPENDENT_FLAG) console.log(' Is resolved xref or dependent of an xref'); |
|
//if(curr.value & BLOCK_REFERENCED_XREF) console.log(' This definition is a referenced xref'); |
|
block.type = curr.value; |
|
} |
|
curr = scanner.next(); |
|
break; |
|
case 100: |
|
// ignore class markers |
|
curr = scanner.next(); |
|
break; |
|
case 330: |
|
block.ownerHandle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 0: |
|
if(curr.value == 'ENDBLK') |
|
break; |
|
block.entities = parseEntities(true); |
|
break; |
|
default: |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
} |
|
|
|
if(groupIs(0, 'ENDBLK')) { |
|
curr = scanner.next(); |
|
break; |
|
} |
|
} |
|
return block; |
|
}; |
|
|
|
/** |
|
* parseTables |
|
* @return {Object} Object representing tables |
|
*/ |
|
var parseTables = function() { |
|
var tables = {}; |
|
curr = scanner.next(); |
|
while(curr.value !== 'EOF') { |
|
if(groupIs(0, 'ENDSEC')) |
|
break; |
|
|
|
if(groupIs(0, 'TABLE')) { |
|
curr = scanner.next(); |
|
|
|
var tableDefinition = tableDefinitions[curr.value]; |
|
if(tableDefinition) { |
|
log.debug(curr.value + ' Table {'); |
|
tables[tableDefinitions[curr.value].tableName] = parseTable(); |
|
log.debug('}'); |
|
} else { |
|
log.debug('Unhandled Table ' + curr.value); |
|
} |
|
} else { |
|
// else ignored |
|
curr = scanner.next(); |
|
} |
|
} |
|
|
|
curr = scanner.next(); |
|
return tables; |
|
}; |
|
|
|
const END_OF_TABLE_VALUE = 'ENDTAB'; |
|
|
|
var parseTable = function() { |
|
var tableDefinition = tableDefinitions[curr.value], |
|
table = {}, |
|
expectedCount = 0, |
|
actualCount; |
|
|
|
curr = scanner.next(); |
|
while(!groupIs(0, END_OF_TABLE_VALUE)) { |
|
|
|
switch(curr.code) { |
|
case 5: |
|
table.handle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 330: |
|
table.ownerHandle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 100: |
|
if(curr.value === 'AcDbSymbolTable') { |
|
// ignore |
|
curr = scanner.next(); |
|
}else{ |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
} |
|
break; |
|
case 70: |
|
expectedCount = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 0: |
|
if(curr.value === tableDefinition.dxfSymbolName) { |
|
table[tableDefinition.tableRecordsProperty] = tableDefinition.parseTableRecords(); |
|
} else { |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
} |
|
break; |
|
default: |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
} |
|
} |
|
var tableRecords = table[tableDefinition.tableRecordsProperty]; |
|
if(tableRecords) { |
|
if(tableRecords.constructor === Array){ |
|
actualCount = tableRecords.length; |
|
} else if(typeof(tableRecords) === 'object') { |
|
actualCount = Object.keys(tableRecords).length; |
|
} |
|
if(expectedCount !== actualCount) log.warn('Parsed ' + actualCount + ' ' + tableDefinition.dxfSymbolName + '\'s but expected ' + expectedCount); |
|
} |
|
curr = scanner.next(); |
|
return table; |
|
}; |
|
|
|
var parseViewPortRecords = function() { |
|
var viewPorts = [], // Multiple table entries may have the same name indicating a multiple viewport configuration |
|
viewPort = {}; |
|
|
|
log.debug('ViewPort {'); |
|
curr = scanner.next(); |
|
while(!groupIs(0, END_OF_TABLE_VALUE)) { |
|
|
|
switch(curr.code) { |
|
case 2: // layer name |
|
viewPort.name = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 10: |
|
viewPort.lowerLeftCorner = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 11: |
|
viewPort.upperRightCorner = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 12: |
|
viewPort.center = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 13: |
|
viewPort.snapBasePoint = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 14: |
|
viewPort.snapSpacing = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 15: |
|
viewPort.gridSpacing = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 16: |
|
viewPort.viewDirectionFromTarget = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 17: |
|
viewPort.viewTarget = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 42: |
|
viewPort.lensLength = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 43: |
|
viewPort.frontClippingPlane = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 44: |
|
viewPort.backClippingPlane = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 45: |
|
viewPort.viewHeight = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 50: |
|
viewPort.snapRotationAngle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 51: |
|
viewPort.viewTwistAngle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 79: |
|
viewPort.orthographicType = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 110: |
|
viewPort.ucsOrigin = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 111: |
|
viewPort.ucsXAxis = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 112: |
|
viewPort.ucsYAxis = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 110: |
|
viewPort.ucsOrigin = parsePoint(); |
|
curr = scanner.next(); |
|
break; |
|
case 281: |
|
viewPort.renderMode = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 281: |
|
// 0 is one distant light, 1 is two distant lights |
|
viewPort.defaultLightingType = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 292: |
|
viewPort.defaultLightingOn = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 330: |
|
viewPort.ownerHandle = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 63: |
|
case 421: |
|
case 431: |
|
viewPort.ambientColor = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 0: |
|
// New ViewPort |
|
if(curr.value === 'VPORT') { |
|
log.debug('}'); |
|
viewPorts.push(viewPort); |
|
log.debug('ViewPort {'); |
|
viewPort = {}; |
|
curr = scanner.next(); |
|
} |
|
break; |
|
default: |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
break; |
|
} |
|
} |
|
// Note: do not call scanner.next() here, |
|
// parseTable() needs the current group |
|
log.debug('}'); |
|
viewPorts.push(viewPort); |
|
|
|
return viewPorts; |
|
}; |
|
|
|
var parseLineTypes = function() { |
|
var ltypes = {}, |
|
ltypeName, |
|
ltype = {}, |
|
length; |
|
|
|
log.debug('LType {'); |
|
curr = scanner.next(); |
|
while(!groupIs(0, 'ENDTAB')) { |
|
|
|
switch(curr.code) { |
|
case 2: |
|
ltype.name = curr.value; |
|
ltypeName = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 3: |
|
ltype.description = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 73: // Number of elements for this line type (dots, dashes, spaces); |
|
length = curr.value; |
|
if(length > 0) ltype.pattern = []; |
|
curr = scanner.next(); |
|
break; |
|
case 40: // total pattern length |
|
ltype.patternLength = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 49: |
|
ltype.pattern.push(curr.value); |
|
curr = scanner.next(); |
|
break; |
|
case 0: |
|
log.debug('}'); |
|
if(length > 0 && length !== ltype.pattern.length) log.warn('lengths do not match on LTYPE pattern'); |
|
ltypes[ltypeName] = ltype; |
|
ltype = {}; |
|
log.debug('LType {'); |
|
curr = scanner.next(); |
|
break; |
|
default: |
|
curr = scanner.next(); |
|
} |
|
} |
|
|
|
log.debug('}'); |
|
ltypes[ltypeName] = ltype; |
|
return ltypes; |
|
}; |
|
|
|
var parseLayers = function() { |
|
var layers = {}, |
|
layerName, |
|
layer = {}; |
|
|
|
log.debug('Layer {'); |
|
curr = scanner.next(); |
|
while(!groupIs(0, 'ENDTAB')) { |
|
|
|
switch(curr.code) { |
|
case 2: // layer name |
|
layer.name = curr.value; |
|
layerName = curr.value; |
|
curr = scanner.next(); |
|
break; |
|
case 62: // color, visibility |
|
layer.visible = curr.value >= 0; |
|
// TODO 0 and 256 are BYBLOCK and BYLAYER respectively. Need to handle these values for layers?. |
|
layer.color = getAcadColor(Math.abs(curr.value)); |
|
curr = scanner.next(); |
|
break; |
|
case 70: // frozen layer |
|
layer.frozen = ((curr.value & 1) != 0 || (curr.value & 2) != 0); |
|
curr = scanner.next(); |
|
break; |
|
case 0: |
|
// New Layer |
|
if(curr.value === 'LAYER') { |
|
log.debug('}'); |
|
layers[layerName] = layer; |
|
log.debug('Layer {'); |
|
layer = {}; |
|
layerName = undefined; |
|
curr = scanner.next(); |
|
} |
|
break; |
|
default: |
|
logUnhandledGroup(curr); |
|
curr = scanner.next(); |
|
break; |
|
} |
|
} |
|
// Note: do not call scanner.next() here, |
|
// parseLayerTable() needs the current group |
|
log.debug('}'); |
|
layers[layerName] = layer; |
|
|
|
return layers; |
|
}; |
|
|
|
var tableDefinitions = { |
|
VPORT: { |
|
tableRecordsProperty: 'viewPorts', |
|
tableName: 'viewPort', |
|
dxfSymbolName: 'VPORT', |
|
parseTableRecords: parseViewPortRecords |
|
}, |
|
LTYPE: { |
|
tableRecordsProperty: 'lineTypes', |
|
tableName: 'lineType', |
|
dxfSymbolName: 'LTYPE', |
|
parseTableRecords: parseLineTypes |
|
}, |
|
LAYER: { |
|
tableRecordsProperty: 'layers', |
|
tableName: 'layer', |
|
dxfSymbolName: 'LAYER', |
|
parseTableRecords: parseLayers |
|
} |
|
}; |
|
|
|
/** |
|
* Is called after the parser first reads the 0:ENTITIES group. The scanner |
|
* should be on the start of the first entity already. |
|
* @return {Array} the resulting entities |
|
*/ |
|
var parseEntities = function(forBlock) { |
|
var entities = []; |
|
|
|
var endingOnValue = forBlock ? 'ENDBLK' : 'ENDSEC'; |
|
|
|
if (!forBlock) { |
|
curr = scanner.next(); |
|
} |
|
while(true) { |
|
|
|
if(curr.code === 0) { |
|
if(curr.value === endingOnValue) { |
|
break; |
|
} |
|
|
|
var entity; |
|
var handler = self._entityHandlers[curr.value]; |
|
if(handler != null) { |
|
log.debug(curr.value + ' {'); |
|
entity = handler.parseEntity(scanner, curr); |
|
curr = scanner.lastReadGroup; |
|
log.debug('}'); |
|
} else { |
|
log.warn('Unhandled entity ' + curr.value); |
|
curr = scanner.next(); |
|
continue; |
|
} |
|
ensureHandle(entity); |
|
entities.push(entity); |
|
} else { |
|
// ignored lines from unsupported entity |
|
curr = scanner.next(); |
|
} |
|
} |
|
if(endingOnValue == 'ENDSEC') curr = scanner.next(); // swallow up ENDSEC, but not ENDBLK |
|
return entities; |
|
}; |
|
|
|
/** |
|
* Parses a 2D or 3D point, returning it as an object with x, y, and |
|
* (sometimes) z property if it is 3D. It is assumed the current group |
|
* is x of the point being read in, and scanner.next() will return the |
|
* y. The parser will determine if there is a z point automatically. |
|
* @return {Object} The 2D or 3D point as an object with x, y[, z] |
|
*/ |
|
var parsePoint = function() { |
|
var point = {}, |
|
code = curr.code; |
|
|
|
point.x = curr.value; |
|
|
|
code += 10; |
|
curr = scanner.next(); |
|
if(curr.code != code) |
|
throw new Error('Expected code for point value to be ' + code + |
|
' but got ' + curr.code + '.'); |
|
point.y = curr.value; |
|
|
|
code += 10; |
|
curr = scanner.next(); |
|
if(curr.code != code) |
|
{ |
|
scanner.rewind(); |
|
return point; |
|
} |
|
point.z = curr.value; |
|
|
|
return point; |
|
}; |
|
|
|
var ensureHandle = function(entity) { |
|
if(!entity) throw new TypeError('entity cannot be undefined or null'); |
|
|
|
if(!entity.handle) entity.handle = lastHandle++; |
|
}; |
|
|
|
parseAll(); |
|
return dxf; |
|
}; |
|
|
|
function logUnhandledGroup(curr) { |
|
log.debug('unhandled group ' + debugCode(curr)); |
|
} |
|
|
|
|
|
function debugCode(curr) { |
|
return curr.code + ':' + curr.value; |
|
} |
|
|
|
/** |
|
* Returns the truecolor value of the given AutoCad color index value |
|
* @return {Number} truecolor value as a number |
|
*/ |
|
function getAcadColor(index) { |
|
return AUTO_CAD_COLOR_INDEX[index]; |
|
} |
|
|
|
const BLOCK_ANONYMOUS_FLAG = 1; |
|
const BLOCK_NON_CONSTANT_FLAG = 2; |
|
const BLOCK_XREF_FLAG = 4; |
|
const BLOCK_XREF_OVERLAY_FLAG = 8; |
|
const BLOCK_EXTERNALLY_DEPENDENT_FLAG = 16; |
|
const BLOCK_RESOLVED_OR_DEPENDENT_FLAG = 32; |
|
const BLOCK_REFERENCED_XREF = 64; |
|
|
|
|
|
|
|
module.exports = DxfParser; |
|
|
|
|
|
/* Notes */ |
|
// Code 6 of an entity indicates inheritance of properties (eg. color). |
|
// BYBLOCK means inherits from block |
|
// BYLAYER (default) mean inherits from layer |
|
},{"./AutoCadColorIndex":1,"./DxfArrayScanner.js":2,"./entities/3dface":5,"./entities/arc":6,"./entities/attdef":7,"./entities/circle":8,"./entities/dimension":9,"./entities/ellipse":10,"./entities/insert":11,"./entities/line":12,"./entities/lwpolyline":13,"./entities/mtext":14,"./entities/point":15,"./entities/polyline":16,"./entities/solid":17,"./entities/spline":18,"./entities/text":19,"loglevel":21}],4:[function(require,module,exports){ |
|
var AUTO_CAD_COLOR_INDEX = require('./AutoCadColorIndex'); |
|
|
|
/** |
|
* Returns the truecolor value of the given AutoCad color index value |
|
* @return {Number} truecolor value as a number |
|
*/ |
|
exports.getAcadColor = function(index) { |
|
return AUTO_CAD_COLOR_INDEX[index]; |
|
} |
|
var getAcadColor = exports.getAcadColor; |
|
|
|
/** |
|
* Parses the 2D or 3D coordinate, vector, or point. When complete, |
|
* the scanner remains on the last group of the coordinate. |
|
* @param {*} scanner |
|
*/ |
|
exports.parsePoint = function(scanner) { |
|
var point = {}; |
|
|
|
// Reread group for the first coordinate |
|
scanner.rewind(); |
|
var curr = scanner.next(); |
|
|
|
code = curr.code; |
|
point.x = curr.value; |
|
|
|
code += 10; |
|
curr = scanner.next(); |
|
if(curr.code != code) |
|
throw new Error('Expected code for point value to be ' + code + |
|
' but got ' + curr.code + '.'); |
|
point.y = curr.value; |
|
|
|
code += 10; |
|
curr = scanner.next(); |
|
if(curr.code != code) |
|
{ |
|
// Only the x and y are specified. Don't read z. |
|
scanner.rewind(); // Let the calling code advance off the point |
|
return point; |
|
} |
|
point.z = curr.value; |
|
|
|
return point; |
|
}; |
|
|
|
/** |
|
* Attempts to parse codes common to all entities. Returns true if the group |
|
* was handled by this function. |
|
* @param {*} entity - the entity currently being parsed |
|
* @param {*} curr - the current group being parsed |
|
*/ |
|
exports.checkCommonEntityProperties = function(entity, curr) { |
|
switch(curr.code) { |
|
case 0: |
|
entity.type = curr.value; |
|
break; |
|
case 5: |
|
entity.handle = curr.value; |
|
break; |
|
case 6: |
|
entity.lineType = curr.value; |
|
break; |
|
case 8: // Layer name |
|
entity.layer = curr.value; |
|
break; |
|
case 48: |
|
entity.lineTypeScale = curr.value; |
|
break; |
|
case 60: |
|
entity.visible = curr.value === 0; |
|
break; |
|
case 62: // Acad Index Color. 0 inherits ByBlock. 256 inherits ByLayer. Default is bylayer |
|
entity.colorIndex = curr.value; |
|
entity.color = getAcadColor(Math.abs(curr.value)); |
|
break; |
|
case 67: |
|
entity.inPaperSpace = curr.value !== 0; |
|
break; |
|
case 100: |
|
//ignore |
|
break; |
|
case 330: |
|
entity.ownerHandle = curr.value; |
|
break; |
|
case 347: |
|
entity.materialObjectHandle = curr.value; |
|
break; |
|
case 370: |
|
//From https://www.woutware.com/Forum/Topic/955/lineweight?returnUrl=%2FForum%2FUserPosts%3FuserId%3D478262319 |
|
// An integer representing 100th of mm, must be one of the following values: |
|
// 0, 5, 9, 13, 15, 18, 20, 25, 30, 35, 40, 50, 53, 60, 70, 80, 90, 100, 106, 120, 140, 158, 200, 211. |
|
// -3 = STANDARD, -2 = BYLAYER, -1 = BYBLOCK |
|
entity.lineweight = curr.value; |
|
break; |
|
case 420: // TrueColor Color |
|
entity.color = curr.value; |
|
break; |
|
case 1000: |
|
entity.extendedData = entity.extendedData || {}; |
|
entity.extendedData.customStrings = entity.extendedData.customStrings || []; |
|
entity.extendedData.customStrings.push(curr.value); |
|
break; |
|
case 1001: |
|
entity.extendedData = entity.extendedData || {}; |
|
entity.extendedData.applicationName = curr.value; |
|
break; |
|
default: |
|
return false; |
|
} |
|
return true; |
|
}; |
|
|
|
},{"./AutoCadColorIndex":1}],5:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = '3DFACE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
|
|
var entity = { type: curr.value, vertices: [] }; |
|
curr = scanner.next(); |
|
while (curr !== 'EOF') { |
|
if (curr.code === 0) break; |
|
switch (curr.code) { |
|
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default |
|
entity.shape = ((curr.value & 1) === 1); |
|
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128); |
|
break; |
|
case 10: // X coordinate of point |
|
entity.vertices = parse3dFaceVertices(scanner, curr); |
|
curr = scanner.lastReadGroup; |
|
break; |
|
default: |
|
checkCommonEntityProperties(entity); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
|
|
function parse3dFaceVertices(scanner, curr) { |
|
var vertices = [], |
|
i; |
|
var vertexIsStarted = false; |
|
var vertexIsFinished = false; |
|
var verticesPer3dFace = 4; // there can be up to four vertices per face, although 3 is most used for TIN |
|
|
|
for (i = 0; i <= verticesPer3dFace; i++) { |
|
var vertex = {}; |
|
while (curr !== 'EOF') { |
|
if (curr.code === 0 || vertexIsFinished) break; |
|
|
|
switch (curr.code) { |
|
case 10: // X0 |
|
case 11: // X1 |
|
case 12: // X2 |
|
case 13: // X3 |
|
if (vertexIsStarted) { |
|
vertexIsFinished = true; |
|
continue; |
|
} |
|
vertex.x = curr.value; |
|
vertexIsStarted = true; |
|
break; |
|
case 20: // Y |
|
case 21: |
|
case 22: |
|
case 23: |
|
vertex.y = curr.value; |
|
break; |
|
case 30: // Z |
|
case 31: |
|
case 32: |
|
case 33: |
|
vertex.z = curr.value; |
|
break; |
|
default: |
|
// it is possible to have entity codes after the vertices. |
|
// So if code is not accounted for return to entity parser where it might be accounted for |
|
return vertices; |
|
continue; |
|
} |
|
curr = scanner.next(); |
|
} |
|
// See https://groups.google.com/forum/#!topic/comp.cad.autocad/9gn8s5O_w6E |
|
vertices.push(vertex); |
|
vertexIsStarted = false; |
|
vertexIsFinished = false; |
|
} |
|
scanner.rewind(); |
|
return vertices; |
|
}; |
|
},{"../ParseHelpers":4}],6:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'ARC'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity, endAngle; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: // X coordinate of point |
|
entity.center = helpers.parsePoint(scanner); |
|
break; |
|
case 40: // radius |
|
entity.radius = curr.value; |
|
break; |
|
case 50: // start angle |
|
entity.startAngle = Math.PI / 180 * curr.value; |
|
break; |
|
case 51: // end angle |
|
entity.endAngle = Math.PI / 180 * curr.value; |
|
entity.angleLength = entity.endAngle - entity.startAngle; // angleLength is deprecated |
|
break; |
|
default: // ignored attribute |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],7:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'ATTDEF'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity = { |
|
type: curr.value, |
|
scale: 1, |
|
textStyle: 'STANDARD' |
|
}; |
|
curr = scanner.next(); |
|
while (curr !== 'EOF') { |
|
if (curr.code === 0) { |
|
break; |
|
} |
|
switch(curr.code) { |
|
case 1: |
|
entity.text = curr.value; |
|
break; |
|
case 2: |
|
entity.tag = curr.value; |
|
break; |
|
case 3: |
|
entity.prompt = curr.value; |
|
break; |
|
case 7: |
|
entity.textStyle = curr.value; |
|
break; |
|
case 10: // X coordinate of 'first alignment point' |
|
entity.startPoint = helpers.parsePoint(scanner); |
|
break; |
|
case 11: // X coordinate of 'second alignment point' |
|
entity.endPoint = helpers.parsePoint(scanner); |
|
break; |
|
case 39: |
|
entity.thickness = curr.value; |
|
break; |
|
case 40: |
|
entity.textHeight = curr.value; |
|
break; |
|
case 41: |
|
entity.scale = curr.value; |
|
break; |
|
case 50: |
|
entity.rotation = curr.value; |
|
break; |
|
case 51: |
|
entity.obliqueAngle = curr.value; |
|
break; |
|
case 70: |
|
entity.invisible = !!(curr.value & 0x01); |
|
entity.constant = !!(curr.value & 0x02); |
|
entity.verificationRequired = !!(curr.value & 0x04); |
|
entity.preset = !!(curr.value & 0x08); |
|
break; |
|
case 71: |
|
entity.backwards = !!(curr.value & 0x02); |
|
entity.mirrored = !!(curr.value & 0x04); |
|
break; |
|
case 72: |
|
// TODO: enum values? |
|
entity.horizontalJustification = curr.value; |
|
break; |
|
case 73: |
|
entity.fieldLength = curr.value; |
|
break; |
|
case 74: |
|
// TODO: enum values? |
|
entity.verticalJustification = curr.value; |
|
break; |
|
case 100: |
|
break; |
|
case 210: |
|
entity.extrusionDirectionX = curr.value; |
|
break; |
|
case 220: |
|
entity.extrusionDirectionY = curr.value; |
|
break; |
|
case 230: |
|
entity.extrusionDirectionZ = curr.value; |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],8:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'CIRCLE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity, endAngle; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: // X coordinate of point |
|
entity.center = helpers.parsePoint(scanner); |
|
break; |
|
case 40: // radius |
|
entity.radius = curr.value; |
|
break; |
|
case 50: // start angle |
|
entity.startAngle = Math.PI / 180 * curr.value; |
|
break; |
|
case 51: // end angle |
|
endAngle = Math.PI / 180 * curr.value; |
|
if(endAngle < entity.startAngle) |
|
entity.angleLength = endAngle + 2 * Math.PI - entity.startAngle; |
|
else |
|
entity.angleLength = endAngle - entity.startAngle; |
|
entity.endAngle = endAngle; |
|
break; |
|
default: // ignored attribute |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],9:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'DIMENSION'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 2: // Referenced block name |
|
entity.block = curr.value; |
|
break; |
|
case 10: // X coordinate of 'first alignment point' |
|
entity.anchorPoint = helpers.parsePoint(scanner); |
|
break; |
|
case 11: |
|
entity.middleOfText = helpers.parsePoint(scanner); |
|
break; |
|
case 71: // 5 = Middle center |
|
entity.attachmentPoint = curr.value; |
|
break; |
|
case 42: // Actual measurement |
|
entity.actualMeasurement = curr.value; |
|
break; |
|
case 1: // Text entered by user explicitly |
|
entity.text = curr.value; |
|
break; |
|
case 50: // Angle of rotated, horizontal, or vertical dimensions |
|
entity.angle = curr.value; |
|
break; |
|
default: // check common entity attributes |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
|
|
|
|
|
|
},{"../ParseHelpers":4}],10:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'ELLIPSE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: |
|
entity.center = helpers.parsePoint(scanner); |
|
break; |
|
case 11: |
|
entity.majorAxisEndPoint = helpers.parsePoint(scanner); |
|
break; |
|
case 40: |
|
entity.axisRatio = curr.value; |
|
break; |
|
case 41: |
|
entity.startAngle = curr.value; |
|
break; |
|
case 42: |
|
entity.endAngle = curr.value; |
|
break; |
|
case 2: |
|
entity.name = curr.value; |
|
break; |
|
default: // check common entity attributes |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
|
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],11:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'INSERT'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 2: |
|
entity.name = curr.value; |
|
break; |
|
case 41: |
|
entity.xScale = curr.value; |
|
break; |
|
case 42: |
|
entity.yScale = curr.value; |
|
break; |
|
case 43: |
|
entity.zScale = curr.value; |
|
break; |
|
case 10: |
|
entity.position = helpers.parsePoint(scanner); |
|
break; |
|
case 50: |
|
entity.rotation = curr.value; |
|
break; |
|
case 70: |
|
entity.columnCount = curr.value; |
|
break; |
|
case 71: |
|
entity.rowCount = curr.value; |
|
break; |
|
case 44: |
|
entity.columnSpacing = curr.value; |
|
break; |
|
case 45: |
|
entity.rowSpacing = curr.value; |
|
break; |
|
case 210: |
|
entity.extrusionDirection = helpers.parsePoint(scanner); |
|
break; |
|
default: // check common entity attributes |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
|
|
|
|
|
|
},{"../ParseHelpers":4}],12:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'LINE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity = { type: curr.value, vertices: [] }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: // X coordinate of point |
|
entity.vertices.unshift(helpers.parsePoint(scanner)); |
|
break; |
|
case 11: |
|
entity.vertices.push(helpers.parsePoint(scanner)); |
|
break; |
|
case 210: |
|
entity.extrusionDirection = helpers.parsePoint(scanner); |
|
break; |
|
case 100: |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
|
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],13:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'LWPOLYLINE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity = { type: curr.value, vertices: [] }, |
|
numberOfVertices = 0; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 38: |
|
entity.elevation = curr.value; |
|
break; |
|
case 39: |
|
entity.depth = curr.value; |
|
break; |
|
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default |
|
entity.shape = ((curr.value & 1) === 1); |
|
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128); |
|
break; |
|
case 90: |
|
numberOfVertices = curr.value; |
|
break; |
|
case 10: // X coordinate of point |
|
entity.vertices = parseLWPolylineVertices(numberOfVertices, scanner); |
|
break; |
|
case 43: |
|
if(curr.value !== 0) entity.width = curr.value; |
|
break; |
|
case 210: |
|
entity.extrusionDirectionX = curr.value; |
|
break; |
|
case 220: |
|
entity.extrusionDirectionY = curr.value; |
|
break; |
|
case 230: |
|
entity.extrusionDirectionZ = curr.value; |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
|
|
function parseLWPolylineVertices(n, scanner) { |
|
if(!n || n <= 0) throw Error('n must be greater than 0 verticies'); |
|
var vertices = [], i; |
|
var vertexIsStarted = false; |
|
var vertexIsFinished = false; |
|
var curr = scanner.lastReadGroup; |
|
|
|
for(i = 0; i < n; i++) { |
|
var vertex = {}; |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0 || vertexIsFinished) break; |
|
|
|
switch(curr.code) { |
|
case 10: // X |
|
if(vertexIsStarted) { |
|
vertexIsFinished = true; |
|
continue; |
|
} |
|
vertex.x = curr.value; |
|
vertexIsStarted = true; |
|
break; |
|
case 20: // Y |
|
vertex.y = curr.value; |
|
break; |
|
case 30: // Z |
|
vertex.z = curr.value; |
|
break; |
|
case 40: // start width |
|
vertex.startWidth = curr.value; |
|
break; |
|
case 41: // end width |
|
vertex.endWidth = curr.value; |
|
break; |
|
case 42: // bulge |
|
if(curr.value != 0) vertex.bulge = curr.value; |
|
break; |
|
default: |
|
// if we do not hit known code return vertices. Code might belong to entity |
|
if (vertexIsStarted) { |
|
vertices.push(vertex); |
|
} |
|
return vertices; |
|
} |
|
curr = scanner.next(); |
|
} |
|
// See https://groups.google.com/forum/#!topic/comp.cad.autocad/9gn8s5O_w6E |
|
vertices.push(vertex); |
|
vertexIsStarted = false; |
|
vertexIsFinished = false; |
|
} |
|
scanner.rewind(); |
|
return vertices; |
|
}; |
|
},{"../ParseHelpers":4}],14:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'MTEXT'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 1: |
|
entity.text = curr.value; |
|
break; |
|
case 3: |
|
entity.text += curr.value; |
|
break; |
|
case 10: |
|
entity.position = helpers.parsePoint(scanner); |
|
break; |
|
case 40: |
|
//Note: this is the text height |
|
entity.height = curr.value; |
|
break; |
|
case 41: |
|
entity.width = curr.value; |
|
break; |
|
case 50: |
|
entity.rotation = curr.value; |
|
break; |
|
case 71: |
|
entity.attachmentPoint = curr.value; |
|
break; |
|
case 72: |
|
entity.drawingDirection = curr.value; |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],15:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'POINT'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: |
|
entity.position = helpers.parsePoint(scanner); |
|
break; |
|
case 39: |
|
entity.thickness = curr.value; |
|
break; |
|
case 210: |
|
entity.extrusionDirection = helpers.parsePoint(scanner); |
|
break; |
|
case 100: |
|
break; |
|
default: // check common entity attributes |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],16:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
var VertexParser = require('./vertex'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'POLYLINE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity = { type: curr.value, vertices: [] }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: // always 0 |
|
case 20: // always 0 |
|
case 30: // elevation |
|
case 39: // thickness |
|
entity.thickness = curr.value; |
|
break; |
|
case 40: // start width |
|
case 41: // end width |
|
break; |
|
case 70: |
|
entity.shape = (curr.value & 1) !== 0; |
|
entity.includesCurveFitVertices = (curr.value & 2) !== 0; |
|
entity.includesSplineFitVertices = (curr.value & 4) !== 0; |
|
entity.is3dPolyline = (curr.value & 8) !== 0; |
|
entity.is3dPolygonMesh = (curr.value & 16) !== 0; |
|
entity.is3dPolygonMeshClosed = (curr.value & 32) !== 0; // 32 = The polygon mesh is closed in the N direction |
|
entity.isPolyfaceMesh = (curr.value & 64) !== 0; |
|
entity.hasContinuousLinetypePattern = (curr.value & 128) !== 0; |
|
break; |
|
case 71: // Polygon mesh M vertex count |
|
case 72: // Polygon mesh N vertex count |
|
case 73: // Smooth surface M density |
|
case 74: // Smooth surface N density |
|
case 75: // Curves and smooth surface type |
|
break; |
|
case 210: |
|
extrusionDirection = helpers.parsePoint(scanner); |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
|
|
entity.vertices = parsePolylineVertices(scanner, curr); |
|
|
|
return entity; |
|
}; |
|
|
|
function parsePolylineVertices(scanner, curr) { |
|
var vertexParser = new VertexParser(); |
|
|
|
var vertices = []; |
|
while (!scanner.isEOF()) { |
|
if (curr.code === 0) { |
|
if (curr.value === 'VERTEX') { |
|
vertices.push(vertexParser.parseEntity(scanner, curr)); |
|
curr = scanner.lastReadGroup; |
|
} else if (curr.value === 'SEQEND') { |
|
parseSeqEnd(scanner, curr); |
|
break; |
|
} |
|
} |
|
} |
|
return vertices; |
|
}; |
|
|
|
function parseSeqEnd(scanner, curr) { |
|
var entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr != 'EOF') { |
|
if (curr.code == 0) break; |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
|
|
},{"../ParseHelpers":4,"./vertex":20}],17:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'SOLID'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, currentGroup) { |
|
var entity; |
|
entity = { type: currentGroup.value }; |
|
entity.points = []; |
|
currentGroup = scanner.next(); |
|
while(currentGroup !== 'EOF') { |
|
if(currentGroup.code === 0) break; |
|
|
|
switch(currentGroup.code) { |
|
case 10: |
|
entity.points[0] = helpers.parsePoint(scanner); |
|
break; |
|
case 11: |
|
entity.points[1] = helpers.parsePoint(scanner); |
|
break; |
|
case 12: |
|
entity.points[2] = helpers.parsePoint(scanner); |
|
break; |
|
case 13: |
|
entity.points[3] = helpers.parsePoint(scanner); |
|
break; |
|
case 210: |
|
entity.extrusionDirection = helpers.parsePoint(scanner); |
|
break; |
|
default: // check common entity attributes |
|
helpers.checkCommonEntityProperties(entity, currentGroup); |
|
break; |
|
} |
|
currentGroup = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],18:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'SPLINE'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') |
|
{ |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: |
|
if (!entity.controlPoints) entity.controlPoints = []; |
|
entity.controlPoints.push(helpers.parsePoint(scanner)); |
|
break; |
|
case 11: |
|
if (!entity.fitPoints) entity.fitPoints = []; |
|
entity.fitPoints.push(helpers.parsePoint(scanner)); |
|
break; |
|
case 12: |
|
entity.startTangent = helpers.parsePoint(scanner); |
|
break; |
|
case 13: |
|
entity.endTangent = helpers.parsePoint(scanner); |
|
break; |
|
case 40: |
|
if (!entity.knotValues) entity.knotValues = []; |
|
entity.knotValues.push(curr.value); |
|
break; |
|
case 70: |
|
if ((curr.value & 1) != 0) entity.closed = true; |
|
if ((curr.value & 2) != 0) entity.periodic = true; |
|
if ((curr.value & 4) != 0) entity.rational = true; |
|
if ((curr.value & 8) != 0) entity.planar = true; |
|
if ((curr.value & 16) != 0) |
|
{ |
|
entity.planar = true; |
|
entity.linear = true; |
|
} |
|
break; |
|
|
|
case 71: |
|
entity.degreeOfSplineCurve = curr.value; |
|
break; |
|
case 72: |
|
entity.numberOfKnots = curr.value; |
|
break; |
|
case 73: |
|
entity.numberOfControlPoints = curr.value; |
|
break; |
|
case 74: |
|
entity.numberOfFitPoints = curr.value; |
|
break; |
|
case 210: |
|
entity.normalVector = helpers.parsePoint(scanner); |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
|
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],19:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'TEXT'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity; |
|
entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
switch(curr.code) { |
|
case 10: // X coordinate of 'first alignment point' |
|
entity.startPoint = helpers.parsePoint(scanner); |
|
break; |
|
case 11: // X coordinate of 'second alignment point' |
|
entity.endPoint = helpers.parsePoint(scanner); |
|
break; |
|
case 40: // Text height |
|
entity.textHeight = curr.value; |
|
break; |
|
case 41: |
|
entity.xScale = curr.value; |
|
break; |
|
case 50: // Rotation in degrees |
|
entity.rotation = curr.value; |
|
break; |
|
case 1: // Text |
|
entity.text = curr.value; |
|
break; |
|
// NOTE: 72 and 73 are meaningless without 11 (second alignment point) |
|
case 72: // Horizontal alignment |
|
entity.halign = curr.value; |
|
break; |
|
case 73: // Vertical alignment |
|
entity.valign = curr.value; |
|
break; |
|
default: // check common entity attributes |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],20:[function(require,module,exports){ |
|
|
|
var helpers = require('../ParseHelpers'); |
|
|
|
module.exports = EntityParser; |
|
|
|
function EntityParser() {} |
|
|
|
EntityParser.ForEntityName = 'VERTEX'; |
|
|
|
EntityParser.prototype.parseEntity = function(scanner, curr) { |
|
var entity = { type: curr.value }; |
|
curr = scanner.next(); |
|
while(curr !== 'EOF') { |
|
if(curr.code === 0) break; |
|
|
|
switch(curr.code) { |
|
case 10: // X |
|
entity.x = curr.value; |
|
break; |
|
case 20: // Y |
|
entity.y = curr.value; |
|
break; |
|
case 30: // Z |
|
entity.z = curr.value; |
|
break; |
|
case 40: // start width |
|
case 41: // end width |
|
case 42: // bulge |
|
if(curr.value != 0) entity.bulge = curr.value; |
|
break; |
|
case 70: // flags |
|
entity.curveFittingVertex = (curr.value & 1) !== 0; |
|
entity.curveFitTangent = (curr.value & 2) !== 0; |
|
entity.splineVertex = (curr.value & 8) !== 0; |
|
entity.splineControlPoint = (curr.value & 16) !== 0; |
|
entity.threeDPolylineVertex = (curr.value & 32) !== 0; |
|
entity.threeDPolylineMesh = (curr.value & 64) !== 0; |
|
entity.polyfaceMeshVertex = (curr.value & 128) !== 0; |
|
break; |
|
case 50: // curve fit tangent direction |
|
case 71: // polyface mesh vertex index |
|
case 72: // polyface mesh vertex index |
|
case 73: // polyface mesh vertex index |
|
case 74: // polyface mesh vertex index |
|
break; |
|
default: |
|
helpers.checkCommonEntityProperties(entity, curr); |
|
break; |
|
} |
|
|
|
curr = scanner.next(); |
|
} |
|
return entity; |
|
}; |
|
},{"../ParseHelpers":4}],21:[function(require,module,exports){ |
|
/* |
|
* loglevel - https://github.com/pimterry/loglevel |
|
* |
|
* Copyright (c) 2013 Tim Perry |
|
* Licensed under the MIT license. |
|
*/ |
|
(function (root, definition) { |
|
if (typeof module === 'object' && module.exports && typeof require === 'function') { |
|
module.exports = definition(); |
|
} else if (typeof define === 'function' && typeof define.amd === 'object') { |
|
define(definition); |
|
} else { |
|
root.log = definition(); |
|
} |
|
}(this, function () { |
|
var self = {}; |
|
var noop = function() {}; |
|
var undefinedType = "undefined"; |
|
|
|
function realMethod(methodName) { |
|
if (typeof console === undefinedType) { |
|
return false; // We can't build a real method without a console to log to |
|
} else if (console[methodName] !== undefined) { |
|
return bindMethod(console, methodName); |
|
} else if (console.log !== undefined) { |
|
return bindMethod(console, 'log'); |
|
} else { |
|
return noop; |
|
} |
|
} |
|
|
|
function bindMethod(obj, methodName) { |
|
var method = obj[methodName]; |
|
if (typeof method.bind === 'function') { |
|
return method.bind(obj); |
|
} else { |
|
try { |
|
return Function.prototype.bind.call(method, obj); |
|
} catch (e) { |
|
// Missing bind shim or IE8 + Modernizr, fallback to wrapping |
|
return function() { |
|
return Function.prototype.apply.apply(method, [obj, arguments]); |
|
}; |
|
} |
|
} |
|
} |
|
|
|
function enableLoggingWhenConsoleArrives(methodName, level) { |
|
return function () { |
|
if (typeof console !== undefinedType) { |
|
replaceLoggingMethods(level); |
|
self[methodName].apply(self, arguments); |
|
} |
|
}; |
|
} |
|
|
|
var logMethods = [ |
|
"trace", |
|
"debug", |
|
"info", |
|
"warn", |
|
"error" |
|
]; |
|
|
|
function replaceLoggingMethods(level) { |
|
for (var i = 0; i < logMethods.length; i++) { |
|
var methodName = logMethods[i]; |
|
self[methodName] = (i < level) ? noop : self.methodFactory(methodName, level); |
|
} |
|
} |
|
|
|
function persistLevelIfPossible(levelNum) { |
|
var levelName = (logMethods[levelNum] || 'silent').toUpperCase(); |
|
|
|
// Use localStorage if available |
|
try { |
|
window.localStorage['loglevel'] = levelName; |
|
return; |
|
} catch (ignore) {} |
|
|
|
// Use session cookie as fallback |
|
try { |
|
window.document.cookie = "loglevel=" + levelName + ";"; |
|
} catch (ignore) {} |
|
} |
|
|
|
function loadPersistedLevel() { |
|
var storedLevel; |
|
|
|
try { |
|
storedLevel = window.localStorage['loglevel']; |
|
} catch (ignore) {} |
|
|
|
if (typeof storedLevel === undefinedType) { |
|
try { |
|
storedLevel = /loglevel=([^;]+)/.exec(window.document.cookie)[1]; |
|
} catch (ignore) {} |
|
} |
|
|
|
if (self.levels[storedLevel] === undefined) { |
|
storedLevel = "WARN"; |
|
} |
|
|
|
self.setLevel(self.levels[storedLevel], false); |
|
} |
|
|
|
/* |
|
* |
|
* Public API |
|
* |
|
*/ |
|
|
|
self.levels = { "TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3, |
|
"ERROR": 4, "SILENT": 5}; |
|
|
|
self.methodFactory = function (methodName, level) { |
|
return realMethod(methodName) || |
|
enableLoggingWhenConsoleArrives(methodName, level); |
|
}; |
|
|
|
self.setLevel = function (level, persist) { |
|
if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) { |
|
level = self.levels[level.toUpperCase()]; |
|
} |
|
if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) { |
|
if (persist !== false) { // defaults to true |
|
persistLevelIfPossible(level); |
|
} |
|
replaceLoggingMethods(level); |
|
if (typeof console === undefinedType && level < self.levels.SILENT) { |
|
return "No console available for logging"; |
|
} |
|
} else { |
|
throw "log.setLevel() called with invalid level: " + level; |
|
} |
|
}; |
|
|
|
self.enableAll = function(persist) { |
|
self.setLevel(self.levels.TRACE, persist); |
|
}; |
|
|
|
self.disableAll = function(persist) { |
|
self.setLevel(self.levels.SILENT, persist); |
|
}; |
|
|
|
// Grab the current global log variable in case of overwrite |
|
var _log = (typeof window !== undefinedType) ? window.log : undefined; |
|
self.noConflict = function() { |
|
if (typeof window !== undefinedType && |
|
window.log === self) { |
|
window.log = _log; |
|
} |
|
|
|
return self; |
|
}; |
|
|
|
loadPersistedLevel(); |
|
return self; |
|
})); |
|
|
|
},{}]},{},[3])(3) |
|
}); |