diff --git a/.github/workflows/build-sr2024.yml b/.github/workflows/build-sr2024.yml
new file mode 100644
index 0000000..d7bb26b
--- /dev/null
+++ b/.github/workflows/build-sr2024.yml
@@ -0,0 +1,50 @@
+name: Build SR2024 floorplan outputs
+
+on:
+ push:
+ paths:
+ - '2024/**'
+ - '.github/workflows/build-sr2024.yml'
+jobs:
+ build-2024:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python 3.11
+ uses: actions/setup-python@v4
+ with:
+ python-version: "3.11"
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r 2024/requirements.txt
+
+ sudo apt-get update
+ sudo apt-get install inkscape
+
+ - name: Install fonts
+ run: |
+ sudo mkdir -p /usr/share/fonts/sr-fonts
+
+ for f in resources/*.zip
+ do
+ unzip $f -d /usr/share/fonts/sr-fonts/$(basename ${f/.zip})
+ done
+
+ sudo fc-cache -fv
+
+ - name: Build sr2024 floorplans
+ run: |
+ cd 2024
+ ./generate_svg.py --teams team_names.yaml
+
+ ./populate-map.py
+ inkscape --export-type=pdf,png --export-dpi=192 output/map-with-teams.svg
+
+ - name: Archive floorplan files
+ uses: actions/upload-artifact@v3
+ with:
+ name: "sr2024 floorplans"
+ path: 2024/output
diff --git a/2024/.gitignore b/2024/.gitignore
new file mode 100644
index 0000000..23e8d39
--- /dev/null
+++ b/2024/.gitignore
@@ -0,0 +1,4 @@
+/venv
+
+full plans/
+output/
diff --git a/2024/README.md b/2024/README.md
new file mode 100644
index 0000000..7e2b6f9
--- /dev/null
+++ b/2024/README.md
@@ -0,0 +1,82 @@
+# Notes for 2024
+
+The templates here are intended to be 100:1 scale diagram of all the areas used in SUSU, they are believed to be within 5% accurate.
+Locations highlighted in red on one of the venue related layers require measurements to be taken to assure their size.
+
+#### Requires:
+- Python 3.6+
+- PyYaml
+
+```bash
+pip3 install --user -U -r requirements.txt
+```
+
+## Layers
+#### Floorplan layers:
+- Notes *(Additional notes)*
+- Dimensions
+ - VenueDimensions *(Dimensions relating to venue floorplan)*
+ - AreaDimensions *(Dimensions relating to area placement and layout)*
+- TLA *(Team names)*
+- Network
+ - Displays *(SRcomp info monitors)*
+ - VenueNetwork *(Venue installed networking)*
+ - NetworkEquipment *(Additional cables, switches, routers and access points)*
+- Power
+ - VenuePower *(Venue power outlets)*
+ - PowerEquipment *(Required power locations)*
+- Areas
+ - AreaTables *(Position of designated tables)*
+ - AreaZones *(Marked out zones)*
+- Shepherding *(Shepherd specific highlighting)*
+- General
+ - GeneralLabels *(global drawing labels)*
+ - VenueFloorplan *(venue floorplans)*
+ - Exits *(Fire exits and lanes)*
+
+
+#### Key Layers:
+- General
+- Network
+- Power
+- Areas
+- Shepherding
+
+
+#### YAML Layer Specification
+```yaml
+image: "cube.svg"
+title: "Cube Layout"
+show:
+ - ALL
+hide:
+ - shepherding
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - shepherding
+```
+
+#### JSON Layer Specification
+```json
+{
+ "image": "cube.svg",
+ "title": "Cube Layout",
+ "show": [
+ "All"
+ ],
+ "hide": [
+ "shepherding"
+ ],
+ "embed": [{
+ "marker": "KEY__",
+ "image": "key.svg",
+ "show":[ "ALL" ],
+ "hide": [ "shepherding" ]
+ }]
+}
+```
diff --git a/2024/generate_svg.py b/2024/generate_svg.py
new file mode 100755
index 0000000..c7267c6
--- /dev/null
+++ b/2024/generate_svg.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python3
+
+import re
+import json
+import argparse
+import xml.etree.ElementTree as ET
+from pathlib import Path
+from contextlib import suppress
+
+import yaml
+
+
+def register_xml_namespaces(xml_file):
+ with open(xml_file, 'r') as file:
+ ns = dict([node for _, node in ET.iterparse(file, events=['start-ns'])])
+
+ for prefix in ns:
+ ET.register_namespace(prefix, ns[prefix])
+
+ return ns
+
+
+def load_config(conf_file):
+ try:
+ with open(conf_file, 'r') as file:
+ conf = json.load(file) # load json specification
+ except json.JSONDecodeError:
+ print(f"Failed to read {conf_file} as JSON, trying YAML")
+ with open(conf_file, 'r') as file:
+ conf = yaml.safe_load(file) # load yaml specification
+
+ return conf
+
+
+def print_layers(
+ root, show=[], hide=[],
+ ns={
+ 'svg': 'http://www.w3.org/2000/svg',
+ 'inkscape': 'http://www.inkscape.org/namespaces/inkscape'
+ },
+ prefix="", autoshow=False
+):
+ if prefix:
+ prefix += '/'
+
+ for child in root.findall('./svg:g[@inkscape:groupmode="layer"]', ns):
+ label = prefix + child.get(f'{{{ns["inkscape"]}}}label', "")
+
+ if autoshow:
+ if label in hide:
+ child.set('style', 'display:none')
+ print(f'Hide: {label}')
+ else:
+ child.attrib.pop('style', None)
+ print(f'Show: {label}')
+ else:
+ if label in hide:
+ child.set('style', 'display:none')
+ print(f'Hide: {label}')
+ elif label in show or 'ALL' in show:
+ child.attrib.pop('style', None)
+ print(f'Show: {label}')
+ child = print_layers(child, show, hide, ns, prefix=label, autoshow=True)
+ else:
+ child.set('style', 'display:none')
+ print(f'Hide: {label}')
+
+ return root
+
+
+def set_titles(root, title, version, scale, ns):
+ with suppress(IndexError, AttributeError, TypeError):
+ root.find('.//svg:text[svg:tspan="{{title}}"]', ns)[0].text = title
+ with suppress(IndexError, AttributeError, TypeError):
+ root.find('.//svg:text[svg:tspan="{{version}}"]', ns)[0].text = f"Version: {version}"
+ with suppress(IndexError, AttributeError, TypeError):
+ root.find('.//svg:text[svg:tspan="{{scale}}" ]', ns)[0].text = f"Scale 1:{scale:.0f}"
+
+ return root
+
+
+def insert_tlas(svg_root, teams, ns):
+ TLA = svg_root.find('svg:g[@inkscape:label="TLA"]', ns) # add team names
+ if TLA:
+ for team in TLA.findall('.//svg:text/svg:tspan', ns):
+ team_no = re.search(r'@T_(\d+)', team.text)
+ if team_no is not None:
+ team.text = teams.get(int(team_no[1]), '')
+
+ return svg_root
+
+
+def embed_svg(embedded, root, ns, template_dir, team_names=None):
+ print(f"Embedding {embedded['image']}")
+ embedded_root = ET.parse(Path(template_dir) / embedded['image']).getroot() # load svg
+
+ if team_names is not None:
+ embedded_root = insert_tlas(embedded_root, team_names, ns)
+
+ # display only selected layers or ALL
+ embedded_root = print_layers(
+ embedded_root,
+ embedded.get('show', ['ALL']),
+ embedded.get('hide', []),
+ ns=ns,
+ )
+
+ embed_marker = embedded['marker']
+ # get container that we will be inserting into
+ embed_parent = root.find(f'.//svg:rect[@id="{embed_marker}"]/..', ns)
+ if embed_parent is None:
+ print(f"Failed to find the marker {embed_marker}")
+ return
+
+ # get the element that will be replaced by the embed
+ embed_child = embed_parent.find(f'./svg:rect[@id="{embed_marker}"]', ns)
+ if embed_child is None:
+ print(f"Failed to find the marker {embed_marker}")
+ return
+
+ embed_index = list(embed_parent).index(embed_child)
+
+ for field in ['x', 'y', 'width', 'height']: # set x, y, height & width from the placeholder
+ embedded_root.set(field, embed_child.get(field))
+
+ embed_parent[embed_index] = embedded_root # replace element with svg
+ print(f"Embedded {embedded['image']}")
+ return root
+
+
+def generate_svg(spec_path, template_dir, out_dir, base_scale, teams_file=None):
+ team_names = None
+ spec = load_config(spec_path)
+
+ svg_file = Path(template_dir) / spec['image']
+ ns = register_xml_namespaces(svg_file)
+
+ root_tree = ET.parse(svg_file) # load svg
+ root = root_tree.getroot()
+
+ root = set_titles(
+ root,
+ spec.get('title', spec['image']),
+ spec.get('version', 0.1),
+ spec.get('scale', 1) * base_scale,
+ ns,
+ )
+
+ if teams_file:
+ team_names = load_config(teams_file)
+ root = insert_tlas(root, team_names, ns)
+
+ # set scale
+ try:
+ old_width = float(root.get('width')[:-2])
+ old_height = float(root.get('height')[:-2])
+ except TypeError:
+ print("Invalid SVG")
+
+ scale = spec.get('scale', 1)
+ root.set('width', str(old_width / scale) + "cm")
+ root.set('height', str(old_height / scale) + "cm")
+
+ # display only selected layers or ALL
+ print_layers(root, spec.get('show', ['ALL']), spec.get('hide', []), ns=ns)
+
+ for embedded in spec.get('embed', []): # add nested svgs (including key)
+ root = embed_svg(embedded, root, ns, template_dir, team_names)
+
+ out_dir = Path(out_dir)
+ out_dir.mkdir(exist_ok=True)
+
+ out_file = spec.get('title', 'output').replace(' ', '_') + '.svg'
+ root_tree.write(out_dir / out_file, xml_declaration=True, encoding='UTF-8')
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('specs', type=Path, nargs=argparse.OPTIONAL, default=Path('layouts/'), help=(
+ "Folder or file containing the YAML/JSON that defines what output SVG's are created, "
+ "defaults to '%(default)s'"
+ ))
+ parser.add_argument('-s', '--base-scale', type=int, default=100, help=(
+ "The initial 1:X scale that the template files are at, defaults to %(default)s"
+ ))
+ parser.add_argument('-t', '--templates', type=Path, default=Path('templates/'), help=(
+ "Folder containing the template SVG's, defaults to '%(default)s'"
+ ))
+ parser.add_argument('--teams', type=Path, default=None, help=(
+ "The YAML/JSON file containing a mapping of number to TLA"
+ ))
+ parser.add_argument('-o', '--output', type=Path, default=Path('output/'), help=(
+ "Folder to store the output SVG's, defaults to '%(default)s'"
+ ))
+
+ args = parser.parse_args()
+
+ if args.specs.is_file():
+ generate_svg(args.specs, args.templates, args.output, args.base_scale, teams_file=args.teams)
+ elif args.specs.is_dir():
+ for spec in args.specs.iterdir():
+ if not spec.is_file():
+ continue
+
+ print(f"Processing spec file {spec}")
+ generate_svg(spec, args.templates, args.output, args.base_scale, teams_file=args.teams)
+ else:
+ print("The specification is neither a file nor directory")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/2024/layouts/cube_layout.yaml b/2024/layouts/cube_layout.yaml
new file mode 100644
index 0000000..78e4fb9
--- /dev/null
+++ b/2024/layouts/cube_layout.yaml
@@ -0,0 +1,15 @@
+image: "cube.svg"
+title: "Cube Layout"
+version: 0.1
+show:
+ - ALL
+hide:
+ - Shepherding
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/cube_network.yaml b/2024/layouts/cube_network.yaml
new file mode 100644
index 0000000..1e536d4
--- /dev/null
+++ b/2024/layouts/cube_network.yaml
@@ -0,0 +1,17 @@
+image: "cube.svg"
+title: "Cube Network"
+version: 0.1
+show:
+ - General
+ - Network
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/cube_power.yaml b/2024/layouts/cube_power.yaml
new file mode 100644
index 0000000..d03f643
--- /dev/null
+++ b/2024/layouts/cube_power.yaml
@@ -0,0 +1,17 @@
+image: "cube.svg"
+title: "Cube Power"
+version: 0.1
+show:
+ - General
+ - Power
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/l2_layout.yaml b/2024/layouts/l2_layout.yaml
new file mode 100644
index 0000000..5debeec
--- /dev/null
+++ b/2024/layouts/l2_layout.yaml
@@ -0,0 +1,16 @@
+image: "L2.svg"
+title: "Level 2 Layout"
+version: 0.1
+scale: 2.5
+show:
+ - ALL
+hide:
+ - Shepherding
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/l2_network_power.yaml b/2024/layouts/l2_network_power.yaml
new file mode 100644
index 0000000..5277202
--- /dev/null
+++ b/2024/layouts/l2_network_power.yaml
@@ -0,0 +1,19 @@
+image: "L2.svg"
+title: "Level 2 Power & Network"
+version: 0.1
+scale: 2.5
+show:
+ - General
+ - Power
+ - Network
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/l2_public.yaml b/2024/layouts/l2_public.yaml
new file mode 100644
index 0000000..0cea12c
--- /dev/null
+++ b/2024/layouts/l2_public.yaml
@@ -0,0 +1,15 @@
+image: "L2.svg"
+title: "Level 2"
+version: 0.1
+scale: 2.5
+show:
+ - General
+ - Areas
+ - TLA
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - General
+ - Areas
\ No newline at end of file
diff --git a/2024/layouts/l3_layout.yaml b/2024/layouts/l3_layout.yaml
new file mode 100644
index 0000000..3c283f4
--- /dev/null
+++ b/2024/layouts/l3_layout.yaml
@@ -0,0 +1,16 @@
+image: "L3.svg"
+title: "Level 3 Layout"
+version: 0.1
+scale: 3
+show:
+ - ALL
+hide:
+ - Shepherding
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/l3_network.yaml b/2024/layouts/l3_network.yaml
new file mode 100644
index 0000000..bd9a7e2
--- /dev/null
+++ b/2024/layouts/l3_network.yaml
@@ -0,0 +1,19 @@
+image: "L3.svg"
+title: "Level 3 Network"
+version: 0.1
+scale: 3
+show:
+ - General
+ - Network
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
+ - Power
\ No newline at end of file
diff --git a/2024/layouts/l3_power.yaml b/2024/layouts/l3_power.yaml
new file mode 100644
index 0000000..f07217d
--- /dev/null
+++ b/2024/layouts/l3_power.yaml
@@ -0,0 +1,18 @@
+image: "L3.svg"
+title: "Level 3 Power"
+version: 0.1
+scale: 3
+show:
+ - General
+ - Power
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/l3_public.yaml b/2024/layouts/l3_public.yaml
new file mode 100644
index 0000000..1bcba59
--- /dev/null
+++ b/2024/layouts/l3_public.yaml
@@ -0,0 +1,15 @@
+image: "L3.svg"
+title: "Level 3"
+version: 0.1
+scale: 3
+show:
+ - General
+ - Areas
+ - TLA
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - General
+ - Areas
\ No newline at end of file
diff --git a/2024/layouts/l4_layout.yaml b/2024/layouts/l4_layout.yaml
new file mode 100644
index 0000000..a8546b5
--- /dev/null
+++ b/2024/layouts/l4_layout.yaml
@@ -0,0 +1,16 @@
+image: "L4.svg"
+title: "Level 4 Layout"
+version: 0.1
+scale: 1.5
+show:
+ - ALL
+hide:
+ - Shepherding
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
\ No newline at end of file
diff --git a/2024/layouts/l4_network.yaml b/2024/layouts/l4_network.yaml
new file mode 100644
index 0000000..40a9262
--- /dev/null
+++ b/2024/layouts/l4_network.yaml
@@ -0,0 +1,19 @@
+image: "L4.svg"
+title: "Level 4 Network"
+version: 0.1
+scale: 1.5
+show:
+ - General
+ - Network
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
+ - Power
\ No newline at end of file
diff --git a/2024/layouts/l4_power.yaml b/2024/layouts/l4_power.yaml
new file mode 100644
index 0000000..eb48ec0
--- /dev/null
+++ b/2024/layouts/l4_power.yaml
@@ -0,0 +1,19 @@
+image: "L4.svg"
+title: "Level 4 Power"
+version: 0.1
+scale: 1.5
+show:
+ - General
+ - Power
+ - Dimensions
+ - Areas
+ - Notes
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - ALL
+ hide:
+ - Shepherding
+ - Network
\ No newline at end of file
diff --git a/2024/layouts/l4_public.yaml b/2024/layouts/l4_public.yaml
new file mode 100644
index 0000000..f3fc867
--- /dev/null
+++ b/2024/layouts/l4_public.yaml
@@ -0,0 +1,15 @@
+image: "L4.svg"
+title: "Level 4"
+version: 0.1
+scale: 1.5
+show:
+ - General
+ - Areas
+ - TLA
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - General
+ - Areas
\ No newline at end of file
diff --git a/2024/layouts/shepherding.yaml b/2024/layouts/shepherding.yaml
new file mode 100644
index 0000000..5eaf0bf
--- /dev/null
+++ b/2024/layouts/shepherding.yaml
@@ -0,0 +1,52 @@
+image: "layout.svg"
+title: "Shepherding"
+version: 0.1
+show:
+ - ALL
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - General
+ - Areas
+ - Shepherding
+-
+ marker: "L2__"
+ image: "L2.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Shepherding
+ hide:
+ - General/GeneralLabels
+-
+ marker: "L3__"
+ image: "L3.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Shepherding
+ hide:
+ - General/GeneralLabels
+-
+ marker: "L4__"
+ image: "L4.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Shepherding
+ hide:
+ - General/GeneralLabels
+-
+ marker: "CUBE__"
+ image: "cube.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ hide:
+ - General/GeneralLabels
diff --git a/2024/layouts/venue_map.yaml b/2024/layouts/venue_map.yaml
new file mode 100644
index 0000000..f8eeff5
--- /dev/null
+++ b/2024/layouts/venue_map.yaml
@@ -0,0 +1,48 @@
+image: "layout.svg"
+title: "Venue Map"
+version: 0.1
+show:
+ - ALL
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - General
+ - Areas
+-
+ marker: "L2__"
+ image: "L2.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ hide:
+ - General/GeneralLabels
+-
+ marker: "L3__"
+ image: "L3.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ hide:
+ - General/GeneralLabels
+-
+ marker: "L4__"
+ image: "L4.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ hide:
+ - General/GeneralLabels
+-
+ marker: "CUBE__"
+ image: "cube.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ hide:
+ - General/GeneralLabels
diff --git a/2024/layouts/venue_tech_map.yaml b/2024/layouts/venue_tech_map.yaml
new file mode 100644
index 0000000..cf249b9
--- /dev/null
+++ b/2024/layouts/venue_tech_map.yaml
@@ -0,0 +1,58 @@
+image: "layout_tech.svg"
+title: "Venue Tech Map"
+version: 0.1
+show:
+ - ALL
+embed:
+-
+ marker: "KEY__"
+ image: "key.svg"
+ show:
+ - General
+ - Areas
+ - Power
+ - Network
+-
+ marker: "L2__"
+ image: "L2.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Power
+ - Network
+ hide:
+ - General/GeneralLabels
+-
+ marker: "L3__"
+ image: "L3.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Power
+ - Network
+ hide:
+ - General/GeneralLabels
+-
+ marker: "L4__"
+ image: "L4.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Power
+ - Network
+ hide:
+ - General/GeneralLabels
+-
+ marker: "CUBE__"
+ image: "cube.svg"
+ show:
+ - General
+ - Areas
+ - TLA
+ - Power
+ - Network
+ hide:
+ - General/GeneralLabels
diff --git a/2024/populate-map.py b/2024/populate-map.py
new file mode 100755
index 0000000..2bde4d6
--- /dev/null
+++ b/2024/populate-map.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+import re
+import argparse
+import xml.etree.ElementTree as ET
+from pathlib import Path
+
+from generate_svg import load_config, register_xml_namespaces
+
+
+def insert_tla_list(svg_root, teams, ns):
+ # Sort teams so the list is alphabetical by TLA
+ teams_alphabetical = sorted(teams.items(), key=lambda x: x[1])
+ teams_alphabetical = (
+ (idx, tla) for idx, tla in teams_alphabetical
+ # remove unused pits, represented with an em dash or hyphen
+ if tla not in ['—', '-']
+ )
+ team_dict = dict(enumerate(teams_alphabetical, start=1))
+
+ TLA = svg_root.find('svg:g[@inkscape:label="TLA"]', ns) # add team names
+ if TLA:
+ for team in TLA.findall('.//svg:text/svg:tspan', ns):
+ if team.text is None:
+ continue
+ team_no = re.search(r'@t_(\d+)', team.text)
+ if team_no is not None:
+ tla_data = team_dict.get(int(team_no[1]))
+ team.text = f"{tla_data[1]}:" if tla_data is not None else ""
+ else:
+ idx_no = re.search(r'@I_(\d+)', team.text)
+ if idx_no is not None:
+ tla_data = team_dict.get(int(idx_no[1]))
+ team.text = str(tla_data[0]) if tla_data is not None else ""
+
+ return svg_root
+
+
+def generate_map_svg(svg_file, out_file, teams_file=None):
+ ns = register_xml_namespaces(svg_file)
+
+ root_tree = ET.parse(svg_file) # load svg
+ root = root_tree.getroot()
+
+ if teams_file:
+ team_names = load_config(teams_file)
+ insert_tla_list(root, team_names, ns)
+
+ root_tree.write(Path(out_file), xml_declaration=True, encoding='UTF-8')
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-i', '--map', type=Path, default=Path('templates/map.svg'), help=(
+ "The template map SVG, defaults to '%(default)s'"
+ ))
+ parser.add_argument('--teams', type=Path, default=Path('team_names.yaml'), help=(
+ "The YAML/JSON file containing a mapping of number to TLA"
+ ))
+ parser.add_argument('-o', '--output', type=Path, default=Path('output/map-with-teams.svg'), help=(
+ "Filepath of the output SVG, defaults to '%(default)s'"
+ ))
+
+ args = parser.parse_args()
+
+ generate_map_svg(args.map, args.output, teams_file=args.teams)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/2024/requirements.txt b/2024/requirements.txt
new file mode 100644
index 0000000..c3726e8
--- /dev/null
+++ b/2024/requirements.txt
@@ -0,0 +1 @@
+pyyaml
diff --git a/2024/team_names.yaml b/2024/team_names.yaml
new file mode 100644
index 0000000..a31588f
--- /dev/null
+++ b/2024/team_names.yaml
@@ -0,0 +1,30 @@
+1: —
+2: —
+3: —
+4: —
+5: —
+6: —
+7: —
+8: —
+9: —
+10: —
+11: —
+12: —
+13: —
+14: —
+15: —
+16: —
+17: —
+18: —
+19: —
+20: —
+21: —
+22: —
+23: —
+24: —
+25: —
+26: —
+27: —
+28: —
+29: —
+30: —
diff --git a/2024/templates/L2.svg b/2024/templates/L2.svg
new file mode 100755
index 0000000..b9e1e7d
--- /dev/null
+++ b/2024/templates/L2.svg
@@ -0,0 +1,2057 @@
+
+
+
+
diff --git a/2024/templates/L3.svg b/2024/templates/L3.svg
new file mode 100755
index 0000000..8b1ad7b
--- /dev/null
+++ b/2024/templates/L3.svg
@@ -0,0 +1,3268 @@
+
+
+
+
diff --git a/2024/templates/L4.svg b/2024/templates/L4.svg
new file mode 100755
index 0000000..f08198d
--- /dev/null
+++ b/2024/templates/L4.svg
@@ -0,0 +1,1200 @@
+
+
+
+
diff --git a/2024/templates/cube.svg b/2024/templates/cube.svg
new file mode 100755
index 0000000..3b01a44
--- /dev/null
+++ b/2024/templates/cube.svg
@@ -0,0 +1,1291 @@
+
+
+
+
diff --git a/2024/templates/key.svg b/2024/templates/key.svg
new file mode 100755
index 0000000..1d50faa
--- /dev/null
+++ b/2024/templates/key.svg
@@ -0,0 +1,328 @@
+
+
+
+
diff --git a/2024/templates/layout.svg b/2024/templates/layout.svg
new file mode 100644
index 0000000..3a70325
--- /dev/null
+++ b/2024/templates/layout.svg
@@ -0,0 +1,194 @@
+
+
+
+
diff --git a/2024/templates/layout_tech.svg b/2024/templates/layout_tech.svg
new file mode 100644
index 0000000..a52ed25
--- /dev/null
+++ b/2024/templates/layout_tech.svg
@@ -0,0 +1,194 @@
+
+
+
+
diff --git a/2024/templates/map.svg b/2024/templates/map.svg
new file mode 100644
index 0000000..2dfffa4
--- /dev/null
+++ b/2024/templates/map.svg
@@ -0,0 +1,10026 @@
+
+
+
+