Merge branch 'unit_testing'

This commit is contained in:
Nick Playfair 2021-02-01 23:44:39 +00:00
commit dae607c891
21 changed files with 21997 additions and 122 deletions

View File

@ -1,5 +1,8 @@
{ {
"extends": ["airbnb", "prettier", "plugin:node/recommended"], "extends": ["airbnb-base", "prettier", "plugin:node/recommended"],
"env": {
"node": true
},
"plugins": ["prettier"], "plugins": ["prettier"],
"rules": { "rules": {
"prettier/prettier": "error", "prettier/prettier": "error",

3
.gitignore vendored
View File

@ -105,4 +105,5 @@ dist
.DS_Store .DS_Store
gerber/ gerber/
hello.txt hello.txt
test/tmp/*

View File

@ -44,28 +44,39 @@ function handleError(e) {
* @returns {Promise} Promise object represents number of files extracted * @returns {Promise} Promise object represents number of files extracted
*/ */
function extractArchive(fileName, tmpDir) { function extractArchive(fileName, tmpDir) {
// Configure archive to use
const archive = new StreamZip({
file: fileName,
storeEntries: true,
});
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Try to extract // Check archive exists
try {
if (!fs.existsSync(fileName)) {
return reject(new Error('Archive does not exist.'));
}
if (!fs.existsSync(tmpDir)) {
return reject(new Error('Temporary folder does not exist.'));
}
} catch (e) {
throw new Error(e);
}
// Configure archive to use
const archive = new StreamZip({
file: fileName,
storeEntries: true,
});
// Handle errors
archive.on('error', (err) =>
reject(new Error(`Error extracting archive: ${err}`))
);
// Extract
archive.on('ready', () => { archive.on('ready', () => {
const extDir = path.join(tmpDir, 'archive'); const extDir = path.join(tmpDir, 'archive');
fs.mkdirSync(extDir, { recursive: true }); fs.mkdirSync(extDir, { recursive: true });
archive.extract(null, extDir, (err, count) => { archive.extract(null, extDir, (err, count) => {
if (!err) { if (err) throw new Error(err);
archive.close(); archive.close();
resolve(count); console.log('Extraction complete');
} else { return resolve(count);
const errMsg = 'Error extracting archive';
console.err(errMsg);
archive.close();
reject(errMsg);
}
}); });
}); });
return true;
}); });
} }
@ -99,6 +110,27 @@ function getLayers(fileName, tmpDir) {
}); });
} }
function getLayers2(dir) {
return new Promise((resolve, reject) => {
// Make sure the directory exists
if (!fs.existsSync(dir)) {
return reject(new Error('Layers folder does not exist.'));
}
// Check that the required layer files exist in source dir
let layersValid = true;
gerberFiles.forEach((layer) => {
if (!fs.existsSync(path.join(dir, layer))) layersValid = false;
});
if (!layersValid) return reject(new Error('Layer not found.'));
// Construct array of layers that match the supplied filenames array
const layers = gerberFiles.map((layerName) => ({
filename: layerName,
gerber: fs.createReadStream(path.join(dir, layerName)),
}));
return resolve(layers);
});
}
/** /**
* Clean up the archive folder in the specified directory * Clean up the archive folder in the specified directory
* @param {string} dir Path to a directory to clean up * @param {string} dir Path to a directory to clean up
@ -155,6 +187,10 @@ function gerberToImage(gerber, imgConfig, tmpDir, outputDir) {
} }
module.exports = { module.exports = {
cleanupFiles,
getLayers,
getLayers2,
extractArchive,
config, config,
gerberToImage, gerberToImage,
}; };

4391
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"description": "Create a PCB image from gerber files", "description": "Create a PCB image from gerber files",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "jest"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -30,15 +30,14 @@
}, },
"devDependencies": { "devDependencies": {
"eslint": "^7.19.0", "eslint": "^7.19.0",
"eslint-config-airbnb": "^18.2.1", "eslint-config-airbnb-base": "^14.2.1",
"eslint-config-node": "^4.1.0", "eslint-config-node": "^4.1.0",
"eslint-config-prettier": "^7.2.0", "eslint-config-prettier": "^7.2.0",
"eslint-plugin-import": "^2.22.1", "eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.3.1", "eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.22.0", "eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0", "jest": "^26.6.3",
"prettier": "^2.2.1" "prettier": "^2.2.1"
} }
} }

BIN
test/Arduino-Pro-Mini.zip Normal file

Binary file not shown.

11
test/ArduinoLicense.txt Normal file
View File

@ -0,0 +1,11 @@
License Information
The hardware is released under Creative Commons Share-alike 3.0.
Hardware authors: Original Arduino Mini design by Team Arduino
Pro Mini design by Nathan Seidle @ SparkFun Electonics
Revision work by Pete Lewis @ SparkFun Electonics
Distributed as-is; no warranty is given.

44
test/index.test.js Normal file
View File

@ -0,0 +1,44 @@
/* eslint-disable */
const path = require('path');
const fs = require('fs-extra');
const fileProc = require('../index.js');
const testGerber = path.join(__dirname, 'Arduino-Pro-Mini.zip');
const testLayers = path.join(__dirname, 'layers');
const emptyFolder = path.join(__dirname, 'layers', 'Empty');
const tmpDir = path.join(__dirname, 'tmp');
// getLayers
test('Promise of an array of layers from a given folder', () => {
return fileProc.getLayers2(testLayers).then(data => {
expect(data).toEqual(
expect.arrayContaining([
expect.objectContaining({
filename: expect.any(String),
gerber: expect.any(fs.ReadStream),
})
])
);
});
});
test('Non-existent folder should reject promise with error', () => {
return expect(fileProc.getLayers2('./invalid_folder')).rejects.toThrow('Layers folder does not exist.');
});
test('Folder with incorrect number of layers should reject promise with error', () => {
return expect(fileProc.getLayers2(emptyFolder)).rejects.toThrow('Layer not found.');
});
// extractArchive
test('Non-existent archive should throw an error', () => {
return expect(fileProc.extractArchive('invalid.zip', tmpDir)).rejects.toThrow(Error);
});
test('Temp dir not existing should throw an error', () => {
return expect(fileProc.extractArchive(testGerber, './invalid_dir')).rejects.toThrow(Error);
});
test('Should extract archive and resolve with the number of files extracted', () => {
return expect(fileProc.extractArchive(testGerber, tmpDir)).resolves.toBe(12);
});

View File

@ -0,0 +1,77 @@
M48
;GenerationSoftware,Autodesk,EAGLE,9.6.2*%
;CreationDate,2021-02-01T16:14:31Z*%
FMAT,2
ICI,OFF
METRIC,TZ,000.000
T2C0.508
T1C1.016
%
G90
M71
T1
X16510Y24130
X13589Y7493
X2540Y31750
X5080Y31750
X7620Y31750
X10160Y31750
X12700Y31750
X15240Y31750
X13589Y20447
X13589Y17907
X1270Y29210
X1270Y26670
X1270Y24130
X1270Y21590
X1270Y19050
X1270Y16510
X1270Y13970
X1270Y11430
X1270Y8890
X1270Y6350
X1270Y3810
X1270Y1270
X16510Y1270
X16510Y3810
X16510Y6350
X16510Y8890
X16510Y11430
X16510Y13970
X16510Y16510
X16510Y29210
X16510Y26670
X13589Y10033
X16510Y21590
X16510Y19050
T2
X12192Y13970
X2794Y2159
X8890Y15621
X9525Y16891
X9322Y19812
X15367Y15240
X14046Y27280
X11176Y26162
X6350Y26416
X6629Y22200
X7366Y11557
X8001Y12700
X11303Y14986
X8890Y4572
X5969Y3048
X10414Y11557
X11811Y5842
X8153Y29261
X6401Y24130
X11405Y24130
X3683Y26035
X7722Y16942
X14757Y25400
X6350Y14478
X10414Y20447
X5105Y29286
X8890Y2667
X9652Y14478
X11430Y12700
M30

View File

View File

@ -0,0 +1,44 @@
G04 EAGLE Gerber RS-274X export*
G75*
%MOMM*%
%FSLAX34Y34*%
%LPD*%
%INVias*%
%IPPOS*%
%AMOC8*
5,1,8,0,0,1.08239X$1,22.5*%
G01*
%ADD10C,1.016000*%
D10*
X114300Y127000D03*
X96520Y144780D03*
X88900Y26670D03*
X51054Y292862D03*
X104140Y204470D03*
X63500Y144780D03*
X147574Y254000D03*
X77216Y169418D03*
X36830Y260350D03*
X114046Y241300D03*
X64008Y241300D03*
X81534Y292608D03*
X118110Y58420D03*
X104140Y115570D03*
X59690Y30480D03*
X88900Y45720D03*
X113030Y149860D03*
X80010Y127000D03*
X73660Y115570D03*
X66294Y221996D03*
X63500Y264160D03*
X111760Y261620D03*
X140462Y272796D03*
X153670Y152400D03*
X93218Y198120D03*
X95250Y168910D03*
X88900Y156210D03*
X27940Y21590D03*
X121920Y139700D03*
M02*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
{
"Header": {
"Comment": "All values are metric (mm)",
"CreationDate": "2021-02-01T16:14:31Z",
"GenerationSoftware": {
"Application": "EAGLE",
"Vendor": "Autodesk",
"Version": "9.6.2"
},
"Part": "Single"
},
"Overall": {
"BoardThickness": 1.57,
"LayerNumber": 2,
"Name": {
"ProjectId": "Arduino-Pro-Mini"
},
"Owner": "nick nick <nick@chaosemerald.co.uk>",
"Size": {
"X": 17.78,
"Y": 33.02
}
}
}

View File

@ -0,0 +1,20 @@
G04 EAGLE Gerber RS-274X export*
G75*
%MOMM*%
%FSLAX34Y34*%
%LPD*%
%IN*%
%IPPOS*%
%AMOC8*
5,1,8,0,0,1.08239X$1,22.5*%
G01*
%ADD10C,0.254000*%
D10*
X0Y0D02*
X177800Y0D01*
X177800Y330200D01*
X0Y330200D01*
X0Y0D01*
M02*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
G04 EAGLE Gerber RS-274X export*
G75*
%MOMM*%
%FSLAX34Y34*%
%LPD*%
%INSoldermask Bottom*%
%IPPOS*%
%AMOC8*
5,1,8,0,0,1.08239X$1,22.5*%
G01*
%ADD10C,2.082800*%
%ADD11R,1.203200X1.303200*%
D10*
X165100Y292100D03*
X165100Y266700D03*
X165100Y241300D03*
X165100Y215900D03*
X165100Y190500D03*
X165100Y165100D03*
X165100Y139700D03*
X165100Y114300D03*
X165100Y88900D03*
X165100Y63500D03*
X165100Y38100D03*
X165100Y12700D03*
X12700Y12700D03*
X12700Y38100D03*
X12700Y63500D03*
X12700Y88900D03*
X12700Y114300D03*
X12700Y139700D03*
X12700Y165100D03*
X12700Y190500D03*
X12700Y215900D03*
X12700Y241300D03*
X12700Y266700D03*
X12700Y292100D03*
X135890Y179070D03*
X135890Y204470D03*
X152400Y317500D03*
X127000Y317500D03*
X101600Y317500D03*
X76200Y317500D03*
X50800Y317500D03*
X25400Y317500D03*
D11*
X129794Y223148D03*
X129794Y240148D03*
X142494Y223148D03*
X142494Y240148D03*
D10*
X135890Y74930D03*
X135890Y100330D03*
M02*

View File

@ -0,0 +1,376 @@
G04 EAGLE Gerber RS-274X export*
G75*
%MOMM*%
%FSLAX34Y34*%
%LPD*%
%INSoldermask Top*%
%IPPOS*%
%AMOC8*
5,1,8,0,0,1.08239X$1,22.5*%
G01*
%ADD10R,1.303200X1.203200*%
%ADD11R,1.803200X1.603200*%
%ADD12C,0.505344*%
%ADD13R,1.203200X1.303200*%
%ADD14R,1.403200X0.753200*%
%ADD15C,2.082800*%
%ADD16R,1.473200X0.762000*%
%ADD17R,0.762000X1.473200*%
%ADD18C,0.838200*%
%ADD19R,1.473200X0.838200*%
%ADD20R,1.727200X0.965200*%
%ADD21C,0.653200*%
%ADD22R,1.534159X3.495041*%
D10*
X80382Y204216D03*
X63382Y204216D03*
D11*
X46990Y274350D03*
X46990Y246350D03*
D10*
X97400Y266700D03*
X80400Y266700D03*
D12*
X94434Y222184D02*
X94434Y215204D01*
X94434Y222184D02*
X101414Y222184D01*
X101414Y215204D01*
X94434Y215204D01*
X94434Y220004D02*
X101414Y220004D01*
X76894Y222184D02*
X76894Y215204D01*
X76894Y222184D02*
X83874Y222184D01*
X83874Y215204D01*
X76894Y215204D01*
X76894Y220004D02*
X83874Y220004D01*
D13*
X45466Y43824D03*
X45466Y60824D03*
D10*
X98670Y72390D03*
X81670Y72390D03*
D13*
X45466Y12074D03*
X45466Y29074D03*
X137160Y57522D03*
X137160Y40522D03*
D12*
X133670Y11992D02*
X140650Y11992D01*
X140650Y5012D01*
X133670Y5012D01*
X133670Y11992D01*
X133670Y9812D02*
X140650Y9812D01*
X140650Y29532D02*
X133670Y29532D01*
X140650Y29532D02*
X140650Y22552D01*
X133670Y22552D01*
X133670Y29532D01*
X133670Y27352D02*
X140650Y27352D01*
D14*
X101901Y232308D03*
X101901Y241808D03*
X101901Y251308D03*
X75899Y251308D03*
X75899Y232308D03*
D11*
X132080Y227300D03*
X132080Y255300D03*
D15*
X165100Y292100D03*
X165100Y266700D03*
X165100Y241300D03*
X165100Y215900D03*
X165100Y190500D03*
X165100Y165100D03*
X165100Y139700D03*
X165100Y114300D03*
X165100Y88900D03*
X165100Y63500D03*
X165100Y38100D03*
X165100Y12700D03*
X12700Y12700D03*
X12700Y38100D03*
X12700Y63500D03*
X12700Y88900D03*
X12700Y114300D03*
X12700Y139700D03*
X12700Y165100D03*
X12700Y190500D03*
X12700Y215900D03*
X12700Y241300D03*
X12700Y266700D03*
X12700Y292100D03*
X135890Y179070D03*
X135890Y204470D03*
D16*
G36*
X80860Y181950D02*
X70444Y192366D01*
X75832Y197754D01*
X86248Y187338D01*
X80860Y181950D01*
G37*
G36*
X75203Y176293D02*
X64787Y186709D01*
X70175Y192097D01*
X80591Y181681D01*
X75203Y176293D01*
G37*
G36*
X69546Y170637D02*
X59130Y181053D01*
X64518Y186441D01*
X74934Y176025D01*
X69546Y170637D01*
G37*
G36*
X63889Y164980D02*
X53473Y175396D01*
X58861Y180784D01*
X69277Y170368D01*
X63889Y164980D01*
G37*
G36*
X58232Y159323D02*
X47816Y169739D01*
X53204Y175127D01*
X63620Y164711D01*
X58232Y159323D01*
G37*
G36*
X52575Y153666D02*
X42159Y164082D01*
X47547Y169470D01*
X57963Y159054D01*
X52575Y153666D01*
G37*
G36*
X46919Y148009D02*
X36503Y158425D01*
X41891Y163813D01*
X52307Y153397D01*
X46919Y148009D01*
G37*
G36*
X41262Y142352D02*
X30846Y152768D01*
X36234Y158156D01*
X46650Y147740D01*
X41262Y142352D01*
G37*
D17*
G36*
X36234Y121244D02*
X30846Y126632D01*
X41262Y137048D01*
X46650Y131660D01*
X36234Y121244D01*
G37*
G36*
X41891Y115587D02*
X36503Y120975D01*
X46919Y131391D01*
X52307Y126003D01*
X41891Y115587D01*
G37*
G36*
X47547Y109930D02*
X42159Y115318D01*
X52575Y125734D01*
X57963Y120346D01*
X47547Y109930D01*
G37*
G36*
X53204Y104273D02*
X47816Y109661D01*
X58232Y120077D01*
X63620Y114689D01*
X53204Y104273D01*
G37*
G36*
X58861Y98616D02*
X53473Y104004D01*
X63889Y114420D01*
X69277Y109032D01*
X58861Y98616D01*
G37*
G36*
X64518Y92959D02*
X59130Y98347D01*
X69546Y108763D01*
X74934Y103375D01*
X64518Y92959D01*
G37*
G36*
X70175Y87303D02*
X64787Y92691D01*
X75203Y103107D01*
X80591Y97719D01*
X70175Y87303D01*
G37*
G36*
X75832Y81646D02*
X70444Y87034D01*
X80860Y97450D01*
X86248Y92062D01*
X75832Y81646D01*
G37*
D16*
G36*
X101968Y81646D02*
X91552Y92062D01*
X96940Y97450D01*
X107356Y87034D01*
X101968Y81646D01*
G37*
G36*
X107625Y87303D02*
X97209Y97719D01*
X102597Y103107D01*
X113013Y92691D01*
X107625Y87303D01*
G37*
G36*
X113282Y92959D02*
X102866Y103375D01*
X108254Y108763D01*
X118670Y98347D01*
X113282Y92959D01*
G37*
G36*
X118939Y98616D02*
X108523Y109032D01*
X113911Y114420D01*
X124327Y104004D01*
X118939Y98616D01*
G37*
G36*
X124596Y104273D02*
X114180Y114689D01*
X119568Y120077D01*
X129984Y109661D01*
X124596Y104273D01*
G37*
G36*
X130253Y109930D02*
X119837Y120346D01*
X125225Y125734D01*
X135641Y115318D01*
X130253Y109930D01*
G37*
G36*
X135909Y115587D02*
X125493Y126003D01*
X130881Y131391D01*
X141297Y120975D01*
X135909Y115587D01*
G37*
G36*
X141566Y121244D02*
X131150Y131660D01*
X136538Y137048D01*
X146954Y126632D01*
X141566Y121244D01*
G37*
D17*
G36*
X136538Y142352D02*
X131150Y147740D01*
X141566Y158156D01*
X146954Y152768D01*
X136538Y142352D01*
G37*
G36*
X130881Y148009D02*
X125493Y153397D01*
X135909Y163813D01*
X141297Y158425D01*
X130881Y148009D01*
G37*
G36*
X125225Y153666D02*
X119837Y159054D01*
X130253Y169470D01*
X135641Y164082D01*
X125225Y153666D01*
G37*
G36*
X119568Y159323D02*
X114180Y164711D01*
X124596Y175127D01*
X129984Y169739D01*
X119568Y159323D01*
G37*
G36*
X113911Y164980D02*
X108523Y170368D01*
X118939Y180784D01*
X124327Y175396D01*
X113911Y164980D01*
G37*
G36*
X108254Y170637D02*
X102866Y176025D01*
X113282Y186441D01*
X118670Y181053D01*
X108254Y170637D01*
G37*
G36*
X102597Y176293D02*
X97209Y181681D01*
X107625Y192097D01*
X113013Y186709D01*
X102597Y176293D01*
G37*
G36*
X96940Y181950D02*
X91552Y187338D01*
X101968Y197754D01*
X107356Y192366D01*
X96940Y181950D01*
G37*
D15*
X152400Y317500D03*
X127000Y317500D03*
X101600Y317500D03*
X76200Y317500D03*
X50800Y317500D03*
X25400Y317500D03*
D10*
X136516Y292100D03*
X119516Y292100D03*
D18*
X39370Y292100D03*
X124460Y25400D03*
D19*
X46990Y226369D03*
X46990Y218131D03*
D20*
X118110Y7620D03*
X62230Y7620D03*
X118110Y45720D03*
X62230Y45720D03*
D15*
X135890Y74930D03*
X135890Y100330D03*
D21*
X49693Y178246D02*
X35143Y178246D01*
X35143Y190246D02*
X49693Y190246D01*
X49693Y202246D02*
X35143Y202246D01*
D22*
X42443Y190221D03*
M02*

View File

@ -0,0 +1,19 @@
G04 EAGLE Gerber RS-274X export*
G75*
%MOMM*%
%FSLAX34Y34*%
%LPD*%
%INSolderpaste Bottom*%
%IPPOS*%
%AMOC8*
5,1,8,0,0,1.08239X$1,22.5*%
G01*
%ADD10R,1.000000X1.100000*%
D10*
X129794Y223148D03*
X129794Y240148D03*
X142494Y223148D03*
X142494Y240148D03*
M02*

View File

@ -0,0 +1,341 @@
G04 EAGLE Gerber RS-274X export*
G75*
%MOMM*%
%FSLAX34Y34*%
%LPD*%
%INSolderpaste Top*%
%IPPOS*%
%AMOC8*
5,1,8,0,0,1.08239X$1,22.5*%
G01*
%ADD10R,1.100000X1.000000*%
%ADD11R,1.600000X1.400000*%
%ADD12C,0.300000*%
%ADD13R,1.000000X1.100000*%
%ADD14R,1.200000X0.550000*%
%ADD15R,1.270000X0.558800*%
%ADD16R,0.558800X1.270000*%
%ADD17R,1.270000X0.635000*%
%ADD18R,2.286000X2.438400*%
%ADD19R,1.524000X0.762000*%
%ADD20C,0.450000*%
D10*
X80382Y204216D03*
X63382Y204216D03*
D11*
X46990Y274350D03*
X46990Y246350D03*
D10*
X97400Y266700D03*
X80400Y266700D03*
D12*
X94424Y222194D02*
X94424Y215194D01*
X94424Y222194D02*
X101424Y222194D01*
X101424Y215194D01*
X94424Y215194D01*
X94424Y218044D02*
X101424Y218044D01*
X101424Y220894D02*
X94424Y220894D01*
X76884Y222194D02*
X76884Y215194D01*
X76884Y222194D02*
X83884Y222194D01*
X83884Y215194D01*
X76884Y215194D01*
X76884Y218044D02*
X83884Y218044D01*
X83884Y220894D02*
X76884Y220894D01*
D13*
X45466Y43824D03*
X45466Y60824D03*
D10*
X98670Y72390D03*
X81670Y72390D03*
D13*
X45466Y12074D03*
X45466Y29074D03*
X137160Y57522D03*
X137160Y40522D03*
D12*
X133660Y12002D02*
X140660Y12002D01*
X140660Y5002D01*
X133660Y5002D01*
X133660Y12002D01*
X133660Y7852D02*
X140660Y7852D01*
X140660Y10702D02*
X133660Y10702D01*
X133660Y29542D02*
X140660Y29542D01*
X140660Y22542D01*
X133660Y22542D01*
X133660Y29542D01*
X133660Y25392D02*
X140660Y25392D01*
X140660Y28242D02*
X133660Y28242D01*
D14*
X101901Y232308D03*
X101901Y241808D03*
X101901Y251308D03*
X75899Y251308D03*
X75899Y232308D03*
D11*
X132080Y227300D03*
X132080Y255300D03*
D15*
G36*
X80860Y183387D02*
X71881Y192366D01*
X75832Y196317D01*
X84811Y187338D01*
X80860Y183387D01*
G37*
G36*
X75203Y177730D02*
X66224Y186709D01*
X70175Y190660D01*
X79154Y181681D01*
X75203Y177730D01*
G37*
G36*
X69546Y172074D02*
X60567Y181053D01*
X64518Y185004D01*
X73497Y176025D01*
X69546Y172074D01*
G37*
G36*
X63889Y166417D02*
X54910Y175396D01*
X58861Y179347D01*
X67840Y170368D01*
X63889Y166417D01*
G37*
G36*
X58232Y160760D02*
X49253Y169739D01*
X53204Y173690D01*
X62183Y164711D01*
X58232Y160760D01*
G37*
G36*
X52575Y155103D02*
X43596Y164082D01*
X47547Y168033D01*
X56526Y159054D01*
X52575Y155103D01*
G37*
G36*
X46919Y149446D02*
X37940Y158425D01*
X41891Y162376D01*
X50870Y153397D01*
X46919Y149446D01*
G37*
G36*
X41262Y143789D02*
X32283Y152768D01*
X36234Y156719D01*
X45213Y147740D01*
X41262Y143789D01*
G37*
D16*
G36*
X36234Y122681D02*
X32283Y126632D01*
X41262Y135611D01*
X45213Y131660D01*
X36234Y122681D01*
G37*
G36*
X41891Y117024D02*
X37940Y120975D01*
X46919Y129954D01*
X50870Y126003D01*
X41891Y117024D01*
G37*
G36*
X47547Y111367D02*
X43596Y115318D01*
X52575Y124297D01*
X56526Y120346D01*
X47547Y111367D01*
G37*
G36*
X53204Y105710D02*
X49253Y109661D01*
X58232Y118640D01*
X62183Y114689D01*
X53204Y105710D01*
G37*
G36*
X58861Y100053D02*
X54910Y104004D01*
X63889Y112983D01*
X67840Y109032D01*
X58861Y100053D01*
G37*
G36*
X64518Y94396D02*
X60567Y98347D01*
X69546Y107326D01*
X73497Y103375D01*
X64518Y94396D01*
G37*
G36*
X70175Y88740D02*
X66224Y92691D01*
X75203Y101670D01*
X79154Y97719D01*
X70175Y88740D01*
G37*
G36*
X75832Y83083D02*
X71881Y87034D01*
X80860Y96013D01*
X84811Y92062D01*
X75832Y83083D01*
G37*
D15*
G36*
X101968Y83083D02*
X92989Y92062D01*
X96940Y96013D01*
X105919Y87034D01*
X101968Y83083D01*
G37*
G36*
X107625Y88740D02*
X98646Y97719D01*
X102597Y101670D01*
X111576Y92691D01*
X107625Y88740D01*
G37*
G36*
X113282Y94396D02*
X104303Y103375D01*
X108254Y107326D01*
X117233Y98347D01*
X113282Y94396D01*
G37*
G36*
X118939Y100053D02*
X109960Y109032D01*
X113911Y112983D01*
X122890Y104004D01*
X118939Y100053D01*
G37*
G36*
X124596Y105710D02*
X115617Y114689D01*
X119568Y118640D01*
X128547Y109661D01*
X124596Y105710D01*
G37*
G36*
X130253Y111367D02*
X121274Y120346D01*
X125225Y124297D01*
X134204Y115318D01*
X130253Y111367D01*
G37*
G36*
X135909Y117024D02*
X126930Y126003D01*
X130881Y129954D01*
X139860Y120975D01*
X135909Y117024D01*
G37*
G36*
X141566Y122681D02*
X132587Y131660D01*
X136538Y135611D01*
X145517Y126632D01*
X141566Y122681D01*
G37*
D16*
G36*
X136538Y143789D02*
X132587Y147740D01*
X141566Y156719D01*
X145517Y152768D01*
X136538Y143789D01*
G37*
G36*
X130881Y149446D02*
X126930Y153397D01*
X135909Y162376D01*
X139860Y158425D01*
X130881Y149446D01*
G37*
G36*
X125225Y155103D02*
X121274Y159054D01*
X130253Y168033D01*
X134204Y164082D01*
X125225Y155103D01*
G37*
G36*
X119568Y160760D02*
X115617Y164711D01*
X124596Y173690D01*
X128547Y169739D01*
X119568Y160760D01*
G37*
G36*
X113911Y166417D02*
X109960Y170368D01*
X118939Y179347D01*
X122890Y175396D01*
X113911Y166417D01*
G37*
G36*
X108254Y172074D02*
X104303Y176025D01*
X113282Y185004D01*
X117233Y181053D01*
X108254Y172074D01*
G37*
G36*
X102597Y177730D02*
X98646Y181681D01*
X107625Y190660D01*
X111576Y186709D01*
X102597Y177730D01*
G37*
G36*
X96940Y183387D02*
X92989Y187338D01*
X101968Y196317D01*
X105919Y192366D01*
X96940Y183387D01*
G37*
D10*
X136516Y292100D03*
X119516Y292100D03*
D17*
X46990Y226369D03*
X46990Y218131D03*
D18*
X46990Y222250D03*
D19*
X118110Y7620D03*
X62230Y7620D03*
X118110Y45720D03*
X62230Y45720D03*
D20*
X49693Y178246D02*
X35143Y178246D01*
X35143Y190246D02*
X49693Y190246D01*
X49693Y202246D02*
X35143Y202246D01*
M02*