diff options
author | jaseg <git@jaseg.de> | 2022-01-19 13:40:04 +0100 |
---|---|---|
committer | jaseg <git@jaseg.de> | 2022-01-19 13:40:04 +0100 |
commit | 6c924609416b82e6be68680874d86447cffa9fd9 (patch) | |
tree | 9b5803acfb5850a56f1c3f485569867b8df7c019 /gerbonara | |
parent | 40286fc92fc05ce82cbad4615f497ba389ac9457 (diff) | |
download | gerbonara-6c924609416b82e6be68680874d86447cffa9fd9.tar.gz gerbonara-6c924609416b82e6be68680874d86447cffa9fd9.tar.bz2 gerbonara-6c924609416b82e6be68680874d86447cffa9fd9.zip |
Matcher WIP
Diffstat (limited to 'gerbonara')
24 files changed, 6171 insertions, 935 deletions
diff --git a/gerbonara/gerber/cam.py b/gerbonara/gerber/cam.py index 36e08ac..57ac000 100644 --- a/gerbonara/gerber/cam.py +++ b/gerbonara/gerber/cam.py @@ -83,7 +83,11 @@ class FileSettings: # Format precision integer_digits, decimal_digits = self.number_format if integer_digits is None or decimal_digits is None: - raise SyntaxError('No number format set and value does not contain a decimal point') + raise SyntaxError('No number format set and value does not contain a decimal point. If this is an Allegro ' + 'Excellon drill file make sure either nc_param.txt or ncdrill.log ends up in the same folder as ' + 'it, because Allegro does not include this critical information in their Excellon output. If you ' + 'call this through ExcellonFile.from_string, you must manually supply from_string with a ' + 'FileSettings object from excellon.parse_allegro_ncparam.') # Remove extraneous information sign = '-' if value[0] == '-' else '' diff --git a/gerbonara/gerber/excellon.py b/gerbonara/gerber/excellon.py index e827c3f..01d42c8 100755 --- a/gerbonara/gerber/excellon.py +++ b/gerbonara/gerber/excellon.py @@ -22,14 +22,12 @@ import functools from enum import Enum from dataclasses import dataclass from collections import Counter +from pathlib import Path from .cam import CamFile, FileSettings from .graphic_objects import Flash, Line, Arc from .apertures import ExcellonTool -from .utils import Inch, MM, InterpMode - -def parse(data, settings=None): - return ExcellonFile.parse(data, settings=settings) +from .utils import Inch, MM, to_unit, InterpMode, RegexMatcher class ExcellonContext: def __init__(self, settings, tools): @@ -60,13 +58,74 @@ class ExcellonContext: def set_current_point(self, unit, x, y): self.current_point = self.unit(x, unit), self.unit(y, unit) +def parse_allegro_ncparam(data, settings=None): + # This function parses data from allegro's nc_param.txt and ncdrill.log files. We have to parse these files because + # allegro Excellon files omit crucial information such as the *number format*. nc_param.txt really is the file we + # want to parse, but sometimes due to user error it doesn't end up in the gerber package. In this case, we want to + # still be able to extract the same information from the human-readable ncdrill.log. + + if settings is None + self.settings = FileSettings(number_format=(None, None)) + + lz_supp, tz_supp = False, False + for line in data.splitlines(): + line = re.sub('\s+', ' ', line.strip()) + + if (match := re.fullmatch(r'FORMAT ([0-9]+\.[0-9]+)', line)): + x, _, y = match[1].partition('.') + settings.number_format = int(x), int(y) + + elif (match := re.fullmatch(r'COORDINATES (ABSOLUTE|.*)', line)): + # I have not been able to find a single incremental-notation allegro file. Probably that is for the better. + settings.notation = match[1].lower() + + elif (match := re.fullmatch(r'OUTPUT-UNITS (METRIC|ENGLISH|INCHES)', line)): + # I have no idea wth is the difference between "ENGLISH" and "INCHES". I think one might just be the one + # Allegro uses in footprint files, with the other one being used in gerber exports. + settings.unit = MM if match[1] == 'METRIC' else Inch + + elif (match := re.fullmatch(r'SUPPRESS-LEAD-ZEROES (YES|NO)', line)): + lz_supp = (match[1] == 'YES') + + elif (match := re.fullmatch(r'SUPPRESS-TRAIL-ZEROES (YES|NO)', line)): + tz_supp = (match[1] == 'YES') + + if lz_supp and tz_supp: + raise SyntaxError('Allegro Excellon parameters specify both leading and trailing zero suppression. We do not ' + 'know how to parse this. Please raise an issue on our issue tracker and provide an example file.') + + settings.zeros = 'leading' if lz_supp else 'trailing' + class ExcellonFile(CamFile): - def __init__(self, objects=None, comments=None, import_settings=None, filename=None): + def __init__(self, objects=None, comments=None, import_settings=None, filename=None, generator=None): super().__init__(filename=filename) self.objects = objects or [] self.comments = comments or [] self.import_settings = import_settings + self.generator = generator # This is a purely informational goodie from the parser. Use it as you wish. + + @classmethod + def open(kls, filename, plated=None): + filename = Path(filename) + + # Parse allegro parameter files. + # Prefer nc_param.txt over ncparam.log since the txt is the machine-readable one. + for fn in 'nc_param.txt', 'ncdrill.log': + if (param_file := filename.parent / fn).isfile(): + settings = parse_allegro_ncparam(param_file.read_text()) + break + else: + settings = None + + return kls.from_string(filename.read_text(), settings=settings, filename=filename, plated=plated) + + @classmethod + def from_string(kls, data, settings=None, filename=filename, plated=None): + parser = ExcellonParser(settings) + parser._do_parse(data) + return kls(objects=parser.objects, comments=parser.comments, import_settings=settings, + generator=parser.generator, filename=filename, plated=plated) def _generate_statements(self, settings): @@ -186,22 +245,6 @@ class ExcellonFile(CamFile): return ((x_min, y_min), (x_max, y_max)) -class RegexMatcher: - def __init__(self): - self.mapping = {} - - def match(self, regex): - def wrapper(fun): - nonlocal self - self.mapping[regex] = fun - return fun - return wrapper - - def handle(self, inst, line): - for regex, handler in self.mapping.items(): - if (match := re.fullmatch(regex, line)): - handler(match) - class ProgramState(Enum): HEADER = 0 DRILLING = 1 @@ -226,13 +269,7 @@ class ExcellonParser(object): self.pos = 0, 0 self.drill_down = False self.is_plated = None - - @classmethod - def parse(kls, data, settings=None): - parser = kls(settings) - parser._do_parse(data) - - return ExcellonFile(objects=parser.objects, comments=parser.comments, import_settings=settings) + self.generator = None def _do_parse(self, data): leftover = None @@ -266,6 +303,7 @@ class ExcellonParser(object): def parse_allegro_tooldef(self, match): # NOTE: We ignore the given tolerances here since they are non-standard. self.program_state = ProgramState.HEADER # TODO is this needed? we need a test file. + self.generator = 'allegro' if (index := int(match['index1'])) != int(match['index2']): # index1 has leading zeros, index2 not. raise SyntaxError('BUG: Allegro excellon tool def has mismatching tool indices. Please file a bug report on our issue tracker and provide this file!') @@ -285,6 +323,11 @@ class ExcellonParser(object): else: unit = MM + if unit != self.settings.unit: + warnings.warn('Allegro Excellon drill file tool definitions in {unit.name}, but file parameters say the ' + 'file should be in {settings.unit.name}. Please double-check that this is correct, and if it is, ' + 'please raise an issue on our issue tracker.', SyntaxWarning) + self.tools[index] = ExcellonTool(diameter=diameter, plated=is_plated, unit=unit) # Searching Github I found that EasyEDA has two different variants of the unit specification here. @@ -299,7 +342,7 @@ class ExcellonParser(object): tools[index] = tool @exprs.match('T([0-9]+)(([A-Z][.0-9]+)+)') # Tool definition: T** with at least one parameter - def parse_tool_definition(self, match): + def parse_normal_tooldef(self, match): # We ignore parameters like feed rate or spindle speed that are not used for EDA -> CAM file transfer. This is # not a parser for the type of Excellon files a CAM program sends to the machine. @@ -307,6 +350,9 @@ class ExcellonParser(object): warnings.warn('Re-definition of tool index {index}, overwriting old definition.', SyntaxWarning) params = { m[0]: settings.parse_gerber_value(m[1:]) for m in re.findall('[BCFHSTZ][.0-9]+', match[2]) } + + if set(params.keys()) == set('TFSC') and self.generator is None: + self.generator = 'target3001' # target files look like altium files without the comments self.tools[index] = ExcellonTool(diameter=params.get('C'), depth_offset=params.get('Z'), plated=self.is_plated) @exprs.match('T([0-9]+)') @@ -352,7 +398,11 @@ class ExcellonParser(object): @exprs.match('M48') def handle_begin_header(self, match): - if self.program_state is not None: + if self.program_state == ProgramState.HEADER: + # It seems that only fritzing puts both a '%' start of header thingy and an M48 statement at the beginning + # of the file. + self.generator = 'fritzing' + elif self.program_state is not None: warnings.warn(f'M48 "header start" statement found in the middle of the file, currently in {self.program_state}', SyntaxWarning) self.program_state = ProgramState.HEADER @@ -509,7 +559,12 @@ class ExcellonParser(object): self.settings.unit = MM if match[1] == 'METRIC' else Inch self.settings.zeros = 'leading' if match[2] == 'LZ' else 'trailing' # Newer EasyEDA exports have this in an altium-like FILE_FORMAT comment instead. Some files even have both. + # This is used by newer autodesk eagles, fritzing and diptrace if match[3]: + if self.generator is None: + # newer eagles identify themselvees through a comment, and fritzing uses this wonky double-header-start + # with a "%" line followed by an "M48" line. Thus, thus must be diptrace. + self.generator = 'diptrace' integer, _, fractional = match[3].partition('.') self.settings.number_format = len(integer), len(fractional) @@ -550,6 +605,23 @@ class ExcellonParser(object): def handle_naked_coordinate(self, match): self.do_interpolation(match) + @exprs.match(r'; Format\s*: ([0-9]+\.[0-9]+) / (Absolute|Incremental) / (Inch|MM) / (Leading|Trailing)') + def parse_siemens_format(self, match): + x, _, y = match[1].split('.') + self.settings.number_format = int(x), int(y) + # NOTE: Siemens files seem to always contain both this comment and an explicit METRIC/INC statement. However, + # the meaning of "leading" and "trailing" is swapped in both: When this comment says leading, we get something + # like "INCH,TZ". + self.settings.notation = {'Leading': 'trailing', 'Trailing': 'leading'}[match[2]] + self.settings.unit = to_unit(match[3]) + self.settings.zeros = match[4].lower() + self.generator = 'siemens' + + @exprs.match('; Contents: (Thru|.*) / (Drill|Mill) / (Plated|Non-Plated)') + def parse_siemens_meta(self, match): + self.is_plated = (match[3] == 'Plated') + self.generator = 'siemens' + @exprs.match(';FILE_FORMAT=([0-9]:[0-9])') def parse_altium_easyeda_number_format_comment(self, match): # Altium or newer EasyEDA exports @@ -567,10 +639,26 @@ class ExcellonParser(object): # These can happen both before a tool definition and before a tool selection statement. # FIXME make sure we do the right thing in both cases. self.is_plated = (match[1] == 'PLATED') + + @exprs.match(';(Layer_Color=[-+0-9a-fA-F]*)') + def parse_altium_layer_color(self, match): + self.generator = 'altium' + self.comments.append(match[1]) @exprs.match(';HEADER:') def parse_allegro_start_of_header(self, match): self.program_state = ProgramState.HEADER + self.generator = 'allegro' + + @exprs.match(';GenerationSoftware,Autodesk,EAGLE,.*\*%') + def parse_eagle_version_header(self, match): + # NOTE: Only newer eagles export drills as XNC files. Older eagles produce an aperture-only gerber file called + # "profile.gbr" instead. + self.generator = 'eagle' + + @exprs.match(';EasyEDA .*') + def parse_easyeda_version_header(self, match): + self.generator = 'easyeda' @exprs.match(';(.*)') def parse_comment(self, match): diff --git a/gerbonara/gerber/excellon_report/excellon_drr.py b/gerbonara/gerber/excellon_report/excellon_drr.py deleted file mode 100644 index ab9e857..0000000 --- a/gerbonara/gerber/excellon_report/excellon_drr.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright 2015 Garret Fick <garret@ficksworkshop.com> - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Excellon DRR File module -==================== -**Excellon file classes** - -Extra parsers for allegro misc files that can be useful when the Excellon file doesn't contain parameter information -""" - diff --git a/gerbonara/gerber/exceptions.py b/gerbonara/gerber/exceptions.py deleted file mode 100644 index 65ae905..0000000 --- a/gerbonara/gerber/exceptions.py +++ /dev/null @@ -1,36 +0,0 @@ -#! /usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright 2015 Hamilton Kibbe <ham@hamiltonkib.be> - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -class ParseError(Exception): - pass - - -class GerberParseError(ParseError): - pass - - -class ExcellonParseError(ParseError): - pass - - -class ExcellonFileError(IOError): - pass - - -class GerberFileError(IOError): - pass diff --git a/gerbonara/gerber/layers.py b/gerbonara/gerber/layers.py index 35f2b00..f980042 100644 --- a/gerbonara/gerber/layers.py +++ b/gerbonara/gerber/layers.py @@ -22,6 +22,72 @@ from collections import namedtuple from .excellon import ExcellonFile
from .ipc356 import IPCNetlist
+def match_fn_eagle(name, suffix):
+ if suffix in ('cmp', 'top') or \ # Older Eagle versions (v7)
+ name.endswith('toplayer.ger') or \ # OSHPark Eagle CAM rules
+ 'copper_top' in name or 'top_copper' in name: # Newer Autodesk Eagle versions (v9)
+ return 'top copper gerber'
+
+ if suffix in ('stc', 'tsm') or \
+ name.endswith('topsoldermask.ger') or \
+ 'soldermask_top' in name or 'top_mask' in name:
+ return 'top mask gerber'
+
+ if suffix in ('plc', 'tsk') or \
+ name.endswith('topsilkscreen.ger') or \
+ 'silkscreen_top' in name or 'top_silk' in name:
+ return 'top silk gerber'
+
+ if suffix in ('crc', 'tsp') or \
+ name.endswith('tcream.ger') or \
+ 'solderpaste_top' in name or 'top_paste' in name:
+ return 'top paste gerber'
+
+ if suffix in ('sol', 'bot') or \
+ name.endswith('bottomlayer.ger') or \
+ 'copper_bottom' in name or 'bottom_copper' in name:
+ return 'bottom copper gerber'
+
+ if suffix in ('sts', 'bsm') or \
+ name.endswith('bottomsoldermask.ger') or \
+ 'soldermask_bottom' in name or 'bottom_mask' in name:
+ return 'bottom mask gerber'
+
+ if suffix in ('pls', 'bsk') or \
+ name.endswith('bottomsilkscreen.ger') or \
+ 'silkscreen_bottom' in name or \
+ 'bottom_silk' in name:
+ return 'bottom silk gerber'
+
+ if suffix in ('crs', 'bsp') or \
+ name.endswith('bcream.ger') or \
+ 'solderpaste_bottom' in name or 'bottom_paste' in name:
+ return 'bottom silk gerber'
+
+ if (m := re.fullmatch(r'ly(\d+)', suffix)):
+ return f'inner{m[1]} copper gerber'
+
+ if (m := re.fullmatch(r'.*internalplane(\d+).ger', suffix)):
+ return f'inner{m[1]} copper gerber'
+
+ if suffix in ('dim', 'mil', 'gml'):
+ return 'outline mechanical gerber'
+
+ if name.endswith('boardoutline.ger'):
+ return 'outline mechanical gerber'
+
+ if name == 'profile.gbr': # older eagle versions
+ return 'outline mechanical gerber'
+
+def match_fn_altium(name, suffix):
+ if suffix == 'gtl':
+ return 'top copper gerber'
+
+ if suffix == 'gts':
+ return 'top silk gerber'
+
+ if suffix ==
+
Hint = namedtuple('Hint', 'layer ext name regex content')
@@ -239,62 +305,8 @@ class PCBLayer(object): return '<PCBLayer: {}>'.format(self.layer_class)
-class DrillLayer(PCBLayer):
- @classmethod
- def from_cam(cls, camfile):
- return cls(camfile.filename, camfile)
-
- def __init__(self, filename=None, cam_source=None, layers=None, **kwargs):
- super(DrillLayer, self).__init__(filename, 'drill', cam_source, **kwargs)
- self.layers = layers if layers is not None else ['top', 'bottom']
-
-
-class InternalLayer(PCBLayer):
- @classmethod
- def from_cam(cls, camfile):
- filename = camfile.filename
- try:
- order = int(re.search(r'\d+', filename).group())
- except AttributeError:
- order = 0
- return cls(filename, camfile, order)
-
- def __init__(self, filename=None, cam_source=None, order=0, **kwargs):
- super(InternalLayer, self).__init__(filename, 'internal', cam_source, **kwargs)
- self.order = order
-
- def __eq__(self, other):
- if not hasattr(other, 'order'):
- raise TypeError()
- return (self.order == other.order)
-
- def __ne__(self, other):
- if not hasattr(other, 'order'):
- raise TypeError()
- return (self.order != other.order)
-
- def __gt__(self, other):
- if not hasattr(other, 'order'):
- raise TypeError()
- return (self.order > other.order)
-
- def __lt__(self, other):
- if not hasattr(other, 'order'):
- raise TypeError()
- return (self.order < other.order)
-
- def __ge__(self, other):
- if not hasattr(other, 'order'):
- raise TypeError()
- return (self.order >= other.order)
-
- def __le__(self, other):
- if not hasattr(other, 'order'):
- raise TypeError()
- return (self.order <= other.order)
-
-class PCB:
+class LayerStack:
@classmethod
def from_directory(cls, directory, board_name=None, verbose=False):
layers = []
diff --git a/gerbonara/gerber/ncparam/allegro.py b/gerbonara/gerber/ncparam/allegro.py deleted file mode 100644 index a67bcf1..0000000 --- a/gerbonara/gerber/ncparam/allegro.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright 2015 Garret Fick <garret@ficksworkshop.com> - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Allegro File module -==================== -**Excellon file classes** - -Extra parsers for allegro misc files that can be useful when the Excellon file doesn't contain parameter information -""" - diff --git a/gerbonara/gerber/panelize/excellon.py b/gerbonara/gerber/panelize/excellon.py deleted file mode 100644 index e6cfcd0..0000000 --- a/gerbonara/gerber/panelize/excellon.py +++ /dev/null @@ -1,403 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com> - -import operator - -from .. import excellon -from ..excellon import ExcellonParser, detect_excellon_format, ExcellonFile, DrillHit, DrillSlot -from ..excellon_statements import ExcellonStatement, UnitStmt, CoordinateStmt, UnknownStmt, \ - SlotStmt, DrillModeStmt, RouteModeStmt, LinearModeStmt, \ - ToolSelectionStmt, ZAxisRoutPositionStmt, \ - RetractWithClampingStmt, RetractWithoutClampingStmt, \ - EndOfProgramStmt -from ..cam import FileSettings -from ..utils import inch, metric, write_gerber_value, parse_gerber_value, rotate_point - -def loads(data, filename=None, settings=None, tools=None, format=None): - if not settings: - settings = FileSettings(**detect_excellon_format(data)) - if format: - settings.format = format - excellon.CoordinateStmt = CoordinateStmtEx - excellon.UnitStmt = UnitStmtEx - file = ExcellonParser(settings, tools).parse_raw(data, filename) - return ExcellonFileEx.from_file(file) - -def write_excellon_header(file, settings, tools): - file.write('M48\nFMAT,2\nICI,OFF\n%s\n' % - UnitStmtEx(settings.units, settings.zeros, settings.format).to_excellon(settings)) - for tool in tools: - file.write(tool.to_excellon(settings) + '\n') - file.write('%%\nG90\n%s\n' % ('M72' if settings.units == 'inch' else 'M71')) - -class ExcellonFileEx(ExcellonFile): - @classmethod - def from_file(cls, file): - def correct_statements(): - for stmt in file.statements: - if isinstance(stmt, UnknownStmt): - line = stmt.stmt.strip() - if line[:3] == 'G02': - yield CircularCWModeStmt() - if len(line) > 3: - yield CoordinateStmtEx.from_excellon(line[3:], file.settings) - elif line[:3] == 'G03': - yield CircularCCWModeStmt() - if len(line) > 3: - yield CoordinateStmtEx.from_excellon(line[3:], file.settings) - elif line[0] == 'X' or line[0] == 'Y' or line[0] == 'A' or line[0] == 'I': - yield CoordinateStmtEx.from_excellon(line, file.settings) - else: - yield stmt - else: - yield stmt - - def generate_hits(statements): - class CoordinateCtx: - def __init__(self, notation): - self.notation = notation - self.x = 0. - self.y = 0. - self.radius = None - self.center_offset = None - - def update(self, x=None, y=None, radius=None, center_offset=None): - if self.notation == 'absolute': - if x is not None: - self.x = x - if y is not None: - self.y = y - else: - if x is not None: - self.x += x - if y is not None: - self.y += y - if radius is not None: - self.radius = radius - if center_offset is not None: - self.center_offset = center_offset - - def node(self, mode, center_offset): - radius, offset = None, None - if mode == DrillRout.MODE_CIRCULER_CW or mode == DrillRout.MODE_CIRCULER_CCW: - if center_offset is None: - radius = self.radius - offset = self.center_offset - else: - radius = None - offset = center_offset - return DrillRout.Node(mode, self.x, self.y, radius, offset) - - STAT_DRILL = 0 - STAT_ROUT_UP = 1 - STAT_ROUT_DOWN = 2 - - status = STAT_DRILL - current_tool = None - rout_mode = None - coordinate_ctx = CoordinateCtx(file.notation) - rout_nodes = [] - - last_position = (0., 0.) - last_radius = None - last_center_offset = None - - def make_rout(status, nodes): - if status != STAT_ROUT_DOWN or len(nodes) == 0 or current_tool is None: - return None - return DrillRout(current_tool, nodes) - - for stmt in statements: - if isinstance(stmt, ToolSelectionStmt): - current_tool = file.tools[stmt.tool] - elif isinstance(stmt, DrillModeStmt): - rout = make_rout(status, rout_nodes) - rout_nodes = [] - if rout is not None: - yield rout - status = STAT_DRILL - rout_mode = None - elif isinstance(stmt, RouteModeStmt): - if status == STAT_DRILL: - status = STAT_ROUT_UP - rout_mode = DrillRout.MODE_ROUT - else: - rout_mode = DrillRout.MODE_LINEAR - - elif isinstance(stmt, LinearModeStmt): - rout_mode = DrillRout.MODE_LINEAR - elif isinstance(stmt, CircularCWModeStmt): - rout_mode = DrillRout.MODE_CIRCULER_CW - elif isinstance(stmt, CircularCCWModeStmt): - rout_mode = DrillRout.MODE_CIRCULER_CCW - elif isinstance(stmt, ZAxisRoutPositionStmt) and status == STAT_ROUT_UP: - status = STAT_ROUT_DOWN - elif isinstance(stmt, RetractWithClampingStmt) or isinstance(stmt, RetractWithoutClampingStmt): - rout = make_rout(status, rout_nodes) - rout_nodes = [] - if rout is not None: - yield rout - status = STAT_ROUT_UP - elif isinstance(stmt, SlotStmt): - coordinate_ctx.update(stmt.x_start, stmt.y_start) - x_start = coordinate_ctx.x - y_start = coordinate_ctx.y - coordinate_ctx.update(stmt.x_end, stmt.y_end) - x_end = coordinate_ctx.x - y_end = coordinate_ctx.y - yield DrillSlotEx(current_tool, (x_start, y_start), - (x_end, y_end), DrillSlotEx.TYPE_G85) - elif isinstance(stmt, CoordinateStmtEx): - center_offset = (stmt.i, stmt.j) \ - if stmt.i is not None and stmt.j is not None else None - coordinate_ctx.update(stmt.x, stmt.y, stmt.radius, center_offset) - if stmt.x is not None or stmt.y is not None: - if status == STAT_DRILL: - yield DrillHitEx(current_tool, (coordinate_ctx.x, coordinate_ctx.y)) - elif status == STAT_ROUT_UP: - rout_nodes = [coordinate_ctx.node(DrillRout.MODE_ROUT, None)] - elif status == STAT_ROUT_DOWN: - rout_nodes.append(coordinate_ctx.node(rout_mode, center_offset)) - - statements = [s for s in correct_statements()] - hits = [h for h in generate_hits(statements)] - return cls(statements, file.tools, hits, file.settings, file.filename) - - @property - def primitives(self): - return [] - - def __init__(self, statements, tools, hits, settings, filename=None): - super(ExcellonFileEx, self).__init__(statements, tools, hits, settings, filename) - - def rotate(self, angle, center=(0,0)): - if angle % 360 == 0: - return - for hit in self.hits: - hit.rotate(angle, center) - - def to_inch(self): - if self.units == 'metric': - for stmt in self.statements: - stmt.to_inch() - for tool in self.tools: - self.tools[tool].to_inch() - for hit in self.hits: - hit.to_inch() - self.units = 'inch' - - def to_metric(self): - if self.units == 'inch': - for stmt in self.statements: - stmt.to_metric() - for tool in self.tools: - self.tools[tool].to_metric() - for hit in self.hits: - hit.to_metric() - self.units = 'metric' - - def write(self, filename=None): - self.notation = 'absolute' - self.zeros = 'trailing' - filename = filename if filename is not None else self.filename - with open(filename, 'w') as f: - write_excellon_header(f, self.settings, [self.tools[t] for t in self.tools]) - for tool in iter(self.tools.values()): - f.write(ToolSelectionStmt( - tool.number).to_excellon(self.settings) + '\n') - for hit in self.hits: - if hit.tool.number == tool.number: - f.write(hit.to_excellon(self.settings) + '\n') - f.write(EndOfProgramStmt().to_excellon() + '\n') - -class DrillHitEx(DrillHit): - def to_inch(self): - self.position = tuple(map(inch, self.position)) - - def to_metric(self): - self.position = tuple(map(metric, self.position)) - - def rotate(self, angle, center=(0, 0)): - self.position = rotate_point(self.position, angle, center) - - def to_excellon(self, settings): - return CoordinateStmtEx(*self.position).to_excellon(settings) - -class DrillSlotEx(DrillSlot): - def to_inch(self): - self.start = tuple(map(inch, self.start)) - self.end = tuple(map(inch, self.end)) - - def to_metric(self): - self.start = tuple(map(metric, self.start)) - self.end = tuple(map(metric, self.end)) - - def rotate(self, angle, center=(0,0)): - self.start = rotate_point(self.start, angle, center) - self.end = rotate_point(self.end, angle, center) - - def to_excellon(self, settings): - return SlotStmt(*self.start, *self.end).to_excellon(settings) - -class DrillRout(object): - MODE_ROUT = 'G00' - MODE_LINEAR = 'G01' - MODE_CIRCULER_CW = 'G02' - MODE_CIRCULER_CCW = 'G03' - - class Node(object): - def __init__(self, mode, x, y, radius=None, center_offset=None): - self.mode = mode - self.position = (x, y) - self.radius = radius - self.center_offset = center_offset - - def to_excellon(self, settings): - center_offset = self.center_offset \ - if self.center_offset is not None else (None, None) - return self.mode + CoordinateStmtEx( - *self.position, self.radius, *center_offset).to_excellon(settings) - - def __init__(self, tool, nodes): - self.tool = tool - self.nodes = nodes - self.nodes[0].mode = self.MODE_ROUT - - def to_excellon(self, settings): - excellon = self.nodes[0].to_excellon(settings) + '\nM15\n' - for node in self.nodes[1:]: - excellon += node.to_excellon(settings) + '\n' - excellon += 'M16\nG05' - return excellon - - def to_inch(self): - for node in self.nodes: - node.position = tuple(map(inch, node.position)) - node.radius = inch( - node.radius) if node.radius is not None else None - if node.center_offset is not None: - node.center_offset = tuple(map(inch, node.center_offset)) - - def to_metric(self): - for node in self.nodes: - node.position = tuple(map(metric, node.position)) - node.radius = metric( - node.radius) if node.radius is not None else None - if node.center_offset is not None: - node.center_offset = tuple(map(metric, node.center_offset)) - - def offset(self, x_offset=0, y_offset=0): - for node in self.nodes: - node.position = tuple(map(operator.add, node.position, (x_offset, y_offset))) - - def rotate(self, angle, center=(0, 0)): - for node in self.nodes: - node.position = rotate_point(node.position, angle, center) - if node.center_offset is not None: - node.center_offset = rotate_point(node.center_offset, angle, (0., 0.)) - -class UnitStmtEx(UnitStmt): - @classmethod - def from_statement(cls, stmt): - return cls(units=stmt.units, zeros=stmt.zeros, format=stmt.format, id=stmt.id) - - def __init__(self, units='inch', zeros='leading', format=None, **kwargs): - super(UnitStmtEx, self).__init__(units, zeros, format, **kwargs) - - def to_excellon(self, settings=None): - format = settings.format if settings else self.format - stmt = None - if self.units == 'inch' and format == (2, 4): - stmt = 'INCH,%s' % ('LZ' if self.zeros == 'leading' else 'TZ') - else: - stmt = '%s,%s,%s.%s' % ('INCH' if self.units == 'inch' else 'METRIC', - 'LZ' if self.zeros == 'leading' else 'TZ', - '0' * format[0], '0' * format[1]) - return stmt - -class CircularCWModeStmt(ExcellonStatement): - - def __init__(self, **kwargs): - super(CircularCWModeStmt, self).__init__(**kwargs) - - def to_excellon(self, settings=None): - return 'G02' - -class CircularCCWModeStmt(ExcellonStatement): - - def __init__(self, **kwargs): - super(CircularCCWModeStmt, self).__init__(**kwargs) - - def to_excellon(self, settings=None): - return 'G02' - -class CoordinateStmtEx(CoordinateStmt): - @classmethod - def from_statement(cls, stmt): - newStmt = cls(x=stmt.x, y=stmt.y) - newStmt.radius = stmt.radius if isinstance(stmt, CoordinateStmtEx) else None - return newStmt - - @classmethod - def from_excellon(cls, line, settings, **kwargs): - stmt = None - if 'A' in line: - parts = line.split('A') - stmt = cls.from_statement(CoordinateStmt.from_excellon(parts[0], settings)) \ - if parts[0] != '' else cls() - stmt.radius = parse_gerber_value( - parts[1], settings.format, settings.zero_suppression) - elif 'I' in line: - jparts = line.split('J') - iparts = jparts[0].split('I') - stmt = cls.from_statement(CoordinateStmt.from_excellon(iparts[0], settings)) \ - if iparts[0] != '' else cls() - stmt.i = parse_gerber_value( - iparts[1], settings.format, settings.zero_suppression) - stmt.j = parse_gerber_value( - jparts[1], settings.format, settings.zero_suppression) - else: - stmt = cls.from_statement(CoordinateStmt.from_excellon(line, settings)) - - return stmt - - def __init__(self, x=None, y=None, radius=None, i=None, j=None, **kwargs): - super(CoordinateStmtEx, self).__init__(x, y, **kwargs) - self.radius = radius - self.i = i - self.j = j - - def to_excellon(self, settings): - stmt = '' - if self.x is not None: - stmt += 'X%s' % write_gerber_value(self.x, settings.format, - settings.zero_suppression) - if self.y is not None: - stmt += 'Y%s' % write_gerber_value(self.y, settings.format, - settings.zero_suppression) - if self.radius is not None: - stmt += 'A%s' % write_gerber_value(self.radius, settings.format, - settings.zero_suppression) - elif self.i is not None and self.j is not None: - stmt += 'I%sJ%s' % (write_gerber_value(self.i, settings.format, - settings.zero_suppression), - write_gerber_value(self.j, settings.format, - settings.zero_suppression)) - return stmt - - def __str__(self): - coord_str = '' - if self.x is not None: - coord_str += 'X: %g ' % self.x - if self.y is not None: - coord_str += 'Y: %g ' % self.y - if self.radius is not None: - coord_str += 'A: %g ' % self.radius - if self.i is not None: - coord_str += 'I: %g ' % self.i - if self.j is not None: - coord_str += 'J: %g ' % self.j - - return '<Coordinate Statement: %s>' % (coord_str) diff --git a/gerbonara/gerber/tests/image_support.py b/gerbonara/gerber/tests/image_support.py index ba28561..36343d9 100644 --- a/gerbonara/gerber/tests/image_support.py +++ b/gerbonara/gerber/tests/image_support.py @@ -63,6 +63,8 @@ def run_cargo_cmd(cmd, args, **kwargs): def svg_to_png(in_svg, out_png, dpi=100, bg='black'): run_cargo_cmd('resvg', ['--background', bg, '--dpi', str(dpi), in_svg, out_png], check=True, stdout=subprocess.DEVNULL) +to_gerbv_svg_units = lambda val, unit='mm': val*72 if unit == 'inch' else val/25.4*72 + def gerbv_export(in_gbr, out_svg, format='svg', origin=(0, 0), size=(6, 6), fg='#ffffff', bg='#000000'): x, y = origin w, h = size diff --git a/gerbonara/gerber/tests/resources/eagle-newer/LICENSE b/gerbonara/gerber/tests/resources/eagle-newer/LICENSE new file mode 100644 index 0000000..42ac60a --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Ganz Youth Workshop + +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. diff --git a/gerbonara/gerber/tests/resources/eagle-newer/README b/gerbonara/gerber/tests/resources/eagle-newer/README new file mode 100644 index 0000000..ba6f91e --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/README @@ -0,0 +1 @@ +From https://github.com/GanzYouthWorkshop/GYW-Electro-Curriculum diff --git a/gerbonara/gerber/tests/resources/eagle-newer/copper_bottom.gbr b/gerbonara/gerber/tests/resources/eagle-newer/copper_bottom.gbr new file mode 100644 index 0000000..f1675de --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/copper_bottom.gbr @@ -0,0 +1,3030 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Copper,L2,Bot,Mixed* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10P,1.814519X8X112.500000*% +%ADD11C,2.540000*% +%ADD12P,2.749271X8X292.500000*% +%ADD13P,1.814519X8X292.500000*% +%ADD14C,1.676400*% +%ADD15C,1.879600*% +%ADD16C,1.879600*% +%ADD17C,1.016000*% +%ADD18C,0.609600*% + +G36* +X67582Y10163D02* +X67582Y10163D01* +X67600Y10161D01* +X67782Y10182D01* +X67965Y10201D01* +X67982Y10206D01* +X67999Y10208D01* +X68174Y10265D01* +X68350Y10319D01* +X68365Y10327D01* +X68382Y10333D01* +X68542Y10423D01* +X68704Y10511D01* +X68717Y10522D01* +X68733Y10531D01* +X68872Y10651D01* +X68893Y10669D01* +X88900Y10669D01* +X108902Y10669D01* +X108983Y10606D01* +X109126Y10491D01* +X109142Y10483D01* +X109156Y10472D01* +X109321Y10390D01* +X109483Y10305D01* +X109500Y10300D01* +X109516Y10292D01* +X109695Y10245D01* +X109870Y10194D01* +X109888Y10192D01* +X109905Y10188D01* +X110236Y10161D01* +X153882Y10161D01* +X153891Y10162D01* +X153900Y10161D01* +X154091Y10182D01* +X154282Y10201D01* +X154291Y10203D01* +X154300Y10204D01* +X154482Y10262D01* +X154667Y10319D01* +X154675Y10323D01* +X154684Y10326D01* +X154852Y10419D01* +X155021Y10511D01* +X155028Y10516D01* +X155036Y10521D01* +X155183Y10645D01* +X155331Y10768D01* +X155336Y10775D01* +X155343Y10781D01* +X155462Y10932D01* +X155583Y11082D01* +X155587Y11090D01* +X155593Y11097D01* +X155680Y11270D01* +X155768Y11439D01* +X155771Y11448D01* +X155775Y11456D01* +X155827Y11642D01* +X155880Y11826D01* +X155881Y11835D01* +X155883Y11844D01* +X155897Y12037D01* +X155913Y12228D01* +X155912Y12236D01* +X155912Y12245D01* +X155888Y12438D01* +X155866Y12627D01* +X155863Y12636D01* +X155862Y12645D01* +X155801Y12828D01* +X155741Y13010D01* +X155737Y13018D01* +X155734Y13026D01* +X155638Y13193D01* +X155543Y13361D01* +X155537Y13368D01* +X155533Y13375D01* +X155318Y13628D01* +X149859Y19087D01* +X149859Y22861D01* +X162561Y22861D01* +X162561Y12192D01* +X162562Y12174D01* +X162561Y12156D01* +X162582Y11974D01* +X162601Y11791D01* +X162606Y11774D01* +X162608Y11757D01* +X162665Y11582D01* +X162719Y11406D01* +X162727Y11391D01* +X162733Y11374D01* +X162823Y11214D01* +X162910Y11052D01* +X162922Y11039D01* +X162931Y11023D01* +X163051Y10884D01* +X163168Y10743D01* +X163182Y10732D01* +X163194Y10718D01* +X163339Y10606D01* +X163482Y10491D01* +X163498Y10483D01* +X163512Y10472D01* +X163677Y10390D01* +X163839Y10305D01* +X163856Y10300D01* +X163872Y10292D01* +X164051Y10245D01* +X164226Y10194D01* +X164244Y10192D01* +X164261Y10188D01* +X164592Y10161D01* +X165608Y10161D01* +X165626Y10163D01* +X165644Y10161D01* +X165826Y10182D01* +X166009Y10201D01* +X166026Y10206D01* +X166043Y10208D01* +X166218Y10265D01* +X166394Y10319D01* +X166409Y10327D01* +X166426Y10333D01* +X166586Y10423D01* +X166748Y10511D01* +X166761Y10522D01* +X166777Y10531D01* +X166916Y10651D01* +X167057Y10768D01* +X167068Y10782D01* +X167082Y10794D01* +X167194Y10939D01* +X167309Y11082D01* +X167317Y11098D01* +X167328Y11112D01* +X167410Y11276D01* +X167495Y11439D01* +X167500Y11456D01* +X167508Y11472D01* +X167555Y11651D01* +X167606Y11826D01* +X167608Y11844D01* +X167612Y11861D01* +X167639Y12192D01* +X167639Y22861D01* +X180341Y22861D01* +X180341Y19087D01* +X174882Y13628D01* +X174876Y13621D01* +X174869Y13616D01* +X174749Y13466D01* +X174627Y13317D01* +X174623Y13309D01* +X174617Y13302D01* +X174529Y13132D01* +X174438Y12961D01* +X174436Y12952D01* +X174432Y12945D01* +X174378Y12760D01* +X174323Y12575D01* +X174323Y12566D01* +X174320Y12558D01* +X174305Y12366D01* +X174287Y12174D01* +X174288Y12165D01* +X174287Y12156D01* +X174309Y11967D01* +X174330Y11774D01* +X174333Y11765D01* +X174334Y11757D01* +X174394Y11575D01* +X174452Y11390D01* +X174456Y11382D01* +X174459Y11374D01* +X174555Y11204D01* +X174647Y11038D01* +X174653Y11031D01* +X174657Y11023D01* +X174783Y10877D01* +X174907Y10731D01* +X174914Y10725D01* +X174920Y10718D01* +X175072Y10601D01* +X175223Y10481D01* +X175231Y10477D01* +X175238Y10472D01* +X175410Y10386D01* +X175582Y10299D01* +X175591Y10296D01* +X175599Y10292D01* +X175785Y10242D01* +X175970Y10191D01* +X175979Y10190D01* +X175988Y10188D01* +X176318Y10161D01* +X583692Y10161D01* +X583710Y10163D01* +X583727Y10161D01* +X583910Y10182D01* +X584092Y10201D01* +X584109Y10206D01* +X584127Y10208D01* +X584302Y10265D01* +X584477Y10319D01* +X584493Y10327D01* +X584510Y10333D01* +X584670Y10423D01* +X584831Y10511D01* +X584845Y10522D01* +X584861Y10531D01* +X585000Y10651D01* +X585141Y10768D01* +X585152Y10782D01* +X585165Y10794D01* +X585278Y10939D01* +X585393Y11082D01* +X585401Y11098D01* +X585412Y11112D01* +X585494Y11276D01* +X585578Y11439D01* +X585583Y11456D01* +X585591Y11472D01* +X585639Y11651D01* +X585690Y11826D01* +X585691Y11844D01* +X585696Y11861D01* +X585723Y12192D01* +X585723Y13208D01* +X585721Y13226D01* +X585723Y13244D01* +X585701Y13426D01* +X585683Y13609D01* +X585678Y13626D01* +X585676Y13643D01* +X585619Y13818D01* +X585565Y13994D01* +X585557Y14009D01* +X585551Y14026D01* +X585461Y14186D01* +X585373Y14348D01* +X585362Y14361D01* +X585353Y14377D01* +X585233Y14516D01* +X585115Y14657D01* +X585102Y14668D01* +X585090Y14682D01* +X584945Y14794D01* +X584802Y14909D01* +X584786Y14917D01* +X584772Y14928D01* +X584607Y15010D01* +X584444Y15095D01* +X584427Y15100D01* +X584411Y15108D01* +X584233Y15155D01* +X584058Y15206D01* +X584040Y15208D01* +X584023Y15212D01* +X583692Y15239D01* +X563117Y15239D01* +X563157Y15496D01* +X563738Y17283D01* +X564520Y18818D01* +X564555Y18909D01* +X564600Y18995D01* +X564628Y19096D01* +X564666Y19193D01* +X564683Y19289D01* +X564710Y19383D01* +X564718Y19487D01* +X564736Y19589D01* +X564733Y19687D01* +X564741Y19784D01* +X564728Y19888D01* +X564726Y19992D01* +X564704Y20087D01* +X564692Y20184D01* +X564659Y20283D01* +X564636Y20384D01* +X564596Y20473D01* +X564566Y20566D01* +X564514Y20657D01* +X564471Y20752D01* +X564415Y20831D01* +X564366Y20916D01* +X564298Y20994D01* +X564237Y21079D01* +X564166Y21146D01* +X564102Y21219D01* +X564019Y21283D01* +X563943Y21354D01* +X563860Y21405D01* +X563783Y21465D01* +X563771Y21471D01* +X558221Y27021D01* +X555243Y34209D01* +X555243Y41991D01* +X558221Y49179D01* +X558405Y49364D01* +X558417Y49377D01* +X558430Y49389D01* +X558544Y49533D01* +X558660Y49675D01* +X558669Y49691D01* +X558680Y49705D01* +X558763Y49869D01* +X558849Y50031D01* +X558854Y50048D01* +X558862Y50064D01* +X558912Y50241D01* +X558964Y50417D01* +X558965Y50434D01* +X558970Y50452D01* +X558984Y50635D01* +X559000Y50818D01* +X558998Y50835D01* +X559000Y50853D01* +X558977Y51036D01* +X558957Y51218D01* +X558952Y51235D01* +X558949Y51253D01* +X558891Y51427D01* +X558835Y51602D01* +X558827Y51617D01* +X558821Y51634D01* +X558729Y51794D01* +X558641Y51954D01* +X558629Y51968D01* +X558620Y51983D01* +X558405Y52236D01* +X558221Y52421D01* +X555243Y59609D01* +X555243Y67391D01* +X558221Y74579D01* +X558405Y74764D01* +X558417Y74777D01* +X558430Y74789D01* +X558544Y74933D01* +X558660Y75075D01* +X558669Y75091D01* +X558680Y75105D01* +X558763Y75269D01* +X558849Y75431D01* +X558854Y75448D01* +X558862Y75464D01* +X558912Y75641D01* +X558964Y75817D01* +X558965Y75834D01* +X558970Y75852D01* +X558984Y76035D01* +X559000Y76218D01* +X558998Y76235D01* +X559000Y76253D01* +X558977Y76436D01* +X558957Y76618D01* +X558952Y76635D01* +X558949Y76653D01* +X558891Y76827D01* +X558835Y77002D01* +X558827Y77017D01* +X558821Y77034D01* +X558729Y77194D01* +X558641Y77354D01* +X558629Y77368D01* +X558620Y77383D01* +X558405Y77636D01* +X558221Y77821D01* +X555243Y85009D01* +X555243Y92790D01* +X556677Y96251D01* +X556680Y96264D01* +X556687Y96275D01* +X556738Y96455D01* +X556793Y96636D01* +X556794Y96649D01* +X556798Y96662D01* +X556813Y96850D01* +X556831Y97037D01* +X556830Y97050D01* +X556831Y97064D01* +X556809Y97250D01* +X556790Y97437D01* +X556785Y97450D01* +X556784Y97463D01* +X556726Y97642D01* +X556670Y97822D01* +X556663Y97833D01* +X556659Y97846D01* +X556566Y98011D01* +X556476Y98175D01* +X556468Y98185D01* +X556461Y98197D01* +X556338Y98339D01* +X556217Y98483D01* +X556207Y98491D01* +X556198Y98502D01* +X556050Y98616D01* +X555902Y98734D01* +X555890Y98740D01* +X555880Y98748D01* +X555712Y98832D01* +X555544Y98918D01* +X555531Y98922D01* +X555519Y98928D01* +X555337Y98977D01* +X555157Y99028D01* +X555144Y99029D01* +X555131Y99032D01* +X554800Y99059D01* +X535284Y99059D01* +X535271Y99058D01* +X535258Y99059D01* +X535072Y99038D01* +X534884Y99019D01* +X534871Y99015D01* +X534858Y99014D01* +X534679Y98956D01* +X534499Y98901D01* +X534487Y98895D01* +X534474Y98891D01* +X534310Y98799D01* +X534145Y98709D01* +X534135Y98701D01* +X534123Y98694D01* +X533980Y98572D01* +X533836Y98452D01* +X533827Y98441D01* +X533817Y98433D01* +X533701Y98284D01* +X533583Y98138D01* +X533577Y98126D01* +X533569Y98116D01* +X533484Y97947D01* +X533398Y97781D01* +X533394Y97768D01* +X533388Y97756D01* +X533338Y97574D01* +X533286Y97394D01* +X533285Y97380D01* +X533282Y97367D01* +X533269Y97179D01* +X533253Y96992D01* +X533255Y96979D01* +X533254Y96966D01* +X533279Y96778D01* +X533300Y96593D01* +X533304Y96580D01* +X533306Y96567D01* +X533408Y96251D01* +X534925Y92588D01* +X534925Y85212D01* +X532102Y78396D01* +X526886Y73180D01* +X526164Y72881D01* +X526115Y72855D01* +X526063Y72836D01* +X525938Y72760D01* +X525809Y72691D01* +X525766Y72656D01* +X525719Y72627D01* +X525612Y72528D01* +X525499Y72435D01* +X525464Y72392D01* +X525423Y72354D01* +X525337Y72236D01* +X525245Y72122D01* +X525219Y72073D01* +X525187Y72028D01* +X525126Y71895D01* +X525058Y71766D01* +X525043Y71712D01* +X525019Y71662D01* +X524986Y71519D01* +X524945Y71379D01* +X524940Y71324D01* +X524928Y71270D01* +X524923Y71123D01* +X524910Y70978D01* +X524917Y70923D01* +X524915Y70867D01* +X524939Y70723D01* +X524956Y70578D01* +X524973Y70525D01* +X524982Y70470D01* +X525034Y70334D01* +X525079Y70195D01* +X525106Y70146D01* +X525126Y70094D01* +X525237Y69911D01* +X525275Y69843D01* +X525287Y69830D01* +X525298Y69811D01* +X525724Y69225D01* +X526504Y67693D01* +X527036Y66058D01* +X527119Y65531D01* +X508000Y65531D01* +X488881Y65531D01* +X488964Y66058D01* +X489496Y67693D01* +X490276Y69225D01* +X490702Y69811D01* +X490730Y69859D01* +X490765Y69902D01* +X490831Y70032D01* +X490905Y70158D01* +X490923Y70211D01* +X490948Y70260D01* +X490988Y70401D01* +X491036Y70539D01* +X491043Y70594D01* +X491058Y70648D01* +X491069Y70793D01* +X491089Y70938D01* +X491085Y70994D01* +X491089Y71049D01* +X491072Y71194D01* +X491062Y71340D01* +X491047Y71394D01* +X491041Y71449D01* +X490995Y71587D01* +X490956Y71728D01* +X490932Y71778D01* +X490914Y71831D01* +X490842Y71958D01* +X490776Y72089D01* +X490742Y72132D01* +X490715Y72181D01* +X490619Y72291D01* +X490529Y72406D01* +X490487Y72442D01* +X490450Y72484D01* +X490334Y72573D01* +X490224Y72669D01* +X490175Y72696D01* +X490131Y72730D01* +X489940Y72828D01* +X489873Y72866D01* +X489856Y72871D01* +X489836Y72881D01* +X489064Y73201D01* +X489054Y73209D01* +X488919Y73319D01* +X488895Y73332D01* +X488874Y73348D01* +X488717Y73426D01* +X488563Y73508D01* +X488538Y73516D01* +X488513Y73528D01* +X488344Y73573D01* +X488177Y73623D01* +X488151Y73625D01* +X488125Y73632D01* +X487794Y73659D01* +X466868Y73659D01* +X461267Y75980D01* +X444280Y92967D01* +X441959Y98568D01* +X441959Y132194D01* +X441957Y132221D01* +X441959Y132247D01* +X441937Y132421D01* +X441919Y132595D01* +X441912Y132620D01* +X441908Y132647D01* +X441853Y132812D01* +X441801Y132979D01* +X441788Y133003D01* +X441780Y133028D01* +X441693Y133180D01* +X441609Y133334D01* +X441592Y133354D01* +X441579Y133377D01* +X441497Y133474D01* +X438657Y140330D01* +X438657Y147828D01* +X438655Y147846D01* +X438657Y147864D01* +X438636Y148046D01* +X438617Y148229D01* +X438612Y148246D01* +X438610Y148263D01* +X438553Y148438D01* +X438499Y148614D01* +X438491Y148629D01* +X438485Y148646D01* +X438395Y148806D01* +X438307Y148968D01* +X438296Y148981D01* +X438287Y148997D01* +X438167Y149136D01* +X438050Y149277D01* +X438036Y149288D01* +X438024Y149302D01* +X437879Y149414D01* +X437736Y149529D01* +X437720Y149537D01* +X437706Y149548D01* +X437541Y149630D01* +X437379Y149715D01* +X437362Y149720D01* +X437346Y149728D01* +X437167Y149775D01* +X436992Y149826D01* +X436974Y149828D01* +X436957Y149832D01* +X436626Y149859D01* +X430924Y149859D01* +X430897Y149857D01* +X430871Y149859D01* +X430697Y149837D01* +X430523Y149819D01* +X430498Y149812D01* +X430471Y149808D01* +X430306Y149753D01* +X430138Y149701D01* +X430115Y149688D01* +X430090Y149680D01* +X429938Y149593D01* +X429784Y149509D01* +X429764Y149492D01* +X429741Y149479D01* +X429488Y149264D01* +X426781Y146557D01* +X411419Y146557D01* +X400557Y157419D01* +X400557Y173228D01* +X400555Y173246D01* +X400557Y173264D01* +X400536Y173446D01* +X400517Y173629D01* +X400512Y173646D01* +X400510Y173663D01* +X400453Y173838D01* +X400399Y174014D01* +X400391Y174029D01* +X400385Y174046D01* +X400295Y174206D01* +X400207Y174368D01* +X400196Y174381D01* +X400187Y174397D01* +X400067Y174536D01* +X399950Y174677D01* +X399936Y174688D01* +X399924Y174702D01* +X399779Y174814D01* +X399636Y174929D01* +X399620Y174937D01* +X399606Y174948D01* +X399441Y175030D01* +X399279Y175115D01* +X399262Y175120D01* +X399246Y175128D01* +X399067Y175175D01* +X398892Y175226D01* +X398874Y175228D01* +X398857Y175232D01* +X398526Y175259D01* +X384598Y175259D01* +X384589Y175258D01* +X384580Y175259D01* +X384387Y175238D01* +X384198Y175219D01* +X384189Y175217D01* +X384180Y175216D01* +X383997Y175158D01* +X383813Y175101D01* +X383805Y175097D01* +X383796Y175094D01* +X383629Y175002D01* +X383459Y174909D01* +X383452Y174904D01* +X383444Y174899D01* +X383296Y174774D01* +X383149Y174652D01* +X383144Y174645D01* +X383137Y174639D01* +X383017Y174487D01* +X382897Y174338D01* +X382893Y174330D01* +X382887Y174323D01* +X382800Y174150D01* +X382712Y173981D01* +X382709Y173972D01* +X382705Y173964D01* +X382653Y173778D01* +X382600Y173594D01* +X382599Y173585D01* +X382597Y173576D01* +X382583Y173383D01* +X382567Y173192D01* +X382568Y173184D01* +X382568Y173175D01* +X382592Y172982D01* +X382614Y172793D01* +X382617Y172784D01* +X382618Y172775D01* +X382679Y172592D01* +X382739Y172410D01* +X382743Y172402D01* +X382746Y172394D01* +X382842Y172227D01* +X382937Y172059D01* +X382943Y172052D01* +X382947Y172045D01* +X383162Y171792D01* +X393920Y161033D01* +X396241Y155432D01* +X396241Y75324D01* +X396243Y75297D01* +X396241Y75271D01* +X396263Y75097D01* +X396281Y74923D01* +X396288Y74898D01* +X396292Y74871D01* +X396348Y74705D01* +X396399Y74538D01* +X396412Y74515D01* +X396420Y74490D01* +X396507Y74338D01* +X396591Y74184D01* +X396608Y74164D01* +X396621Y74141D01* +X396836Y73888D01* +X399543Y71181D01* +X399543Y55372D01* +X399545Y55354D01* +X399543Y55336D01* +X399564Y55154D01* +X399583Y54971D01* +X399588Y54954D01* +X399590Y54937D01* +X399647Y54762D01* +X399701Y54586D01* +X399709Y54571D01* +X399715Y54554D01* +X399805Y54394D01* +X399893Y54232D01* +X399904Y54219D01* +X399913Y54203D01* +X400033Y54064D01* +X400150Y53923D01* +X400164Y53912D01* +X400176Y53898D01* +X400321Y53786D01* +X400464Y53671D01* +X400480Y53663D01* +X400494Y53652D01* +X400659Y53570D01* +X400821Y53485D01* +X400838Y53480D01* +X400854Y53472D01* +X401033Y53425D01* +X401208Y53374D01* +X401226Y53372D01* +X401243Y53368D01* +X401574Y53341D01* +X407276Y53341D01* +X407303Y53343D01* +X407329Y53341D01* +X407503Y53363D01* +X407677Y53381D01* +X407702Y53388D01* +X407729Y53392D01* +X407894Y53447D01* +X408062Y53499D01* +X408085Y53512D01* +X408110Y53520D01* +X408262Y53607D01* +X408416Y53691D01* +X408436Y53708D01* +X408459Y53721D01* +X408712Y53936D01* +X411419Y56643D01* +X426781Y56643D01* +X437643Y45781D01* +X437643Y30419D01* +X426781Y19557D01* +X411419Y19557D01* +X408712Y22264D01* +X408692Y22281D01* +X408674Y22302D01* +X408536Y22409D01* +X408401Y22519D01* +X408377Y22532D01* +X408356Y22548D01* +X408199Y22626D01* +X408045Y22708D01* +X408020Y22716D01* +X407995Y22728D01* +X407826Y22773D01* +X407659Y22823D01* +X407633Y22825D01* +X407607Y22832D01* +X407276Y22859D01* +X392824Y22859D01* +X392797Y22857D01* +X392771Y22859D01* +X392597Y22837D01* +X392423Y22819D01* +X392398Y22812D01* +X392371Y22808D01* +X392205Y22752D01* +X392038Y22701D01* +X392015Y22688D01* +X391990Y22680D01* +X391838Y22593D01* +X391684Y22509D01* +X391664Y22492D01* +X391641Y22479D01* +X391388Y22264D01* +X388681Y19557D01* +X373319Y19557D01* +X367401Y25475D01* +X367388Y25487D01* +X367376Y25500D01* +X367232Y25614D01* +X367090Y25730D01* +X367074Y25739D01* +X367060Y25750D01* +X366896Y25833D01* +X366734Y25919D01* +X366717Y25924D01* +X366701Y25932D01* +X366524Y25982D01* +X366348Y26034D01* +X366331Y26035D01* +X366313Y26040D01* +X366130Y26053D01* +X365947Y26070D01* +X365930Y26068D01* +X365912Y26069D01* +X365730Y26047D01* +X365547Y26027D01* +X365530Y26021D01* +X365512Y26019D01* +X365339Y25961D01* +X365163Y25905D01* +X365148Y25897D01* +X365131Y25891D01* +X364971Y25799D01* +X364811Y25710D01* +X364797Y25699D01* +X364782Y25690D01* +X364529Y25475D01* +X364233Y25179D01* +X358632Y22859D01* +X342024Y22859D01* +X341997Y22857D01* +X341971Y22859D01* +X341797Y22837D01* +X341623Y22819D01* +X341598Y22812D01* +X341571Y22808D01* +X341406Y22753D01* +X341238Y22701D01* +X341215Y22688D01* +X341190Y22680D01* +X341038Y22593D01* +X340884Y22509D01* +X340864Y22492D01* +X340841Y22479D01* +X340588Y22264D01* +X337881Y19557D01* +X322519Y19557D01* +X319812Y22264D01* +X319792Y22281D01* +X319774Y22302D01* +X319636Y22409D01* +X319501Y22519D01* +X319477Y22532D01* +X319456Y22548D01* +X319299Y22626D01* +X319145Y22708D01* +X319120Y22716D01* +X319095Y22728D01* +X318926Y22773D01* +X318759Y22823D01* +X318733Y22825D01* +X318707Y22832D01* +X318376Y22859D01* +X303924Y22859D01* +X303897Y22857D01* +X303871Y22859D01* +X303697Y22837D01* +X303523Y22819D01* +X303498Y22812D01* +X303471Y22808D01* +X303306Y22753D01* +X303138Y22701D01* +X303115Y22688D01* +X303090Y22680D01* +X302938Y22593D01* +X302784Y22509D01* +X302764Y22492D01* +X302741Y22479D01* +X302488Y22264D01* +X299781Y19557D01* +X284419Y19557D01* +X275326Y28650D01* +X275313Y28662D01* +X275301Y28675D01* +X275157Y28789D01* +X275015Y28905D01* +X274999Y28914D01* +X274985Y28925D01* +X274821Y29008D01* +X274659Y29094D01* +X274642Y29099D01* +X274626Y29107D01* +X274449Y29156D01* +X274273Y29209D01* +X274256Y29210D01* +X274238Y29215D01* +X274055Y29228D01* +X273872Y29245D01* +X273855Y29243D01* +X273837Y29244D01* +X273655Y29221D01* +X273472Y29202D01* +X273455Y29196D01* +X273437Y29194D01* +X273264Y29136D01* +X273088Y29080D01* +X273073Y29071D01* +X273056Y29066D01* +X272896Y28974D01* +X272736Y28885D01* +X272722Y28874D01* +X272707Y28865D01* +X272454Y28650D01* +X268983Y25180D01* +X263382Y22859D01* +X240424Y22859D01* +X240397Y22857D01* +X240371Y22859D01* +X240197Y22837D01* +X240023Y22819D01* +X239998Y22812D01* +X239971Y22808D01* +X239806Y22753D01* +X239638Y22701D01* +X239615Y22688D01* +X239590Y22680D01* +X239438Y22593D01* +X239284Y22509D01* +X239264Y22492D01* +X239241Y22479D01* +X238988Y22264D01* +X236281Y19557D01* +X220919Y19557D01* +X210057Y30419D01* +X210057Y45781D01* +X220919Y56643D01* +X236281Y56643D01* +X238988Y53936D01* +X239008Y53919D01* +X239026Y53898D01* +X239164Y53791D01* +X239299Y53681D01* +X239323Y53668D01* +X239344Y53652D01* +X239501Y53574D01* +X239655Y53492D01* +X239680Y53484D01* +X239705Y53472D01* +X239874Y53427D01* +X240041Y53377D01* +X240067Y53375D01* +X240093Y53368D01* +X240424Y53341D01* +X252476Y53341D01* +X252494Y53343D01* +X252512Y53341D01* +X252694Y53362D01* +X252877Y53381D01* +X252894Y53386D01* +X252911Y53388D01* +X253086Y53445D01* +X253262Y53499D01* +X253277Y53507D01* +X253294Y53513D01* +X253454Y53603D01* +X253616Y53691D01* +X253629Y53702D01* +X253645Y53711D01* +X253784Y53831D01* +X253925Y53948D01* +X253936Y53962D01* +X253950Y53974D01* +X254062Y54119D01* +X254177Y54262D01* +X254185Y54278D01* +X254196Y54292D01* +X254278Y54457D01* +X254363Y54619D01* +X254368Y54636D01* +X254376Y54652D01* +X254423Y54831D01* +X254474Y55006D01* +X254476Y55024D01* +X254480Y55041D01* +X254507Y55372D01* +X254507Y58481D01* +X265369Y69343D01* +X281214Y69343D01* +X281230Y69338D01* +X281248Y69336D01* +X281265Y69332D01* +X281448Y69318D01* +X281631Y69302D01* +X281649Y69304D01* +X281666Y69302D01* +X281849Y69325D01* +X282031Y69345D01* +X282048Y69350D01* +X282066Y69353D01* +X282239Y69411D01* +X282415Y69467D01* +X282431Y69475D01* +X282448Y69481D01* +X282607Y69573D01* +X282767Y69661D01* +X282781Y69673D01* +X282796Y69682D01* +X283049Y69897D01* +X287576Y74423D01* +X289507Y74423D01* +X289516Y74424D01* +X289525Y74423D01* +X289717Y74444D01* +X289908Y74463D01* +X289916Y74465D01* +X289925Y74466D01* +X290108Y74524D01* +X290293Y74581D01* +X290301Y74585D01* +X290309Y74588D01* +X290477Y74681D01* +X290647Y74773D01* +X290654Y74778D01* +X290661Y74783D01* +X290808Y74907D01* +X290956Y75030D01* +X290962Y75037D01* +X290968Y75043D01* +X291087Y75194D01* +X291208Y75344D01* +X291212Y75352D01* +X291218Y75359D01* +X291306Y75532D01* +X291394Y75701D01* +X291396Y75710D01* +X291400Y75718D01* +X291452Y75904D01* +X291505Y76088D01* +X291506Y76097D01* +X291508Y76106D01* +X291522Y76299D01* +X291538Y76490D01* +X291537Y76498D01* +X291538Y76507D01* +X291513Y76700D01* +X291491Y76889D01* +X291488Y76898D01* +X291487Y76907D01* +X291426Y77090D01* +X291366Y77272D01* +X291362Y77280D01* +X291359Y77288D01* +X291263Y77455D01* +X291168Y77623D01* +X291163Y77630D01* +X291158Y77637D01* +X290943Y77890D01* +X285425Y83409D01* +X282447Y90597D01* +X282447Y98379D01* +X285425Y105567D01* +X290927Y111069D01* +X297791Y113912D01* +X297791Y113913D01* +X297792Y113913D01* +X298115Y114047D01* +X305897Y114047D01* +X313085Y111069D01* +X318587Y105567D01* +X321565Y98379D01* +X321565Y90597D01* +X318587Y83409D01* +X313085Y77907D01* +X310978Y77034D01* +X305897Y74929D01* +X301022Y74929D01* +X301013Y74928D01* +X301004Y74929D01* +X300812Y74908D01* +X300621Y74889D01* +X300612Y74887D01* +X300604Y74886D01* +X300421Y74828D01* +X300236Y74771D01* +X300228Y74767D01* +X300220Y74764D01* +X300051Y74671D01* +X299882Y74579D01* +X299875Y74574D01* +X299867Y74569D01* +X299720Y74445D01* +X299573Y74322D01* +X299567Y74315D01* +X299560Y74309D01* +X299441Y74158D01* +X299320Y74008D01* +X299316Y74000D01* +X299311Y73993D01* +X299223Y73820D01* +X299135Y73651D01* +X299133Y73642D01* +X299128Y73634D01* +X299077Y73448D01* +X299024Y73264D01* +X299023Y73255D01* +X299020Y73246D01* +X299006Y73053D01* +X298991Y72862D01* +X298992Y72854D01* +X298991Y72845D01* +X299015Y72652D01* +X299038Y72463D01* +X299040Y72454D01* +X299041Y72445D01* +X299103Y72262D01* +X299162Y72080D01* +X299167Y72072D01* +X299170Y72064D01* +X299266Y71897D01* +X299360Y71729D01* +X299366Y71722D01* +X299371Y71715D01* +X299585Y71462D01* +X303023Y68024D01* +X303023Y65531D01* +X292100Y65531D01* +X292083Y65530D01* +X292065Y65531D01* +X291882Y65510D01* +X291700Y65491D01* +X291683Y65486D01* +X291665Y65484D01* +X291490Y65427D01* +X291315Y65373D01* +X291299Y65365D01* +X291282Y65359D01* +X291122Y65269D01* +X290961Y65182D01* +X290947Y65170D01* +X290932Y65161D01* +X290792Y65041D01* +X290652Y64924D01* +X290640Y64910D01* +X290627Y64898D01* +X290514Y64753D01* +X290399Y64610D01* +X290391Y64594D01* +X290380Y64580D01* +X290298Y64415D01* +X290214Y64253D01* +X290209Y64236D01* +X290201Y64220D01* +X290153Y64042D01* +X290102Y63866D01* +X290101Y63848D01* +X290096Y63831D01* +X290069Y63500D01* +X290071Y63482D01* +X290069Y63465D01* +X290069Y63464D01* +X290091Y63282D01* +X290109Y63099D01* +X290114Y63082D01* +X290116Y63064D01* +X290173Y62890D01* +X290227Y62714D01* +X290236Y62699D01* +X290241Y62682D01* +X290332Y62521D01* +X290419Y62360D01* +X290430Y62347D01* +X290439Y62331D01* +X290559Y62192D01* +X290677Y62051D01* +X290691Y62040D01* +X290702Y62026D01* +X290847Y61914D01* +X290990Y61799D01* +X291006Y61790D01* +X291020Y61780D01* +X291185Y61698D01* +X291348Y61613D01* +X291365Y61608D01* +X291381Y61600D01* +X291559Y61552D01* +X291735Y61502D01* +X291752Y61500D01* +X291770Y61496D01* +X292100Y61469D01* +X303023Y61469D01* +X303023Y58976D01* +X301672Y57624D01* +X301660Y57611D01* +X301647Y57599D01* +X301533Y57455D01* +X301416Y57313D01* +X301408Y57297D01* +X301397Y57283D01* +X301314Y57119D01* +X301228Y56957D01* +X301223Y56940D01* +X301215Y56924D01* +X301165Y56747D01* +X301113Y56571D01* +X301111Y56554D01* +X301107Y56536D01* +X301093Y56353D01* +X301077Y56170D01* +X301079Y56153D01* +X301077Y56135D01* +X301100Y55953D01* +X301120Y55770D01* +X301125Y55753D01* +X301128Y55735D01* +X301186Y55562D01* +X301242Y55386D01* +X301250Y55371D01* +X301256Y55354D01* +X301347Y55195D01* +X301436Y55034D01* +X301448Y55020D01* +X301457Y55005D01* +X301672Y54752D01* +X302488Y53936D01* +X302508Y53919D01* +X302526Y53898D01* +X302664Y53791D01* +X302799Y53681D01* +X302823Y53668D01* +X302844Y53652D01* +X303001Y53574D01* +X303155Y53492D01* +X303180Y53484D01* +X303205Y53472D01* +X303374Y53427D01* +X303541Y53377D01* +X303567Y53375D01* +X303593Y53368D01* +X303924Y53341D01* +X318376Y53341D01* +X318403Y53343D01* +X318429Y53341D01* +X318603Y53363D01* +X318777Y53381D01* +X318802Y53388D01* +X318829Y53392D01* +X318994Y53447D01* +X319162Y53499D01* +X319185Y53512D01* +X319210Y53520D01* +X319362Y53607D01* +X319516Y53691D01* +X319536Y53708D01* +X319559Y53721D01* +X319812Y53936D01* +X322519Y56643D01* +X337881Y56643D01* +X339940Y54584D01* +X339947Y54578D01* +X339952Y54571D01* +X340102Y54451D01* +X340251Y54329D01* +X340259Y54324D01* +X340266Y54319D01* +X340436Y54230D01* +X340607Y54140D01* +X340616Y54137D01* +X340623Y54133D01* +X340808Y54080D01* +X340993Y54025D01* +X341002Y54024D01* +X341010Y54022D01* +X341201Y54006D01* +X341394Y53989D01* +X341403Y53990D01* +X341412Y53989D01* +X341601Y54011D01* +X341794Y54032D01* +X341803Y54035D01* +X341811Y54036D01* +X341993Y54095D01* +X342178Y54154D01* +X342186Y54158D01* +X342194Y54161D01* +X342363Y54256D01* +X342530Y54349D01* +X342537Y54354D01* +X342545Y54359D01* +X342691Y54485D01* +X342837Y54609D01* +X342843Y54616D01* +X342850Y54622D01* +X342967Y54773D01* +X343087Y54925D01* +X343091Y54933D01* +X343096Y54940D01* +X343182Y55112D01* +X343269Y55284D01* +X343272Y55292D01* +X343276Y55300D01* +X343326Y55486D01* +X343377Y55672D01* +X343378Y55681D01* +X343380Y55689D01* +X343407Y56020D01* +X343407Y58481D01* +X354269Y69343D01* +X360426Y69343D01* +X360444Y69345D01* +X360462Y69343D01* +X360644Y69364D01* +X360827Y69383D01* +X360844Y69388D01* +X360861Y69390D01* +X361036Y69447D01* +X361212Y69501D01* +X361227Y69509D01* +X361244Y69515D01* +X361404Y69605D01* +X361566Y69693D01* +X361579Y69704D01* +X361595Y69713D01* +X361734Y69833D01* +X361875Y69950D01* +X361886Y69964D01* +X361900Y69976D01* +X362012Y70121D01* +X362127Y70264D01* +X362135Y70280D01* +X362146Y70294D01* +X362228Y70459D01* +X362313Y70621D01* +X362318Y70638D01* +X362326Y70654D01* +X362373Y70833D01* +X362424Y71008D01* +X362426Y71026D01* +X362430Y71043D01* +X362440Y71163D01* +X365164Y73888D01* +X365181Y73908D01* +X365202Y73926D01* +X365309Y74064D01* +X365419Y74199D01* +X365432Y74223D01* +X365448Y74244D01* +X365526Y74401D01* +X365608Y74555D01* +X365616Y74580D01* +X365628Y74604D01* +X365673Y74774D01* +X365723Y74941D01* +X365725Y74967D01* +X365732Y74993D01* +X365759Y75324D01* +X365759Y145246D01* +X365757Y145272D01* +X365759Y145299D01* +X365737Y145473D01* +X365719Y145646D01* +X365712Y145672D01* +X365708Y145698D01* +X365653Y145864D01* +X365601Y146031D01* +X365588Y146055D01* +X365580Y146080D01* +X365493Y146232D01* +X365409Y146385D01* +X365392Y146406D01* +X365379Y146429D01* +X365164Y146682D01* +X362582Y149264D01* +X362561Y149281D01* +X362544Y149302D01* +X362406Y149409D01* +X362271Y149519D01* +X362247Y149532D01* +X362226Y149548D01* +X362069Y149626D01* +X361915Y149708D01* +X361889Y149716D01* +X361865Y149728D01* +X361696Y149773D01* +X361529Y149823D01* +X361502Y149825D01* +X361476Y149832D01* +X361146Y149859D01* +X342024Y149859D01* +X341997Y149857D01* +X341971Y149859D01* +X341797Y149837D01* +X341623Y149819D01* +X341598Y149812D01* +X341571Y149808D01* +X341405Y149752D01* +X341238Y149701D01* +X341215Y149688D01* +X341190Y149680D01* +X341038Y149593D01* +X340884Y149509D01* +X340864Y149492D01* +X340841Y149479D01* +X340588Y149264D01* +X337881Y146557D01* +X333567Y146557D01* +X333536Y146554D01* +X333504Y146556D01* +X333335Y146534D01* +X333166Y146517D01* +X333136Y146508D01* +X333105Y146504D01* +X332789Y146403D01* +X327644Y144271D01* +X315267Y144271D01* +X315240Y144269D01* +X315214Y144271D01* +X315040Y144249D01* +X314866Y144231D01* +X314841Y144224D01* +X314814Y144220D01* +X314648Y144165D01* +X314481Y144113D01* +X314458Y144100D01* +X314432Y144092D01* +X314281Y144005D01* +X314127Y143921D01* +X314107Y143904D01* +X314084Y143891D01* +X313831Y143676D01* +X313085Y142931D01* +X305897Y139953D01* +X298115Y139953D01* +X290927Y142931D01* +X285425Y148433D01* +X282447Y155621D01* +X282447Y163403D01* +X285425Y170591D01* +X286625Y171792D01* +X286631Y171799D01* +X286638Y171804D01* +X286759Y171955D01* +X286881Y172103D01* +X286885Y172111D01* +X286890Y172118D01* +X286979Y172288D01* +X287069Y172459D01* +X287072Y172468D01* +X287076Y172475D01* +X287129Y172660D01* +X287184Y172845D01* +X287185Y172854D01* +X287187Y172862D01* +X287203Y173053D01* +X287220Y173246D01* +X287219Y173255D01* +X287220Y173264D01* +X287198Y173453D01* +X287177Y173646D01* +X287174Y173655D01* +X287173Y173663D01* +X287114Y173845D01* +X287055Y174030D01* +X287051Y174038D01* +X287048Y174046D01* +X286954Y174213D01* +X286861Y174382D01* +X286855Y174389D01* +X286850Y174397D01* +X286725Y174542D01* +X286600Y174689D01* +X286593Y174695D01* +X286587Y174702D01* +X286437Y174818D01* +X286284Y174939D01* +X286276Y174943D01* +X286269Y174948D01* +X286099Y175033D01* +X285925Y175121D01* +X285917Y175124D01* +X285909Y175128D01* +X285723Y175177D01* +X285537Y175229D01* +X285528Y175230D01* +X285520Y175232D01* +X285189Y175259D01* +X273611Y175259D01* +X273602Y175258D01* +X273593Y175259D01* +X273401Y175238D01* +X273210Y175219D01* +X273202Y175217D01* +X273193Y175216D01* +X273010Y175158D01* +X272825Y175101D01* +X272817Y175097D01* +X272809Y175094D01* +X272641Y175001D01* +X272471Y174909D01* +X272464Y174904D01* +X272457Y174899D01* +X272309Y174774D01* +X272162Y174652D01* +X272156Y174645D01* +X272150Y174639D01* +X272030Y174487D01* +X271910Y174338D01* +X271906Y174330D01* +X271900Y174323D01* +X271813Y174151D01* +X271724Y173981D01* +X271722Y173972D01* +X271718Y173964D01* +X271666Y173778D01* +X271613Y173594D01* +X271612Y173585D01* +X271610Y173576D01* +X271596Y173384D01* +X271580Y173192D01* +X271581Y173184D01* +X271580Y173175D01* +X271605Y172982D01* +X271627Y172793D01* +X271630Y172784D01* +X271631Y172775D01* +X271692Y172592D01* +X271752Y172410D01* +X271756Y172402D01* +X271759Y172394D01* +X271854Y172228D01* +X271950Y172059D01* +X271955Y172052D01* +X271960Y172045D01* +X272175Y171792D01* +X273375Y170591D01* +X276353Y163403D01* +X276353Y155621D01* +X273375Y148433D01* +X267873Y142931D01* +X260685Y139953D01* +X252903Y139953D01* +X245715Y142931D01* +X244969Y143676D01* +X244949Y143693D01* +X244931Y143714D01* +X244793Y143821D01* +X244658Y143931D01* +X244634Y143944D01* +X244613Y143960D01* +X244456Y144038D01* +X244302Y144120D01* +X244277Y144128D01* +X244253Y144140D01* +X244083Y144185D01* +X243916Y144235D01* +X243890Y144237D01* +X243864Y144244D01* +X243533Y144271D01* +X231156Y144271D01* +X226011Y146403D01* +X225981Y146412D01* +X225953Y146426D01* +X225788Y146470D01* +X225625Y146519D01* +X225594Y146522D01* +X225564Y146530D01* +X225234Y146557D01* +X220919Y146557D01* +X218212Y149264D01* +X218192Y149281D01* +X218174Y149302D01* +X218036Y149409D01* +X217901Y149519D01* +X217877Y149532D01* +X217856Y149548D01* +X217699Y149626D01* +X217545Y149708D01* +X217520Y149716D01* +X217495Y149728D01* +X217326Y149773D01* +X217159Y149823D01* +X217133Y149825D01* +X217107Y149832D01* +X216776Y149859D01* +X197654Y149859D01* +X197628Y149857D01* +X197601Y149859D01* +X197427Y149837D01* +X197254Y149819D01* +X197228Y149812D01* +X197202Y149808D01* +X197036Y149753D01* +X196869Y149701D01* +X196845Y149688D01* +X196820Y149680D01* +X196668Y149593D01* +X196515Y149509D01* +X196494Y149492D01* +X196471Y149479D01* +X196218Y149264D01* +X180936Y133982D01* +X180919Y133961D01* +X180898Y133944D01* +X180791Y133806D01* +X180681Y133671D01* +X180668Y133647D01* +X180652Y133626D01* +X180574Y133469D01* +X180492Y133315D01* +X180484Y133289D01* +X180472Y133265D01* +X180427Y133096D01* +X180377Y132929D01* +X180375Y132902D01* +X180368Y132876D01* +X180341Y132546D01* +X180341Y94131D01* +X180343Y94104D01* +X180341Y94077D01* +X180363Y93903D01* +X180381Y93730D01* +X180388Y93704D01* +X180392Y93678D01* +X180447Y93512D01* +X180499Y93345D01* +X180512Y93321D01* +X180520Y93296D01* +X180607Y93145D01* +X180691Y92991D01* +X180708Y92971D01* +X180721Y92947D01* +X180936Y92694D01* +X184480Y89150D01* +X187961Y80747D01* +X187961Y71653D01* +X184480Y63250D01* +X178050Y56820D01* +X177813Y56721D01* +X169647Y53339D01* +X160553Y53339D01* +X152150Y56820D01* +X145720Y63250D01* +X142239Y71653D01* +X142239Y80747D01* +X145720Y89150D01* +X149264Y92694D01* +X149281Y92715D01* +X149302Y92732D01* +X149409Y92870D01* +X149519Y93006D01* +X149532Y93029D01* +X149548Y93051D01* +X149626Y93208D01* +X149708Y93362D01* +X149716Y93387D01* +X149728Y93411D01* +X149773Y93581D01* +X149823Y93747D01* +X149825Y93774D01* +X149832Y93800D01* +X149859Y94131D01* +X149859Y124460D01* +X149857Y124478D01* +X149859Y124496D01* +X149838Y124678D01* +X149819Y124861D01* +X149814Y124878D01* +X149812Y124895D01* +X149755Y125070D01* +X149701Y125246D01* +X149693Y125261D01* +X149687Y125278D01* +X149597Y125438D01* +X149509Y125600D01* +X149498Y125613D01* +X149489Y125629D01* +X149369Y125768D01* +X149252Y125909D01* +X149238Y125920D01* +X149226Y125934D01* +X149081Y126046D01* +X148938Y126161D01* +X148922Y126169D01* +X148908Y126180D01* +X148743Y126262D01* +X148581Y126347D01* +X148564Y126352D01* +X148548Y126360D01* +X148369Y126407D01* +X148194Y126458D01* +X148176Y126460D01* +X148159Y126464D01* +X147828Y126491D01* +X115343Y126491D01* +X115329Y126490D01* +X115316Y126491D01* +X115130Y126470D01* +X114942Y126451D01* +X114929Y126447D01* +X114916Y126446D01* +X114737Y126388D01* +X114557Y126333D01* +X114545Y126327D01* +X114533Y126323D01* +X114368Y126231D01* +X114203Y126141D01* +X114193Y126133D01* +X114181Y126126D01* +X114038Y126004D01* +X113894Y125884D01* +X113886Y125873D01* +X113875Y125865D01* +X113759Y125716D01* +X113642Y125570D01* +X113635Y125558D01* +X113627Y125548D01* +X113542Y125379D01* +X113456Y125213D01* +X113452Y125200D01* +X113446Y125188D01* +X113396Y125005D01* +X113345Y124826D01* +X113344Y124812D01* +X113340Y124799D01* +X113327Y124611D01* +X113312Y124424D01* +X113313Y124411D01* +X113312Y124398D01* +X113337Y124210D01* +X113359Y124025D01* +X113363Y124012D01* +X113365Y123999D01* +X113466Y123683D01* +X115825Y117988D01* +X115825Y110612D01* +X113002Y103796D01* +X112242Y103036D01* +X112230Y103023D01* +X112217Y103011D01* +X112103Y102867D01* +X111987Y102725D01* +X111978Y102709D01* +X111967Y102695D01* +X111884Y102531D01* +X111798Y102369D01* +X111793Y102352D01* +X111785Y102336D01* +X111736Y102159D01* +X111683Y101983D01* +X111682Y101965D01* +X111677Y101948D01* +X111663Y101765D01* +X111647Y101582D01* +X111649Y101564D01* +X111647Y101547D01* +X111670Y101365D01* +X111690Y101182D01* +X111696Y101165D01* +X111698Y101147D01* +X111756Y100974D01* +X111812Y100798D01* +X111820Y100782D01* +X111826Y100766D01* +X111918Y100607D01* +X112007Y100446D01* +X112018Y100432D01* +X112027Y100417D01* +X112242Y100164D01* +X113002Y99404D01* +X115825Y92588D01* +X115825Y85212D01* +X113002Y78396D01* +X112242Y77636D01* +X112230Y77623D01* +X112217Y77611D01* +X112103Y77467D01* +X111987Y77325D01* +X111978Y77309D01* +X111967Y77295D01* +X111884Y77131D01* +X111798Y76969D01* +X111793Y76952D01* +X111785Y76936D01* +X111736Y76759D01* +X111683Y76583D01* +X111682Y76565D01* +X111677Y76548D01* +X111663Y76365D01* +X111647Y76182D01* +X111649Y76164D01* +X111647Y76147D01* +X111670Y75965D01* +X111690Y75782D01* +X111696Y75765D01* +X111698Y75747D01* +X111756Y75574D01* +X111812Y75398D01* +X111820Y75382D01* +X111826Y75366D01* +X111918Y75207D01* +X112007Y75046D01* +X112018Y75032D01* +X112027Y75017D01* +X112242Y74764D01* +X113002Y74004D01* +X115825Y67188D01* +X115825Y59812D01* +X113002Y52996D01* +X112242Y52236D01* +X112230Y52223D01* +X112217Y52211D01* +X112103Y52067D01* +X111987Y51925D01* +X111978Y51909D01* +X111967Y51895D01* +X111884Y51731D01* +X111798Y51569D01* +X111793Y51552D01* +X111785Y51536D01* +X111736Y51359D01* +X111683Y51183D01* +X111682Y51165D01* +X111677Y51148D01* +X111663Y50965D01* +X111647Y50782D01* +X111649Y50764D01* +X111647Y50747D01* +X111671Y50564D01* +X111690Y50382D01* +X111696Y50365D01* +X111698Y50347D01* +X111756Y50174D01* +X111812Y49998D01* +X111820Y49982D01* +X111826Y49966D01* +X111918Y49807D01* +X112007Y49646D01* +X112018Y49632D01* +X112027Y49617D01* +X112242Y49364D01* +X113002Y48604D01* +X115825Y41788D01* +X115825Y34412D01* +X113002Y27596D01* +X107786Y22380D01* +X107064Y22081D01* +X107015Y22055D01* +X106963Y22036D01* +X106838Y21960D01* +X106709Y21891D01* +X106666Y21856D01* +X106619Y21827D01* +X106512Y21728D01* +X106399Y21635D01* +X106364Y21592D01* +X106323Y21554D01* +X106237Y21436D01* +X106145Y21322D01* +X106119Y21273D01* +X106087Y21228D01* +X106026Y21095D01* +X105958Y20966D01* +X105942Y20912D01* +X105919Y20862D01* +X105886Y20720D01* +X105845Y20579D01* +X105840Y20524D01* +X105828Y20470D01* +X105823Y20324D01* +X105810Y20178D01* +X105817Y20123D01* +X105815Y20067D01* +X105839Y19923D01* +X105856Y19778D01* +X105873Y19725D01* +X105882Y19670D01* +X105934Y19534D01* +X105979Y19395D01* +X106006Y19346D01* +X106026Y19294D01* +X106137Y19111D01* +X106175Y19043D01* +X106187Y19030D01* +X106198Y19011D01* +X106624Y18425D01* +X107404Y16893D01* +X107936Y15258D01* +X108019Y14731D01* +X88900Y14731D01* +X69781Y14731D01* +X69864Y15258D01* +X70396Y16893D01* +X71176Y18425D01* +X71602Y19011D01* +X71630Y19059D01* +X71665Y19102D01* +X71731Y19232D01* +X71805Y19358D01* +X71823Y19411D01* +X71849Y19460D01* +X71888Y19601D01* +X71936Y19739D01* +X71943Y19794D01* +X71958Y19848D01* +X71969Y19994D01* +X71989Y20138D01* +X71985Y20194D01* +X71989Y20249D01* +X71972Y20394D01* +X71962Y20540D01* +X71947Y20594D01* +X71941Y20649D01* +X71895Y20788D01* +X71856Y20929D01* +X71832Y20978D01* +X71814Y21031D01* +X71742Y21158D01* +X71676Y21289D01* +X71642Y21332D01* +X71615Y21381D01* +X71518Y21491D01* +X71429Y21606D01* +X71387Y21642D01* +X71350Y21684D01* +X71234Y21774D01* +X71124Y21869D01* +X71075Y21896D01* +X71031Y21930D01* +X70840Y22028D01* +X70773Y22066D01* +X70756Y22071D01* +X70736Y22081D01* +X70014Y22380D01* +X64798Y27596D01* +X61975Y34412D01* +X61975Y41788D01* +X64798Y48604D01* +X65558Y49364D01* +X65570Y49378D01* +X65583Y49389D01* +X65697Y49533D01* +X65813Y49675D01* +X65822Y49691D01* +X65833Y49705D01* +X65916Y49869D01* +X66002Y50031D01* +X66007Y50048D01* +X66015Y50064D01* +X66064Y50241D01* +X66117Y50417D01* +X66118Y50435D01* +X66123Y50452D01* +X66137Y50635D01* +X66153Y50818D01* +X66151Y50836D01* +X66153Y50853D01* +X66130Y51035D01* +X66110Y51218D01* +X66104Y51235D01* +X66102Y51253D01* +X66044Y51426D01* +X65988Y51602D01* +X65980Y51618D01* +X65974Y51634D01* +X65882Y51794D01* +X65793Y51954D01* +X65782Y51968D01* +X65773Y51983D01* +X65558Y52236D01* +X64798Y52996D01* +X61975Y59812D01* +X61975Y67188D01* +X64798Y74004D01* +X65558Y74764D01* +X65570Y74778D01* +X65583Y74789D01* +X65697Y74933D01* +X65813Y75075D01* +X65822Y75091D01* +X65833Y75105D01* +X65916Y75269D01* +X66002Y75431D01* +X66007Y75448D01* +X66015Y75464D01* +X66064Y75641D01* +X66117Y75817D01* +X66118Y75835D01* +X66123Y75852D01* +X66137Y76035D01* +X66153Y76218D01* +X66151Y76236D01* +X66153Y76253D01* +X66130Y76435D01* +X66110Y76618D01* +X66104Y76635D01* +X66102Y76653D01* +X66044Y76826D01* +X65988Y77002D01* +X65980Y77018D01* +X65974Y77034D01* +X65882Y77194D01* +X65793Y77354D01* +X65782Y77368D01* +X65773Y77383D01* +X65558Y77636D01* +X64798Y78396D01* +X61975Y85212D01* +X61975Y92588D01* +X64798Y99404D01* +X65558Y100164D01* +X65570Y100178D01* +X65583Y100189D01* +X65697Y100333D01* +X65813Y100475D01* +X65822Y100491D01* +X65833Y100505D01* +X65916Y100669D01* +X66002Y100831D01* +X66007Y100848D01* +X66015Y100864D01* +X66064Y101041D01* +X66117Y101217D01* +X66118Y101235D01* +X66123Y101252D01* +X66137Y101435D01* +X66153Y101618D01* +X66151Y101636D01* +X66153Y101653D01* +X66130Y101835D01* +X66110Y102018D01* +X66104Y102035D01* +X66102Y102053D01* +X66044Y102226D01* +X65988Y102402D01* +X65980Y102418D01* +X65974Y102434D01* +X65882Y102594D01* +X65793Y102754D01* +X65782Y102768D01* +X65773Y102783D01* +X65558Y103036D01* +X64798Y103796D01* +X61975Y110612D01* +X61975Y117988D01* +X64798Y124804D01* +X65558Y125564D01* +X65570Y125578D01* +X65583Y125589D01* +X65697Y125733D01* +X65813Y125875D01* +X65822Y125891D01* +X65833Y125905D01* +X65916Y126069D01* +X66002Y126231D01* +X66007Y126248D01* +X66015Y126264D01* +X66064Y126441D01* +X66117Y126617D01* +X66118Y126635D01* +X66123Y126652D01* +X66137Y126835D01* +X66153Y127018D01* +X66151Y127036D01* +X66153Y127053D01* +X66130Y127235D01* +X66110Y127418D01* +X66104Y127435D01* +X66102Y127453D01* +X66044Y127626D01* +X65988Y127802D01* +X65980Y127818D01* +X65974Y127834D01* +X65882Y127994D01* +X65793Y128154D01* +X65782Y128168D01* +X65773Y128183D01* +X65558Y128436D01* +X64798Y129196D01* +X61975Y136012D01* +X61975Y143388D01* +X64798Y150204D01* +X65558Y150964D01* +X65570Y150978D01* +X65583Y150989D01* +X65697Y151133D01* +X65813Y151275D01* +X65822Y151291D01* +X65833Y151305D01* +X65916Y151469D01* +X66002Y151631D01* +X66007Y151648D01* +X66015Y151664D01* +X66064Y151841D01* +X66117Y152017D01* +X66118Y152035D01* +X66123Y152052D01* +X66137Y152235D01* +X66153Y152418D01* +X66151Y152436D01* +X66153Y152453D01* +X66130Y152635D01* +X66110Y152818D01* +X66104Y152835D01* +X66102Y152853D01* +X66044Y153026D01* +X65988Y153202D01* +X65980Y153218D01* +X65974Y153234D01* +X65882Y153394D01* +X65793Y153554D01* +X65782Y153568D01* +X65773Y153583D01* +X65558Y153836D01* +X64798Y154596D01* +X61975Y161412D01* +X61975Y168788D01* +X64798Y175604D01* +X65558Y176364D01* +X65570Y176378D01* +X65583Y176389D01* +X65697Y176533D01* +X65813Y176675D01* +X65822Y176691D01* +X65833Y176705D01* +X65916Y176869D01* +X66002Y177031D01* +X66007Y177048D01* +X66015Y177064D01* +X66064Y177241D01* +X66117Y177417D01* +X66118Y177435D01* +X66123Y177452D01* +X66137Y177635D01* +X66153Y177818D01* +X66151Y177836D01* +X66153Y177853D01* +X66130Y178035D01* +X66110Y178218D01* +X66104Y178235D01* +X66102Y178253D01* +X66044Y178426D01* +X65988Y178602D01* +X65980Y178618D01* +X65974Y178634D01* +X65882Y178794D01* +X65793Y178954D01* +X65782Y178968D01* +X65773Y178983D01* +X65558Y179236D01* +X64798Y179996D01* +X61975Y186812D01* +X61975Y194188D01* +X64230Y199631D01* +X64233Y199644D01* +X64240Y199655D01* +X64292Y199836D01* +X64346Y200016D01* +X64347Y200029D01* +X64351Y200042D01* +X64366Y200230D01* +X64384Y200417D01* +X64383Y200430D01* +X64384Y200444D01* +X64362Y200631D01* +X64342Y200817D01* +X64339Y200830D01* +X64337Y200843D01* +X64278Y201023D01* +X64223Y201202D01* +X64216Y201213D01* +X64212Y201226D01* +X64119Y201391D01* +X64029Y201555D01* +X64021Y201565D01* +X64014Y201577D01* +X63891Y201719D01* +X63770Y201863D01* +X63760Y201871D01* +X63751Y201882D01* +X63603Y201997D01* +X63455Y202114D01* +X63444Y202120D01* +X63433Y202128D01* +X63264Y202212D01* +X63097Y202298D01* +X63084Y202302D01* +X63072Y202308D01* +X62889Y202357D01* +X62710Y202408D01* +X62697Y202409D01* +X62684Y202412D01* +X62353Y202439D01* +X12192Y202439D01* +X12174Y202437D01* +X12156Y202439D01* +X11974Y202418D01* +X11791Y202399D01* +X11774Y202394D01* +X11757Y202392D01* +X11582Y202335D01* +X11406Y202281D01* +X11391Y202273D01* +X11374Y202267D01* +X11214Y202177D01* +X11052Y202089D01* +X11039Y202078D01* +X11023Y202069D01* +X10884Y201949D01* +X10743Y201832D01* +X10732Y201818D01* +X10718Y201806D01* +X10606Y201661D01* +X10491Y201518D01* +X10483Y201502D01* +X10472Y201488D01* +X10390Y201323D01* +X10305Y201161D01* +X10300Y201144D01* +X10292Y201128D01* +X10245Y200949D01* +X10194Y200774D01* +X10192Y200756D01* +X10188Y200739D01* +X10161Y200408D01* +X10161Y12192D01* +X10163Y12174D01* +X10161Y12156D01* +X10182Y11974D01* +X10201Y11791D01* +X10206Y11774D01* +X10208Y11757D01* +X10265Y11582D01* +X10319Y11406D01* +X10327Y11391D01* +X10333Y11374D01* +X10423Y11214D01* +X10511Y11052D01* +X10522Y11039D01* +X10531Y11023D01* +X10651Y10884D01* +X10768Y10743D01* +X10782Y10732D01* +X10794Y10718D01* +X10939Y10606D01* +X11082Y10491D01* +X11098Y10483D01* +X11112Y10472D01* +X11277Y10390D01* +X11439Y10305D01* +X11456Y10300D01* +X11472Y10292D01* +X11651Y10245D01* +X11826Y10194D01* +X11844Y10192D01* +X11861Y10188D01* +X12192Y10161D01* +X67564Y10161D01* +X67582Y10163D01* +G37* +G36* +X480729Y104142D02* +X480729Y104142D01* +X480742Y104141D01* +X480928Y104162D01* +X481116Y104181D01* +X481129Y104185D01* +X481142Y104186D01* +X481321Y104244D01* +X481501Y104299D01* +X481513Y104305D01* +X481526Y104309D01* +X481690Y104401D01* +X481855Y104491D01* +X481865Y104499D01* +X481877Y104506D01* +X482020Y104628D01* +X482164Y104748D01* +X482173Y104759D01* +X482183Y104767D01* +X482299Y104916D01* +X482417Y105062D01* +X482423Y105074D01* +X482431Y105084D01* +X482516Y105253D01* +X482602Y105419D01* +X482606Y105432D01* +X482612Y105444D01* +X482662Y105626D01* +X482714Y105806D01* +X482715Y105820D01* +X482718Y105833D01* +X482731Y106021D01* +X482747Y106208D01* +X482745Y106221D01* +X482746Y106234D01* +X482721Y106422D01* +X482700Y106607D01* +X482696Y106620D01* +X482694Y106633D01* +X482592Y106949D01* +X481075Y110612D01* +X481075Y117988D01* +X483898Y124804D01* +X489114Y130020D01* +X489459Y130162D01* +X489459Y130163D01* +X495930Y132843D01* +X520070Y132843D01* +X526936Y129999D01* +X526946Y129991D01* +X527081Y129881D01* +X527105Y129868D01* +X527126Y129852D01* +X527283Y129774D01* +X527437Y129692D01* +X527462Y129684D01* +X527487Y129672D01* +X527656Y129627D01* +X527823Y129577D01* +X527849Y129575D01* +X527875Y129568D01* +X528206Y129541D01* +X554800Y129541D01* +X554813Y129542D01* +X554827Y129541D01* +X555013Y129562D01* +X555201Y129581D01* +X555213Y129585D01* +X555227Y129586D01* +X555406Y129644D01* +X555585Y129699D01* +X555597Y129705D01* +X555610Y129709D01* +X555775Y129801D01* +X555939Y129891D01* +X555950Y129899D01* +X555961Y129906D01* +X556104Y130028D01* +X556249Y130148D01* +X556257Y130159D01* +X556267Y130167D01* +X556383Y130315D01* +X556501Y130462D01* +X556507Y130474D01* +X556516Y130484D01* +X556600Y130653D01* +X556687Y130819D01* +X556690Y130832D01* +X556696Y130844D01* +X556746Y131025D01* +X556798Y131206D01* +X556799Y131220D01* +X556803Y131233D01* +X556816Y131421D01* +X556831Y131608D01* +X556829Y131621D01* +X556830Y131634D01* +X556806Y131822D01* +X556784Y132007D01* +X556780Y132020D01* +X556778Y132033D01* +X556677Y132349D01* +X555243Y135810D01* +X555243Y143591D01* +X558221Y150779D01* +X558405Y150964D01* +X558417Y150977D01* +X558430Y150989D01* +X558544Y151133D01* +X558660Y151275D01* +X558669Y151291D01* +X558680Y151305D01* +X558763Y151469D01* +X558849Y151631D01* +X558854Y151648D01* +X558862Y151664D01* +X558912Y151841D01* +X558964Y152017D01* +X558965Y152034D01* +X558970Y152052D01* +X558984Y152235D01* +X559000Y152418D01* +X558998Y152435D01* +X559000Y152453D01* +X558977Y152636D01* +X558957Y152818D01* +X558952Y152835D01* +X558949Y152853D01* +X558891Y153027D01* +X558835Y153202D01* +X558827Y153217D01* +X558821Y153234D01* +X558729Y153394D01* +X558641Y153554D01* +X558629Y153568D01* +X558620Y153583D01* +X558405Y153836D01* +X558221Y154021D01* +X555243Y161209D01* +X555243Y168990D01* +X556677Y172451D01* +X556680Y172464D01* +X556687Y172475D01* +X556738Y172655D01* +X556793Y172836D01* +X556794Y172849D01* +X556798Y172862D01* +X556813Y173050D01* +X556831Y173237D01* +X556830Y173250D01* +X556831Y173264D01* +X556809Y173450D01* +X556790Y173637D01* +X556785Y173650D01* +X556784Y173663D01* +X556726Y173842D01* +X556670Y174022D01* +X556663Y174033D01* +X556659Y174046D01* +X556566Y174211D01* +X556476Y174375D01* +X556468Y174385D01* +X556461Y174397D01* +X556338Y174539D01* +X556217Y174683D01* +X556207Y174691D01* +X556198Y174702D01* +X556050Y174816D01* +X555902Y174934D01* +X555890Y174940D01* +X555880Y174948D01* +X555712Y175032D01* +X555544Y175118D01* +X555531Y175122D01* +X555519Y175128D01* +X555337Y175177D01* +X555157Y175228D01* +X555144Y175229D01* +X555131Y175232D01* +X554800Y175259D01* +X473850Y175259D01* +X473841Y175258D01* +X473832Y175259D01* +X473640Y175238D01* +X473449Y175219D01* +X473441Y175217D01* +X473432Y175216D01* +X473249Y175158D01* +X473064Y175101D01* +X473057Y175097D01* +X473048Y175094D01* +X472879Y175001D01* +X472710Y174909D01* +X472704Y174904D01* +X472696Y174899D01* +X472548Y174774D01* +X472401Y174652D01* +X472396Y174645D01* +X472389Y174639D01* +X472269Y174487D01* +X472149Y174338D01* +X472145Y174330D01* +X472139Y174323D01* +X472051Y174150D01* +X471963Y173981D01* +X471961Y173972D01* +X471957Y173964D01* +X471905Y173779D01* +X471852Y173594D01* +X471851Y173585D01* +X471849Y173576D01* +X471835Y173384D01* +X471819Y173192D01* +X471820Y173184D01* +X471819Y173175D01* +X471844Y172983D01* +X471866Y172793D01* +X471869Y172784D01* +X471870Y172775D01* +X471931Y172593D01* +X471991Y172410D01* +X471995Y172402D01* +X471998Y172394D01* +X472094Y172226D01* +X472189Y172059D01* +X472195Y172052D01* +X472199Y172045D01* +X472414Y171792D01* +X472920Y171286D01* +X475743Y164470D01* +X475743Y140330D01* +X472899Y133464D01* +X472891Y133454D01* +X472781Y133319D01* +X472768Y133295D01* +X472752Y133274D01* +X472674Y133117D01* +X472592Y132963D01* +X472584Y132938D01* +X472572Y132913D01* +X472527Y132744D01* +X472477Y132577D01* +X472475Y132551D01* +X472468Y132525D01* +X472441Y132194D01* +X472441Y108754D01* +X472443Y108728D01* +X472441Y108701D01* +X472463Y108527D01* +X472481Y108354D01* +X472488Y108328D01* +X472492Y108302D01* +X472547Y108136D01* +X472599Y107969D01* +X472612Y107945D01* +X472620Y107920D01* +X472707Y107768D01* +X472791Y107615D01* +X472808Y107594D01* +X472821Y107571D01* +X473036Y107318D01* +X475618Y104736D01* +X475639Y104719D01* +X475656Y104698D01* +X475794Y104591D01* +X475929Y104481D01* +X475953Y104468D01* +X475974Y104452D01* +X476131Y104374D01* +X476285Y104292D01* +X476311Y104284D01* +X476335Y104272D01* +X476504Y104227D01* +X476671Y104177D01* +X476698Y104175D01* +X476724Y104168D01* +X477054Y104141D01* +X480716Y104141D01* +X480729Y104142D01* +G37* +%LPC*% +G36* +X252903Y74929D02* +X252903Y74929D01* +X245715Y77907D01* +X240213Y83409D01* +X237235Y90597D01* +X237235Y98379D01* +X240213Y105567D01* +X245715Y111069D01* +X252579Y113912D01* +X252579Y113913D01* +X252580Y113913D01* +X252903Y114047D01* +X260685Y114047D01* +X267873Y111069D01* +X273375Y105567D01* +X276353Y98379D01* +X276353Y90597D01* +X273375Y83409D01* +X267873Y77907D01* +X265766Y77034D01* +X260685Y74929D01* +X252903Y74929D01* +G37* +%LPD*% +G36* +X155940Y152911D02* +X155940Y152911D01* +X155967Y152909D01* +X156141Y152931D01* +X156314Y152949D01* +X156340Y152956D01* +X156366Y152960D01* +X156532Y153015D01* +X156699Y153067D01* +X156723Y153080D01* +X156748Y153088D01* +X156900Y153175D01* +X157053Y153259D01* +X157074Y153276D01* +X157097Y153289D01* +X157350Y153504D01* +X175638Y171792D01* +X175644Y171799D01* +X175651Y171804D01* +X175771Y171954D01* +X175893Y172103D01* +X175897Y172111D01* +X175903Y172118D01* +X175992Y172289D01* +X176082Y172459D01* +X176084Y172467D01* +X176088Y172475D01* +X176142Y172661D01* +X176197Y172845D01* +X176197Y172854D01* +X176200Y172862D01* +X176215Y173054D01* +X176233Y173246D01* +X176232Y173255D01* +X176233Y173264D01* +X176211Y173453D01* +X176190Y173646D01* +X176187Y173655D01* +X176186Y173663D01* +X176126Y173845D01* +X176068Y174030D01* +X176064Y174038D01* +X176061Y174046D01* +X175966Y174215D01* +X175873Y174382D01* +X175867Y174389D01* +X175863Y174397D01* +X175737Y174543D01* +X175613Y174689D01* +X175606Y174695D01* +X175600Y174702D01* +X175448Y174819D01* +X175297Y174939D01* +X175289Y174943D01* +X175282Y174948D01* +X175110Y175034D01* +X174938Y175121D01* +X174929Y175124D01* +X174921Y175128D01* +X174735Y175178D01* +X174550Y175229D01* +X174541Y175230D01* +X174532Y175232D01* +X174202Y175259D01* +X116184Y175259D01* +X116171Y175258D01* +X116158Y175259D01* +X115972Y175238D01* +X115784Y175219D01* +X115771Y175215D01* +X115758Y175214D01* +X115578Y175156D01* +X115399Y175101D01* +X115387Y175095D01* +X115374Y175091D01* +X115210Y174999D01* +X115045Y174909D01* +X115035Y174901D01* +X115023Y174894D01* +X114880Y174772D01* +X114736Y174652D01* +X114727Y174641D01* +X114717Y174633D01* +X114601Y174484D01* +X114483Y174338D01* +X114477Y174326D01* +X114469Y174316D01* +X114384Y174146D01* +X114298Y173981D01* +X114294Y173968D01* +X114288Y173956D01* +X114238Y173773D01* +X114186Y173594D01* +X114185Y173580D01* +X114182Y173567D01* +X114169Y173379D01* +X114153Y173192D01* +X114155Y173179D01* +X114154Y173166D01* +X114179Y172978D01* +X114200Y172793D01* +X114204Y172780D01* +X114206Y172767D01* +X114308Y172451D01* +X115825Y168788D01* +X115825Y161412D01* +X113466Y155717D01* +X113462Y155704D01* +X113456Y155693D01* +X113404Y155512D01* +X113350Y155332D01* +X113348Y155319D01* +X113345Y155306D01* +X113329Y155118D01* +X113311Y154931D01* +X113313Y154918D01* +X113312Y154904D01* +X113334Y154717D01* +X113353Y154531D01* +X113357Y154518D01* +X113359Y154505D01* +X113417Y154325D01* +X113473Y154146D01* +X113479Y154135D01* +X113484Y154122D01* +X113576Y153957D01* +X113666Y153793D01* +X113675Y153783D01* +X113681Y153771D01* +X113804Y153629D01* +X113925Y153485D01* +X113936Y153477D01* +X113945Y153466D01* +X114093Y153351D01* +X114240Y153234D01* +X114252Y153228D01* +X114263Y153220D01* +X114431Y153136D01* +X114598Y153050D01* +X114611Y153046D01* +X114623Y153040D01* +X114806Y152991D01* +X114986Y152940D01* +X114999Y152939D01* +X115012Y152936D01* +X115343Y152909D01* +X155914Y152909D01* +X155940Y152911D01* +G37* +%LPC*% +G36* +X459231Y52831D02* +X459231Y52831D01* +X459231Y69919D01* +X459758Y69836D01* +X461393Y69304D01* +X462925Y68524D01* +X464316Y67513D01* +X465531Y66298D01* +X466542Y64907D01* +X467322Y63375D01* +X467854Y61740D01* +X468123Y60042D01* +X468123Y52831D01* +X459231Y52831D01* +G37* +%LPD*% +%LPC*% +G36* +X459231Y48769D02* +X459231Y48769D01* +X468123Y48769D01* +X468123Y41558D01* +X467854Y39860D01* +X467322Y38225D01* +X466542Y36693D01* +X465531Y35302D01* +X464316Y34087D01* +X462925Y33076D01* +X461393Y32296D01* +X459758Y31764D01* +X459231Y31681D01* +X459231Y48769D01* +G37* +%LPD*% +%LPC*% +G36* +X510031Y52577D02* +X510031Y52577D01* +X510031Y61469D01* +X527119Y61469D01* +X527036Y60942D01* +X526504Y59307D01* +X525724Y57775D01* +X524713Y56384D01* +X523498Y55169D01* +X522107Y54158D01* +X520575Y53378D01* +X518940Y52846D01* +X517242Y52577D01* +X510031Y52577D01* +G37* +%LPD*% +%LPC*% +G36* +X446277Y52831D02* +X446277Y52831D01* +X446277Y60042D01* +X446546Y61740D01* +X447078Y63375D01* +X447858Y64907D01* +X448869Y66298D01* +X450084Y67513D01* +X451475Y68524D01* +X453007Y69304D01* +X454642Y69836D01* +X455169Y69919D01* +X455169Y52831D01* +X446277Y52831D01* +G37* +%LPD*% +%LPC*% +G36* +X498758Y52577D02* +X498758Y52577D01* +X497060Y52846D01* +X495425Y53378D01* +X493893Y54158D01* +X492502Y55169D01* +X491287Y56384D01* +X490276Y57775D01* +X489496Y59307D01* +X488964Y60942D01* +X488881Y61469D01* +X505969Y61469D01* +X505969Y52577D01* +X498758Y52577D01* +G37* +%LPD*% +%LPC*% +G36* +X454642Y31764D02* +X454642Y31764D01* +X453007Y32296D01* +X451475Y33076D01* +X450084Y34087D01* +X448869Y35302D01* +X447858Y36693D01* +X447078Y38225D01* +X446546Y39860D01* +X446277Y41558D01* +X446277Y48769D01* +X455169Y48769D01* +X455169Y31681D01* +X454642Y31764D01* +G37* +%LPD*% +%LPC*% +G36* +X167639Y27939D02* +X167639Y27939D01* +X167639Y40641D01* +X171413Y40641D01* +X180341Y31713D01* +X180341Y27939D01* +X167639Y27939D01* +G37* +%LPD*% +%LPC*% +G36* +X149859Y27939D02* +X149859Y27939D01* +X149859Y31713D01* +X158787Y40641D01* +X162561Y40641D01* +X162561Y27939D01* +X149859Y27939D01* +G37* +%LPD*% +D10* +X292100Y63500D03* +X273050Y50800D03* +X292100Y38100D03* +X381000Y63500D03* +X361950Y50800D03* +X381000Y38100D03* +D11* +X165100Y76200D03* +D12* +X165100Y25400D03* +D13* +X228600Y165100D03* +X228600Y38100D03* +D10* +X330200Y38100D03* +X330200Y165100D03* +D14* +X457200Y160782D02* +X457200Y144018D01* +X457200Y59182D02* +X457200Y42418D01* +D10* +X419100Y38100D03* +X419100Y165100D03* +D14* +X499618Y88900D02* +X516382Y88900D01* +X516382Y114300D02* +X499618Y114300D01* +X499618Y63500D02* +X516382Y63500D01* +X97282Y190500D02* +X80518Y190500D01* +X80518Y165100D02* +X97282Y165100D01* +X97282Y139700D02* +X80518Y139700D01* +X80518Y114300D02* +X97282Y114300D01* +X97282Y88900D02* +X80518Y88900D01* +X80518Y63500D02* +X97282Y63500D01* +X97282Y38100D02* +X80518Y38100D01* +X80518Y12700D02* +X97282Y12700D01* +D15* +X574802Y12700D02* +X593598Y12700D01* +X593598Y38100D02* +X574802Y38100D01* +X574802Y63500D02* +X593598Y63500D01* +X593598Y88900D02* +X574802Y88900D01* +X574802Y114300D02* +X593598Y114300D01* +X593598Y139700D02* +X574802Y139700D01* +X574802Y165100D02* +X593598Y165100D01* +X593598Y190500D02* +X574802Y190500D01* +D16* +X302006Y159512D03* +X302006Y94488D03* +X256794Y159512D03* +X256794Y94488D03* +D17* +X165100Y12700D02* +X88900Y12700D01* +X165100Y12700D02* +X203200Y12700D01* +X457200Y12700D01* +X508000Y12700D01* +X584200Y12700D01* +X165100Y12700D02* +X165100Y25400D01* +X508000Y12700D02* +X508000Y63500D01* +X457200Y50800D02* +X457200Y12700D01* +X292100Y63500D02* +X279400Y76200D01* +X215900Y76200D01* +X203200Y63500D01* +X203200Y12700D01* +X330200Y190500D02* +X584200Y190500D01* +X381000Y152400D02* +X381000Y63500D01* +X381000Y152400D02* +X368300Y165100D01* +X330200Y165100D01* +X324612Y159512D02* +X302006Y159512D01* +X324612Y159512D02* +X330200Y165100D01* +X330200Y190500D02* +X88900Y190500D01* +X330200Y190500D02* +X330200Y165100D01* +X165100Y139700D02* +X165100Y76200D01* +X165100Y139700D02* +X190500Y165100D01* +X228600Y165100D01* +X234188Y159512D02* +X256794Y159512D01* +X234188Y159512D02* +X228600Y165100D01* +D18* +X165100Y139700D02* +X88900Y139700D01* +D17* +X228600Y38100D02* +X260350Y38100D01* +X273050Y50800D01* +X292100Y38100D02* +X330200Y38100D01* +X361950Y44450D02* +X361950Y50800D01* +X361950Y44450D02* +X355600Y38100D01* +X330200Y38100D01* +X419100Y165100D02* +X444500Y165100D01* +X457200Y152400D01* +X469900Y88900D02* +X508000Y88900D01* +X469900Y88900D02* +X457200Y101600D01* +X457200Y152400D01* +X508000Y114300D02* +X584200Y114300D01* +X419100Y38100D02* +X381000Y38100D01* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/copper_top.gbr b/gerbonara/gerber/tests/resources/eagle-newer/copper_top.gbr new file mode 100644 index 0000000..fbbc160 --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/copper_top.gbr @@ -0,0 +1,93 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Copper,L1,Top,Mixed* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10P,1.429621X8X112.500000*% +%ADD11C,2.540000*% +%ADD12P,2.749271X8X292.500000*% +%ADD13P,1.429621X8X292.500000*% +%ADD14C,1.320800*% +%ADD15C,1.524000*% +%ADD16C,1.879600*% + + +D10* +X292100Y63500D03* +X273050Y50800D03* +X292100Y38100D03* +X381000Y63500D03* +X361950Y50800D03* +X381000Y38100D03* +D11* +X165100Y76200D03* +D12* +X165100Y25400D03* +D13* +X228600Y165100D03* +X228600Y38100D03* +D10* +X330200Y38100D03* +X330200Y165100D03* +D14* +X457200Y159004D02* +X457200Y145796D01* +X457200Y57404D02* +X457200Y44196D01* +D10* +X419100Y38100D03* +X419100Y165100D03* +D14* +X501396Y88900D02* +X514604Y88900D01* +X514604Y114300D02* +X501396Y114300D01* +X501396Y63500D02* +X514604Y63500D01* +X95504Y190500D02* +X82296Y190500D01* +X82296Y165100D02* +X95504Y165100D01* +X95504Y139700D02* +X82296Y139700D01* +X82296Y114300D02* +X95504Y114300D01* +X95504Y88900D02* +X82296Y88900D01* +X82296Y63500D02* +X95504Y63500D01* +X95504Y38100D02* +X82296Y38100D01* +X82296Y12700D02* +X95504Y12700D01* +D15* +X576580Y12700D02* +X591820Y12700D01* +X591820Y38100D02* +X576580Y38100D01* +X576580Y63500D02* +X591820Y63500D01* +X591820Y88900D02* +X576580Y88900D01* +X576580Y114300D02* +X591820Y114300D01* +X591820Y139700D02* +X576580Y139700D01* +X576580Y165100D02* +X591820Y165100D01* +X591820Y190500D02* +X576580Y190500D01* +D16* +X302006Y159512D03* +X302006Y94488D03* +X256794Y159512D03* +X256794Y94488D03* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/drills.xln b/gerbonara/gerber/tests/resources/eagle-newer/drills.xln new file mode 100644 index 0000000..acd3daf --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/drills.xln @@ -0,0 +1,53 @@ +M48 +;GenerationSoftware,Autodesk,EAGLE,9.0.0*% +;CreationDate,2019-08-08T19:20:38Z*% +FMAT,2 +ICI,OFF +METRIC,TZ,000.000 +T2C0.813 +T1C1.016 +% +G90 +M71 +T1 +X25679Y9449 +X16510Y2540 +X16510Y7620 +X58420Y1270 +X58420Y3810 +X58420Y6350 +X58420Y8890 +X58420Y11430 +X58420Y13970 +X58420Y16510 +X58420Y19050 +X30201Y15951 +X30201Y9449 +X25679Y15951 +T2 +X41910Y3810 +X41910Y16510 +X50800Y8890 +X50800Y11430 +X50800Y6350 +X29210Y6350 +X8890Y16510 +X8890Y13970 +X8890Y11430 +X8890Y8890 +X8890Y6350 +X8890Y3810 +X8890Y1270 +X27305Y5080 +X29210Y3810 +X38100Y6350 +X36195Y5080 +X38100Y3810 +X22860Y16510 +X22860Y3810 +X33020Y3810 +X33020Y16510 +X45720Y15240 +X45720Y5080 +X8890Y19050 +M30
\ No newline at end of file diff --git a/gerbonara/gerber/tests/resources/eagle-newer/gerber_job.gbrjob b/gerbonara/gerber/tests/resources/eagle-newer/gerber_job.gbrjob new file mode 100644 index 0000000..1e726d4 --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/gerber_job.gbrjob @@ -0,0 +1,11 @@ +G04 Gerber job file.* +%TF.FileFunction,JobInfo*% +%TF.GenerationSoftware,Autodesk,EAGLE,9.0.0*% +%TF.CreationDate,2019-08-08T19:20:39Z*% +%TF.Part,Single*% +%MOMM*% +%TJ.B_Owner,ganzakademia kimmelgabor <kimmelgabor@gmail.com>*% +%TJ.B_ID,dallamcseng?*% +%TJ.B_LayerNum,2*% +%TJ.B_Thickness,1.570000*% +M02*
\ No newline at end of file diff --git a/gerbonara/gerber/tests/resources/eagle-newer/profile.gbr b/gerbonara/gerber/tests/resources/eagle-newer/profile.gbr new file mode 100644 index 0000000..bc00e0e --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/profile.gbr @@ -0,0 +1,23 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Profile,NP* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10C,0.000000*% + + +D10* +X0Y0D02* +X622100Y0D01* +X622100Y212600D01* +X0Y212600D01* +X0Y0D01* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/silkscreen_bottom.gbr b/gerbonara/gerber/tests/resources/eagle-newer/silkscreen_bottom.gbr new file mode 100644 index 0000000..8d9f2f8 --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/silkscreen_bottom.gbr @@ -0,0 +1,43 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Legend,Bot,1* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:39Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10C,0.127000*% + + +D10* +X114925Y62865D02* +X124458Y62865D01* +X126365Y60958D01* +X126365Y57145D01* +X124458Y55239D01* +X114925Y55239D01* +X124458Y51171D02* +X126365Y49264D01* +X126365Y45451D01* +X124458Y43545D01* +X122552Y43545D01* +X120645Y45451D01* +X120645Y49264D01* +X118739Y51171D01* +X116832Y51171D01* +X114925Y49264D01* +X114925Y45451D01* +X116832Y43545D01* +X113019Y47358D02* +X128272Y47358D01* +X118739Y39477D02* +X114925Y35664D01* +X126365Y35664D01* +X126365Y39477D02* +X126365Y31851D01* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/silkscreen_top.gbr b/gerbonara/gerber/tests/resources/eagle-newer/silkscreen_top.gbr new file mode 100644 index 0000000..fca8d20 --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/silkscreen_top.gbr @@ -0,0 +1,2422 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Legend,Top,1* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:39Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10C,0.127000*% +%ADD11C,0.152400*% +%ADD12R,2.286000X0.635000*% +%ADD13R,0.609600X0.863600*% +%ADD14R,2.032000X0.508000*% +%ADD15R,0.508000X1.905000*% +%ADD16C,0.050800*% +%ADD17C,0.660400*% +%ADD18R,0.762000X0.660400*% +%ADD19R,0.660400X0.660400*% +%ADD20C,0.203200*% + + +D10* +X294639Y24251D02* +X295272Y24319D01* +X295902Y24402D01* +X296530Y24501D01* +X297156Y24614D01* +X297778Y24742D01* +X298398Y24884D01* +X299014Y25042D01* +X299626Y25214D01* +X300234Y25401D01* +X300837Y25602D01* +X301435Y25817D01* +X302028Y26047D01* +X302615Y26290D01* +X303196Y26548D01* +X303771Y26819D01* +X304340Y27104D01* +X304901Y27403D01* +X305455Y27715D01* +X306002Y28040D01* +X306540Y28377D01* +X307070Y28728D01* +X307592Y29091D01* +X308105Y29467D01* +X308609Y29854D01* +X294640Y24251D02* +X293991Y24197D01* +X293342Y24159D01* +X292691Y24137D01* +X292040Y24130D01* +X291389Y24139D01* +X290739Y24165D01* +X290089Y24206D01* +X289441Y24263D01* +X288794Y24336D01* +X288149Y24424D01* +X287506Y24529D01* +X286866Y24649D01* +X286230Y24784D01* +X285596Y24935D01* +X284967Y25102D01* +X284342Y25283D01* +X283721Y25480D01* +X283106Y25692D01* +X282496Y25919D01* +X281891Y26161D01* +X281293Y26418D01* +X280701Y26689D01* +X280116Y26974D01* +X279538Y27274D01* +X278968Y27587D01* +X278405Y27915D01* +X277851Y28256D01* +X277305Y28610D01* +X276768Y28978D01* +X276239Y29359D01* +X275721Y29752D01* +X275212Y30158D01* +X274713Y30576D01* +X274225Y31007D01* +X273747Y31449D01* +X273280Y31903D01* +X272825Y32368D01* +X272381Y32844D01* +X271948Y33330D01* +X271528Y33827D01* +X271120Y34334D01* +X270724Y34851D01* +X270341Y35378D01* +X269971Y35914D01* +X269614Y36458D01* +X269271Y37011D01* +X268941Y37572D01* +X268625Y38142D01* +X268323Y38718D01* +X268036Y39302D01* +X267762Y39893D01* +X267503Y40490D01* +X267259Y41094D01* +X267029Y41703D01* +X266815Y42317D01* +X266615Y42937D01* +X266615Y58663D02* +X266814Y59278D01* +X267026Y59889D01* +X267254Y60494D01* +X267496Y61093D01* +X267753Y61686D01* +X268024Y62273D01* +X268309Y62853D01* +X268608Y63426D01* +X268921Y63992D01* +X269248Y64550D01* +X269588Y65100D01* +X269941Y65641D01* +X270307Y66174D01* +X270686Y66697D01* +X271078Y67212D01* +X271481Y67716D01* +X271898Y68211D01* +X272325Y68696D01* +X272765Y69170D01* +X273216Y69633D01* +X273678Y70085D01* +X274151Y70526D01* +X274634Y70955D01* +X275128Y71372D01* +X275631Y71778D01* +X276144Y72171D01* +X276667Y72551D01* +X277199Y72919D01* +X277739Y73273D01* +X278288Y73615D01* +X278845Y73943D01* +X279410Y74257D01* +X279982Y74558D01* +X280561Y74845D01* +X281148Y75117D01* +X281740Y75376D01* +X282339Y75619D01* +X282943Y75849D01* +X283553Y76063D01* +X284168Y76263D01* +X284787Y76448D01* +X285411Y76618D01* +X286039Y76772D01* +X286670Y76911D01* +X287304Y77035D01* +X287942Y77144D01* +X288581Y77237D01* +X289223Y77314D01* +X289866Y77376D01* +X290511Y77423D01* +X291157Y77453D01* +X291803Y77468D01* +X292449Y77468D01* +X293096Y77451D01* +X293741Y77419D01* +X294386Y77372D01* +X295029Y77309D01* +X295671Y77230D01* +X296310Y77136D01* +X296947Y77026D01* +X297582Y76901D01* +X298213Y76760D01* +X298840Y76604D01* +X299463Y76433D01* +X300082Y76247D01* +X300697Y76046D01* +X301306Y75831D01* +X301910Y75600D01* +X302508Y75355D01* +X303100Y75096D01* +X303686Y74822D01* +X304265Y74534D01* +X304836Y74232D01* +X305401Y73917D01* +X305957Y73588D01* +X306505Y73245D01* +X307045Y72889D01* +X307576Y72521D01* +X308098Y72139D01* +X308610Y71745D01* +X308610Y29855D01* +X294640Y28263D02* +X294640Y24251D01* +X294640Y47937D02* +X294640Y53663D01* +X294640Y73337D02* +X294640Y77349D01* +X260985Y18425D02* +X260985Y6985D01* +X260985Y18425D02* +X266705Y18425D01* +X268612Y16518D01* +X268612Y14612D01* +X266705Y12705D01* +X268612Y10798D01* +X268612Y8892D01* +X266705Y6985D01* +X260985Y6985D01* +X260985Y12705D02* +X266705Y12705D01* +X278399Y18425D02* +X280305Y16518D01* +X278399Y18425D02* +X274586Y18425D01* +X272679Y16518D01* +X272679Y8892D01* +X274586Y6985D01* +X278399Y6985D01* +X280305Y8892D01* +X284373Y18425D02* +X291999Y18425D01* +X284373Y18425D02* +X284373Y12705D01* +X288186Y14612D01* +X290093Y14612D01* +X291999Y12705D01* +X291999Y8892D01* +X290093Y6985D01* +X286280Y6985D01* +X284373Y8892D01* +X301787Y6985D02* +X301787Y18425D01* +X296067Y12705D01* +X303693Y12705D01* +X307761Y18425D02* +X315387Y18425D01* +X315387Y16518D01* +X307761Y8892D01* +X307761Y6985D01* +D11* +X355515Y42937D02* +X355713Y42322D01* +X355926Y41711D01* +X356154Y41106D01* +X356396Y40507D01* +X356653Y39914D01* +X356924Y39327D01* +X357209Y38747D01* +X357508Y38174D01* +X357821Y37608D01* +X358148Y37050D01* +X358487Y36501D01* +X358841Y35959D01* +X359207Y35426D01* +X359586Y34903D01* +X359977Y34388D01* +X360381Y33884D01* +X360797Y33389D01* +X361225Y32905D01* +X361665Y32431D01* +X362116Y31967D01* +X362578Y31515D01* +X363050Y31074D01* +X363534Y30645D01* +X364027Y30228D01* +X364531Y29822D01* +X365044Y29429D01* +X365567Y29049D01* +X366098Y28681D01* +X366639Y28327D01* +X367188Y27985D01* +X367745Y27657D01* +X368310Y27343D01* +X368882Y27042D01* +X369461Y26755D01* +X370047Y26483D01* +X370640Y26225D01* +X371238Y25981D01* +X371843Y25751D01* +X372453Y25537D01* +X373067Y25337D01* +X373687Y25152D01* +X374311Y24983D01* +X374938Y24828D01* +X375569Y24689D01* +X376204Y24565D01* +X376841Y24456D01* +X377481Y24363D01* +X378123Y24286D01* +X378766Y24224D01* +X379411Y24177D01* +X380056Y24147D01* +X380703Y24132D01* +X381349Y24132D01* +X381995Y24149D01* +X382641Y24181D01* +X383286Y24228D01* +X383929Y24291D01* +X384570Y24370D01* +X385210Y24464D01* +X385847Y24574D01* +X386481Y24699D01* +X387112Y24840D01* +X387739Y24996D01* +X388363Y25166D01* +X388982Y25352D01* +X389596Y25553D01* +X390206Y25769D01* +X390810Y26000D01* +X391408Y26245D01* +X392000Y26504D01* +X392585Y26778D01* +X393164Y27066D01* +X393736Y27367D01* +X394300Y27683D01* +X394856Y28012D01* +X395405Y28355D01* +X395944Y28710D01* +X396475Y29079D01* +X396997Y29460D01* +X397510Y29854D01* +X397510Y71750D02* +X396998Y72144D01* +X396476Y72526D01* +X395945Y72894D01* +X395405Y73250D01* +X394857Y73593D01* +X394301Y73922D01* +X393736Y74237D01* +X393165Y74539D01* +X392586Y74827D01* +X392000Y75101D01* +X391408Y75360D01* +X390810Y75605D01* +X390206Y75836D01* +X389597Y76051D01* +X388982Y76252D01* +X388363Y76438D01* +X387740Y76609D01* +X387113Y76765D01* +X386482Y76906D01* +X385847Y77031D01* +X385210Y77141D01* +X384571Y77235D01* +X383929Y77314D01* +X383286Y77377D01* +X382641Y77424D01* +X381996Y77456D01* +X381349Y77473D01* +X380703Y77473D01* +X380057Y77458D01* +X379411Y77428D01* +X378766Y77381D01* +X378123Y77319D01* +X377481Y77242D01* +X376842Y77149D01* +X376204Y77040D01* +X375570Y76916D01* +X374939Y76777D01* +X374311Y76623D01* +X373687Y76453D01* +X373068Y76268D01* +X372453Y76068D01* +X371843Y75854D01* +X371239Y75624D01* +X370640Y75381D01* +X370048Y75122D01* +X369461Y74850D01* +X368882Y74563D01* +X368310Y74262D01* +X367745Y73948D01* +X367188Y73620D01* +X366639Y73278D01* +X366099Y72924D01* +X365567Y72556D01* +X365044Y72176D01* +X364531Y71783D01* +X364028Y71377D01* +X363534Y70960D01* +X363051Y70531D01* +X362578Y70090D01* +X362116Y69638D01* +X361665Y69175D01* +X361225Y68701D01* +X360798Y68216D01* +X360381Y67721D01* +X359978Y67217D01* +X359586Y66702D01* +X359207Y66179D01* +X358841Y65646D01* +X358488Y65105D01* +X358148Y64555D01* +X357821Y63997D01* +X357508Y63431D01* +X357209Y62858D01* +X356924Y62278D01* +X356653Y61691D01* +X356396Y61098D01* +X356154Y60499D01* +X355926Y59894D01* +X355714Y59283D01* +X355515Y58668D01* +X397510Y71750D02* +X397510Y29850D01* +X383540Y28260D02* +X383540Y24250D01* +X383540Y47940D02* +X383540Y53660D01* +X383540Y73340D02* +X383540Y77350D01* +D10* +X381625Y83185D02* +X393065Y83185D01* +X381625Y83185D02* +X381625Y88905D01* +X383532Y90812D01* +X385439Y90812D01* +X387345Y88905D01* +X389252Y90812D01* +X391158Y90812D01* +X393065Y88905D01* +X393065Y83185D01* +X387345Y83185D02* +X387345Y88905D01* +X381625Y100599D02* +X383532Y102505D01* +X381625Y100599D02* +X381625Y96786D01* +X383532Y94879D01* +X391158Y94879D01* +X393065Y96786D01* +X393065Y100599D01* +X391158Y102505D01* +X381625Y106573D02* +X381625Y114199D01* +X381625Y106573D02* +X387345Y106573D01* +X385439Y110386D01* +X385439Y112293D01* +X387345Y114199D01* +X391158Y114199D01* +X393065Y112293D01* +X393065Y108480D01* +X391158Y106573D01* +X381625Y118267D02* +X381625Y125893D01* +X381625Y118267D02* +X387345Y118267D01* +X385439Y122080D01* +X385439Y123987D01* +X387345Y125893D01* +X391158Y125893D01* +X393065Y123987D01* +X393065Y120174D01* +X391158Y118267D01* +X381625Y129961D02* +X381625Y137587D01* +X383532Y137587D01* +X391158Y129961D01* +X393065Y129961D01* +D11* +X165100Y62230D02* +X165100Y59690D01* +X153670Y59690D01* +X153670Y53340D01* +X176530Y53340D01* +X176530Y59690D01* +X165100Y59690D01* +X165100Y44450D02* +X165100Y39370D01* +X177800Y83820D02* +X185420Y83820D01* +X181610Y87630D02* +X181610Y80010D01* +X120650Y50800D02* +X120663Y51891D01* +X120704Y52981D01* +X120770Y54070D01* +X120864Y55157D01* +X120984Y56241D01* +X121131Y57322D01* +X121304Y58399D01* +X121504Y59472D01* +X121730Y60539D01* +X121982Y61600D01* +X122260Y62655D01* +X122564Y63703D01* +X122893Y64743D01* +X123248Y65775D01* +X123628Y66797D01* +X124034Y67810D01* +X124463Y68813D01* +X124918Y69805D01* +X125396Y70785D01* +X125899Y71754D01* +X126425Y72709D01* +X126974Y73652D01* +X127546Y74581D01* +X128141Y75495D01* +X128758Y76395D01* +X129397Y77279D01* +X130058Y78147D01* +X130740Y78999D01* +X131442Y79834D01* +X132165Y80651D01* +X132907Y81450D01* +X133669Y82231D01* +X134450Y82993D01* +X135249Y83735D01* +X136066Y84458D01* +X136901Y85160D01* +X137753Y85842D01* +X138621Y86503D01* +X139505Y87142D01* +X140405Y87759D01* +X141319Y88354D01* +X142248Y88926D01* +X143191Y89475D01* +X144146Y90001D01* +X145115Y90504D01* +X146095Y90982D01* +X147087Y91437D01* +X148090Y91866D01* +X149103Y92272D01* +X150125Y92652D01* +X151157Y93007D01* +X152197Y93336D01* +X153245Y93640D01* +X154300Y93918D01* +X155361Y94170D01* +X156428Y94396D01* +X157501Y94596D01* +X158578Y94769D01* +X159659Y94916D01* +X160743Y95036D01* +X161830Y95130D01* +X162919Y95196D01* +X164009Y95237D01* +X165100Y95250D01* +X166191Y95237D01* +X167281Y95196D01* +X168370Y95130D01* +X169457Y95036D01* +X170541Y94916D01* +X171622Y94769D01* +X172699Y94596D01* +X173772Y94396D01* +X174839Y94170D01* +X175900Y93918D01* +X176955Y93640D01* +X178003Y93336D01* +X179043Y93007D01* +X180075Y92652D01* +X181097Y92272D01* +X182110Y91866D01* +X183113Y91437D01* +X184105Y90982D01* +X185085Y90504D01* +X186054Y90001D01* +X187009Y89475D01* +X187952Y88926D01* +X188881Y88354D01* +X189795Y87759D01* +X190695Y87142D01* +X191579Y86503D01* +X192447Y85842D01* +X193299Y85160D01* +X194134Y84458D01* +X194951Y83735D01* +X195750Y82993D01* +X196531Y82231D01* +X197293Y81450D01* +X198035Y80651D01* +X198758Y79834D01* +X199460Y78999D01* +X200142Y78147D01* +X200803Y77279D01* +X201442Y76395D01* +X202059Y75495D01* +X202654Y74581D01* +X203226Y73652D01* +X203775Y72709D01* +X204301Y71754D01* +X204804Y70785D01* +X205282Y69805D01* +X205737Y68813D01* +X206166Y67810D01* +X206572Y66797D01* +X206952Y65775D01* +X207307Y64743D01* +X207636Y63703D01* +X207940Y62655D01* +X208218Y61600D01* +X208470Y60539D01* +X208696Y59472D01* +X208896Y58399D01* +X209069Y57322D01* +X209216Y56241D01* +X209336Y55157D01* +X209430Y54070D01* +X209496Y52981D01* +X209537Y51891D01* +X209550Y50800D01* +X209537Y49709D01* +X209496Y48619D01* +X209430Y47530D01* +X209336Y46443D01* +X209216Y45359D01* +X209069Y44278D01* +X208896Y43201D01* +X208696Y42128D01* +X208470Y41061D01* +X208218Y40000D01* +X207940Y38945D01* +X207636Y37897D01* +X207307Y36857D01* +X206952Y35825D01* +X206572Y34803D01* +X206166Y33790D01* +X205737Y32787D01* +X205282Y31795D01* +X204804Y30815D01* +X204301Y29846D01* +X203775Y28891D01* +X203226Y27948D01* +X202654Y27019D01* +X202059Y26105D01* +X201442Y25205D01* +X200803Y24321D01* +X200142Y23453D01* +X199460Y22601D01* +X198758Y21766D01* +X198035Y20949D01* +X197293Y20150D01* +X196531Y19369D01* +X195750Y18607D01* +X194951Y17865D01* +X194134Y17142D01* +X193299Y16440D01* +X192447Y15758D01* +X191579Y15097D01* +X190695Y14458D01* +X189795Y13841D01* +X188881Y13246D01* +X187952Y12674D01* +X187009Y12125D01* +X186054Y11599D01* +X185085Y11096D01* +X184105Y10618D01* +X183113Y10163D01* +X182110Y9734D01* +X181097Y9328D01* +X180075Y8948D01* +X179043Y8593D01* +X178003Y8264D01* +X176955Y7960D01* +X175900Y7682D01* +X174839Y7430D01* +X173772Y7204D01* +X172699Y7004D01* +X171622Y6831D01* +X170541Y6684D01* +X169457Y6564D01* +X168370Y6470D01* +X167281Y6404D01* +X166191Y6363D01* +X165100Y6350D01* +X164009Y6363D01* +X162919Y6404D01* +X161830Y6470D01* +X160743Y6564D01* +X159659Y6684D01* +X158578Y6831D01* +X157501Y7004D01* +X156428Y7204D01* +X155361Y7430D01* +X154300Y7682D01* +X153245Y7960D01* +X152197Y8264D01* +X151157Y8593D01* +X150125Y8948D01* +X149103Y9328D01* +X148090Y9734D01* +X147087Y10163D01* +X146095Y10618D01* +X145115Y11096D01* +X144146Y11599D01* +X143191Y12125D01* +X142248Y12674D01* +X141319Y13246D01* +X140405Y13841D01* +X139505Y14458D01* +X138621Y15097D01* +X137753Y15758D01* +X136901Y16440D01* +X136066Y17142D01* +X135249Y17865D01* +X134450Y18607D01* +X133669Y19369D01* +X132907Y20150D01* +X132165Y20949D01* +X131442Y21766D01* +X130740Y22601D01* +X130058Y23453D01* +X129397Y24321D01* +X128758Y25205D01* +X128141Y26105D01* +X127546Y27019D01* +X126974Y27948D01* +X126425Y28891D01* +X125899Y29846D01* +X125396Y30815D01* +X124918Y31795D01* +X124463Y32787D01* +X124034Y33790D01* +X123628Y34803D01* +X123248Y35825D01* +X122893Y36857D01* +X122564Y37897D01* +X122260Y38945D01* +X121982Y40000D01* +X121730Y41061D01* +X121504Y42128D01* +X121304Y43201D01* +X121131Y44278D01* +X120984Y45359D01* +X120864Y46443D01* +X120770Y47530D01* +X120704Y48619D01* +X120663Y49709D01* +X120650Y50800D01* +D10* +X135499Y47219D02* +X146939Y47219D01* +X141219Y41499D02* +X135499Y47219D01* +X141219Y49126D02* +X141219Y41499D01* +X135499Y53193D02* +X135499Y60820D01* +X137406Y60820D01* +X145032Y53193D01* +X146939Y53193D01* +X145032Y64887D02* +X139313Y64887D01* +X145032Y64887D02* +X146939Y66794D01* +X146939Y72513D01* +X139313Y72513D01* +D12* +X165100Y45085D03* +D11* +X243840Y142240D02* +X243838Y142340D01* +X243832Y142439D01* +X243822Y142539D01* +X243809Y142637D01* +X243791Y142736D01* +X243770Y142833D01* +X243745Y142929D01* +X243716Y143025D01* +X243683Y143119D01* +X243647Y143212D01* +X243607Y143303D01* +X243563Y143393D01* +X243516Y143481D01* +X243466Y143567D01* +X243412Y143651D01* +X243355Y143733D01* +X243295Y143812D01* +X243231Y143890D01* +X243165Y143964D01* +X243096Y144036D01* +X243024Y144105D01* +X242950Y144171D01* +X242872Y144235D01* +X242793Y144295D01* +X242711Y144352D01* +X242627Y144406D01* +X242541Y144456D01* +X242453Y144503D01* +X242363Y144547D01* +X242272Y144587D01* +X242179Y144623D01* +X242085Y144656D01* +X241989Y144685D01* +X241893Y144710D01* +X241796Y144731D01* +X241697Y144749D01* +X241599Y144762D01* +X241499Y144772D01* +X241400Y144778D01* +X241300Y144780D01* +X215900Y144780D02* +X215800Y144778D01* +X215701Y144772D01* +X215601Y144762D01* +X215503Y144749D01* +X215404Y144731D01* +X215307Y144710D01* +X215211Y144685D01* +X215115Y144656D01* +X215021Y144623D01* +X214928Y144587D01* +X214837Y144547D01* +X214747Y144503D01* +X214659Y144456D01* +X214573Y144406D01* +X214489Y144352D01* +X214407Y144295D01* +X214328Y144235D01* +X214250Y144171D01* +X214176Y144105D01* +X214104Y144036D01* +X214035Y143964D01* +X213969Y143890D01* +X213905Y143812D01* +X213845Y143733D01* +X213788Y143651D01* +X213734Y143567D01* +X213684Y143481D01* +X213637Y143393D01* +X213593Y143303D01* +X213553Y143212D01* +X213517Y143119D01* +X213484Y143025D01* +X213455Y142929D01* +X213430Y142833D01* +X213409Y142736D01* +X213391Y142637D01* +X213378Y142539D01* +X213368Y142439D01* +X213362Y142340D01* +X213360Y142240D01* +X213360Y60960D02* +X213362Y60860D01* +X213368Y60761D01* +X213378Y60661D01* +X213391Y60563D01* +X213409Y60464D01* +X213430Y60367D01* +X213455Y60271D01* +X213484Y60175D01* +X213517Y60081D01* +X213553Y59988D01* +X213593Y59897D01* +X213637Y59807D01* +X213684Y59719D01* +X213734Y59633D01* +X213788Y59549D01* +X213845Y59467D01* +X213905Y59388D01* +X213969Y59310D01* +X214035Y59236D01* +X214104Y59164D01* +X214176Y59095D01* +X214250Y59029D01* +X214328Y58965D01* +X214407Y58905D01* +X214489Y58848D01* +X214573Y58794D01* +X214659Y58744D01* +X214747Y58697D01* +X214837Y58653D01* +X214928Y58613D01* +X215021Y58577D01* +X215115Y58544D01* +X215211Y58515D01* +X215307Y58490D01* +X215404Y58469D01* +X215503Y58451D01* +X215601Y58438D01* +X215701Y58428D01* +X215800Y58422D01* +X215900Y58420D01* +X241300Y58420D02* +X241400Y58422D01* +X241499Y58428D01* +X241599Y58438D01* +X241697Y58451D01* +X241796Y58469D01* +X241893Y58490D01* +X241989Y58515D01* +X242085Y58544D01* +X242179Y58577D01* +X242272Y58613D01* +X242363Y58653D01* +X242453Y58697D01* +X242541Y58744D01* +X242627Y58794D01* +X242711Y58848D01* +X242793Y58905D01* +X242872Y58965D01* +X242950Y59029D01* +X243024Y59095D01* +X243096Y59164D01* +X243165Y59236D01* +X243231Y59310D01* +X243295Y59388D01* +X243355Y59467D01* +X243412Y59549D01* +X243466Y59633D01* +X243516Y59719D01* +X243563Y59807D01* +X243607Y59897D01* +X243647Y59988D01* +X243683Y60081D01* +X243716Y60175D01* +X243745Y60271D01* +X243770Y60367D01* +X243791Y60464D01* +X243809Y60563D01* +X243822Y60661D01* +X243832Y60761D01* +X243838Y60860D01* +X243840Y60960D01* +X241300Y144780D02* +X215900Y144780D01* +X243840Y142240D02* +X243840Y135890D01* +X242570Y134620D01* +X213360Y135890D02* +X213360Y142240D01* +X213360Y135890D02* +X214630Y134620D01* +X242570Y68580D02* +X243840Y67310D01* +X242570Y68580D02* +X242570Y134620D01* +X214630Y68580D02* +X213360Y67310D01* +X214630Y68580D02* +X214630Y134620D01* +X243840Y67310D02* +X243840Y60960D01* +X213360Y60960D02* +X213360Y67310D01* +X215900Y58420D02* +X241300Y58420D01* +D10* +X226181Y89158D02* +X222367Y92971D01* +X233807Y92971D01* +X233807Y89158D02* +X233807Y96785D01* +X231900Y100852D02* +X224274Y100852D01* +X222367Y102759D01* +X222367Y106572D01* +X224274Y108479D01* +X231900Y108479D01* +X233807Y106572D01* +X233807Y102759D01* +X231900Y100852D01* +X224274Y108479D01* +X224274Y112546D02* +X231900Y112546D01* +X224274Y112546D02* +X222367Y114453D01* +X222367Y118266D01* +X224274Y120172D01* +X231900Y120172D01* +X233807Y118266D01* +X233807Y114453D01* +X231900Y112546D01* +X224274Y120172D01* +X222367Y124240D02* +X233807Y124240D01* +X229994Y124240D02* +X233807Y129960D01* +X229994Y124240D02* +X226181Y129960D01* +D13* +X228600Y54102D03* +X228600Y149098D03* +D11* +X314960Y60960D02* +X314962Y60860D01* +X314968Y60761D01* +X314978Y60661D01* +X314991Y60563D01* +X315009Y60464D01* +X315030Y60367D01* +X315055Y60271D01* +X315084Y60175D01* +X315117Y60081D01* +X315153Y59988D01* +X315193Y59897D01* +X315237Y59807D01* +X315284Y59719D01* +X315334Y59633D01* +X315388Y59549D01* +X315445Y59467D01* +X315505Y59388D01* +X315569Y59310D01* +X315635Y59236D01* +X315704Y59164D01* +X315776Y59095D01* +X315850Y59029D01* +X315928Y58965D01* +X316007Y58905D01* +X316089Y58848D01* +X316173Y58794D01* +X316259Y58744D01* +X316347Y58697D01* +X316437Y58653D01* +X316528Y58613D01* +X316621Y58577D01* +X316715Y58544D01* +X316811Y58515D01* +X316907Y58490D01* +X317004Y58469D01* +X317103Y58451D01* +X317201Y58438D01* +X317301Y58428D01* +X317400Y58422D01* +X317500Y58420D01* +X342900Y58420D02* +X343000Y58422D01* +X343099Y58428D01* +X343199Y58438D01* +X343297Y58451D01* +X343396Y58469D01* +X343493Y58490D01* +X343589Y58515D01* +X343685Y58544D01* +X343779Y58577D01* +X343872Y58613D01* +X343963Y58653D01* +X344053Y58697D01* +X344141Y58744D01* +X344227Y58794D01* +X344311Y58848D01* +X344393Y58905D01* +X344472Y58965D01* +X344550Y59029D01* +X344624Y59095D01* +X344696Y59164D01* +X344765Y59236D01* +X344831Y59310D01* +X344895Y59388D01* +X344955Y59467D01* +X345012Y59549D01* +X345066Y59633D01* +X345116Y59719D01* +X345163Y59807D01* +X345207Y59897D01* +X345247Y59988D01* +X345283Y60081D01* +X345316Y60175D01* +X345345Y60271D01* +X345370Y60367D01* +X345391Y60464D01* +X345409Y60563D01* +X345422Y60661D01* +X345432Y60761D01* +X345438Y60860D01* +X345440Y60960D01* +X345440Y142240D02* +X345438Y142340D01* +X345432Y142439D01* +X345422Y142539D01* +X345409Y142637D01* +X345391Y142736D01* +X345370Y142833D01* +X345345Y142929D01* +X345316Y143025D01* +X345283Y143119D01* +X345247Y143212D01* +X345207Y143303D01* +X345163Y143393D01* +X345116Y143481D01* +X345066Y143567D01* +X345012Y143651D01* +X344955Y143733D01* +X344895Y143812D01* +X344831Y143890D01* +X344765Y143964D01* +X344696Y144036D01* +X344624Y144105D01* +X344550Y144171D01* +X344472Y144235D01* +X344393Y144295D01* +X344311Y144352D01* +X344227Y144406D01* +X344141Y144456D01* +X344053Y144503D01* +X343963Y144547D01* +X343872Y144587D01* +X343779Y144623D01* +X343685Y144656D01* +X343589Y144685D01* +X343493Y144710D01* +X343396Y144731D01* +X343297Y144749D01* +X343199Y144762D01* +X343099Y144772D01* +X343000Y144778D01* +X342900Y144780D01* +X317500Y144780D02* +X317400Y144778D01* +X317301Y144772D01* +X317201Y144762D01* +X317103Y144749D01* +X317004Y144731D01* +X316907Y144710D01* +X316811Y144685D01* +X316715Y144656D01* +X316621Y144623D01* +X316528Y144587D01* +X316437Y144547D01* +X316347Y144503D01* +X316259Y144456D01* +X316173Y144406D01* +X316089Y144352D01* +X316007Y144295D01* +X315928Y144235D01* +X315850Y144171D01* +X315776Y144105D01* +X315704Y144036D01* +X315635Y143964D01* +X315569Y143890D01* +X315505Y143812D01* +X315445Y143733D01* +X315388Y143651D01* +X315334Y143567D01* +X315284Y143481D01* +X315237Y143393D01* +X315193Y143303D01* +X315153Y143212D01* +X315117Y143119D01* +X315084Y143025D01* +X315055Y142929D01* +X315030Y142833D01* +X315009Y142736D01* +X314991Y142637D01* +X314978Y142539D01* +X314968Y142439D01* +X314962Y142340D01* +X314960Y142240D01* +X317500Y58420D02* +X342900Y58420D01* +X314960Y60960D02* +X314960Y67310D01* +X316230Y68580D01* +X345440Y67310D02* +X345440Y60960D01* +X345440Y67310D02* +X344170Y68580D01* +X316230Y134620D02* +X314960Y135890D01* +X316230Y134620D02* +X316230Y68580D01* +X344170Y134620D02* +X345440Y135890D01* +X344170Y134620D02* +X344170Y68580D01* +X314960Y135890D02* +X314960Y142240D01* +X345440Y142240D02* +X345440Y135890D01* +X342900Y144780D02* +X317500Y144780D01* +D10* +X324983Y74298D02* +X328797Y70485D01* +X324983Y74298D02* +X336423Y74298D01* +X336423Y70485D02* +X336423Y78112D01* +X334516Y82179D02* +X326890Y82179D01* +X324983Y84086D01* +X324983Y87899D01* +X326890Y89805D01* +X334516Y89805D01* +X336423Y87899D01* +X336423Y84086D01* +X334516Y82179D01* +X326890Y89805D01* +X324983Y93873D02* +X336423Y93873D01* +X332610Y93873D02* +X336423Y99593D01* +X332610Y93873D02* +X328797Y99593D01* +D13* +X330200Y149098D03* +X330200Y54102D03* +D11* +X457200Y101600D02* +X457200Y107950D01* +X463550Y91440D02* +X450850Y91440D01* +X457200Y101600D01* +X457200Y86360D01* +X463550Y91440D02* +X457200Y101600D01* +X450850Y101600D01* +X463550Y101600D02* +X463550Y99060D01* +X463550Y101600D02* +X457200Y101600D01* +X467360Y81280D02* +X467358Y81180D01* +X467352Y81081D01* +X467342Y80981D01* +X467329Y80883D01* +X467311Y80784D01* +X467290Y80687D01* +X467265Y80591D01* +X467236Y80495D01* +X467203Y80401D01* +X467167Y80308D01* +X467127Y80217D01* +X467083Y80127D01* +X467036Y80039D01* +X466986Y79953D01* +X466932Y79869D01* +X466875Y79787D01* +X466815Y79708D01* +X466751Y79630D01* +X466685Y79556D01* +X466616Y79484D01* +X466544Y79415D01* +X466470Y79349D01* +X466392Y79285D01* +X466313Y79225D01* +X466231Y79168D01* +X466147Y79114D01* +X466061Y79064D01* +X465973Y79017D01* +X465883Y78973D01* +X465792Y78933D01* +X465699Y78897D01* +X465605Y78864D01* +X465509Y78835D01* +X465413Y78810D01* +X465316Y78789D01* +X465217Y78771D01* +X465119Y78758D01* +X465019Y78748D01* +X464920Y78742D01* +X464820Y78740D01* +X467360Y121920D02* +X467358Y122020D01* +X467352Y122119D01* +X467342Y122219D01* +X467329Y122317D01* +X467311Y122416D01* +X467290Y122513D01* +X467265Y122609D01* +X467236Y122705D01* +X467203Y122799D01* +X467167Y122892D01* +X467127Y122983D01* +X467083Y123073D01* +X467036Y123161D01* +X466986Y123247D01* +X466932Y123331D01* +X466875Y123413D01* +X466815Y123492D01* +X466751Y123570D01* +X466685Y123644D01* +X466616Y123716D01* +X466544Y123785D01* +X466470Y123851D01* +X466392Y123915D01* +X466313Y123975D01* +X466231Y124032D01* +X466147Y124086D01* +X466061Y124136D01* +X465973Y124183D01* +X465883Y124227D01* +X465792Y124267D01* +X465699Y124303D01* +X465605Y124336D01* +X465509Y124365D01* +X465413Y124390D01* +X465316Y124411D01* +X465217Y124429D01* +X465119Y124442D01* +X465019Y124452D01* +X464920Y124458D01* +X464820Y124460D01* +X449580Y124460D02* +X449480Y124458D01* +X449381Y124452D01* +X449281Y124442D01* +X449183Y124429D01* +X449084Y124411D01* +X448987Y124390D01* +X448891Y124365D01* +X448795Y124336D01* +X448701Y124303D01* +X448608Y124267D01* +X448517Y124227D01* +X448427Y124183D01* +X448339Y124136D01* +X448253Y124086D01* +X448169Y124032D01* +X448087Y123975D01* +X448008Y123915D01* +X447930Y123851D01* +X447856Y123785D01* +X447784Y123716D01* +X447715Y123644D01* +X447649Y123570D01* +X447585Y123492D01* +X447525Y123413D01* +X447468Y123331D01* +X447414Y123247D01* +X447364Y123161D01* +X447317Y123073D01* +X447273Y122983D01* +X447233Y122892D01* +X447197Y122799D01* +X447164Y122705D01* +X447135Y122609D01* +X447110Y122513D01* +X447089Y122416D01* +X447071Y122317D01* +X447058Y122219D01* +X447048Y122119D01* +X447042Y122020D01* +X447040Y121920D01* +X447040Y81280D02* +X447042Y81180D01* +X447048Y81081D01* +X447058Y80981D01* +X447071Y80883D01* +X447089Y80784D01* +X447110Y80687D01* +X447135Y80591D01* +X447164Y80495D01* +X447197Y80401D01* +X447233Y80308D01* +X447273Y80217D01* +X447317Y80127D01* +X447364Y80039D01* +X447414Y79953D01* +X447468Y79869D01* +X447525Y79787D01* +X447585Y79708D01* +X447649Y79630D01* +X447715Y79556D01* +X447784Y79484D01* +X447856Y79415D01* +X447930Y79349D01* +X448008Y79285D01* +X448087Y79225D01* +X448169Y79168D01* +X448253Y79114D01* +X448339Y79064D01* +X448427Y79017D01* +X448517Y78973D01* +X448608Y78933D01* +X448701Y78897D01* +X448795Y78864D01* +X448891Y78835D01* +X448987Y78810D01* +X449084Y78789D01* +X449183Y78771D01* +X449281Y78758D01* +X449381Y78748D01* +X449480Y78742D01* +X449580Y78740D01* +X464820Y78740D01* +X464820Y124460D02* +X449580Y124460D01* +X467360Y121920D02* +X467360Y81280D01* +X447040Y81280D02* +X447040Y121920D01* +D14* +X457200Y118110D03* +D15* +X457200Y69215D03* +X457200Y133985D03* +D10* +X470525Y117256D02* +X470525Y109629D01* +X470525Y117256D02* +X472432Y117256D01* +X480058Y109629D01* +X481965Y109629D01* +X481965Y117256D01* +X481965Y121323D02* +X470525Y121323D01* +X470525Y127043D01* +X472432Y128950D01* +X476245Y128950D01* +X478152Y127043D01* +X478152Y121323D01* +X481965Y133017D02* +X470525Y133017D01* +X481965Y133017D02* +X481965Y138737D01* +X480058Y140643D01* +X472432Y140643D01* +X470525Y138737D01* +X470525Y133017D01* +X472432Y144711D02* +X470525Y146618D01* +X470525Y150431D01* +X472432Y152337D01* +X474339Y152337D01* +X476245Y150431D01* +X476245Y148524D01* +X476245Y150431D02* +X478152Y152337D01* +X480058Y152337D01* +X481965Y150431D01* +X481965Y146618D01* +X480058Y144711D01* +X485778Y156405D02* +X481965Y160218D01* +X480058Y160218D01* +X480058Y158312D01* +X481965Y158312D01* +X481965Y160218D01* +X472432Y164201D02* +X470525Y166108D01* +X470525Y169921D01* +X472432Y171827D01* +X474339Y171827D01* +X476245Y169921D01* +X476245Y168014D01* +X476245Y169921D02* +X478152Y171827D01* +X480058Y171827D01* +X481965Y169921D01* +X481965Y166108D01* +X480058Y164201D01* +D11* +X403860Y60960D02* +X403862Y60860D01* +X403868Y60761D01* +X403878Y60661D01* +X403891Y60563D01* +X403909Y60464D01* +X403930Y60367D01* +X403955Y60271D01* +X403984Y60175D01* +X404017Y60081D01* +X404053Y59988D01* +X404093Y59897D01* +X404137Y59807D01* +X404184Y59719D01* +X404234Y59633D01* +X404288Y59549D01* +X404345Y59467D01* +X404405Y59388D01* +X404469Y59310D01* +X404535Y59236D01* +X404604Y59164D01* +X404676Y59095D01* +X404750Y59029D01* +X404828Y58965D01* +X404907Y58905D01* +X404989Y58848D01* +X405073Y58794D01* +X405159Y58744D01* +X405247Y58697D01* +X405337Y58653D01* +X405428Y58613D01* +X405521Y58577D01* +X405615Y58544D01* +X405711Y58515D01* +X405807Y58490D01* +X405904Y58469D01* +X406003Y58451D01* +X406101Y58438D01* +X406201Y58428D01* +X406300Y58422D01* +X406400Y58420D01* +X431800Y58420D02* +X431900Y58422D01* +X431999Y58428D01* +X432099Y58438D01* +X432197Y58451D01* +X432296Y58469D01* +X432393Y58490D01* +X432489Y58515D01* +X432585Y58544D01* +X432679Y58577D01* +X432772Y58613D01* +X432863Y58653D01* +X432953Y58697D01* +X433041Y58744D01* +X433127Y58794D01* +X433211Y58848D01* +X433293Y58905D01* +X433372Y58965D01* +X433450Y59029D01* +X433524Y59095D01* +X433596Y59164D01* +X433665Y59236D01* +X433731Y59310D01* +X433795Y59388D01* +X433855Y59467D01* +X433912Y59549D01* +X433966Y59633D01* +X434016Y59719D01* +X434063Y59807D01* +X434107Y59897D01* +X434147Y59988D01* +X434183Y60081D01* +X434216Y60175D01* +X434245Y60271D01* +X434270Y60367D01* +X434291Y60464D01* +X434309Y60563D01* +X434322Y60661D01* +X434332Y60761D01* +X434338Y60860D01* +X434340Y60960D01* +X434340Y142240D02* +X434338Y142340D01* +X434332Y142439D01* +X434322Y142539D01* +X434309Y142637D01* +X434291Y142736D01* +X434270Y142833D01* +X434245Y142929D01* +X434216Y143025D01* +X434183Y143119D01* +X434147Y143212D01* +X434107Y143303D01* +X434063Y143393D01* +X434016Y143481D01* +X433966Y143567D01* +X433912Y143651D01* +X433855Y143733D01* +X433795Y143812D01* +X433731Y143890D01* +X433665Y143964D01* +X433596Y144036D01* +X433524Y144105D01* +X433450Y144171D01* +X433372Y144235D01* +X433293Y144295D01* +X433211Y144352D01* +X433127Y144406D01* +X433041Y144456D01* +X432953Y144503D01* +X432863Y144547D01* +X432772Y144587D01* +X432679Y144623D01* +X432585Y144656D01* +X432489Y144685D01* +X432393Y144710D01* +X432296Y144731D01* +X432197Y144749D01* +X432099Y144762D01* +X431999Y144772D01* +X431900Y144778D01* +X431800Y144780D01* +X406400Y144780D02* +X406300Y144778D01* +X406201Y144772D01* +X406101Y144762D01* +X406003Y144749D01* +X405904Y144731D01* +X405807Y144710D01* +X405711Y144685D01* +X405615Y144656D01* +X405521Y144623D01* +X405428Y144587D01* +X405337Y144547D01* +X405247Y144503D01* +X405159Y144456D01* +X405073Y144406D01* +X404989Y144352D01* +X404907Y144295D01* +X404828Y144235D01* +X404750Y144171D01* +X404676Y144105D01* +X404604Y144036D01* +X404535Y143964D01* +X404469Y143890D01* +X404405Y143812D01* +X404345Y143733D01* +X404288Y143651D01* +X404234Y143567D01* +X404184Y143481D01* +X404137Y143393D01* +X404093Y143303D01* +X404053Y143212D01* +X404017Y143119D01* +X403984Y143025D01* +X403955Y142929D01* +X403930Y142833D01* +X403909Y142736D01* +X403891Y142637D01* +X403878Y142539D01* +X403868Y142439D01* +X403862Y142340D01* +X403860Y142240D01* +X406400Y58420D02* +X431800Y58420D01* +X403860Y60960D02* +X403860Y67310D01* +X405130Y68580D01* +X434340Y67310D02* +X434340Y60960D01* +X434340Y67310D02* +X433070Y68580D01* +X405130Y134620D02* +X403860Y135890D01* +X405130Y134620D02* +X405130Y68580D01* +X433070Y134620D02* +X434340Y135890D01* +X433070Y134620D02* +X433070Y68580D01* +X403860Y135890D02* +X403860Y142240D01* +X434340Y142240D02* +X434340Y135890D01* +X431800Y144780D02* +X406400Y144780D01* +D10* +X413883Y74298D02* +X417697Y70485D01* +X413883Y74298D02* +X425323Y74298D01* +X425323Y70485D02* +X425323Y78112D01* +X423416Y82179D02* +X415790Y82179D01* +X413883Y84086D01* +X413883Y87899D01* +X415790Y89805D01* +X423416Y89805D01* +X425323Y87899D01* +X425323Y84086D01* +X423416Y82179D01* +X415790Y89805D01* +X413883Y93873D02* +X425323Y93873D01* +X421510Y93873D02* +X425323Y99593D01* +X421510Y93873D02* +X417697Y99593D01* +D13* +X419100Y149098D03* +X419100Y54102D03* +D10* +X524510Y67950D02* +X524510Y109850D01* +X496641Y113030D02* +X496057Y112747D01* +X495481Y112449D01* +X494912Y112138D01* +X494351Y111813D01* +X493798Y111474D01* +X493253Y111122D01* +X492717Y110757D01* +X492190Y110379D01* +X491673Y109988D01* +X491165Y109585D01* +X490667Y109169D01* +X490179Y108742D01* +X489702Y108303D01* +X489235Y107852D01* +X488780Y107390D01* +X488336Y106917D01* +X487904Y106434D01* +X487483Y105940D01* +X487075Y105436D01* +X486679Y104922D01* +X486296Y104399D01* +X485925Y103867D01* +X485568Y103325D01* +X485224Y102776D01* +X484893Y102218D01* +X484576Y101652D01* +X484273Y101079D01* +X483984Y100498D01* +X483709Y99911D01* +X483448Y99317D01* +X483202Y98717D01* +X482971Y98111D01* +X482754Y97499D01* +X482553Y96883D01* +X482366Y96262D01* +X482195Y95636D01* +X482039Y95007D01* +X481898Y94374D01* +X481772Y93737D01* +X481663Y93098D01* +X481568Y92457D01* +X481490Y91813D01* +X481427Y91167D01* +X481379Y90520D01* +X481348Y89873D01* +X481332Y89224D01* +X481332Y88576D01* +X481348Y87927D01* +X481379Y87280D01* +X481427Y86633D01* +X481490Y85987D01* +X481568Y85343D01* +X481663Y84702D01* +X481772Y84063D01* +X481898Y83426D01* +X482039Y82793D01* +X482195Y82164D01* +X482366Y81538D01* +X482553Y80917D01* +X482754Y80301D01* +X482971Y79689D01* +X483202Y79083D01* +X483448Y78483D01* +X483709Y77889D01* +X483984Y77302D01* +X484273Y76721D01* +X484576Y76148D01* +X484893Y75582D01* +X485224Y75024D01* +X485568Y74475D01* +X485925Y73933D01* +X486296Y73401D01* +X486679Y72878D01* +X487075Y72364D01* +X487483Y71860D01* +X487904Y71366D01* +X488336Y70883D01* +X488780Y70410D01* +X489235Y69948D01* +X489702Y69497D01* +X490179Y69058D01* +X490667Y68631D01* +X491165Y68215D01* +X491673Y67812D01* +X492190Y67421D01* +X492717Y67043D01* +X493253Y66678D01* +X493798Y66326D01* +X494351Y65987D01* +X494912Y65662D01* +X495481Y65351D01* +X496057Y65053D01* +X496641Y64770D01* +X519359Y64765D02* +X519905Y65030D01* +X520445Y65307D01* +X520978Y65596D01* +X521505Y65898D01* +X522025Y66211D01* +X522538Y66536D01* +X523043Y66873D01* +X523540Y67221D01* +X524029Y67580D01* +X524510Y67950D01* +X509270Y74860D02* +X509270Y77540D01* +X509270Y100260D02* +X509270Y102940D01* +X519118Y113147D02* +X519691Y112876D01* +X520257Y112591D01* +X520816Y112294D01* +X521368Y111983D01* +X521912Y111658D01* +X522448Y111322D01* +X522977Y110972D01* +X523497Y110610D01* +X524008Y110236D01* +X524510Y109850D01* +X528945Y64135D02* +X538478Y64135D01* +X540385Y66042D01* +X540385Y69855D01* +X538478Y71762D01* +X528945Y71762D01* +X528945Y75829D02* +X540385Y75829D01* +X532759Y79642D02* +X528945Y75829D01* +X532759Y79642D02* +X528945Y83455D01* +X540385Y83455D01* +X534665Y87523D02* +X534665Y95149D01* +X530852Y103030D02* +X528945Y106843D01* +X530852Y103030D02* +X534665Y99217D01* +X538478Y99217D01* +X540385Y101124D01* +X540385Y104937D01* +X538478Y106843D01* +X536572Y106843D01* +X534665Y104937D01* +X534665Y99217D01* +X530852Y114724D02* +X528945Y118537D01* +X530852Y114724D02* +X534665Y110911D01* +X538478Y110911D01* +X540385Y112818D01* +X540385Y116631D01* +X538478Y118537D01* +X536572Y118537D01* +X534665Y116631D01* +X534665Y110911D01* +X540385Y126418D02* +X528945Y126418D01* +X528945Y122605D02* +X528945Y130231D01* +D11* +X78740Y0D02* +X73660Y0D01* +X0Y0D01* +X0Y21590D01* +X0Y25400D01* +X0Y29210D01* +X0Y46990D01* +X0Y50800D01* +X0Y54610D01* +X0Y72390D01* +X0Y76200D01* +X0Y80010D01* +X0Y97790D01* +X0Y101600D01* +X0Y105410D01* +X0Y123190D01* +X0Y127000D02* +X73660Y127000D01* +X73660Y21590D02* +X73660Y0D01* +X73660Y21590D02* +X73660Y25400D01* +X73660Y29210D01* +X73660Y46990D01* +X73660Y50800D01* +X73660Y54610D01* +X73660Y72390D01* +X73660Y76200D01* +X73660Y80010D01* +X73660Y97790D01* +X73660Y101600D01* +X73660Y105410D01* +X73660Y123190D01* +X73660Y127000D01* +X73660Y101600D02* +X0Y101600D01* +X0Y76200D02* +X73660Y76200D01* +X73660Y50800D02* +X0Y50800D01* +X0Y25400D02* +X73660Y25400D01* +D16* +X73660Y21590D02* +X0Y21590D01* +X0Y29210D02* +X73660Y29210D01* +X73660Y46990D02* +X0Y46990D01* +X0Y54610D02* +X73660Y54610D01* +X73660Y72390D02* +X0Y72390D01* +X0Y80010D02* +X73660Y80010D01* +X73660Y97790D02* +X0Y97790D01* +X0Y105410D02* +X73660Y105410D01* +D11* +X73660Y123190D02* +X0Y123190D01* +X0Y127000D01* +X0Y130810D01* +D16* +X73660Y130810D01* +D11* +X78740Y203200D02* +X78740Y0D01* +X0Y130810D02* +X0Y148590D01* +X0Y152400D02* +X73660Y152400D01* +X73660Y130810D02* +X73660Y127000D01* +X73660Y130810D02* +X73660Y148590D01* +X73660Y152400D01* +D16* +X73660Y148590D02* +X0Y148590D01* +D11* +X0Y152400D01* +X0Y156210D01* +X0Y173990D01* +X0Y177800D01* +X73660Y177800D01* +D16* +X73660Y156210D02* +X0Y156210D01* +D11* +X73660Y156210D02* +X73660Y152400D01* +X73660Y156210D02* +X73660Y173990D01* +X73660Y177800D01* +X0Y177800D02* +X0Y181610D01* +X0Y203200D01* +X73660Y203200D01* +X78740Y203200D01* +X73660Y181610D02* +X73660Y177800D01* +X73660Y181610D02* +X73660Y203200D01* +D16* +X73660Y181610D02* +X0Y181610D01* +X0Y173990D02* +X73660Y173990D01* +D10* +X59062Y159385D02* +X51435Y159385D01* +X59062Y167012D01* +X59062Y168918D01* +X57155Y170825D01* +X53342Y170825D01* +X51435Y168918D01* +X53342Y18425D02* +X51435Y16518D01* +X53342Y18425D02* +X57155Y18425D01* +X59062Y16518D01* +X59062Y14612D01* +X57155Y12705D01* +X59062Y10798D01* +X59062Y8892D01* +X57155Y6985D01* +X53342Y6985D01* +X51435Y8892D01* +X51435Y10798D01* +X53342Y12705D01* +X51435Y14612D01* +X51435Y16518D01* +X53342Y12705D02* +X57155Y12705D01* +X51435Y143518D02* +X53342Y145425D01* +X57155Y145425D01* +X59062Y143518D01* +X59062Y141612D01* +X57155Y139705D01* +X55248Y139705D01* +X57155Y139705D02* +X59062Y137798D01* +X59062Y135892D01* +X57155Y133985D01* +X53342Y133985D01* +X51435Y135892D01* +X57155Y120025D02* +X57155Y108585D01* +X51435Y114305D02* +X57155Y120025D01* +X59062Y114305D02* +X51435Y114305D01* +X51435Y94625D02* +X59062Y94625D01* +X51435Y94625D02* +X51435Y88905D01* +X55248Y90812D01* +X57155Y90812D01* +X59062Y88905D01* +X59062Y85092D01* +X57155Y83185D01* +X53342Y83185D01* +X51435Y85092D01* +X59062Y69225D02* +X55248Y67318D01* +X51435Y63505D01* +X51435Y59692D01* +X53342Y57785D01* +X57155Y57785D01* +X59062Y59692D01* +X59062Y61598D01* +X57155Y63505D01* +X51435Y63505D01* +X51435Y43825D02* +X59062Y43825D01* +X59062Y41918D01* +X51435Y34292D01* +X51435Y32385D01* +X51435Y192412D02* +X55248Y196225D01* +X55248Y184785D01* +X51435Y184785D02* +X59062Y184785D01* +D11* +X599440Y0D02* +X627380Y0D01* +X599440Y0D02* +X599440Y25400D01* +X627380Y25400D02* +X627380Y0D01* +X627380Y50800D02* +X599440Y50800D01* +X627380Y50800D02* +X627380Y76200D01* +X627380Y25400D02* +X599440Y25400D01* +X599440Y50800D01* +X627380Y50800D02* +X627380Y25400D01* +D17* +X635000Y63500D02* +X681990Y63500D01* +X681990Y38100D02* +X635000Y38100D01* +X635000Y12700D02* +X681990Y12700D01* +D11* +X599440Y50800D02* +X599440Y76200D01* +X599440Y101600D01* +X627380Y101600D01* +X599440Y101600D02* +X599440Y127000D01* +X627380Y127000D01* +X627380Y101600D01* +X627380Y76200D02* +X599440Y76200D01* +X627380Y76200D02* +X627380Y101600D01* +X599440Y127000D02* +X599440Y152400D01* +X627380Y152400D02* +X627380Y127000D01* +X627380Y177800D02* +X599440Y177800D01* +X599440Y203200D01* +X627380Y203200D01* +X627380Y177800D01* +X627380Y152400D02* +X599440Y152400D01* +X599440Y177800D01* +X627380Y177800D02* +X627380Y152400D01* +D17* +X635000Y190500D02* +X681990Y190500D01* +X681990Y165100D02* +X635000Y165100D01* +X635000Y139700D02* +X681990Y139700D01* +X681990Y114300D02* +X635000Y114300D01* +X635000Y88900D02* +X681990Y88900D01* +D10* +X605155Y192412D02* +X608968Y196225D01* +X608968Y184785D01* +X605155Y184785D02* +X612782Y184785D01* +X612782Y159385D02* +X605155Y159385D01* +X612782Y167012D01* +X612782Y168918D01* +X610875Y170825D01* +X607062Y170825D01* +X605155Y168918D01* +X607062Y145425D02* +X605155Y143518D01* +X607062Y145425D02* +X610875Y145425D01* +X612782Y143518D01* +X612782Y141612D01* +X610875Y139705D01* +X608968Y139705D01* +X610875Y139705D02* +X612782Y137798D01* +X612782Y135892D01* +X610875Y133985D01* +X607062Y133985D01* +X605155Y135892D01* +X610875Y120025D02* +X610875Y108585D01* +X605155Y114305D02* +X610875Y120025D01* +X612782Y114305D02* +X605155Y114305D01* +X605155Y94625D02* +X612782Y94625D01* +X605155Y94625D02* +X605155Y88905D01* +X608968Y90812D01* +X610875Y90812D01* +X612782Y88905D01* +X612782Y85092D01* +X610875Y83185D01* +X607062Y83185D01* +X605155Y85092D01* +X612782Y69225D02* +X608968Y67318D01* +X605155Y63505D01* +X605155Y59692D01* +X607062Y57785D01* +X610875Y57785D01* +X612782Y59692D01* +X612782Y61598D01* +X610875Y63505D01* +X605155Y63505D01* +X605155Y43825D02* +X612782Y43825D01* +X612782Y41918D01* +X605155Y34292D01* +X605155Y32385D01* +X607062Y18425D02* +X605155Y16518D01* +X607062Y18425D02* +X610875Y18425D01* +X612782Y16518D01* +X612782Y14612D01* +X610875Y12705D01* +X612782Y10798D01* +X612782Y8892D01* +X610875Y6985D01* +X607062Y6985D01* +X605155Y8892D01* +X605155Y10798D01* +X607062Y12705D01* +X605155Y14612D01* +X605155Y16518D01* +X607062Y12705D02* +X610875Y12705D01* +D18* +X631190Y63500D03* +X631190Y38100D03* +X631190Y12700D03* +X631190Y190500D03* +X631190Y165100D03* +X631190Y139700D03* +X631190Y114300D03* +X631190Y88900D03* +D19* +X596138Y12700D03* +X596138Y38100D03* +X596138Y63500D03* +X596138Y88900D03* +X596138Y114300D03* +X596138Y139700D03* +X596138Y165100D03* +X596138Y190500D03* +D20* +X309880Y148590D02* +X309880Y105410D01* +X248920Y105410D02* +X248920Y148590D01* +X269240Y96520D02* +X289380Y96520D01* +X289680Y157480D02* +X269240Y157480D01* +X261620Y127000D02* +X261625Y127436D01* +X261641Y127872D01* +X261668Y128308D01* +X261706Y128743D01* +X261754Y129176D01* +X261812Y129609D01* +X261882Y130040D01* +X261962Y130469D01* +X262052Y130896D01* +X262153Y131320D01* +X262264Y131742D01* +X262386Y132161D01* +X262517Y132577D01* +X262659Y132990D01* +X262811Y133399D01* +X262973Y133804D01* +X263145Y134205D01* +X263327Y134602D01* +X263518Y134994D01* +X263719Y135381D01* +X263930Y135764D01* +X264150Y136141D01* +X264379Y136512D01* +X264616Y136878D01* +X264863Y137238D01* +X265119Y137592D01* +X265383Y137939D01* +X265656Y138280D01* +X265937Y138613D01* +X266226Y138940D01* +X266523Y139260D01* +X266828Y139572D01* +X267140Y139877D01* +X267460Y140174D01* +X267787Y140463D01* +X268120Y140744D01* +X268461Y141017D01* +X268808Y141281D01* +X269162Y141537D01* +X269522Y141784D01* +X269888Y142021D01* +X270259Y142250D01* +X270636Y142470D01* +X271019Y142681D01* +X271406Y142882D01* +X271798Y143073D01* +X272195Y143255D01* +X272596Y143427D01* +X273001Y143589D01* +X273410Y143741D01* +X273823Y143883D01* +X274239Y144014D01* +X274658Y144136D01* +X275080Y144247D01* +X275504Y144348D01* +X275931Y144438D01* +X276360Y144518D01* +X276791Y144588D01* +X277224Y144646D01* +X277657Y144694D01* +X278092Y144732D01* +X278528Y144759D01* +X278964Y144775D01* +X279400Y144780D01* +X279836Y144775D01* +X280272Y144759D01* +X280708Y144732D01* +X281143Y144694D01* +X281576Y144646D01* +X282009Y144588D01* +X282440Y144518D01* +X282869Y144438D01* +X283296Y144348D01* +X283720Y144247D01* +X284142Y144136D01* +X284561Y144014D01* +X284977Y143883D01* +X285390Y143741D01* +X285799Y143589D01* +X286204Y143427D01* +X286605Y143255D01* +X287002Y143073D01* +X287394Y142882D01* +X287781Y142681D01* +X288164Y142470D01* +X288541Y142250D01* +X288912Y142021D01* +X289278Y141784D01* +X289638Y141537D01* +X289992Y141281D01* +X290339Y141017D01* +X290680Y140744D01* +X291013Y140463D01* +X291340Y140174D01* +X291660Y139877D01* +X291972Y139572D01* +X292277Y139260D01* +X292574Y138940D01* +X292863Y138613D01* +X293144Y138280D01* +X293417Y137939D01* +X293681Y137592D01* +X293937Y137238D01* +X294184Y136878D01* +X294421Y136512D01* +X294650Y136141D01* +X294870Y135764D01* +X295081Y135381D01* +X295282Y134994D01* +X295473Y134602D01* +X295655Y134205D01* +X295827Y133804D01* +X295989Y133399D01* +X296141Y132990D01* +X296283Y132577D01* +X296414Y132161D01* +X296536Y131742D01* +X296647Y131320D01* +X296748Y130896D01* +X296838Y130469D01* +X296918Y130040D01* +X296988Y129609D01* +X297046Y129176D01* +X297094Y128743D01* +X297132Y128308D01* +X297159Y127872D01* +X297175Y127436D01* +X297180Y127000D01* +X297175Y126564D01* +X297159Y126128D01* +X297132Y125692D01* +X297094Y125257D01* +X297046Y124824D01* +X296988Y124391D01* +X296918Y123960D01* +X296838Y123531D01* +X296748Y123104D01* +X296647Y122680D01* +X296536Y122258D01* +X296414Y121839D01* +X296283Y121423D01* +X296141Y121010D01* +X295989Y120601D01* +X295827Y120196D01* +X295655Y119795D01* +X295473Y119398D01* +X295282Y119006D01* +X295081Y118619D01* +X294870Y118236D01* +X294650Y117859D01* +X294421Y117488D01* +X294184Y117122D01* +X293937Y116762D01* +X293681Y116408D01* +X293417Y116061D01* +X293144Y115720D01* +X292863Y115387D01* +X292574Y115060D01* +X292277Y114740D01* +X291972Y114428D01* +X291660Y114123D01* +X291340Y113826D01* +X291013Y113537D01* +X290680Y113256D01* +X290339Y112983D01* +X289992Y112719D01* +X289638Y112463D01* +X289278Y112216D01* +X288912Y111979D01* +X288541Y111750D01* +X288164Y111530D01* +X287781Y111319D01* +X287394Y111118D01* +X287002Y110927D01* +X286605Y110745D01* +X286204Y110573D01* +X285799Y110411D01* +X285390Y110259D01* +X284977Y110117D01* +X284561Y109986D01* +X284142Y109864D01* +X283720Y109753D01* +X283296Y109652D01* +X282869Y109562D01* +X282440Y109482D01* +X282009Y109412D01* +X281576Y109354D01* +X281143Y109306D01* +X280708Y109268D01* +X280272Y109241D01* +X279836Y109225D01* +X279400Y109220D01* +X278964Y109225D01* +X278528Y109241D01* +X278092Y109268D01* +X277657Y109306D01* +X277224Y109354D01* +X276791Y109412D01* +X276360Y109482D01* +X275931Y109562D01* +X275504Y109652D01* +X275080Y109753D01* +X274658Y109864D01* +X274239Y109986D01* +X273823Y110117D01* +X273410Y110259D01* +X273001Y110411D01* +X272596Y110573D01* +X272195Y110745D01* +X271798Y110927D01* +X271406Y111118D01* +X271019Y111319D01* +X270636Y111530D01* +X270259Y111750D01* +X269888Y111979D01* +X269522Y112216D01* +X269162Y112463D01* +X268808Y112719D01* +X268461Y112983D01* +X268120Y113256D01* +X267787Y113537D01* +X267460Y113826D01* +X267140Y114123D01* +X266828Y114428D01* +X266523Y114740D01* +X266226Y115060D01* +X265937Y115387D01* +X265656Y115720D01* +X265383Y116061D01* +X265119Y116408D01* +X264863Y116762D01* +X264616Y117122D01* +X264379Y117488D01* +X264150Y117859D01* +X263930Y118236D01* +X263719Y118619D01* +X263518Y119006D01* +X263327Y119398D01* +X263145Y119795D01* +X262973Y120196D01* +X262811Y120601D01* +X262659Y121010D01* +X262517Y121423D01* +X262386Y121839D01* +X262264Y122258D01* +X262153Y122680D01* +X262052Y123104D01* +X261962Y123531D01* +X261882Y123960D01* +X261812Y124391D01* +X261754Y124824D01* +X261706Y125257D01* +X261668Y125692D01* +X261641Y126128D01* +X261625Y126564D01* +X261620Y127000D01* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/soldermask_bottom.gbr b/gerbonara/gerber/tests/resources/eagle-newer/soldermask_bottom.gbr new file mode 100644 index 0000000..9c2f67e --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/soldermask_bottom.gbr @@ -0,0 +1,93 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Soldermask,Bot,1* +G04 #@! %TF.FilePolarity,Negative* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10P,2.034460X8X112.500000*% +%ADD11C,2.743200*% +%ADD12P,2.969212X8X292.500000*% +%ADD13P,2.034460X8X292.500000*% +%ADD14C,1.879600*% +%ADD15C,2.082800*% +%ADD16C,2.082800*% + + +D10* +X292100Y63500D03* +X273050Y50800D03* +X292100Y38100D03* +X381000Y63500D03* +X361950Y50800D03* +X381000Y38100D03* +D11* +X165100Y76200D03* +D12* +X165100Y25400D03* +D13* +X228600Y165100D03* +X228600Y38100D03* +D10* +X330200Y38100D03* +X330200Y165100D03* +D14* +X457200Y160782D02* +X457200Y144018D01* +X457200Y59182D02* +X457200Y42418D01* +D10* +X419100Y38100D03* +X419100Y165100D03* +D14* +X499618Y88900D02* +X516382Y88900D01* +X516382Y114300D02* +X499618Y114300D01* +X499618Y63500D02* +X516382Y63500D01* +X97282Y190500D02* +X80518Y190500D01* +X80518Y165100D02* +X97282Y165100D01* +X97282Y139700D02* +X80518Y139700D01* +X80518Y114300D02* +X97282Y114300D01* +X97282Y88900D02* +X80518Y88900D01* +X80518Y63500D02* +X97282Y63500D01* +X97282Y38100D02* +X80518Y38100D01* +X80518Y12700D02* +X97282Y12700D01* +D15* +X574802Y12700D02* +X593598Y12700D01* +X593598Y38100D02* +X574802Y38100D01* +X574802Y63500D02* +X593598Y63500D01* +X593598Y88900D02* +X574802Y88900D01* +X574802Y114300D02* +X593598Y114300D01* +X593598Y139700D02* +X574802Y139700D01* +X574802Y165100D02* +X593598Y165100D01* +X593598Y190500D02* +X574802Y190500D01* +D16* +X302006Y159512D03* +X302006Y94488D03* +X256794Y159512D03* +X256794Y94488D03* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/soldermask_top.gbr b/gerbonara/gerber/tests/resources/eagle-newer/soldermask_top.gbr new file mode 100644 index 0000000..6450ac1 --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/soldermask_top.gbr @@ -0,0 +1,93 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Soldermask,Top,1* +G04 #@! %TF.FilePolarity,Negative* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* +%ADD10P,1.649562X8X112.500000*% +%ADD11C,2.743200*% +%ADD12P,2.969212X8X292.500000*% +%ADD13P,1.649562X8X292.500000*% +%ADD14C,1.524000*% +%ADD15C,1.727200*% +%ADD16C,2.082800*% + + +D10* +X292100Y63500D03* +X273050Y50800D03* +X292100Y38100D03* +X381000Y63500D03* +X361950Y50800D03* +X381000Y38100D03* +D11* +X165100Y76200D03* +D12* +X165100Y25400D03* +D13* +X228600Y165100D03* +X228600Y38100D03* +D10* +X330200Y38100D03* +X330200Y165100D03* +D14* +X457200Y159004D02* +X457200Y145796D01* +X457200Y57404D02* +X457200Y44196D01* +D10* +X419100Y38100D03* +X419100Y165100D03* +D14* +X501396Y88900D02* +X514604Y88900D01* +X514604Y114300D02* +X501396Y114300D01* +X501396Y63500D02* +X514604Y63500D01* +X95504Y190500D02* +X82296Y190500D01* +X82296Y165100D02* +X95504Y165100D01* +X95504Y139700D02* +X82296Y139700D01* +X82296Y114300D02* +X95504Y114300D01* +X95504Y88900D02* +X82296Y88900D01* +X82296Y63500D02* +X95504Y63500D01* +X95504Y38100D02* +X82296Y38100D01* +X82296Y12700D02* +X95504Y12700D01* +D15* +X576580Y12700D02* +X591820Y12700D01* +X591820Y38100D02* +X576580Y38100D01* +X576580Y63500D02* +X591820Y63500D01* +X591820Y88900D02* +X576580Y88900D01* +X576580Y114300D02* +X591820Y114300D01* +X591820Y139700D02* +X576580Y139700D01* +X576580Y165100D02* +X591820Y165100D01* +X591820Y190500D02* +X576580Y190500D01* +D16* +X302006Y159512D03* +X302006Y94488D03* +X256794Y159512D03* +X256794Y94488D03* +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/solderpaste_bottom.gbr b/gerbonara/gerber/tests/resources/eagle-newer/solderpaste_bottom.gbr new file mode 100644 index 0000000..46b20c7 --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/solderpaste_bottom.gbr @@ -0,0 +1,16 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Paste,Bot* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* + + +M02* diff --git a/gerbonara/gerber/tests/resources/eagle-newer/solderpaste_top.gbr b/gerbonara/gerber/tests/resources/eagle-newer/solderpaste_top.gbr new file mode 100644 index 0000000..b273e7d --- /dev/null +++ b/gerbonara/gerber/tests/resources/eagle-newer/solderpaste_top.gbr @@ -0,0 +1,16 @@ +G04 EAGLE Gerber X2 export* +G04 #@! %TF.Part,Single* +G04 #@! %TF.FileFunction,Paste,Top* +G04 #@! %TF.FilePolarity,Positive* +G04 #@! %TF.GenerationSoftware,Autodesk,EAGLE,9.0.0* +G04 #@! %TF.CreationDate,2019-08-08T19:20:38Z* +G75* +%MOMM*% +%FSLAX34Y34*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5*% +G01* + + +M02* diff --git a/gerbonara/gerber/tests/test_excellon.py b/gerbonara/gerber/tests/test_excellon.py index ef34f67..545bec9 100644 --- a/gerbonara/gerber/tests/test_excellon.py +++ b/gerbonara/gerber/tests/test_excellon.py @@ -1,366 +1,56 @@ #! /usr/bin/env python # -*- coding: utf-8 -*- - -# Author: Hamilton Kibbe <ham@hamiltonkib.be> +# Author: Jan Götte <code@jaseg.de> import os +import re +import math +import functools +import tempfile +import shutil +from argparse import Namespace +from itertools import chain +from pathlib import Path +from contextlib import contextmanager +from PIL import Image + import pytest +from ..excellon import ExcellonFile from ..cam import FileSettings -from ..excellon import read, detect_excellon_format, ExcellonFile, ExcellonParser -from ..excellon import DrillHit, DrillSlot -from ..excellon_statements import ExcellonTool, RouteModeStmt - - -NCDRILL_FILE = os.path.join(os.path.dirname(__file__), "resources/ncdrill.DRD") - - -def test_format_detection(): - """ Test file type detection - """ - with open(NCDRILL_FILE, "r") as f: - data = f.read() - settings = detect_excellon_format(data) - assert settings["format"] == (2, 4) - assert settings["zeros"] == "trailing" - - settings = detect_excellon_format(filename=NCDRILL_FILE) - assert settings["format"] == (2, 4) - assert settings["zeros"] == "trailing" - - -def test_read(): - ncdrill = read(NCDRILL_FILE) - assert isinstance(ncdrill, ExcellonFile) - - -def test_write(): - ncdrill = read(NCDRILL_FILE) - ncdrill.write("test.ncd") - with open(NCDRILL_FILE, "r") as src: - srclines = src.readlines() - with open("test.ncd", "r") as res: - for idx, line in enumerate(res): - assert line.strip() == srclines[idx].strip() - os.remove("test.ncd") - - -def test_read_settings(): - ncdrill = read(NCDRILL_FILE) - assert ncdrill.settings["format"] == (2, 4) - assert ncdrill.settings["zeros"] == "trailing" - - -def test_bounding_box(): - ncdrill = read(NCDRILL_FILE) - xbound, ybound = ncdrill.bounding_box - pytest.approx(xbound, (0.1300, 2.1430)) - pytest.approx(ybound, (0.3946, 1.7164)) - - -def test_report(): - ncdrill = read(NCDRILL_FILE) - rprt = ncdrill.report() - - -def test_conversion(): - import copy - - ncdrill = read(NCDRILL_FILE) - assert ncdrill.settings.units == "inch" - ncdrill_inch = copy.deepcopy(ncdrill) - - ncdrill.to_metric() - assert ncdrill.settings.units == "metric" - for tool in iter(ncdrill_inch.tools.values()): - tool.to_metric() - - for statement in ncdrill_inch.statements: - statement.to_metric() - - for m_tool, i_tool in zip( - iter(ncdrill.tools.values()), iter(ncdrill_inch.tools.values()) - ): - assert i_tool == m_tool - - for m, i in zip(ncdrill.primitives, ncdrill_inch.primitives): - - assert m.position == i.position, "%s not equal to %s" % (m, i) - assert m.diameter == i.diameter, "%s not equal to %s" % (m, i) - - -def test_parser_hole_count(): - settings = FileSettings(**detect_excellon_format(NCDRILL_FILE)) - p = ExcellonParser(settings) - p.parse(NCDRILL_FILE) - assert p.hole_count == 36 - - -def test_parser_hole_sizes(): - settings = FileSettings(**detect_excellon_format(NCDRILL_FILE)) - p = ExcellonParser(settings) - p.parse(NCDRILL_FILE) - assert p.hole_sizes == [0.0236, 0.0354, 0.04, 0.126, 0.128] - - -def test_parse_whitespace(): - p = ExcellonParser(FileSettings()) - assert p._parse_line(" ") == None - - -def test_parse_comment(): - p = ExcellonParser(FileSettings()) - p._parse_line(";A comment") - assert p.statements[0].comment == "A comment" - - -def test_parse_format_comment(): - p = ExcellonParser(FileSettings()) - p._parse_line("; FILE_FORMAT=9:9 ") - assert p.format == (9, 9) - - -def test_parse_header(): - p = ExcellonParser(FileSettings()) - p._parse_line("M48 ") - assert p.state == "HEADER" - p._parse_line("M95 ") - assert p.state == "DRILL" - - -def test_parse_rout(): - p = ExcellonParser(FileSettings()) - p._parse_line("G00X040944Y019842") - assert p.state == "ROUT" - p._parse_line("G05 ") - assert p.state == "DRILL" - - -def test_parse_version(): - p = ExcellonParser(FileSettings()) - p._parse_line("VER,1 ") - assert p.statements[0].version == 1 - p._parse_line("VER,2 ") - assert p.statements[1].version == 2 - - -def test_parse_format(): - p = ExcellonParser(FileSettings()) - p._parse_line("FMAT,1 ") - assert p.statements[0].format == 1 - p._parse_line("FMAT,2 ") - assert p.statements[1].format == 2 - - -def test_parse_units(): - settings = FileSettings(units="inch", zeros="trailing") - p = ExcellonParser(settings) - p._parse_line(";METRIC,LZ") - assert p.units == "inch" - assert p.zeros == "trailing" - p._parse_line("METRIC,LZ") - assert p.units == "metric" - assert p.zeros == "leading" - - -def test_parse_incremental_mode(): - settings = FileSettings(units="inch", zeros="trailing") - p = ExcellonParser(settings) - assert p.notation == "absolute" - p._parse_line("ICI,ON ") - assert p.notation == "incremental" - p._parse_line("ICI,OFF ") - assert p.notation == "absolute" - - -def test_parse_absolute_mode(): - settings = FileSettings(units="inch", zeros="trailing") - p = ExcellonParser(settings) - assert p.notation == "absolute" - p._parse_line("ICI,ON ") - assert p.notation == "incremental" - p._parse_line("G90 ") - assert p.notation == "absolute" - - -def test_parse_repeat_hole(): - p = ExcellonParser(FileSettings()) - p.active_tool = ExcellonTool(FileSettings(), number=8) - p._parse_line("R03X1.5Y1.5") - assert p.statements[0].count == 3 - - -def test_parse_incremental_position(): - p = ExcellonParser(FileSettings(notation="incremental")) - p._parse_line("X01Y01") - p._parse_line("X01Y01") - assert p.pos == [2.0, 2.0] - - -def test_parse_unknown(): - p = ExcellonParser(FileSettings()) - p._parse_line("Not A Valid Statement") - assert p.statements[0].stmt == "Not A Valid Statement" - - -def test_drill_hit_units_conversion(): - """ Test unit conversion for drill hits - """ - # Inch hit - settings = FileSettings(units="inch") - tool = ExcellonTool(settings, diameter=1.0) - hit = DrillHit(tool, (1.0, 1.0)) - - assert hit.tool.settings.units == "inch" - assert hit.tool.diameter == 1.0 - assert hit.position == (1.0, 1.0) - - # No Effect - hit.to_inch() - - assert hit.tool.settings.units == "inch" - assert hit.tool.diameter == 1.0 - assert hit.position == (1.0, 1.0) - - # Should convert - hit.to_metric() - - assert hit.tool.settings.units == "metric" - assert hit.tool.diameter == 25.4 - assert hit.position == (25.4, 25.4) - - # No Effect - hit.to_metric() - - assert hit.tool.settings.units == "metric" - assert hit.tool.diameter == 25.4 - assert hit.position == (25.4, 25.4) - - # Convert back to inch - hit.to_inch() - - assert hit.tool.settings.units == "inch" - assert hit.tool.diameter == 1.0 - assert hit.position == (1.0, 1.0) - - -def test_drill_hit_offset(): - TEST_VECTORS = [ - ((0.0, 0.0), (0.0, 1.0), (0.0, 1.0)), - ((0.0, 0.0), (1.0, 1.0), (1.0, 1.0)), - ((1.0, 1.0), (0.0, -1.0), (1.0, 0.0)), - ((1.0, 1.0), (-1.0, -1.0), (0.0, 0.0)), - ] - for position, offset, expected in TEST_VECTORS: - settings = FileSettings(units="inch") - tool = ExcellonTool(settings, diameter=1.0) - hit = DrillHit(tool, position) - - assert hit.position == position - - hit.offset(offset[0], offset[1]) - - assert hit.position == expected - - -def test_drill_slot_units_conversion(): - """ Test unit conversion for drill hits - """ - # Inch hit - settings = FileSettings(units="inch") - tool = ExcellonTool(settings, diameter=1.0) - hit = DrillSlot(tool, (1.0, 1.0), (10.0, 10.0), DrillSlot.TYPE_ROUT) - - assert hit.tool.settings.units == "inch" - assert hit.tool.diameter == 1.0 - assert hit.start == (1.0, 1.0) - assert hit.end == (10.0, 10.0) - - # No Effect - hit.to_inch() - - assert hit.tool.settings.units == "inch" - assert hit.tool.diameter == 1.0 - assert hit.start == (1.0, 1.0) - assert hit.end == (10.0, 10.0) - - # Should convert - hit.to_metric() - - assert hit.tool.settings.units == "metric" - assert hit.tool.diameter == 25.4 - assert hit.start == (25.4, 25.4) - assert hit.end == (254.0, 254.0) - - # No Effect - hit.to_metric() - - assert hit.tool.settings.units == "metric" - assert hit.tool.diameter == 25.4 - assert hit.start == (25.4, 25.4) - assert hit.end == (254.0, 254.0) - - # Convert back to inch - hit.to_inch() - - assert hit.tool.settings.units == "inch" - assert hit.tool.diameter == 1.0 - assert hit.start == (1.0, 1.0) - assert hit.end == (10.0, 10.0) - - -def test_drill_slot_offset(): - TEST_VECTORS = [ - ((0.0, 0.0), (1.0, 1.0), (0.0, 0.0), (0.0, 0.0), (1.0, 1.0)), - ((0.0, 0.0), (1.0, 1.0), (1.0, 0.0), (1.0, 0.0), (2.0, 1.0)), - ((0.0, 0.0), (1.0, 1.0), (1.0, 1.0), (1.0, 1.0), (2.0, 2.0)), - ((0.0, 0.0), (1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0), (0.0, 2.0)), - ] - for start, end, offset, expected_start, expected_end in TEST_VECTORS: - settings = FileSettings(units="inch") - tool = ExcellonTool(settings, diameter=1.0) - slot = DrillSlot(tool, start, end, DrillSlot.TYPE_ROUT) - - assert slot.start == start - assert slot.end == end - - slot.offset(offset[0], offset[1]) - - assert slot.start == expected_start - assert slot.end == expected_end - - -def test_drill_slot_bounds(): - TEST_VECTORS = [ - ((0.0, 0.0), (1.0, 1.0), 1.0, ((-0.5, 1.5), (-0.5, 1.5))), - ((0.0, 0.0), (1.0, 1.0), 0.5, ((-0.25, 1.25), (-0.25, 1.25))), - ] - for start, end, diameter, expected in TEST_VECTORS: - settings = FileSettings(units="inch") - tool = ExcellonTool(settings, diameter=diameter) - slot = DrillSlot(tool, start, end, DrillSlot.TYPE_ROUT) - assert slot.bounding_box == expected +from .image_support import * +from .utils import * + +REFERENCE_FILES = [ + 'easyeda/Gerber_Drill_NPTH.DRL', + 'easyeda/Gerber_Drill_PTH.DRL', + 'allegro-2/MinnowMax_RevA1_IPC356A.ipc', + 'altium-composite-drill/NC Drill/LimeSDR-QPCIe_1v2-SlotHoles.TXT', + 'altium-composite-drill/NC Drill/LimeSDR-QPCIe_1v2-RoundHoles.TXT', + 'pcb-rnd/power-art.xln', + 'siemens/80101_0125_F200_ThruHoleNonPlated.ncd', + 'siemens/80101_0125_F200_ThruHolePlated.ncd', + 'siemens/80101_0125_F200_ContourPlated.ncd', + 'Target3001/IRNASIoTbank1.2.Drill', + 'altium-old-composite-drill.txt', + 'fritzing/combined.txt', + 'ncdrill.DRD', + 'upverter/design_export.drl', + 'diptrace/mainboard.drl', + 'diptrace/panel.drl', + 'diptrace/keyboard.drl', + ] + +@filter_syntax_warnings +@pytest.mark.parametrize('reference', REFERENCE_FILES, indirect=True) +def test_round_trip(reference, tmpfile): + tmp = tmpfile('Output excellon', '.drl') + + ExcellonFile.open(reference).save(tmp) + + mean, _max, hist = excellon_difference(reference, tmp, diff_out=tmpfile('Difference', '.png')) + assert mean < 5e-5 + assert hist[9] == 0 + assert hist[3:].sum() < 5e-5*hist.size -def test_handling_multi_line_g00_and_g1(): - """Route Mode statements with coordinates on separate line are handled - """ - test_data = """ -% -M48 -M72 -T01C0.0236 -% -T01 -G00 -X040944Y019842 -M15 -G01 -X040944Y020708 -M16 -""" - uut = ExcellonParser() - uut.parse_raw(test_data) - assert ( - len([stmt for stmt in uut.statements if isinstance(stmt, RouteModeStmt)]) == 2 - ) diff --git a/gerbonara/gerber/tests/test_rs274x.py b/gerbonara/gerber/tests/test_rs274x.py index 7382997..68c5367 100644 --- a/gerbonara/gerber/tests/test_rs274x.py +++ b/gerbonara/gerber/tests/test_rs274x.py @@ -1,7 +1,6 @@ #! /usr/bin/env python # -*- coding: utf-8 -*- - -# Author: Hamilton Kibbe <ham@hamiltonkib.be> +# Author: Jan Götte <code@jaseg.de> import os import re import math diff --git a/gerbonara/gerber/utils.py b/gerbonara/gerber/utils.py index 060aa0b..d1045ad 100644 --- a/gerbonara/gerber/utils.py +++ b/gerbonara/gerber/utils.py @@ -27,6 +27,21 @@ import os from enum import Enum from math import radians, sin, cos, sqrt, atan2, pi +class RegexMatcher: + def __init__(self): + self.mapping = {} + + def match(self, regex): + def wrapper(fun): + nonlocal self + self.mapping[regex] = fun + return fun + return wrapper + + def handle(self, inst, line): + for regex, handler in self.mapping.items(): + if (match := re.fullmatch(regex, line)): + handler(match) class LengthUnit: def __init__(self, name, shorthand, this_in_mm): @@ -73,7 +88,7 @@ MILLIMETERS_PER_INCH = 25.4 Inch = LengthUnit('inch', 'in', MILLIMETERS_PER_INCH) MM = LengthUnit('millimeter', 'mm', 1) units = {'inch': Inch, 'mm': MM, None: None} -to_unit = lambda name: units[name] +to_unit = lambda name: units[name.lower() if name else None] class InterpMode(Enum): |