Compare commits

..

2 Commits
main ... falko

Author SHA1 Message Date
Falko 746fd8c267 dins 2026-05-03 09:13:26 +02:00
Falko 40a121a122 falkosachen 2026-05-03 09:13:26 +02:00
27 changed files with 5627 additions and 18693 deletions

1
.python-version 100644
View File

@ -0,0 +1 @@
3.11

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
id,price_eur, price_cn, price_usd, bestprice_eur, bestprice_cn, bestprice_usd,a,b,c,d,e,f,g,h,i,j,k,l,m
BB-108899,99.95,_,_,_,_,_,Listenpreis:99.95 EUR (7.2 ct/Teil),"DetailsVon: BlueBrixxEAN: 4060904014783Release: 2026Kategorien: Gebäude, Kinder, PopkulturHersteller-Kategorien: BBPlay, The Three Investigators",Inhalt1393 Teile,PreiseListenpreis:99.95 EUR (7.2 ct/Teil),"EU:BlueBrixx - 99,95 €¹"
BB-108899,99.95,_,_,_,_,_,Listenpreis:99.95 EUR (7.2 ct/Teil),"DetailsVon: BlueBrixxEAN: 4060904014783Release: 2026Kategorien: Gebäude, Kinder, PopkulturHersteller-Kategorien: BBPlay, The Three Investigators",Inhalt1393 Teile,PreiseListenpreis:99.95 EUR (7.2 ct/Teil),"EU:BlueBrixx - 99,95 €¹"
BB-108569,29.95,_,_,_,_,_,Listenpreis:29.95 EUR (5.2 ct/Teil),DetailsVon: BlueBrixxEAN: 4060904023020Steine von: XingbaoRelease: 2026Kategorie: TiereHersteller-Kategorie: BBPro,Inhalt579 TeileMaße: 25.5 x 24.3 x 59.6 cm (B x H x T),PreiseListenpreis:29.95 EUR (5.2 ct/Teil),"EU:BlueBrixx - 29,95 €¹"

Can't render this file because it is too large.

212
lego/graph.py 100644
View File

@ -0,0 +1,212 @@
# %% [markdown]
# Build the Lego Knowledge Graph using the sources in `/data`.
# %%
from rdflib import Graph, Namespace, XSD, OWL, RDF, RDFS, SKOS, URIRef, Literal
import pandas as pd
from datetime import datetime
# %% [markdown]
# Setup the requirements for building a knowledge graph
# %%
g = Graph()
thm = Namespace("https://thm.de/")
THM = Namespace("https://thm.de/ont/")
# %% [markdown]
# # Rebrickable
# %% [markdown]
# ![Rebrickable](\data\rebrickable\downloads_schema_v3.png)
# %%
re_colors = pd.read_csv("data/rebrickable/colors.csv")
re_elements = pd.read_csv("data/rebrickable/elements.csv")
re_inventories = pd.read_csv("data/rebrickable/inventories.csv")
re_inventory_minifigs = pd.read_csv("data/rebrickable/inventory_minifigs.csv")
re_inventory_parts = pd.read_csv("data/rebrickable/inventory_parts.csv")
re_inventory_sets = pd.read_csv("data/rebrickable/inventory_sets.csv")
re_minifigs = pd.read_csv("data/rebrickable/minifigs.csv")
re_part_categories = pd.read_csv("data/rebrickable/part_categories.csv")
re_part_relationships = pd.read_csv("data/rebrickable/part_relationships.csv")
re_parts = pd.read_csv("data/rebrickable/parts.csv")
re_sets = pd.read_csv("data/rebrickable/sets.csv")
re_themes = pd.read_csv("data/rebrickable/themes.csv")
# %% [markdown]
# Colors
# %%
for color in re_colors.itertuples(index=False):
color_ref = thm[f"colors/{color.id}"]
g.add((color_ref, RDFS.label, Literal(color.name, lang="en")))
g.add((color_ref, THM.color, Literal(color.rgb)))
g.add((color_ref, THM.is_transparent, Literal(color.is_trans, datatype=XSD.boolean)))
if not pd.isna(color.y1):
# First appearance
g.add((color_ref, THM.first_year, Literal(datetime(year = int(color.y1), month=1, day=1))))
if not pd.isna(color.y2):
# Last appearance
g.add((color_ref, THM.last_year, Literal(datetime(year = int(color.y2), month=1, day=1))))
# %% [markdown]
# Part Categories
# %%
for part_category in re_part_categories.itertuples(index=False):
part_category_ref = thm[f"part_category/{part_category.id}"]
g.add((part_category_ref, RDFS.label, Literal(part_category_ref, lang="en")))
# %% [markdown]
# Parts
# %%
for part in re_parts.itertuples(index=False):
part_ref = thm[f"part/{part.part_num}"]
g.add((part_ref, RDFS.label, Literal(part.name, lang="en")))
g.add((part_ref, THM.part_category, thm[f"part_category/{part.part_cat_id}"]))
g.add((part_ref, THM.part_material, Literal(part.part_material)))
# %% [markdown]
# Elements
# %%
for element in re_elements.itertuples(index=False):
part_ref = thm[f"part/{element.part_num}"]
color_ref = thm[f"colors/{element.color_id}"]
g.add((part_ref, THM.has_color, color_ref))
# %% [markdown]
# Part Relationships
# %%
for part_relationship in re_part_relationships.itertuples(index=False):
part_ref_parent = thm[f"part/{part_relationship.parent_part_num}"]
part_ref_child = thm[f"part/{part_relationship.child_part_num}"]
g.add((part_ref_parent, THM.has_child, part_ref_child))
# %% [markdown]
# Themes
# %%
for theme in re_themes.itertuples(index=False):
theme_ref = thm[f"theme/{int(theme.id)}"]
g.add((theme_ref, RDFS.label, Literal(theme.name, lang="en")))
if not pd.isna(theme.parent_id):
g.add((theme_ref, THM.parent_theme, thm[f"theme/{int(theme.parent_id)}"]))
# %% [markdown]
# Sets
# %%
for lego_set in re_sets.itertuples(index=False):
set_ref = thm[f"set/lego/{lego_set.set_num}"]
g.add((set_ref, RDFS.label, Literal(lego_set.name, lang="en")))
g.add((set_ref, THM.year, Literal(datetime(int(lego_set.year), 1, 1))))
g.add((set_ref, THM.theme, thm[f"theme/{int(lego_set.theme_id)}"]))
g.add((set_ref, THM.num_parts, Literal(int(lego_set.num_parts), datatype=XSD.integer)))
g.add((set_ref, THM.brand, Literal("Lego")))
# %% [markdown]
# Minifigures
# %%
for minifig in re_minifigs.itertuples(index=False):
minifig_ref = thm[f"minifig/{minifig.fig_num}"]
g.add((set_ref, RDFS.label, Literal(minifig.name, lang="en")))
g.add((set_ref, THM.num_parts, Literal(int(minifig.num_parts), datatype=XSD.integer)))
# %% [markdown]
# Now the ugly part: Inventories
# %%
for inventory in re_inventories.itertuples(index=False):
inventory_ref = thm[f"inventory/{inventory.id}"]
g.add((inventory_ref, THM.set, thm[f"sets/lego/{inventory.set_num}"]))
# %% [markdown]
# Inventories relate sets, minifigures and parts to each other, creating a kind of "top level set"
# (this takes a lot of time)
# %%
for inventory_part in re_inventory_parts.itertuples(index=False):
inventory_part_ref = thm[f"inventory_part/{inventory_part.inventory_id}/{inventory_part.part_num}"]
inventory_ref = thm[f"inventory/{inventory_part.inventory_id}"]
part_ref = thm[f"part/{inventory_part.part_num}"]
g.add((inventory_part_ref, RDFS.domain, inventory_ref))
g.add((inventory_part_ref, RDFS.range, part_ref))
g.add((inventory_part_ref, RDF.type, RDF.Property))
g.add((inventory_part_ref, THM.quantity, Literal(int(inventory_part.quantity), datatype=XSD.integer)))
g.add((inventory_part_ref, THM.is_spare, Literal(inventory_part.is_spare, datatype=XSD.boolean)))
g.add((inventory_part_ref, THM.color, thm[f"color/{inventory_part.color_id}"]))
# %%
for inventory_set in re_inventory_sets.itertuples(index=False):
inventory_set_ref = thm[f"inventory_set/{inventory_set.inventory_id}/{inventory_set.set_num}"]
inventory_ref = thm[f"inventory/{inventory_set.inventory_id}"]
set_ref = thm[f"set/lego/{inventory_set.set_num}"]
g.add((inventory_set_ref, RDFS.domain, inventory_ref))
g.add((inventory_set_ref, RDFS.range, set_ref))
g.add((inventory_set_ref, RDF.type, RDF.Property))
g.add((inventory_set_ref, THM.quantity, Literal(int(inventory_set.quantity), datatype=XSD.integer)))
# %%
for inventory_minifig in re_inventory_minifigs.itertuples(index=False):
inventory_minifig_ref = thm[f"inventory_minifig/{inventory_minifig.inventory_id}/{inventory_minifig.fig_num}"]
inventory_ref = thm[f"inventory/{inventory_minifig.inventory_id}"]
minifig_ref = thm[f"minifig/lego/{inventory_minifig.fig_num}"]
g.add((inventory_minifig_ref, RDFS.domain, inventory_ref))
g.add((inventory_minifig_ref, RDFS.range, minifig_ref))
g.add((inventory_minifig_ref, RDF.type, RDF.Property))
g.add((inventory_minifig_ref, THM.quantity, Literal(int(inventory_minifig.quantity), datatype=XSD.integer)))
# %% [markdown]
# Serialize the graph in turtle format
# %% [markdown]
# ```
# ___-------___
# _-~~ ~~-_
# _-~ /~-_
# /^\__/^\ /~ \ / \
# /| O|| O| / \_______________/ \
# | |___||__| / / \ \
# | \ / / \ \
# | (_______) /______/ \_________ \
# | / / \ / \
# \ \^\\ \ / \ /
# \ || \______________/ _-_ //\__//
# \ ||------_-~~-_ ------------- \ --/~ ~\ || __/
# ~-----||====/~ |==================| |/~~~~~
# (_(__/ ./ / \_\ \.
# (_(___/ \_____)_)
# ```
# %%
g.bind("thmont", THM)
g.serialize("lego_graph_rebrickable.ttl", format="turtle")

View File

@ -10,14 +10,15 @@
},
{
"cell_type": "code",
"execution_count": 257,
"execution_count": 2,
"id": "90209948",
"metadata": {},
"outputs": [],
"source": [
"from rdflib import Graph, Namespace, XSD, OWL, RDF, RDFS, SKOS, URIRef, Literal\n",
"import pandas as pd\n",
"import numpy as np"
"from datetime import datetime\n",
"import os"
]
},
{
@ -30,7 +31,7 @@
},
{
"cell_type": "code",
"execution_count": 258,
"execution_count": 3,
"id": "8e573135",
"metadata": {},
"outputs": [],
@ -40,6 +41,61 @@
"THM = Namespace(\"https://thm.de/ont/\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "class_hierarchy",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Graph identifier=Ne25ca93489ee450c8158409bd5d2a548 (<class 'rdflib.graph.Graph'>)>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Class hierarchy\n",
"g.add((THM.LegoEntity, RDF.type, OWL.Class))\n",
"g.add((THM.LegoEntity, RDFS.subClassOf, OWL.Thing))\n",
"\n",
"g.add((THM.PhysicalItem, RDF.type, OWL.Class))\n",
"g.add((THM.PhysicalItem, RDFS.subClassOf, THM.LegoEntity))\n",
"g.add((THM.Set, RDF.type, OWL.Class))\n",
"g.add((THM.Set, RDFS.subClassOf, THM.PhysicalItem))\n",
"g.add((THM.Part, RDF.type, OWL.Class))\n",
"g.add((THM.Part, RDFS.subClassOf, THM.PhysicalItem))\n",
"g.add((THM.Minifigure, RDF.type, OWL.Class))\n",
"g.add((THM.Minifigure, RDFS.subClassOf, THM.PhysicalItem))\n",
"\n",
"g.add((THM.CatalogEntry, RDF.type, OWL.Class))\n",
"g.add((THM.CatalogEntry, RDFS.subClassOf, THM.LegoEntity))\n",
"g.add((THM.Color, RDF.type, OWL.Class))\n",
"g.add((THM.Color, RDFS.subClassOf, THM.CatalogEntry))\n",
"g.add((THM.PartCategory, RDF.type, OWL.Class))\n",
"g.add((THM.PartCategory, RDFS.subClassOf, THM.CatalogEntry))\n",
"g.add((THM.Theme, RDF.type, OWL.Class))\n",
"g.add((THM.Theme, RDFS.subClassOf, THM.CatalogEntry))\n",
"\n",
"g.add((THM.Inventory, RDF.type, OWL.Class))\n",
"g.add((THM.Inventory, RDFS.subClassOf, THM.LegoEntity))\n",
"g.add((THM.InventoryEntry, RDF.type, OWL.Class))\n",
"g.add((THM.InventoryEntry, RDFS.subClassOf, THM.LegoEntity))\n",
"g.add((THM.InventoryPart, RDF.type, OWL.Class))\n",
"g.add((THM.InventoryPart, RDFS.subClassOf, THM.InventoryEntry))\n",
"g.add((THM.InventorySet, RDF.type, OWL.Class))\n",
"g.add((THM.InventorySet, RDFS.subClassOf, THM.InventoryEntry))\n",
"g.add((THM.InventoryMinifig, RDF.type, OWL.Class))\n",
"g.add((THM.InventoryMinifig, RDFS.subClassOf, THM.InventoryEntry))\n",
"\n",
"g.add((THM.Producer, RDF.type, OWL.Class))\n",
"g.add((THM.Producer, RDFS.subClassOf, THM.LegoEntity))"
]
},
{
"cell_type": "markdown",
"id": "d56199d5",
@ -58,7 +114,7 @@
},
{
"cell_type": "code",
"execution_count": 259,
"execution_count": 5,
"id": "d8a1fe84",
"metadata": {},
"outputs": [],
@ -87,7 +143,7 @@
},
{
"cell_type": "code",
"execution_count": 260,
"execution_count": 6,
"id": "ae505704",
"metadata": {},
"outputs": [],
@ -95,17 +151,15 @@
"for color in re_colors.itertuples(index=False):\n",
" color_ref = thm[f\"color/{color.id}\"]\n",
"\n",
" g.add((color_ref, RDF.type, THM.Color ))\n",
" g.add((color_ref, RDF.type, THM.Color))\n",
" g.add((color_ref, RDFS.label, Literal(color.name, lang=\"en\")))\n",
" g.add((color_ref, THM.rgbcolor, Literal(color.rgb)))\n",
" g.add((color_ref, THM.color, Literal(color.rgb)))\n",
" g.add((color_ref, THM.is_transparent, Literal(color.is_trans, datatype=XSD.boolean)))\n",
" \n",
" if not pd.isna(color.y1):\n",
" # First appearance\n",
" g.add((color_ref, THM.first_year, Literal(int(color.y1), datatype=XSD.integer)))\n",
" g.add((color_ref, THM.first_year, Literal(datetime(year = int(color.y1), month=1, day=1))))\n",
" if not pd.isna(color.y2):\n",
" # Last appearance\n",
" g.add((color_ref, THM.last_year, Literal(int(color.y2), datatype=XSD.integer)))\n"
" g.add((color_ref, THM.last_year, Literal(datetime(year = int(color.y2), month=1, day=1))))\n"
]
},
{
@ -118,7 +172,7 @@
},
{
"cell_type": "code",
"execution_count": 261,
"execution_count": 7,
"id": "fb9e17d6",
"metadata": {},
"outputs": [],
@ -126,8 +180,8 @@
"for part_category in re_part_categories.itertuples(index=False):\n",
" part_category_ref = thm[f\"part_category/{part_category.id}\"]\n",
"\n",
" g.add((part_category_ref, RDF.type, THM.PartCategory ))\n",
" g.add((part_category_ref, RDFS.label, Literal(part_category_ref, lang=\"en\")))"
" g.add((part_category_ref, RDF.type, THM.PartCategory))\n",
" g.add((part_category_ref, RDFS.label, Literal(part_category.name, lang=\"en\")))"
]
},
{
@ -140,7 +194,7 @@
},
{
"cell_type": "code",
"execution_count": 262,
"execution_count": 8,
"id": "8fdb080e",
"metadata": {},
"outputs": [],
@ -164,24 +218,16 @@
},
{
"cell_type": "code",
"execution_count": 263,
"execution_count": 9,
"id": "579b1d67",
"metadata": {},
"outputs": [],
"source": [
"for element in re_elements.itertuples(index=False):\n",
" element_ref = thm[f\"element/{element.element_id}\"]\n",
" part_ref = thm[f\"part/{element.part_num}\"]\n",
" color_ref = thm[f\"color/{element.color_id}\"]\n",
"\n",
" g.add((element_ref, RDF.type, RDF.Property))\n",
" g.add((element_ref, RDF.type, THM.Element))\n",
"\n",
" g.add((element_ref, RDFS.domain, THM.Part))\n",
" g.add((element_ref, RDFS.range, THM.Color))\n",
"\n",
" g.add((element_ref, THM.color, color_ref))\n",
" g.add((part_ref, THM.part, part_ref))"
" g.add((part_ref, THM.has_color, color_ref))"
]
},
{
@ -194,7 +240,7 @@
},
{
"cell_type": "code",
"execution_count": 264,
"execution_count": 10,
"id": "00db079a",
"metadata": {},
"outputs": [],
@ -203,8 +249,7 @@
" part_ref_parent = thm[f\"part/{part_relationship.parent_part_num}\"]\n",
" part_ref_child = thm[f\"part/{part_relationship.child_part_num}\"]\n",
"\n",
" g.add((part_ref_parent, THM.has_child, part_ref_child))\n",
" g.add((part_ref_child, THM.has_parent, part_ref_parent))"
" g.add((part_ref_parent, THM.has_child, part_ref_child))"
]
},
{
@ -217,7 +262,7 @@
},
{
"cell_type": "code",
"execution_count": 265,
"execution_count": 11,
"id": "1a529aae",
"metadata": {},
"outputs": [],
@ -242,7 +287,7 @@
},
{
"cell_type": "code",
"execution_count": 266,
"execution_count": 12,
"id": "29b357ef",
"metadata": {},
"outputs": [],
@ -252,7 +297,7 @@
"\n",
" g.add((set_ref, RDF.type, THM.Set))\n",
" g.add((set_ref, RDFS.label, Literal(lego_set.name, lang=\"en\")))\n",
" g.add((set_ref, THM.year, Literal(int(lego_set.year), datatype=XSD.integer)))\n",
" g.add((set_ref, THM.year, Literal(datetime(int(lego_set.year), 1, 1))))\n",
" g.add((set_ref, THM.theme, thm[f\"theme/{int(lego_set.theme_id)}\"]))\n",
" g.add((set_ref, THM.num_parts, Literal(int(lego_set.num_parts), datatype=XSD.integer)))\n",
" g.add((set_ref, THM.brand, Literal(\"Lego\")))"
@ -268,7 +313,7 @@
},
{
"cell_type": "code",
"execution_count": 267,
"execution_count": 13,
"id": "a67b3e70",
"metadata": {},
"outputs": [],
@ -276,7 +321,7 @@
"for minifig in re_minifigs.itertuples(index=False):\n",
" minifig_ref = thm[f\"minifig/{minifig.fig_num}\"]\n",
"\n",
" g.add((minifig_ref, RDF.type, THM.Minifig))\n",
" g.add((minifig_ref, RDF.type, THM.Minifigure))\n",
" g.add((minifig_ref, RDFS.label, Literal(minifig.name, lang=\"en\")))\n",
" g.add((minifig_ref, THM.num_parts, Literal(int(minifig.num_parts), datatype=XSD.integer)))"
]
@ -291,7 +336,7 @@
},
{
"cell_type": "code",
"execution_count": 268,
"execution_count": 14,
"id": "0c97dc4d",
"metadata": {},
"outputs": [],
@ -314,47 +359,25 @@
},
{
"cell_type": "code",
"execution_count": 269,
"execution_count": 15,
"id": "dc2ba03e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'\\nfor inventory_part in re_inventory_parts.itertuples(index=False):\\n inventory_part_ref = thm[f\"inventory_part/{inventory_part.inventory_id}/{inventory_part.part_num}\"]\\n\\n inventory_ref = thm[f\"inventory/{inventory_part.inventory_id}\"]\\n part_ref = thm[f\"part/{inventory_part.part_num}\"]\\n\\n g.add((inventory_part_ref, RDF.type, THM.PartInv))\\n g.add((inventory_part_ref, RDF.type, RDF.Property))\\n\\n g.add((inventory_part_ref, RDFS.domain, THM.Inventory))\\n g.add((inventory_part_ref, RDFS.range, THM.Part))\\n\\n g.add((inventory_ref, THM.contains, inventory_part_ref))\\n g.add((part_ref, THM.belongs, inventory_part_ref))\\n\\n g.add((inventory_part_ref, THM.quantity, Literal(int(inventory_part.quantity), datatype=XSD.integer)))\\n g.add((inventory_part_ref, THM.is_spare, Literal(inventory_part.is_spare, datatype=XSD.boolean)))\\n g.add((inventory_part_ref, THM.color, thm[f\"color/{inventory_part.color_id}\"]))\\n'"
]
},
"execution_count": 269,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"\"\"\"\n",
"for inventory_part in re_inventory_parts.itertuples(index=False):\n",
" inventory_part_ref = thm[f\"inventory_part/{inventory_part.inventory_id}/{inventory_part.part_num}\"]\n",
" \n",
" inventory_ref = thm[f\"inventory/{inventory_part.inventory_id}\"]\n",
" part_ref = thm[f\"part/{inventory_part.part_num}\"]\n",
"\n",
" g.add((inventory_part_ref, RDF.type, THM.PartInv))\n",
" g.add((inventory_part_ref, RDF.type, RDF.Property))\n",
"\n",
" g.add((inventory_part_ref, RDFS.domain, THM.Inventory))\n",
" g.add((inventory_part_ref, RDFS.range, THM.Part))\n",
" \n",
" g.add((inventory_ref, THM.contains, inventory_part_ref))\n",
" g.add((part_ref, THM.belongs, inventory_part_ref))\n",
"\n",
" g.add((inventory_part_ref, RDF.type, THM.InventoryPart))\n",
" g.add((inventory_part_ref, THM.inventory, thm[f\"inventory/{inventory_part.inventory_id}\"]))\n",
" g.add((inventory_part_ref, THM.part, thm[f\"part/{inventory_part.part_num}\"]))\n",
" g.add((inventory_part_ref, THM.quantity, Literal(int(inventory_part.quantity), datatype=XSD.integer)))\n",
" g.add((inventory_part_ref, THM.is_spare, Literal(inventory_part.is_spare, datatype=XSD.boolean)))\n",
" g.add((inventory_part_ref, THM.color, thm[f\"color/{inventory_part.color_id}\"]))\n",
"\"\"\""
" g.add((inventory_part_ref, THM.color, thm[f\"color/{inventory_part.color_id}\"]))"
]
},
{
"cell_type": "code",
"execution_count": 270,
"execution_count": 16,
"id": "8715a1cf",
"metadata": {},
"outputs": [],
@ -362,24 +385,15 @@
"for inventory_set in re_inventory_sets.itertuples(index=False):\n",
" inventory_set_ref = thm[f\"inventory_set/{inventory_set.inventory_id}/{inventory_set.set_num}\"]\n",
"\n",
" inventory_ref = thm[f\"inventory/{inventory_set.inventory_id}\"]\n",
" set_ref = thm[f\"set/lego/{inventory_set.set_num}\"]\n",
"\n",
" g.add((inventory_set_ref, RDF.type, THM.SetInv))\n",
" g.add((inventory_set_ref, RDF.type, RDF.Property))\n",
"\n",
" g.add((inventory_set_ref, RDFS.domain, THM.Inventory))\n",
" g.add((inventory_set_ref, RDFS.range, THM.Set))\n",
"\n",
" g.add((inventory_ref, THM.contains, inventory_set_ref))\n",
" g.add((set_ref, THM.belongs, inventory_set_ref))\n",
" \n",
" g.add((inventory_set_ref, RDF.type, THM.InventorySet))\n",
" g.add((inventory_set_ref, THM.inventory, thm[f\"inventory/{inventory_set.inventory_id}\"]))\n",
" g.add((inventory_set_ref, THM.set, thm[f\"set/lego/{inventory_set.set_num}\"]))\n",
" g.add((inventory_set_ref, THM.quantity, Literal(int(inventory_set.quantity), datatype=XSD.integer)))"
]
},
{
"cell_type": "code",
"execution_count": 271,
"execution_count": 17,
"id": "08c2c580",
"metadata": {},
"outputs": [],
@ -387,18 +401,9 @@
"for inventory_minifig in re_inventory_minifigs.itertuples(index=False):\n",
" inventory_minifig_ref = thm[f\"inventory_minifig/{inventory_minifig.inventory_id}/{inventory_minifig.fig_num}\"]\n",
"\n",
" inventory_ref = thm[f\"inventory/{inventory_minifig.inventory_id}\"]\n",
" minifig_ref = thm[f\"minifig/{inventory_minifig.fig_num}\"]\n",
"\n",
" g.add((inventory_minifig_ref, RDF.type, THM.MinifigInv))\n",
" g.add((inventory_minifig_ref, RDF.type, RDF.Property))\n",
"\n",
" g.add((inventory_minifig_ref, RDFS.domain, THM.Inventory))\n",
" g.add((inventory_minifig_ref, RDFS.range, THM.Minifig))\n",
"\n",
" g.add((inventory_ref, THM.contains, inventory_minifig_ref))\n",
" g.add((minifig_ref, THM.belongs, inventory_minifig_ref))\n",
" \n",
" g.add((inventory_minifig_ref, RDF.type, THM.InventoryMinifig))\n",
" g.add((inventory_minifig_ref, THM.inventory, thm[f\"inventory/{inventory_minifig.inventory_id}\"]))\n",
" g.add((inventory_minifig_ref, THM.minifig, thm[f\"minifig/{inventory_minifig.fig_num}\"]))\n",
" g.add((inventory_minifig_ref, THM.quantity, Literal(int(inventory_minifig.quantity), datatype=XSD.integer)))"
]
},
@ -420,26 +425,17 @@
},
{
"cell_type": "code",
"execution_count": 272,
"execution_count": 18,
"id": "1e0ac437",
"metadata": {},
"outputs": [],
"source": [
"bs_sets = pd.read_csv(\"./data/brickset/sets.csv\")\n",
"bs_parts = pd.read_csv(\"./data/brickset/parts.csv\")"
]
},
{
"cell_type": "markdown",
"id": "d120c079",
"metadata": {},
"source": [
"Add Set prices"
"bs_sets = pd.read_csv(\"./data/brickset/sets.csv\")"
]
},
{
"cell_type": "code",
"execution_count": 273,
"execution_count": 19,
"id": "fd944ccb",
"metadata": {},
"outputs": [],
@ -449,40 +445,14 @@
" set_ref = thm[f\"set/lego/{num}\"]\n",
"\n",
" if (set_ref, None, None) in g:\n",
" #brickset prices already in euro\n",
" #choose the cheapest price since the usual customer wont choose the highest price\n",
" options = [bs_set.USRetailPrice, bs_set.DERetailPrice, bs_set.UKRetailPrice, bs_set.CARetailPrice]\n",
" options = [int(opt) for opt in options if not pd.isna(opt)]\n",
"\n",
" if len(options) >= 1:\n",
" cheapest = min(options)\n",
" g.add((set_ref, THM.price_new, Literal(cheapest, datatype=XSD.float)))"
]
},
{
"cell_type": "markdown",
"id": "cbd69fa6",
"metadata": {},
"source": [
"Only concrete elements (parts considering their shape, color and print) can have prices"
]
},
{
"cell_type": "code",
"execution_count": 274,
"id": "307a3210",
"metadata": {},
"outputs": [],
"source": [
"\n",
"for bs_element in bs_parts.itertuples(index=False):\n",
" element_ref = thm[f\"element/{bs_element.ElementID}\"]\n",
" \n",
" if (element_ref, None, None) in g:\n",
" if not pd.isna(bs_element.BrickLinkSoldPriceNew):\n",
" g.add((element_ref, THM.price_new, Literal(bs_element.BrickLinkSoldPriceNew, datatype=XSD.float)))\n",
" if not pd.isna(bs_element.BrickLinkSoldPriceUsed):\n",
" g.add((element_ref, THM.price_used, Literal(bs_element.BrickLinkSoldPriceUsed, datatype=XSD.float)))"
" if not pd.isna(bs_set.USRetailPrice):\n",
" g.add((set_ref, THM.us_retail_price, Literal(bs_set.USRetailPrice, datatype=XSD.float)))\n",
" if not pd.isna(bs_set.DERetailPrice):\n",
" g.add((set_ref, THM.de_retail_price, Literal(bs_set.DERetailPrice, datatype=XSD.float)))\n",
" if not pd.isna(bs_set.UKRetailPrice):\n",
" g.add((set_ref, THM.us_retail_price, Literal(bs_set.UKRetailPrice, datatype=XSD.float)))\n",
" if not pd.isna(bs_set.CARetailPrice):\n",
" g.add((set_ref, THM.ca_retail_price, Literal(bs_set.CARetailPrice, datatype=XSD.float)))"
]
},
{
@ -497,7 +467,7 @@
},
{
"cell_type": "code",
"execution_count": 275,
"execution_count": 20,
"id": "a8beb593",
"metadata": {},
"outputs": [],
@ -509,7 +479,17 @@
},
{
"cell_type": "code",
"execution_count": 276,
"execution_count": 21,
"id": "b14e6e89",
"metadata": {},
"outputs": [],
"source": [
"additional_entries = 0"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "bbf5462b",
"metadata": {},
"outputs": [],
@ -518,9 +498,11 @@
" set_ref = thm[f\"set/lego/{bl_set.set_id}\"]\n",
"\n",
" if not (set_ref, None, None) in g:\n",
" g.add((set_ref, RDFS.label, Literal(lego_set.name, lang=\"en\")))\n",
" additional_entries += 1\n",
" g.add((set_ref, RDF.type, THM.Set))\n",
" g.add((set_ref, RDFS.label, Literal(bl_set.set_name, lang=\"en\")))\n",
" if not pd.isna(bl_set.year) and str(bl_set.year).isnumeric():\n",
" g.add((set_ref, THM.year, Literal(int(bl_set.year))))\n",
" g.add((set_ref, THM.first_year, Literal(datetime(int(bl_set.year), 1, 1))))\n",
" if not pd.isna(bl_set.parts) and str(bl_set.parts).isnumeric():\n",
" g.add((set_ref, THM.num_parts, Literal(int(bl_set.parts), datatype=XSD.integer)))\n",
" g.add((set_ref, THM.brand, Literal(\"Lego\")))"
@ -528,139 +510,129 @@
},
{
"cell_type": "code",
"execution_count": 277,
"execution_count": 23,
"id": "ef52582e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'\\nfor bl_part in bl_parts.itertuples(index=False):\\n part_ref = thm[f\"part/{bl_part.part_id}\"]\\n\\n if not (part_ref, None, None) in g:\\n additional_entries += 1\\n g.add((part_ref, RDFS.label, Literal(bl_part.part_name, lang=\"en\")))\\n'"
]
},
"execution_count": 277,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"\"\"\"\n",
"for bl_part in bl_parts.itertuples(index=False):\n",
" part_ref = thm[f\"part/{bl_part.part_id}\"]\n",
"\n",
" if not (part_ref, None, None) in g:\n",
" additional_entries += 1\n",
" g.add((part_ref, RDFS.label, Literal(bl_part.part_name, lang=\"en\")))\n",
"\"\"\""
" g.add((part_ref, RDF.type, THM.Part))\n",
" g.add((part_ref, RDFS.label, Literal(bl_part.part_name, lang=\"en\")))"
]
},
{
"cell_type": "code",
"execution_count": 278,
"execution_count": 24,
"id": "8bf0ffeb",
"metadata": {},
"outputs": [],
"source": [
"for bl_minifig in bl_minifigs.itertuples(index=False):\n",
" minifig_ref = thm[f\"minifig/{bl_minifig.minifig_id}\"]\n",
"\n",
" if not (minifig_ref, None, None) in g:\n",
" additional_entries += 1\n",
" g.add((minifig_ref, RDF.type, THM.Minifigure))\n",
" g.add((minifig_ref, RDFS.label, Literal(bl_minifig.minifig_name, lang=\"en\")))"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "3491b032",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'\\nfor bl_minifig in bl_minifigs.itertuples(index=False):\\n minifig_ref = thm[f\"minfig/{bl_minifig.minifig_id}\"]\\n\\n if not (minifig_ref, None, None) in g:\\n g.add((minifig_ref, RDFS.label, Literal(bl_minifig.minifig_name, lang=\"en\")))\\n'"
]
},
"execution_count": 278,
"metadata": {},
"output_type": "execute_result"
"name": "stdout",
"output_type": "stream",
"text": [
"Added 107748 items\n"
]
}
],
"source": [
"\"\"\"\n",
"for bl_minifig in bl_minifigs.itertuples(index=False):\n",
" minifig_ref = thm[f\"minfig/{bl_minifig.minifig_id}\"]\n",
"\n",
" if not (minifig_ref, None, None) in g:\n",
" g.add((minifig_ref, RDFS.label, Literal(bl_minifig.minifig_name, lang=\"en\")))\n",
"\"\"\""
"print(f\"Added {additional_entries} items\")"
]
},
{
"cell_type": "markdown",
"id": "e73471b9",
"id": "6eca7f24",
"metadata": {},
"source": [
"# Merlins Steine"
"# Merlin"
]
},
{
"cell_type": "code",
"execution_count": 279,
"id": "ab1ec488",
"execution_count": 26,
"id": "c1e9ff32",
"metadata": {},
"outputs": [],
"source": [
"me_sets = pd.read_csv(\"./data/merlin/others.csv\")"
"merlin_sets = pd.read_csv(\"./data/merlin/others.csv\")"
]
},
{
"cell_type": "code",
"execution_count": 293,
"id": "9bcd2956",
"execution_count": 27,
"id": "217dc4d2",
"metadata": {},
"outputs": [],
"source": [
"t = me_sets[me_sets[\"brand\"] == \"Pantasy\"]"
]
},
{
"cell_type": "code",
"execution_count": 294,
"id": "9ab21460",
"metadata": {},
"outputs": [],
"source": [
"t[\"ratio\"] = t[\"price_eur\"] / t[\"num_parts\"]"
]
},
{
"cell_type": "code",
"execution_count": 295,
"id": "459c3a4c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"np.float64(0.43016261640379705)"
]
},
"execution_count": 295,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t[\"ratio\"].mean()"
]
},
{
"cell_type": "code",
"execution_count": 282,
"id": "bfcf2840",
"metadata": {},
"outputs": [],
"source": [
"for me_set in me_sets.itertuples(index=False):\n",
" if not pd.isna(me_set.brand) and not pd.isna(me_set.id):\n",
" set_ref = thm[f\"set/{me_set.brand}/{me_set.id}\"]\n",
"additional_entries = 0\n",
"\n",
"for merlin_set in merlin_sets.itertuples(index=False):\n",
" set_ref = thm[f\"set/lego/{merlin_set.id}\"]\n",
" producer_ref = thm[f\"producer/{merlin_set.producer}\"]\n",
"\n",
" if not (producer_ref, None, None) in g:\n",
" g.add((producer_ref, RDF.type, THM.Producer))\n",
" g.add((producer_ref, RDFS.label, Literal(merlin_set.producer)))\n",
"\n",
" if not (set_ref, None, None) in g:\n",
" additional_entries += 1\n",
" g.add((set_ref, RDF.type, THM.Set))\n",
" g.add((set_ref, RDFS.label, Literal(me_set.name, lang=\"en\")))\n",
" if not pd.isna(me_set.release):\n",
" g.add((set_ref, THM.year, Literal(int(me_set.release), datatype=XSD.integer)))\n",
" g.add((set_ref, RDFS.label, Literal(merlin_set.name)))\n",
" g.add((set_ref, THM.brand, producer_ref))\n",
" if not pd.isna(merlin_set.year):\n",
" g.add((set_ref, THM.first_year, Literal(int(merlin_set.year), datatype=XSD.integer)))\n",
" if not pd.isna(merlin_set.parts):\n",
" g.add((set_ref, THM.num_parts, Literal(int(merlin_set.parts), datatype=XSD.integer)))\n",
" g.add((set_ref, THM.size_word, Literal(merlin_set.size)))\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "54eaa79e",
"metadata": {},
"outputs": [],
"source": [
"merlin_prices = pd.read_csv(\"./data/merlin/prices.csv\")\n",
"\n",
" if not pd.isna(me_set.num_parts):\n",
" g.add((set_ref, THM.num_parts, Literal(int(me_set.num_parts), datatype=XSD.integer)))\n",
" g.add((set_ref, THM.brand, Literal(me_set.brand)))\n",
" if not pd.isna(me_set.price_eur):\n",
" g.add((set_ref, THM.price_new, Literal(me_set.price_eur, datatype=XSD.float)))"
"for merlin_price in merlin_prices.itertuples(index=False):\n",
" set_ref = thm[f\"set/lego/{merlin_price.id}\"]\n",
" if merlin_price.price_eur not in [None, \"_\"]:\n",
" g.add((set_ref, THM.eur_price, Literal(merlin_price.price_eur, datatype=XSD.float)))\n",
" #usd (data src not clean)\n",
" if merlin_price._3 not in [None, \"_\"]:\n",
" g.add((set_ref, THM.usd_price, Literal(merlin_price._3, datatype=XSD.float)))\n",
" # cn \n",
" if merlin_price._2 not in [None, \"_\"]:\n",
" g.add((set_ref, THM.cn_price, Literal(merlin_price._2, datatype=XSD.float)))\n",
" # best price euro \n",
" if merlin_price._4 not in [None, \"_\"]:\n",
" g.add((set_ref, THM.eur_bestprice, Literal(merlin_price._4, datatype=XSD.float)))\n",
" # best price cn\n",
" if merlin_price._5 not in [None, \"_\"]:\n",
" g.add((set_ref, THM.cn_bestprice, Literal(merlin_price._5, datatype=XSD.float)))\n",
" # best price usd\n",
" if merlin_price._6 not in [None, \"_\"]:\n",
" g.add((set_ref, THM.usd_bestprice, Literal(merlin_price._6, datatype=XSD.float)))\n"
]
},
{
@ -697,31 +669,67 @@
},
{
"cell_type": "code",
"execution_count": 283,
"execution_count": 29,
"id": "1a30bff8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Graph identifier=Naee4bab906a6444290a3659ffe0fbd45 (<class 'rdflib.graph.Graph'>)>"
"<Graph identifier=Ne25ca93489ee450c8158409bd5d2a548 (<class 'rdflib.graph.Graph'>)>"
]
},
"execution_count": 283,
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g.bind(\"thm\", THM)\n",
"g.bind(\"thmont\", THM)\n",
"\n",
"g.serialize(\"lego_graph.ttl\", format=\"turtle\")"
"g.serialize(\"lego_graph_rebrickable.ttl\", format=\"turtle\")"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "7b9c3bcf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(rdflib.term.URIRef('https://thm.de/inventory_part/102116/3626cpr3530'), rdflib.term.Literal('Minifig Head Chitauri, Gold Armor, Lime Eyes, Large Open Mouth with Teeth Print', lang='en'), rdflib.term.Literal('1', datatype=rdflib.term.URIRef('http://www.w3.org/2001/XMLSchema#integer')))\n",
"(rdflib.term.URIRef('https://thm.de/inventory_part/102116/970c12'), rdflib.term.Literal('Hips and Dark Bluish Gray Legs', lang='en'), rdflib.term.Literal('1', datatype=rdflib.term.URIRef('http://www.w3.org/2001/XMLSchema#integer')))\n",
"(rdflib.term.URIRef('https://thm.de/inventory_part/102116/973c14h14pr5739'), rdflib.term.Literal('Torso Armor, Light Bluish Gray and Olive Green Panels Print, Light Bluish Gray Arms and Hands', lang='en'), rdflib.term.Literal('1', datatype=rdflib.term.URIRef('http://www.w3.org/2001/XMLSchema#integer')))\n"
]
}
],
"source": [
"import rdflib\n",
" \n",
"query = \"\"\"\n",
"SELECT ?inventory_part ?part_name ?quantity\n",
"WHERE {\n",
" ?inventory thmont:set <https://thm.de/set/lego/fig-011397> .\n",
" ?inventory_part thmont:inventory ?inventory ;\n",
" thmont:part ?part ;\n",
" thmont:quantity ?quantity .\n",
" ?part rdfs:label ?part_name .\n",
"}\n",
"\"\"\"\n",
"\n",
"qres = g.query(query)\n",
"\n",
"for row in qres:\n",
" print(row)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv (3.14.4)",
"display_name": "kgr",
"language": "python",
"name": "python3"
},
@ -735,7 +743,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.4"
"version": "3.11.2"
}
},
"nbformat": 4,

View File

@ -30,7 +30,7 @@
a4paper,margin=25mm
}
\title{\huge{Knowledge Graph - Lego}}
\title{\huge{Knowledgegraphen - Lego}}
\date{\today}
\author{
\begin{tabular}{ccc}
@ -49,7 +49,7 @@
%... then configure it.
\fancyhead{} % clear all header fields
\fancyhead[L]{Lego}
\fancyhead[R]{KGR - Knowledge Graphen}
\fancyhead[R]{KGR - Knowledgegraphen}
\fancyfoot{} % clear all footer fields
\fancyfoot[LE,RO]{\thepage}
@ -74,16 +74,16 @@
\begin{enumerate}
\item \label{item:min_set_count} Was ist die minimale Anzahl an Sets, die benötigt wird um ein anderes Set zusammenzubauen?
\item \label{item:min_set_price} Was ist der geringste Preis einer Auswahl an Sets um ein anderes Set zusammenzubauen?
\item \label{item:set_span} Welche anderen Sets, können mit Sets, die sich schon im eigenen Besitz befinden zusammengebaut werden?
\item Sind Sets von anderen Herstellern im Vergleich zu Lego Sets, auf den durchschnittlichen Teilepreis betrachtet billiger?
\item Haben neuere Sets im Vergleich zu älteren Sets eine geringere Teileanzahl, da auf eine grössere Anzahl an speziell angefertigten Teilen zugegriffen werden kann?
\item Haben Sets mit höherer Teileanzahl eine höhere Anzahl an Minifiguren?
\item \label{item:set_span} Welche anderen Sets, können mit Sets, die sich schon im eigenen Besitz befinden zusammengebaut werden?
\item \label{item:equivalent_part} Welche Lego-Teile besitzen äquivalente Teile von anderen Marken?
\end{enumerate}
\subsection{Nutzen}
Wird ein Set an Klemmbausteinen nicht mehr vertrieben, an welchem dennoch Nachfrage besteht, existieren folgende Möglichkeiten:
Wird ein Set an Klemmbausteinen nicht mehr vertrieben und man möchte das Set dennoch haben, so ergeben sich mehrere Möglichkeiten:
\begin{itemize}
\item Man kauft das Set von einem Zweitanbieter
\item Man stellt sich die benötigten Teile des Sets selbst zusammen. Dies geschieht entweder indem die Teile einzeln von Zweitanbietern gekauft werden oder durch den Erwerb von anderen Sets, welche die benötigten Teile enthalten. Siehe Fragen: \ref{item:min_set_count} und \ref{item:min_set_price}.
@ -114,7 +114,6 @@
\begin{figure}[H]
\includegraphics[width=\columnwidth]{bilder/downloads_schema_v3.png}
\caption{Datenbankschema \textit{Rebrickable} \cite{FreeLEGOCatalog}}
\label{fig:rebrickable_scheme}
\end{figure}
Der Datensatz konnte über die URL \url{https://rebrickable.com/downloads/} erhalten werden.
@ -128,7 +127,7 @@
\toprule
& Brickset \\ \midrule
URL & \url{https://brickset.com/}\\
Beschaffung & CSV-Download \\
Beschaffung & Webscraping/CSV-Download \\
Lizenz & nicht spezifiziert \\
Erhalt & 23.04.2026 \\ \bottomrule
\end{tabularx}
@ -180,17 +179,14 @@
\subsection{Integrationsprozess}
Jedes von Lego veröffentlichte Teil besitzt der Form zugrunde eine eindeutige Teile-Nummer, auch Design-ID genannt. Die Teilenummer wird nur aufgrund der Form eines Legosteins vergeben und kann auf dem Lego-Stein abgelesen werden. Üblicherweise besitzt eine Design-ID 4-5 Stellen. Abhängig von der Form, Farbe und des Drucks besitzt jeder Lego-Stein eine 6-7 stellige Element-ID. Die Element-IDs von Teilen eines Lego-Sets befindet sich als Auflistung aller Teile in der Bauanleitung eines Lego-Sets.\\
Sets besitzen ebenfalls eine Set-Nummer. Einige Set-Nummern werden mit einem Suffix bspw. \textit{-1} angegeben. Dieser Suffix gibt Aufschluss über die Version des Sets. Allerdings gibt es spezielle Lego-Sets, welche in Teil-Sets aufgegliedert werden oder mehrere Bauvarianten besitzen \cite{FreeLEGOCatalog}. Diese Art von Sets wird mithilfe von Inventaren modelliert (Siehe \ref{fig:rebrickable_scheme}). Ein Inventar kann als übergeordnetes Set verstanden werden. Ein Inventar kann somit Set-, Minifiguren- und Teile-Inventare besitzen, die angeben in welcher Stückzahl ein Teil-Set, eine Minifigur oder ein Teil vorhanden ist\\
Lego-Minifiguren erhalten durch Lego keine eindeutige Identifikationsnummer. Zur eindeutigen Identifikation von Minifiguren wird die von \textit{Rebrickable} vergebene ID verwendet. Auf Minifiguren-Seiten von \textit{Rebrickable} sind Referenzen zu IDs derselben Minifigur auf anderen Seiten enthalten. Diese Referenzen sind innerhalb des bereitgestellten Datensatzes nicht abgebildet.\\
Da die einzige Quelle für andere Hersteller nur \textit{Merlins Steine} ist und diese nur Sets enthält, wird der Hersteller in der IRI nur für Sets miteinbezogen.
Jedes von Lego veröffentlichte Teil besitzt der Form zugrunde eine eindeutige Teile-Nummer, auch Design-ID genannt. Die Teilenummer wird nur aufgrund der Form eines Legosteins vergeben und kann auf dem Lego-Stein abgelesen werden. Üblicherweise besitzt eine Design-ID 4-5 Stellen. Abhängig von der Form, Farbe und des Drucks besitzt jeder Lego-Stein eine 6-7 stellige Element-ID. Diese Element-ID lässt sich Lego-Sets besitzen ebenfalls eine Set-Nummer. Allerdings gibt es spezielle Lego-Sets, welche in Teil-Sets aufgegliedert werden oder mehrere Bauvarianten besitzen \cite{FreeLEGOCatalog}. Diese sind in der Modellierung dieser Arbeit nicht weiter berücksichtigt. Stattdessen wird das zugrundeliegende Hauptset betrachtet. Lego-Minifiguren erhalten durch Lego keine eindeutige Identifikationsnummer. Zur eindeutigen Identifikation von Minifiguren wird die von \textit{Rebrickable} vergebene ID verwendet.\\
Da die einzige Quelle für andere Hersteller nur \textit{Merlins Steine} ist und diese nur Sets enthält, wird der Hersteller in der IRI miteinbezogen.
\begin{verbatim}
https://thm.de/set/{brand}/{id}
https://thm.de/set/{brand}/{id}
\end{verbatim}
Um die Dateigrösse des Graph zu reduzieren wurde \texttt{thm}, statt \texttt{th-mannheim} verwendet.
\begin{figure}[H]
\centering
\includegraphics[width=0.8\columnwidth]{bilder/example_part_number.png}
\includegraphics[width=\columnwidth]{bilder/example_part_number.png}
\caption{Lego Stein mit Teile-Nummer (Design-ID) 41769 \cite{cunninghamSellLEGOBricklink2018}}
\label{fig:lego_example_part_number}
\end{figure}
@ -203,170 +199,22 @@ https://thm.de/set/{brand}/{id}
\subsection{Pipeline}
Die Datensätze von \textit{Bricklink} und \textit{Merlins Steine} wurden durch Webscraping erhoben. Entstandene Fehler durch Ausnahmefälle mussten manuell bereinigt werden. Demnach ist dieser Teil nicht automatisierbar. Abbildung \ref{fig:pipeline} zeigt die Pipeline zur Erstellung des Knowledge Graph.
\begin{figure}[H]
\includegraphics[width=\columnwidth]{./bilder/kgr_pipeline1.drawio.png}
\caption{Pipeline Erstellung Knowledge Graph}
\label{fig:pipeline}
\end{figure}
\section{Evaluation}
\subsection{Ergebnis}
Das Projekt kann unter der URL: \url{https://gitty.informatik.hs-mannheim.de/2211275/kgr} betrachtet werden.
Der resultierende Knowledge-Graph ist über 300 MB gross. Die Dateigrösse lässt sich auf die Zuordnungen von Teilen zu Inventaren zurückführen.
\subsection{Beispiel-Queries}
Erhalten der Gesamtheit aller Lego Star Wars Minifiguren:
\begin{verbatim}
SELECT DISTINCT ?name
WHERE {
?set thmont:theme ?theme.
?theme rdf:type thmont:Theme.
?set rdf:type thmont:Set.
?theme rdfs:label "Star Wars"@en.
?inventory thmont:set ?set.
?inventory rdf:type thmont:Inventory.
?inventory thmont:contains ?minifig_inv.
?minifig_inv rdf:type thmont:MinifigInv.
?minifig thmont:belongs ?minifig_inv.
?minifig rdfs:label ?name.
}
\end{verbatim}
Anzahl aller Minifiguren enthalten in allen Lego-Sets gruppiert nach Figur.
\begin{verbatim}
SELECT
(SUM(?quantity) as ?sum) ?minifig ?name
WHERE {
?minifig rdf:type thm:Minifig.
?minifig_inv rdf:type thm:MinifigInv.
?minifig thm:belongs ?minifig_inv.
?minifig_inv thm:quantity ?quantity.
?minifig rdfs:label ?name.
}
GROUP BY ?minifig ?name
ORDER BY DESC(?sum)
\end{verbatim}
Durchschnittliche Anzahl an Teilen je Set gruppiert nach Jahren.
\begin{verbatim}
SELECT ?year (AVG(?part_count) as ?avgp)
WHERE {
?set thm:year ?year.
?set thm:num_parts ?part_count.
}
GROUP BY ?year
ORDER BY DESC(?avgp)
\end{verbatim}
Durchschnittlicher Teilepreis gruppiert nach Marken. \label{verb:ppp_query}
\begin{verbatim}
SELECT ?brand (AVG(?price)/AVG(?num) as ?t)
WHERE {
?set thm:num_parts ?num.
?set rdfs:label ?name.
?set rdf:type thm:Set.
?set thm:brand ?brand.
?set thm:price_new ?price.
FILTER (?num > 0)
}
GROUP BY ?brand
ORDER BY DESC(?t)
\end{verbatim}
\subsection{Abdeckung}
Tabelle \ref{tab:coverage} zeigt einen Überblick welche der Prädikate (Graph, Name, Kategorie, Preise, Jahr) der Knowledge Graph für Minifiguren (Figs), Teile und Sets abdeckt (X=enthalten,-=Fehlt). Das Prädikat \textit{Graph} spiegelt wider, ob das Prädikat im Graph vorhanden ist.
\begin{table}[H]
\centering
\begin{tabular}{@{}lllllll@{}}
\toprule
& \multicolumn{3}{l}{Lego} & \multicolumn{3}{l}{Andere Marken} \\ \midrule
& Figs & Teile & Sets & Figs & Teile & Sets \\ \midrule
Graph & X & X & X & - & - & X \\
Name & X & X & X & - & - & X\\
Kateg. & - & X & X & - & - & - \\
Preise & - & X & X & - & - & X \\
Jahr & - & - & X & - & - & X \\ \bottomrule
\end{tabular}
\caption{Abdeckung des Graphen für Lego und weitere Klemmbausteinmarken}
\label{tab:coverage}
\end{table}
Da Lego keine IDs für Minifiguren vergibt ist das erkennen zweier gleichartiger Figuren schwieriger. Die Preise von \textit{Brickset} konnten nicht den Minifiguren aus \textit{Rebrickable} zugeordnet werden. Da \textit{Rebrickable} die Zuordnung von Minifiguren zu Sets liefert, wurde die Entscheidung getroffen auf die Preiszuordnung zu verzichten. Für Figuren und Teile weiterer Marken, waren eine Zuordnung nur schwer bis gar nicht möglich. Diese Zuordnung wäre beispielsweise durch Bilderkennung, anhand vom Hersteller bereitgestellte Bauanleitungen in Form von .PDF-Dateien möglich.
\subsection{Konsistenz}
\subsection{Qualität}
Es wird betrachtet, ob die ursprünglichen Fragestellungen mithilfe des Knowledge Graphen beantwortet werden können.
\begin{enumerate}
\item Was ist die minimale Anzahl an Sets, die benötigt wird um ein anderes Set zusammenzubauen?
\item Was ist der geringste Preis einer Auswahl an Sets um ein anderes Set zusammenzubauen?
\item Welche anderen Sets, können mit Sets, die sich schon im eigenen Besitz befinden zusammengebaut werden?\\
\textit{Der Knowledge Graph beinhaltet die Daten, sodass die Fragestellungen 1., 2., 3. beantwortet werden können. Eine effiziente Softwarelösung besitzt eine höhere geschätzte Komplexität und liegt ausserhalb des Rahmens dieser Arbeit.}
\item Sind Sets von anderen Herstellern im Vergleich zu Lego Sets, auf den durchschnittlichen Teilepreis betrachtet billiger?\\
\textit{Diese Frage kann mithilfe der letzten Beispiel-Query \ref{verb:ppp_query} beantwortet werden. Abbildung \ref{fig:ppp} zeigt die Teile-Preise je Hersteller. Lego hat den höchsten Teilepreis mit 0.096 \texteuro und BlueBrixx den niedrigsten mit 0.0437 \texteuro.
\begin{figure}[H]
\centering
\includegraphics[width=\columnwidth]{./bilder/diagram_avg_part_price_brand.png}
\caption{Hersteller sortiert nach durchschnittlichem Teile-Preis in \texteuro}
\label{fig:ppp}
\end{figure}
}
\item Haben neuere Sets im Vergleich zu älteren Sets eine geringere Teileanzahl, da auf eine grössere Anzahl an speziell angefertigten Teilen zugegriffen werden kann?\\
\textit{Es ist das Gegenteil zu erkennen. Eine Erklärung dafür könnte sein, dass die Klemmbaustein-Marken mehrheitlich Sets für \ac{AFOL} herausbringen im Vergleich zu vorherigen Jahren. Diese Sets sind meistens komplexer und besitzen demnach eine höhere Teileanzahl.}
\begin{figure}[H]
\centering
\includegraphics[width=\columnwidth]{./bilder/diagram_avg_parts_per_year.png}
\caption{Durchschnittliche Teileanzahl nach Jahren aller Klemmbausteinmarken}
\label{fig:avg_parts_per_year}
\end{figure}
\begin{verbatim}
SELECT (AVG(?parts) as ?total) ?year
WHERE {
?set rdf:type thm:Set.
?set thm:brand ?brand.
?set thm:year ?year.
?set rdfs:label ?name.
?set thm:num_parts ?parts.
}
GROUP BY ?year
ORDER BY ASC(?total)
\end{verbatim}
\item Haben Sets mit höherer Teileanzahl eine höhere Anzahl an Minifiguren?\\
\textit{Zwischen der Anzahl Minifiguren $M$ und der Anzahl an Teilen $T$ eines Sets kann eine mittelstarke Korrelation $\rho_{M,T} \approx 0.5926$ festgestellt werden. Hier gab es mehrere interessante Ausreisser: \href{https://rebrickable.com/sets/BIGBOX-1/the-ultimate-battle-for-chima}{BIGBOX-1,The Ultimate Battle for Chima}, \href{https://rebrickable.com/sets/2000409-2/window-exploration-bag/}{2000409-2, Window Exploration Bag 2} und \href{https://rebrickable.com/sets/2000409-1/window-exploration-bag/}{2000409-1, Window Exploration Bag 1}.}
\textit{
\begin{figure}[H]
\centering
\includegraphics[width=\columnwidth]{./bilder/diagram_correlation_parts_figs.png}
\caption{Anzahl Minifiguren und Teile}
\label{fig:scatter_parts_figs}
\end{figure}
}
Der Datensatz konnte mithilfe folgender SPARQL-Query erhalten werden. Hier werden Sets mit 0 Teilen herausgefiltert.
\begin{verbatim}
SELECT ?part_num (SUM(?qty) as ?total)
WHERE {
?set rdf:type thm:Set.
?set thm:brand ?brand.
?set rdfs:label ?name.
?set thm:num_parts ?part_num.
?inv thm:set ?set.
?inv rdf:type thm:Inventory.
?inv thm:contains ?fig_inv.
?fig_inv thm:quantity ?qty.
FILTER(?part_num > 0).
}
GROUP BY ?set ?part_num ?name ?inv
\end{verbatim}
\item Welche Lego-Teile besitzen äquivalente Teile von anderen Marken?\\
\textit{Der Knowledge Graph bietet keine Möglichkeit dies zu beantwortet, da keine Datensätze über Teile, die nicht von Lego produziert worden sind, in die Erstellung des Graph eingeflossen sind.}
\end{enumerate}
\section{Ausblick}
\begin{itemize}
\item Es fehlen tiefer greifende Daten zu anderen Klemmbausteinmarken, neben Lego. Ein erhalten der Daten wäre nur durch direkte Anfrage beim Hersteller oder durch aufwändige Methodik, wie Bilderkennung möglich.
\item identische Minifiguren könnten mit höherem Aufwand gegenseitig zugeordnet werden. So würde eine Verbindung zwischen der Inventarisierung durch \textit{Rebrickable } und Preisen von \textit{Brickset} entstehen.
\item Zur Beantwortung der Fragestellungen 1,2,3 ist eine eigene Softwarelösung und eine Erweiterung des Graphen vonnöten. \textit{Rebrickable} bietet selber Werkzeuge \url{https://rebrickable.com/help/build-engine/} an, um diese Fragestellung zu beantworten.
\end{itemize}
\section*{Abkürzungsverzeichnis}
\begin{acronym}[Abkürzungsverzeichnis]
\acro{MOC}{My Own Creation}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,31 +0,0 @@
<mxfile host="app.diagrams.net">
<diagram name="Seite-1" id="_iVW848-2TJ0zfREs3N2">
<mxGraphModel dx="808" dy="425" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-11" edge="1" parent="1" source="Hu6JBMkSkJOX-7uFVOw6-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="Hu6JBMkSkJOX-7uFVOw6-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-2" parent="1" style="rounded=1;whiteSpace=wrap;html=1;" value="Bricklink,&amp;nbsp;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;Brickset&lt;/span&gt;&lt;div&gt;Rebrickable,&amp;nbsp;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;Merlin&lt;/span&gt;&lt;/div&gt;" vertex="1">
<mxGeometry height="50" width="110" x="50" y="150" as="geometry" />
</mxCell>
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-12" edge="1" parent="1" source="Hu6JBMkSkJOX-7uFVOw6-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="Hu6JBMkSkJOX-7uFVOw6-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-3" parent="1" style="rounded=1;whiteSpace=wrap;html=1;" value="Datensätze als .CSV" vertex="1">
<mxGeometry height="50" width="120" x="200" y="150" as="geometry" />
</mxCell>
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-7" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;rounded=0;" value="Manuelle Abfrage &amp;amp; Transformation" vertex="1">
<mxGeometry height="30" width="100" x="130" y="210" as="geometry" />
</mxCell>
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-8" parent="1" style="rounded=1;whiteSpace=wrap;html=1;" value="lego_graph.ttl" vertex="1">
<mxGeometry height="50" width="120" x="360" y="150" as="geometry" />
</mxCell>
<mxCell id="Hu6JBMkSkJOX-7uFVOw6-10" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;rounded=0;" value="Jupyter Notebook" vertex="1">
<mxGeometry height="30" width="100" x="290" y="210" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1 +0,0 @@
,Lambda/Roman,Lambda,03.05.2026 11:29,file:///C:/Users/Roman/AppData/Roaming/LibreOffice/4;

View File

@ -1,6 +0,0 @@
"brand","t"
"Lego","0.09687904"
"Cobi","0.07586302"
"Pantasy","0.05728256"
"MouldKing","0.05323224"
"BlueBrixx","0.043733075"
1 brand t
2 Lego 0.09687904
3 Cobi 0.07586302
4 Pantasy 0.05728256
5 MouldKing 0.05323224
6 BlueBrixx 0.043733075

View File

@ -1,78 +0,0 @@
"total","year"
"0.0","2027"
"1.0","1950"
"100.263888888888888888888889","1973"
"101.025641025641025641025641","1972"
"103.288135593220338983050847","1985"
"103.794871794871794871794872","1974"
"104.323741007194244604316547","1992"
"104.347058823529411764705882","1994"
"105.636363636363636363636364","1980"
"106.891608391608391608391608","1997"
"113.566666666666666666666667","1967"
"12.435897435897435897435897","1955"
"12.5","1953"
"122.129411764705882352941176","1988"
"123.9125295508274231678487","1998"
"124.003865979381443298969072","2012"
"124.326375711574952561669829","2014"
"125.840579710144927536231884","1993"
"126.522070015220700152207002","2011"
"127.65641025641025641025641","1995"
"129.071428571428571428571429","1968"
"131.587837837837837837837838","1991"
"132.5","2013"
"134.275735294117647058823529","2003"
"134.780487804878048780487805","1975"
"139.038461538461538461538462","2004"
"14.25","1959"
"140.74025974025974025974026","1978"
"142.662337662337662337662338","1976"
"147.16195121951219512195122","2015"
"148.229656419529837251356239","2009"
"159.889","2016"
"16.0","1956"
"161.840396753832281334535618","2017"
"163.051724137931034482758621","1990"
"165.224489795918367346938776","1996"
"165.62577962577962577962578","2007"
"166.35746606334841628959276","2006"
"174.373493975903614457831325","2005"
"175.333333333333333333333333","1960"
"179.64218455743879472693032","2010"
"18.015151515151515151515152","1958"
"183.630669546436285097192225","2008"
"204.192013593882752761257434","2018"
"277.083064516129032258064516","2019"
"34.291666666666666666666667","1957"
"341.934300993124522536287242","2021"
"391.574585635359116022099448","2020"
"40.868421052631578947368421","1964"
"403.468056489576328177538668","2022"
"43.819672131147540983606557","1966"
"475.79951690821256038647343","2023"
"48.964285714285714285714286","1965"
"500.052801724137931034482759","2026"
"593.916924664602683178534572","2024"
"612.001367365542388331814038","2025"
"64.955056179775280898876404","1982"
"65.820833333333333333333333","1987"
"67.295081967213114754098361","1963"
"71.92","1969"
"75.561224489795918367346939","1984"
"77.122807017543859649122807","1977"
"8.357142857142857142857143","1954"
"80.690476190476190476190476","1970"
"85.846153846153846153846154","1962"
"87.706521739130434782608696","2001"
"88.775362318840579710144928","1989"
"91.280701754385964912280702","1971"
"92.6796875","1999"
"93.075980392156862745098039","2000"
"93.593939393939393939393939","1986"
"93.785714285714285714285714","1981"
"93.853333333333333333333333","1983"
"94.418524871355060034305317","2002"
"94.88","1961"
"96.4","1949"
"96.913978494623655913978495","1979"
1 total year
2 0.0 2027
3 1.0 1950
4 100.263888888888888888888889 1973
5 101.025641025641025641025641 1972
6 103.288135593220338983050847 1985
7 103.794871794871794871794872 1974
8 104.323741007194244604316547 1992
9 104.347058823529411764705882 1994
10 105.636363636363636363636364 1980
11 106.891608391608391608391608 1997
12 113.566666666666666666666667 1967
13 12.435897435897435897435897 1955
14 12.5 1953
15 122.129411764705882352941176 1988
16 123.9125295508274231678487 1998
17 124.003865979381443298969072 2012
18 124.326375711574952561669829 2014
19 125.840579710144927536231884 1993
20 126.522070015220700152207002 2011
21 127.65641025641025641025641 1995
22 129.071428571428571428571429 1968
23 131.587837837837837837837838 1991
24 132.5 2013
25 134.275735294117647058823529 2003
26 134.780487804878048780487805 1975
27 139.038461538461538461538462 2004
28 14.25 1959
29 140.74025974025974025974026 1978
30 142.662337662337662337662338 1976
31 147.16195121951219512195122 2015
32 148.229656419529837251356239 2009
33 159.889 2016
34 16.0 1956
35 161.840396753832281334535618 2017
36 163.051724137931034482758621 1990
37 165.224489795918367346938776 1996
38 165.62577962577962577962578 2007
39 166.35746606334841628959276 2006
40 174.373493975903614457831325 2005
41 175.333333333333333333333333 1960
42 179.64218455743879472693032 2010
43 18.015151515151515151515152 1958
44 183.630669546436285097192225 2008
45 204.192013593882752761257434 2018
46 277.083064516129032258064516 2019
47 34.291666666666666666666667 1957
48 341.934300993124522536287242 2021
49 391.574585635359116022099448 2020
50 40.868421052631578947368421 1964
51 403.468056489576328177538668 2022
52 43.819672131147540983606557 1966
53 475.79951690821256038647343 2023
54 48.964285714285714285714286 1965
55 500.052801724137931034482759 2026
56 593.916924664602683178534572 2024
57 612.001367365542388331814038 2025
58 64.955056179775280898876404 1982
59 65.820833333333333333333333 1987
60 67.295081967213114754098361 1963
61 71.92 1969
62 75.561224489795918367346939 1984
63 77.122807017543859649122807 1977
64 8.357142857142857142857143 1954
65 80.690476190476190476190476 1970
66 85.846153846153846153846154 1962
67 87.706521739130434782608696 2001
68 88.775362318840579710144928 1989
69 91.280701754385964912280702 1971
70 92.6796875 1999
71 93.075980392156862745098039 2000
72 93.593939393939393939393939 1986
73 93.785714285714285714285714 1981
74 93.853333333333333333333333 1983
75 94.418524871355060034305317 2002
76 94.88 1961
77 96.4 1949
78 96.913978494623655913978495 1979

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "7cce205d",
"metadata": {},
"source": [
"# Querries"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "34c85d02",
"metadata": {},
"outputs": [
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 8\u001b[39m\n\u001b[32m 4\u001b[39m \n\u001b[32m 5\u001b[39m \n\u001b[32m 6\u001b[39m g = rdflib.Graph()\n\u001b[32m 7\u001b[39m \n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m g.parse(filename, format=\u001b[33m'ttl'\u001b[39m)\n\u001b[32m 9\u001b[39m \n\u001b[32m 10\u001b[39m query = \"\"\"\n\u001b[32m 11\u001b[39m \n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/graph.py:1660\u001b[39m, in \u001b[36mGraph.parse\u001b[39m\u001b[34m(self, source, publicID, format, location, file, data, **args)\u001b[39m\n\u001b[32m 1657\u001b[39m parser = plugin.get(\u001b[38;5;28mformat\u001b[39m, Parser)()\n\u001b[32m 1658\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 1659\u001b[39m \u001b[38;5;66;03m# TODO FIXME: Parser.parse should have **kwargs argument.\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1660\u001b[39m \u001b[30;43mparser\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mparse\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43msource\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1661\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mSyntaxError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m se:\n\u001b[32m 1662\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m could_not_guess_format:\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:2034\u001b[39m, in \u001b[36mTurtleParser.parse\u001b[39m\u001b[34m(self, source, graph, encoding, turtle)\u001b[39m\n\u001b[32m 2032\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m stream:\n\u001b[32m 2033\u001b[39m stream = source.getByteStream()\n\u001b[32m-> \u001b[39m\u001b[32m2034\u001b[39m \u001b[30;43mp\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mloadStream\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 2036\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m prefix, namespace \u001b[38;5;129;01min\u001b[39;00m p._bindings.items():\n\u001b[32m 2037\u001b[39m graph.bind(prefix, namespace)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:492\u001b[39m, in \u001b[36mSinkParser.loadStream\u001b[39m\u001b[34m(self, stream)\u001b[39m\n\u001b[32m 491\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mloadStream\u001b[39m(\u001b[38;5;28mself\u001b[39m, stream: Union[IO[\u001b[38;5;28mstr\u001b[39m], IO[\u001b[38;5;28mbytes\u001b[39m]]) -> Optional[Formula]:\n\u001b[32m--> \u001b[39m\u001b[32m492\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mloadBuf\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mread\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:498\u001b[39m, in \u001b[36mSinkParser.loadBuf\u001b[39m\u001b[34m(self, buf)\u001b[39m\n\u001b[32m 495\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Parses a buffer and returns its top level formula\"\"\"\u001b[39;00m\n\u001b[32m 496\u001b[39m \u001b[38;5;28mself\u001b[39m.startDoc()\n\u001b[32m--> \u001b[39m\u001b[32m498\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mfeed\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mbuf\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 499\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.endDoc()\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:524\u001b[39m, in \u001b[36mSinkParser.feed\u001b[39m\u001b[34m(self, octets)\u001b[39m\n\u001b[32m 521\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j < \u001b[32m0\u001b[39m:\n\u001b[32m 522\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m524\u001b[39m i = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mdirectiveOrStatement\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43ms\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mj\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 525\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m i < \u001b[32m0\u001b[39m:\n\u001b[32m 526\u001b[39m \u001b[38;5;66;03m# print(\"# next char: %s\" % s[j])\u001b[39;00m\n\u001b[32m 527\u001b[39m \u001b[38;5;28mself\u001b[39m.BadSyntax(s, j, \u001b[33m\"\u001b[39m\u001b[33mexpected directive or statement\u001b[39m\u001b[33m\"\u001b[39m)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:543\u001b[39m, in \u001b[36mSinkParser.directiveOrStatement\u001b[39m\u001b[34m(self, argstr, h)\u001b[39m\n\u001b[32m 540\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j >= \u001b[32m0\u001b[39m:\n\u001b[32m 541\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.checkDot(argstr, j)\n\u001b[32m--> \u001b[39m\u001b[32m543\u001b[39m j = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mstatement\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 544\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j >= \u001b[32m0\u001b[39m:\n\u001b[32m 545\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.checkDot(argstr, j)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:791\u001b[39m, in \u001b[36mSinkParser.statement\u001b[39m\u001b[34m(self, argstr, i)\u001b[39m\n\u001b[32m 788\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m i < \u001b[32m0\u001b[39m:\n\u001b[32m 789\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m i\n\u001b[32m--> \u001b[39m\u001b[32m791\u001b[39m j = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mproperty_list\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mr\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43m0\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 793\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j < \u001b[32m0\u001b[39m:\n\u001b[32m 794\u001b[39m \u001b[38;5;28mself\u001b[39m.BadSyntax(argstr, i, \u001b[33m\"\u001b[39m\u001b[33mexpected propertylist\u001b[39m\u001b[33m\"\u001b[39m)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:1153\u001b[39m, in \u001b[36mSinkParser.property_list\u001b[39m\u001b[34m(self, argstr, i, subj)\u001b[39m\n\u001b[32m 1150\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m i \u001b[38;5;66;03m# void but valid\u001b[39;00m\n\u001b[32m 1152\u001b[39m objs: typing.List[Any] = []\n\u001b[32m-> \u001b[39m\u001b[32m1153\u001b[39m i = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mobjectList\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mj\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mobjs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1154\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m i < \u001b[32m0\u001b[39m:\n\u001b[32m 1155\u001b[39m \u001b[38;5;28mself\u001b[39m.BadSyntax(argstr, j, \u001b[33m\"\u001b[39m\u001b[33mobjectList expected\u001b[39m\u001b[33m\"\u001b[39m)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:1203\u001b[39m, in \u001b[36mSinkParser.objectList\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 1202\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mobjectList\u001b[39m(\u001b[38;5;28mself\u001b[39m, argstr: \u001b[38;5;28mstr\u001b[39m, i: \u001b[38;5;28mint\u001b[39m, res: MutableSequence[Any]) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1203\u001b[39m i = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mobject\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1204\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m i < \u001b[32m0\u001b[39m:\n\u001b[32m 1205\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m -\u001b[32m1\u001b[39m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:1500\u001b[39m, in \u001b[36mSinkParser.object\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 1494\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mobject\u001b[39m(\n\u001b[32m 1495\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1496\u001b[39m argstr: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m 1497\u001b[39m i: \u001b[38;5;28mint\u001b[39m,\n\u001b[32m 1498\u001b[39m res: MutableSequence[Any],\n\u001b[32m 1499\u001b[39m ) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1500\u001b[39m j = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43msubject\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1501\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j >= \u001b[32m0\u001b[39m:\n\u001b[32m 1502\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m j\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:798\u001b[39m, in \u001b[36mSinkParser.subject\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 797\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34msubject\u001b[39m(\u001b[38;5;28mself\u001b[39m, argstr: \u001b[38;5;28mstr\u001b[39m, i: \u001b[38;5;28mint\u001b[39m, res: MutableSequence[Any]) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m798\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mitem\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:890\u001b[39m, in \u001b[36mSinkParser.item\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 889\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mitem\u001b[39m(\u001b[38;5;28mself\u001b[39m, argstr: \u001b[38;5;28mstr\u001b[39m, i, res: MutableSequence[Any]) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m890\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mpath\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:897\u001b[39m, in \u001b[36mSinkParser.path\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 895\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mpath\u001b[39m(\u001b[38;5;28mself\u001b[39m, argstr: \u001b[38;5;28mstr\u001b[39m, i: \u001b[38;5;28mint\u001b[39m, res: MutableSequence[Any]) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m 896\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"Parse the path production.\"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m897\u001b[39m j = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mnodeOrLiteral\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 898\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j < \u001b[32m0\u001b[39m:\n\u001b[32m 899\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m j \u001b[38;5;66;03m# nope\u001b[39;00m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:1528\u001b[39m, in \u001b[36mSinkParser.nodeOrLiteral\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 1527\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mnodeOrLiteral\u001b[39m(\u001b[38;5;28mself\u001b[39m, argstr: \u001b[38;5;28mstr\u001b[39m, i: \u001b[38;5;28mint\u001b[39m, res: MutableSequence[Any]) -> \u001b[38;5;28mint\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1528\u001b[39m j = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mnode\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1529\u001b[39m startline = \u001b[38;5;28mself\u001b[39m.lines \u001b[38;5;66;03m# Remember where for error messages\u001b[39;00m\n\u001b[32m 1530\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j >= \u001b[32m0\u001b[39m:\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:1115\u001b[39m, in \u001b[36mSinkParser.node\u001b[39m\u001b[34m(self, argstr, i, res, subjectAlready)\u001b[39m\n\u001b[32m 1112\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m j\n\u001b[32m 1114\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m subj \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m: \u001b[38;5;66;03m# If this can be a named node, then check for a name.\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1115\u001b[39m j = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43muri_ref2\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margstr\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mres\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1116\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m j >= \u001b[32m0\u001b[39m:\n\u001b[32m 1117\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m j\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/plugins/parsers/notation3.py:1254\u001b[39m, in \u001b[36mSinkParser.uri_ref2\u001b[39m\u001b[34m(self, argstr, i, res)\u001b[39m\n\u001b[32m 1252\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1253\u001b[39m \u001b[38;5;28mself\u001b[39m.BadSyntax(argstr, i, \u001b[33m'\u001b[39m\u001b[33mPrefix \u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m:\u001b[39m\u001b[33m\"\u001b[39m\u001b[33m not bound\u001b[39m\u001b[33m'\u001b[39m % (pfx))\n\u001b[32m-> \u001b[39m\u001b[32m1254\u001b[39m symb = \u001b[38;5;28mself\u001b[39m._store.newSymbol(\u001b[30;43mns\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m+\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mln\u001b[39;49m)\n\u001b[32m 1255\u001b[39m res.append(\u001b[38;5;28mself\u001b[39m._variables.get(symb, symb))\n\u001b[32m 1256\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m j\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/term.py:359\u001b[39m, in \u001b[36mURIRef.__add__\u001b[39m\u001b[34m(self, other)\u001b[39m\n\u001b[32m 358\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m__add__\u001b[39m(\u001b[38;5;28mself\u001b[39m, other) -> URIRef:\n\u001b[32m--> \u001b[39m\u001b[32m359\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m__class__\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstr\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m+\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mother\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/th/kgr/.venv/lib/python3.11/site-packages/rdflib/term.py:286\u001b[39m, in \u001b[36mURIRef.__new__\u001b[39m\u001b[34m(cls, value, base)\u001b[39m\n\u001b[32m 283\u001b[39m \u001b[34m__neg__\u001b[39m: Callable[[URIRef], NegatedPath]\n\u001b[32m 284\u001b[39m \u001b[34m__truediv__\u001b[39m: Callable[[URIRef, Union[URIRef, Path]], SequencePath]\n\u001b[32m--> \u001b[39m\u001b[32m286\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m__new__\u001b[39m(\u001b[38;5;28mcls\u001b[39m, value: \u001b[38;5;28mstr\u001b[39m, base: Optional[\u001b[38;5;28mstr\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[32m 287\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m base \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 288\u001b[39m ends_in_hash = value.endswith(\u001b[33m\"\u001b[39m\u001b[33m#\u001b[39m\u001b[33m\"\u001b[39m)\n",
"\u001b[31mKeyboardInterrupt\u001b[39m: "
]
}
],
"source": [
"import rdflib\n",
" \n",
"filename = \"lego_graph_rebrickable.ttl\"\n",
"\n",
"\n",
"g = rdflib.Graph()\n",
"\n",
"g.parse(filename, format='ttl')\n",
"\n",
"query = \"\"\"\n",
"\n",
"SELECT ?person\n",
"WHERE {\n",
" ?person thmont:color <https://thm.de/color/19>\n",
"\n",
"\"\"\"\n",
"\n",
"qres = g.query(query)\n",
"\n",
"for row in qres :\n",
" print(\"%s\" % row)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "kgr",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 3,
"id": "ad994162",
"metadata": {},
"outputs": [],
@ -14,12 +14,13 @@
"import pandas as pd\n",
"import time\n",
"import random\n",
"import re"
"import re\n",
"import pprint"
]
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 4,
"id": "b5536e8c",
"metadata": {},
"outputs": [],
@ -29,33 +30,45 @@
},
{
"cell_type": "code",
"execution_count": 16,
"id": "6d109e8a",
"execution_count": null,
"id": "a5daea73",
"metadata": {},
"outputs": [],
"outputs": [
{
"ename": "FileNotFoundError",
"evalue": "[Errno 2] No such file or directory: 'bluebrixx.json'",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mFileNotFoundError\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[11]\u001b[39m\u001b[32m, line 5\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m open(\u001b[33m\"./others.csv\"\u001b[39m, mode=\u001b[33m\"w+\"\u001b[39m, encoding=\u001b[33m\"utf8\"\u001b[39m, newline=\u001b[33m\"\"\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m producerfile:\n\u001b[32m 2\u001b[39m writer = csv.writer(producerfile)\n\u001b[32m 3\u001b[39m writer.writerow([\u001b[33m\"id\"\u001b[39m, \u001b[33m\"producer\"\u001b[39m, \u001b[33m\"name\"\u001b[39m, \u001b[33m\"size\"\u001b[39m, \u001b[33m\"parts\"\u001b[39m, \u001b[33m\"year\"\u001b[39m])\n\u001b[32m 4\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m producer \u001b[38;5;28;01min\u001b[39;00m producers:\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m open(\u001b[33mf\"{producer}.json\"\u001b[39m, mode=\u001b[33m\"r\"\u001b[39m, encoding=\u001b[33m\"utf8\"\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m sourcefile:\n\u001b[32m 6\u001b[39m data = json.loads(sourcefile.read())\n\u001b[32m 7\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m row \u001b[38;5;28;01min\u001b[39;00m data[\u001b[33m\"data\"\u001b[39m]:\n\u001b[32m 8\u001b[39m _, id, _, name, rating, _, _, size, parts, year, _ = row\n",
"\u001b[31mFileNotFoundError\u001b[39m: [Errno 2] No such file or directory: 'bluebrixx.json'"
]
}
],
"source": [
"id_to_name = dict()\n",
"for producer in producers:\n",
" with open(f\"../data/merlin/{producer}.json\", mode=\"r\", encoding=\"utf8\") as prodfile:\n",
" listings = json.load(prodfile)[\"data\"]\n",
"with open(\"./others.csv\", mode=\"w+\", encoding=\"utf8\", newline=\"\") as producerfile:\n",
" writer = csv.writer(producerfile)\n",
" writer.writerow([\"id\", \"producer\", \"name\", \"size\", \"parts\", \"year\"])\n",
" for producer in producers:\n",
" with open(f\"data/merlin/{producer}.json\", mode=\"r\", encoding=\"utf8\") as sourcefile:\n",
" data = json.loads(sourcefile.read())\n",
" for row in data[\"data\"]:\n",
" _, id, _, name, rating, _, _, size, parts, year, _ = row\n",
"\n",
" for listing in listings:\n",
" name = listing[3] \n",
" id = listing[1]\n",
"\n",
" id_to_name[id] = name"
" writer.writerow([id, producer, name, size, parts, year])"
]
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 16,
"id": "ab997198",
"metadata": {},
"outputs": [],
"source": [
"# uvp preise bestimmen :(\n",
"def get_all_ids() -> list[str]:\n",
" df = pd.read_csv(\"../data/merlin/others.csv\")\n",
" df = pd.read_csv(\"./others.csv\")\n",
" return df[\"id\"].to_list()"
]
},
@ -66,18 +79,19 @@
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"' with open(\"../data/merlin/prices.csv\", mode=\"a+\", encoding=\"utf8\", newline=\"\") as pricefile:\\n for idx, id in enumerate(get_all_ids()[3663:]):\\n try:\\n small_id = id.lower()\\n\\n response = rq.get(f\"https://www.merlinssteine.de/sets/{small_id}\")\\n soup = bs4.BeautifulSoup(response.text)\\n\\n # Prices\\n price_eur = soup.find(id=\"listprice_eur\")\\n price_usd = soup.find(id=\"listprice_usd\")\\n price_cn = soup.find(id=\"listprice_cn\")\\n bestprice_eur = soup.find(id=\"bestprice_eur\")\\n bestprice_usd = soup.find(id=\"bestprice_usd\")\\n bestprice_cn = soup.find(id=\"bestprice_cn\")\\n\\n all_prices = [price_eur, price_cn, price_usd, bestprice_eur, bestprice_cn, bestprice_usd]\\n\\n #categories\\n other_dump = [description.text.replace(\"\\n\", \"\") for description in soup.find_all(class_=\"setpage_ct\")]\\n writer = csv.writer(pricefile)\\n\\n all_prices = [p.text if p != None else \"_\" for p in all_prices]\\n writer.writerow([id, *all_prices, *other_dump])\\n time.sleep(random.randint(2, 3))\\n except Exception as e:\\n print(e) '"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[18]\u001b[39m\u001b[32m, line 26\u001b[39m\n\u001b[32m 22\u001b[39m \n\u001b[32m 23\u001b[39m \u001b[38;5;66;03m#all_prices = [p.text if p != None else \"_\" for p in all_prices]\u001b[39;00m\n\u001b[32m 24\u001b[39m writer.writerow([id, price_eur, price_cn, price_usd, bestprice_eur, bestprice_cn, bestprice_usd])\n\u001b[32m 25\u001b[39m time.sleep((random.randint(\u001b[32m2\u001b[39m, \u001b[32m3\u001b[39m))/\u001b[32m10\u001b[39m)\n\u001b[32m---> \u001b[39m\u001b[32m26\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m Exception \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 27\u001b[39m print(e)\n",
"\u001b[31mKeyboardInterrupt\u001b[39m: "
]
}
],
"source": [
"\"\"\" with open(\"../data/merlin/prices.csv\", mode=\"a+\", encoding=\"utf8\", newline=\"\") as pricefile:\n",
"with open(\"./prices2.csv\", mode=\"a+\", encoding=\"utf8\", newline=\"\") as pricefile:\n",
" for idx, id in enumerate(get_all_ids()[3663:]):\n",
" try:\n",
" small_id = id.lower()\n",
@ -93,22 +107,22 @@
" bestprice_usd = soup.find(id=\"bestprice_usd\")\n",
" bestprice_cn = soup.find(id=\"bestprice_cn\")\n",
"\n",
" all_prices = [price_eur, price_cn, price_usd, bestprice_eur, bestprice_cn, bestprice_usd]\n",
" #all_prices = [price_eur, price_cn, price_usd, bestprice_eur, bestprice_cn, bestprice_usd]\n",
" \n",
" #categories\n",
" other_dump = [description.text.replace(\"\\n\", \"\") for description in soup.find_all(class_=\"setpage_ct\")]\n",
" #other_dump = [description.text.replace(\"\\n\", \"\") for description in soup.find_all(class_=\"setpage_ct\")]\n",
" writer = csv.writer(pricefile)\n",
" \n",
" all_prices = [p.text if p != None else \"_\" for p in all_prices]\n",
" writer.writerow([id, *all_prices, *other_dump])\n",
" time.sleep(random.randint(2, 3))\n",
" #all_prices = [p.text if p != None else \"_\" for p in all_prices]\n",
" writer.writerow([id, price_eur, price_cn, price_usd, bestprice_eur, bestprice_cn, bestprice_usd])\n",
" time.sleep((random.randint(2, 3))/10)\n",
" except Exception as e:\n",
" print(e) \"\"\""
" print(e)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": null,
"id": "4a10a1e3",
"metadata": {},
"outputs": [],
@ -128,7 +142,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": null,
"id": "9c00f188",
"metadata": {},
"outputs": [],
@ -177,82 +191,79 @@
},
{
"cell_type": "code",
"execution_count": 21,
"id": "9b44a0e5",
"metadata": {},
"outputs": [],
"source": [
"def rm_epsilon(l : list[str]) ->list[str]:\n",
" return list(filter(lambda s : len(s) > 0, l))"
]
},
{
"cell_type": "code",
"execution_count": 56,
"execution_count": null,
"id": "ae53869e",
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'Listenpreis:': '14.95 EUR (7.3 ct/Teil) (7.9 ct/g)',\n",
" 'DetailsVon:': 'BlueBrixx',\n",
" 'EAN:': '4060904003671',\n",
" 'Steine von:': 'Qunlong',\n",
" 'Kategorie:': 'EisenbahnHersteller-',\n",
" 'Kategorien:': 'BBSpecial, BRIX',\n",
" 'Anleitung': 'Ohne Bauabschnitte',\n",
" 'Bewertungen': 'Bewerten',\n",
" 'Hersteller-Videos': 'video-1',\n",
" 'Inhalt': '205 Teile',\n",
" 'Gewicht': ': 190 g',\n",
" 'Keine Aufkleber': '',\n",
" 'Keine Drucke': '',\n",
" 'Farbverteilung': '',\n",
" 'TeilelistenBrickLink': 'XMLRebrickable CSVLEGO PaB CSVSetDB CSV',\n",
" 'PreiseListenpreis:': '14.95 EUR (7.3 ct/Teil) (7.9 ct/g)'}\n"
]
}
],
"source": [
"me_details = pd.DataFrame({\n",
" \"id\" : [],\n",
" \"name\" : [],\n",
" \"price_eur\" : [],\n",
" \"price_cn\" : [],\n",
" \"price_us\" : [],\n",
" \"brand\" : [],\n",
" \"ean\" : [],\n",
" \"producer\" : [],\n",
" \"release\" : [],\n",
" \"category\" : [],\n",
" \"producer_category\" : [],\n",
" \"num_parts\" : [],\n",
" })\n",
"details = {\n",
" \"id\" : [],\n",
" \"listprice_eur\" : [],\n",
" \"listprice_cn\" : [],\n",
" \"listprice_usd\" : [],\n",
" \"bestprice_eur\" : [],\n",
" \"bestprice_cn\" : [],\n",
" \"bestprice_usd\" : [],\n",
" \"brand\" : [],\n",
" \"ean\" : [],\n",
" \"producer\" : [],\n",
" \"release\" : [],\n",
" \"scale\" : [],\n",
" \"category\" : [],\n",
" \"producer_category\" : [],\n",
" \"num_parts\" : [],\n",
" \"width\" : [],\n",
" \"height\" : [],\n",
" \"depth\" : [],\n",
" \"designer\" : [],\n",
" \"weight\" : [],\n",
" \"age\" : []\n",
"}\n",
"import random\n",
"\n",
"me_details = pd.DataFrame(details)\n",
"\n",
"with open(\"../data/merlin/prices.csv\", mode=\"r\", encoding=\"utf8\") as price_file:\n",
" reader = csv.reader(price_file)\n",
"\n",
" for row in reader:\n",
" id, lp_eur, lp_cn, lp_usd, bp_eur, bp_cn, bp_usd, *other = row\n",
" other = filter(lambda s: not \"Wikipedia\" in s, other)\n",
" # for row in reader:\n",
" # id, lp_eur, lp_cn, lp_usd, bp_eur, bp_cn, bp_usd, *other = row\n",
" \n",
" # me_details.loc[-1] = [id, lp_eur, lp_cn, lp_usd, bp_eur, bp_cn, bp_usd] + list(range(0, 12))\n",
" # me_details.index = me_details.index + 1\n",
" id, lp_eur, lp_cn, lp_usd, bp_eur, bp_cn, bp_usd, *other = [row for row in reader][random.randint(0, 4500)]\n",
" other = filter(lambda s: not \"Wikipedia\" in s, other)\n",
"\n",
" retrieved = split_by_keywords(\"\".join(other), keywords)\n",
"\n",
" brand = retrieved.get(\"DetailsVon:\", \"\").replace(\" \", \"\")\n",
" ean = retrieved.get(\"EAN:\", \"\")\n",
" producer = retrieved.get(\"Steine von:\", \"\")\n",
" age = retrieved.get(\"Altersempfehlung:\", \"\")\n",
" release = retrieved.get(\"Release:\", \"\").split(\" \")[-1]\n",
" num_parts = retrieved.get(\"Inhalt\", \"\").split(\"Teile\")[0].replace(\"Ein Teil\", \"1\").replace(\"Preise\", \"\").replace(\"Mit Fernsteuerung / Elektrik\", \"1\").replace(\"Eine Minifigur\", \"1\").replace(\"Minifiguren\", \"\").strip()\n",
"\n",
" category = retrieved.get(\"Kategorie:\", \"\").strip().split(\",\")\n",
" categories = \",\".join(rm_epsilon(retrieved.get(\"Kategorien:\", \"\") .split(\",\") + category)).replace(\"Hersteller\", \"\")\n",
" producer_category = retrieved.get(\"Hersteller-Kategorie:\", \"\").split(\",\")\n",
" producer_categories = \",\".join(rm_epsilon(retrieved.get(\"Hersteller-Kategorien:\", \"\").split(\",\") + producer_category))\n",
"\n",
" if brand == \"\":\n",
" continue\n",
" me_extra = pd.DataFrame({\n",
" \"id\" : [id],\n",
" \"name\" : [id_to_name.get(id, \"\")],\n",
" \"price_eur\" : [lp_eur.replace(\"_\", \"\")],\n",
" \"price_us\" : [lp_usd.replace(\"_\", \"\")],\n",
" \"price_cn\" : [lp_cn.replace(\"_\", \"\")],\n",
" \"brand\" : [brand],\n",
" \"ean\" : [ean],\n",
" \"producer\" : [producer],\n",
" \"release\" : [release],\n",
" \"category\" : [categories],\n",
" \"producer_category\" : [producer_categories],\n",
" \"num_parts\" : [num_parts],\n",
" })\n",
"\n",
" me_details = pd.concat([me_details, me_extra])"
" pprint.pp(split_by_keywords(\"\".join(other), keywords))\n"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "1b5bcea6",
"execution_count": null,
"id": "b83aa413",
"metadata": {},
"outputs": [
{
@ -277,53 +288,55 @@
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>id</th>\n",
" <th>name</th>\n",
" <th>price_eur</th>\n",
" <th>price_cn</th>\n",
" <th>price_us</th>\n",
" <th>listprice_eur</th>\n",
" <th>listprice_cn</th>\n",
" <th>listprice_usd</th>\n",
" <th>bestprice_eur</th>\n",
" <th>bestprice_cn</th>\n",
" <th>bestprice_usd</th>\n",
" <th>brand</th>\n",
" <th>ean</th>\n",
" <th>producer</th>\n",
" <th>release</th>\n",
" <th>...</th>\n",
" <th>scale</th>\n",
" <th>category</th>\n",
" <th>producer_category</th>\n",
" <th>num_parts</th>\n",
" <th>width</th>\n",
" <th>height</th>\n",
" <th>depth</th>\n",
" <th>designer</th>\n",
" <th>weight</th>\n",
" <th>age</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" </tbody>\n",
"</table>\n",
"<p>0 rows × 21 columns</p>\n",
"</div>"
],
"text/plain": [
"Empty DataFrame\n",
"Columns: [id, name, price_eur, price_cn, price_us, brand, ean, producer, release, category, producer_category, num_parts]\n",
"Index: []"
"Columns: [id, listprice_eur, listprice_cn, listprice_usd, bestprice_eur, bestprice_cn, bestprice_usd, brand, ean, producer, release, scale, category, producer_category, num_parts, width, height, depth, designer, weight, age]\n",
"Index: []\n",
"\n",
"[0 rows x 21 columns]"
]
},
"execution_count": 57,
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"me_details[\"Mit Fernsteuerung / Elektrik\" == me_details[\"num_parts\"]]"
]
},
{
"cell_type": "code",
"execution_count": 58,
"id": "0fb65dec",
"metadata": {},
"outputs": [],
"source": [
"me_details.to_csv(\"../data/merlin/others.csv\", index=False)"
"me_details"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv (3.14.4)",
"display_name": "kgr",
"language": "python",
"name": "python3"
},
@ -337,7 +350,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.4"
"version": "3.11.2"
}
},
"nbformat": 4,

13
pyproject.toml 100644
View File

@ -0,0 +1,13 @@
[project]
name = "kgr"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"bs4>=0.0.2",
"pandas>=3.0.2",
"rdflib>=7.6.0",
"requests>=2.33.1",
"sparqlwrapper>=2.0.0",
]

408
uv.lock 100644
View File

@ -0,0 +1,408 @@
version = 1
revision = 3
requires-python = ">=3.11"
resolution-markers = [
"python_full_version >= '3.14' and sys_platform == 'win32'",
"python_full_version >= '3.14' and sys_platform == 'emscripten'",
"python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
"python_full_version < '3.14' and sys_platform == 'win32'",
"python_full_version < '3.14' and sys_platform == 'emscripten'",
"python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
]
[[package]]
name = "beautifulsoup4"
version = "4.14.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "soupsieve" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" },
]
[[package]]
name = "bs4"
version = "0.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "beautifulsoup4" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c9/aa/4acaf814ff901145da37332e05bb510452ebed97bc9602695059dd46ef39/bs4-0.0.2.tar.gz", hash = "sha256:a48685c58f50fe127722417bae83fe6badf500d54b55f7e39ffe43b798653925", size = 698, upload-time = "2024-01-17T18:15:47.371Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/51/bb/bf7aab772a159614954d84aa832c129624ba6c32faa559dfb200a534e50b/bs4-0.0.2-py2.py3-none-any.whl", hash = "sha256:abf8742c0805ef7f662dce4b51cca104cffe52b835238afc169142ab9b3fbccc", size = 1189, upload-time = "2024-01-17T18:15:48.613Z" },
]
[[package]]
name = "certifi"
version = "2026.4.22"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" },
]
[[package]]
name = "charset-normalizer"
version = "3.4.7"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" },
{ url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" },
{ url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" },
{ url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" },
{ url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" },
{ url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" },
{ url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" },
{ url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" },
{ url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" },
{ url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" },
{ url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" },
{ url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" },
{ url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" },
{ url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" },
{ url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" },
{ url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" },
{ url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" },
{ url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" },
{ url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" },
{ url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" },
{ url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" },
{ url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" },
{ url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" },
{ url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" },
{ url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" },
{ url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" },
{ url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" },
{ url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" },
{ url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" },
{ url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" },
{ url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" },
{ url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" },
{ url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" },
{ url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" },
{ url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" },
{ url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" },
{ url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" },
{ url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" },
{ url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" },
{ url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" },
{ url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" },
{ url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" },
{ url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" },
{ url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" },
{ url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" },
{ url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" },
{ url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" },
{ url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" },
{ url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" },
{ url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" },
{ url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" },
{ url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" },
{ url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" },
{ url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" },
{ url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" },
{ url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" },
{ url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" },
{ url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" },
{ url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" },
{ url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" },
{ url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" },
{ url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" },
{ url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" },
{ url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" },
{ url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" },
{ url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" },
{ url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" },
{ url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" },
{ url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" },
{ url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" },
{ url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" },
{ url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" },
{ url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" },
{ url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" },
{ url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" },
{ url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" },
{ url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" },
{ url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" },
{ url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" },
{ url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" },
{ url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" },
]
[[package]]
name = "idna"
version = "3.13"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" },
]
[[package]]
name = "kgr"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "bs4" },
{ name = "pandas" },
{ name = "rdflib" },
{ name = "requests" },
{ name = "sparqlwrapper" },
]
[package.metadata]
requires-dist = [
{ name = "bs4", specifier = ">=0.0.2" },
{ name = "pandas", specifier = ">=3.0.2" },
{ name = "rdflib", specifier = ">=7.6.0" },
{ name = "requests", specifier = ">=2.33.1" },
{ name = "sparqlwrapper", specifier = ">=2.0.0" },
]
[[package]]
name = "numpy"
version = "2.4.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587, upload-time = "2026-03-29T13:22:01.298Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/c6/4218570d8c8ecc9704b5157a3348e486e84ef4be0ed3e38218ab473c83d2/numpy-2.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f983334aea213c99992053ede6168500e5f086ce74fbc4acc3f2b00f5762e9db", size = 16976799, upload-time = "2026-03-29T13:18:15.438Z" },
{ url = "https://files.pythonhosted.org/packages/dd/92/b4d922c4a5f5dab9ed44e6153908a5c665b71acf183a83b93b690996e39b/numpy-2.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72944b19f2324114e9dc86a159787333b77874143efcf89a5167ef83cfee8af0", size = 14971552, upload-time = "2026-03-29T13:18:18.606Z" },
{ url = "https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015", size = 5476566, upload-time = "2026-03-29T13:18:21.532Z" },
{ url = "https://files.pythonhosted.org/packages/28/34/b3fdcec6e725409223dd27356bdf5a3c2cc2282e428218ecc9cb7acc9763/numpy-2.4.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:ba1f4fc670ed79f876f70082eff4f9583c15fb9a4b89d6188412de4d18ae2f40", size = 6806482, upload-time = "2026-03-29T13:18:23.634Z" },
{ url = "https://files.pythonhosted.org/packages/68/62/63417c13aa35d57bee1337c67446761dc25ea6543130cf868eace6e8157b/numpy-2.4.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a87ec22c87be071b6bdbd27920b129b94f2fc964358ce38f3822635a3e2e03d", size = 15973376, upload-time = "2026-03-29T13:18:26.677Z" },
{ url = "https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502", size = 16925137, upload-time = "2026-03-29T13:18:30.14Z" },
{ url = "https://files.pythonhosted.org/packages/7e/43/80020edacb3f84b9efdd1591120a4296462c23fd8db0dde1666f6ef66f13/numpy-2.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d4e437e295f18ec29bc79daf55e8a47a9113df44d66f702f02a293d93a2d6dd", size = 17329414, upload-time = "2026-03-29T13:18:33.733Z" },
{ url = "https://files.pythonhosted.org/packages/fd/06/af0658593b18a5f73532d377188b964f239eb0894e664a6c12f484472f97/numpy-2.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa3236c78803afbcb255045fbef97a9e25a1f6c9888357d205ddc42f4d6eba5", size = 18658397, upload-time = "2026-03-29T13:18:37.511Z" },
{ url = "https://files.pythonhosted.org/packages/e6/ce/13a09ed65f5d0ce5c7dd0669250374c6e379910f97af2c08c57b0608eee4/numpy-2.4.4-cp311-cp311-win32.whl", hash = "sha256:30caa73029a225b2d40d9fae193e008e24b2026b7ee1a867b7ee8d96ca1a448e", size = 6239499, upload-time = "2026-03-29T13:18:40.372Z" },
{ url = "https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e", size = 12614257, upload-time = "2026-03-29T13:18:42.95Z" },
{ url = "https://files.pythonhosted.org/packages/87/c5/8168052f080c26fa984c413305012be54741c9d0d74abd7fbeeccae3889f/numpy-2.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:fcfe2045fd2e8f3cb0ce9d4ba6dba6333b8fa05bb8a4939c908cd43322d14c7e", size = 10486775, upload-time = "2026-03-29T13:18:45.835Z" },
{ url = "https://files.pythonhosted.org/packages/28/05/32396bec30fb2263770ee910142f49c1476d08e8ad41abf8403806b520ce/numpy-2.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", size = 16689272, upload-time = "2026-03-29T13:18:49.223Z" },
{ url = "https://files.pythonhosted.org/packages/c5/f3/a983d28637bfcd763a9c7aafdb6d5c0ebf3d487d1e1459ffdb57e2f01117/numpy-2.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", size = 14699573, upload-time = "2026-03-29T13:18:52.629Z" },
{ url = "https://files.pythonhosted.org/packages/9b/fd/e5ecca1e78c05106d98028114f5c00d3eddb41207686b2b7de3e477b0e22/numpy-2.4.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", size = 5204782, upload-time = "2026-03-29T13:18:55.579Z" },
{ url = "https://files.pythonhosted.org/packages/de/2f/702a4594413c1a8632092beae8aba00f1d67947389369b3777aed783fdca/numpy-2.4.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", size = 6552038, upload-time = "2026-03-29T13:18:57.769Z" },
{ url = "https://files.pythonhosted.org/packages/7f/37/eed308a8f56cba4d1fdf467a4fc67ef4ff4bf1c888f5fc980481890104b1/numpy-2.4.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", size = 15670666, upload-time = "2026-03-29T13:19:00.341Z" },
{ url = "https://files.pythonhosted.org/packages/0a/0d/0e3ecece05b7a7e87ab9fb587855548da437a061326fff64a223b6dcb78a/numpy-2.4.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", size = 16645480, upload-time = "2026-03-29T13:19:03.63Z" },
{ url = "https://files.pythonhosted.org/packages/34/49/f2312c154b82a286758ee2f1743336d50651f8b5195db18cdb63675ff649/numpy-2.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", size = 17020036, upload-time = "2026-03-29T13:19:07.428Z" },
{ url = "https://files.pythonhosted.org/packages/7b/e9/736d17bd77f1b0ec4f9901aaec129c00d59f5d84d5e79bba540ef12c2330/numpy-2.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", size = 18368643, upload-time = "2026-03-29T13:19:10.775Z" },
{ url = "https://files.pythonhosted.org/packages/63/f6/d417977c5f519b17c8a5c3bc9e8304b0908b0e21136fe43bf628a1343914/numpy-2.4.4-cp312-cp312-win32.whl", hash = "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", size = 5961117, upload-time = "2026-03-29T13:19:13.464Z" },
{ url = "https://files.pythonhosted.org/packages/2d/5b/e1deebf88ff431b01b7406ca3583ab2bbb90972bbe1c568732e49c844f7e/numpy-2.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", size = 12320584, upload-time = "2026-03-29T13:19:16.155Z" },
{ url = "https://files.pythonhosted.org/packages/58/89/e4e856ac82a68c3ed64486a544977d0e7bdd18b8da75b78a577ca31c4395/numpy-2.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", size = 10221450, upload-time = "2026-03-29T13:19:18.994Z" },
{ url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933, upload-time = "2026-03-29T13:19:22.47Z" },
{ url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532, upload-time = "2026-03-29T13:19:25.581Z" },
{ url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661, upload-time = "2026-03-29T13:19:28.31Z" },
{ url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539, upload-time = "2026-03-29T13:19:30.97Z" },
{ url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806, upload-time = "2026-03-29T13:19:33.887Z" },
{ url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682, upload-time = "2026-03-29T13:19:37.336Z" },
{ url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810, upload-time = "2026-03-29T13:19:40.963Z" },
{ url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394, upload-time = "2026-03-29T13:19:44.859Z" },
{ url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556, upload-time = "2026-03-29T13:19:47.661Z" },
{ url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311, upload-time = "2026-03-29T13:19:50.67Z" },
{ url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060, upload-time = "2026-03-29T13:19:54.229Z" },
{ url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302, upload-time = "2026-03-29T13:19:57.585Z" },
{ url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407, upload-time = "2026-03-29T13:20:00.601Z" },
{ url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631, upload-time = "2026-03-29T13:20:02.855Z" },
{ url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691, upload-time = "2026-03-29T13:20:06.004Z" },
{ url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241, upload-time = "2026-03-29T13:20:09.417Z" },
{ url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767, upload-time = "2026-03-29T13:20:13.126Z" },
{ url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169, upload-time = "2026-03-29T13:20:17.096Z" },
{ url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477, upload-time = "2026-03-29T13:20:20.195Z" },
{ url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487, upload-time = "2026-03-29T13:20:22.946Z" },
{ url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002, upload-time = "2026-03-29T13:20:25.909Z" },
{ url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353, upload-time = "2026-03-29T13:20:29.504Z" },
{ url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914, upload-time = "2026-03-29T13:20:33.547Z" },
{ url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005, upload-time = "2026-03-29T13:20:36.45Z" },
{ url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974, upload-time = "2026-03-29T13:20:39.014Z" },
{ url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591, upload-time = "2026-03-29T13:20:42.146Z" },
{ url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700, upload-time = "2026-03-29T13:20:46.204Z" },
{ url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781, upload-time = "2026-03-29T13:20:50.242Z" },
{ url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959, upload-time = "2026-03-29T13:20:54.019Z" },
{ url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768, upload-time = "2026-03-29T13:20:56.912Z" },
{ url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181, upload-time = "2026-03-29T13:20:59.548Z" },
{ url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035, upload-time = "2026-03-29T13:21:02.524Z" },
{ url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958, upload-time = "2026-03-29T13:21:05.671Z" },
{ url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020, upload-time = "2026-03-29T13:21:08.635Z" },
{ url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758, upload-time = "2026-03-29T13:21:10.949Z" },
{ url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948, upload-time = "2026-03-29T13:21:14.047Z" },
{ url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325, upload-time = "2026-03-29T13:21:17.561Z" },
{ url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883, upload-time = "2026-03-29T13:21:21.106Z" },
{ url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474, upload-time = "2026-03-29T13:21:24.828Z" },
{ url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500, upload-time = "2026-03-29T13:21:28.205Z" },
{ url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755, upload-time = "2026-03-29T13:21:31.107Z" },
{ url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643, upload-time = "2026-03-29T13:21:34.339Z" },
{ url = "https://files.pythonhosted.org/packages/6b/33/8fae8f964a4f63ed528264ddf25d2b683d0b663e3cba26961eb838a7c1bd/numpy-2.4.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:58c8b5929fcb8287cbd6f0a3fae19c6e03a5c48402ae792962ac465224a629a4", size = 16854491, upload-time = "2026-03-29T13:21:38.03Z" },
{ url = "https://files.pythonhosted.org/packages/bc/d0/1aabee441380b981cf8cdda3ae7a46aa827d1b5a8cce84d14598bc94d6d9/numpy-2.4.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eea7ac5d2dce4189771cedb559c738a71512768210dc4e4753b107a2048b3d0e", size = 14895830, upload-time = "2026-03-29T13:21:41.509Z" },
{ url = "https://files.pythonhosted.org/packages/a5/b8/aafb0d1065416894fccf4df6b49ef22b8db045187949545bced89c034b8e/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:51fc224f7ca4d92656d5a5eb315f12eb5fe2c97a66249aa7b5f562528a3be38c", size = 5400927, upload-time = "2026-03-29T13:21:44.747Z" },
{ url = "https://files.pythonhosted.org/packages/d6/77/063baa20b08b431038c7f9ff5435540c7b7265c78cf56012a483019ca72d/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:28a650663f7314afc3e6ec620f44f333c386aad9f6fc472030865dc0ebb26ee3", size = 6715557, upload-time = "2026-03-29T13:21:47.406Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a8/379542d45a14f149444c5c4c4e7714707239ce9cc1de8c2803958889da14/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19710a9ca9992d7174e9c52f643d4272dcd1558c5f7af7f6f8190f633bd651a7", size = 15804253, upload-time = "2026-03-29T13:21:50.753Z" },
{ url = "https://files.pythonhosted.org/packages/a2/c8/f0a45426d6d21e7ea3310a15cf90c43a14d9232c31a837702dba437f3373/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b2aec6af35c113b05695ebb5749a787acd63cafc83086a05771d1e1cd1e555f", size = 16753552, upload-time = "2026-03-29T13:21:54.344Z" },
{ url = "https://files.pythonhosted.org/packages/04/74/f4c001f4714c3ad9ce037e18cf2b9c64871a84951eaa0baf683a9ca9301c/numpy-2.4.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f2cf083b324a467e1ab358c105f6cad5ea950f50524668a80c486ff1db24e119", size = 12509075, upload-time = "2026-03-29T13:21:57.644Z" },
]
[[package]]
name = "pandas"
version = "3.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy" },
{ name = "python-dateutil" },
{ name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/da/99/b342345300f13440fe9fe385c3c481e2d9a595ee3bab4d3219247ac94e9a/pandas-3.0.2.tar.gz", hash = "sha256:f4753e73e34c8d83221ba58f232433fca2748be8b18dbca02d242ed153945043", size = 4645855, upload-time = "2026-03-31T06:48:30.816Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/97/35/6411db530c618e0e0005187e35aa02ce60ae4c4c4d206964a2f978217c27/pandas-3.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a727a73cbdba2f7458dc82449e2315899d5140b449015d822f515749a46cbbe0", size = 10326926, upload-time = "2026-03-31T06:46:08.29Z" },
{ url = "https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbbd4aa20ca51e63b53bbde6a0fa4254b1aaabb74d2f542df7a7959feb1d760c", size = 9926987, upload-time = "2026-03-31T06:46:11.724Z" },
{ url = "https://files.pythonhosted.org/packages/52/77/9b1c2d6070b5dbe239a7bc889e21bfa58720793fb902d1e070695d87c6d0/pandas-3.0.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:339dda302bd8369dedeae979cb750e484d549b563c3f54f3922cb8ff4978c5eb", size = 10757067, upload-time = "2026-03-31T06:46:14.903Z" },
{ url = "https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:61c2fd96d72b983a9891b2598f286befd4ad262161a609c92dc1652544b46b76", size = 11258787, upload-time = "2026-03-31T06:46:17.683Z" },
{ url = "https://files.pythonhosted.org/packages/90/e3/3f1126d43d3702ca8773871a81c9f15122a1f412342cc56284ffda5b1f70/pandas-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c934008c733b8bbea273ea308b73b3156f0181e5b72960790b09c18a2794fe1e", size = 11771616, upload-time = "2026-03-31T06:46:20.532Z" },
{ url = "https://files.pythonhosted.org/packages/2e/cf/0f4e268e1f5062e44a6bda9f925806721cd4c95c2b808a4c82ebe914f96b/pandas-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:60a80bb4feacbef5e1447a3f82c33209c8b7e07f28d805cfd1fb951e5cb443aa", size = 12337623, upload-time = "2026-03-31T06:46:23.754Z" },
{ url = "https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed72cb3f45190874eb579c64fa92d9df74e98fd63e2be7f62bce5ace0ade61df", size = 9897372, upload-time = "2026-03-31T06:46:26.703Z" },
{ url = "https://files.pythonhosted.org/packages/8f/eb/781516b808a99ddf288143cec46b342b3016c3414d137da1fdc3290d8860/pandas-3.0.2-cp311-cp311-win_arm64.whl", hash = "sha256:f12b1a9e332c01e09510586f8ca9b108fd631fd656af82e452d7315ef6df5f9f", size = 9154922, upload-time = "2026-03-31T06:46:30.284Z" },
{ url = "https://files.pythonhosted.org/packages/f3/b0/c20bd4d6d3f736e6bd6b55794e9cd0a617b858eaad27c8f410ea05d953b7/pandas-3.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:232a70ebb568c0c4d2db4584f338c1577d81e3af63292208d615907b698a0f18", size = 10347921, upload-time = "2026-03-31T06:46:33.36Z" },
{ url = "https://files.pythonhosted.org/packages/35/d0/4831af68ce30cc2d03c697bea8450e3225a835ef497d0d70f31b8cdde965/pandas-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:970762605cff1ca0d3f71ed4f3a769ea8f85fc8e6348f6e110b8fea7e6eb5a14", size = 9888127, upload-time = "2026-03-31T06:46:36.253Z" },
{ url = "https://files.pythonhosted.org/packages/61/a9/16ea9346e1fc4a96e2896242d9bc674764fb9049b0044c0132502f7a771e/pandas-3.0.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aff4e6f4d722e0652707d7bcb190c445fe58428500c6d16005b02401764b1b3d", size = 10399577, upload-time = "2026-03-31T06:46:39.224Z" },
{ url = "https://files.pythonhosted.org/packages/c4/a8/3a61a721472959ab0ce865ef05d10b0d6bfe27ce8801c99f33d4fa996e65/pandas-3.0.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef8b27695c3d3dc78403c9a7d5e59a62d5464a7e1123b4e0042763f7104dc74f", size = 10880030, upload-time = "2026-03-31T06:46:42.412Z" },
{ url = "https://files.pythonhosted.org/packages/da/65/7225c0ea4d6ce9cb2160a7fb7f39804871049f016e74782e5dade4d14109/pandas-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f8d68083e49e16b84734eb1a4dcae4259a75c90fb6e2251ab9a00b61120c06ab", size = 11409468, upload-time = "2026-03-31T06:46:45.2Z" },
{ url = "https://files.pythonhosted.org/packages/fa/5b/46e7c76032639f2132359b5cf4c785dd8cf9aea5ea64699eac752f02b9db/pandas-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:32cc41f310ebd4a296d93515fcac312216adfedb1894e879303987b8f1e2b97d", size = 11936381, upload-time = "2026-03-31T06:46:48.293Z" },
{ url = "https://files.pythonhosted.org/packages/7b/8b/721a9cff6fa6a91b162eb51019c6243b82b3226c71bb6c8ef4a9bd65cbc6/pandas-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:a4785e1d6547d8427c5208b748ae2efb64659a21bd82bf440d4262d02bfa02a4", size = 9744993, upload-time = "2026-03-31T06:46:51.488Z" },
{ url = "https://files.pythonhosted.org/packages/d5/18/7f0bd34ae27b28159aa80f2a6799f47fda34f7fb938a76e20c7b7fe3b200/pandas-3.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:08504503f7101300107ecdc8df73658e4347586db5cfdadabc1592e9d7e7a0fd", size = 9056118, upload-time = "2026-03-31T06:46:54.548Z" },
{ url = "https://files.pythonhosted.org/packages/bf/ca/3e639a1ea6fcd0617ca4e8ca45f62a74de33a56ae6cd552735470b22c8d3/pandas-3.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5918ba197c951dec132b0c5929a00c0bf05d5942f590d3c10a807f6e15a57d3", size = 10321105, upload-time = "2026-03-31T06:46:57.327Z" },
{ url = "https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668", size = 9864088, upload-time = "2026-03-31T06:46:59.935Z" },
{ url = "https://files.pythonhosted.org/packages/5c/2b/341f1b04bbca2e17e13cd3f08c215b70ef2c60c5356ef1e8c6857449edc7/pandas-3.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:710246ba0616e86891b58ab95f2495143bb2bc83ab6b06747c74216f583a6ac9", size = 10369066, upload-time = "2026-03-31T06:47:02.792Z" },
{ url = "https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e", size = 10876780, upload-time = "2026-03-31T06:47:06.205Z" },
{ url = "https://files.pythonhosted.org/packages/98/fe/2249ae5e0a69bd0ddf17353d0a5d26611d70970111f5b3600cdc8be883e7/pandas-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3b723df9087a9a9a840e263ebd9f88b64a12075d1bf2ea401a5a42f254f084d", size = 11375181, upload-time = "2026-03-31T06:47:09.383Z" },
{ url = "https://files.pythonhosted.org/packages/de/64/77a38b09e70b6464883b8d7584ab543e748e42c1b5d337a2ee088e0df741/pandas-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3096110bf9eac0070b7208465f2740e2d8a670d5cb6530b5bb884eca495fd39", size = 11928899, upload-time = "2026-03-31T06:47:12.686Z" },
{ url = "https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991", size = 9746574, upload-time = "2026-03-31T06:47:15.64Z" },
{ url = "https://files.pythonhosted.org/packages/88/39/21304ae06a25e8bf9fc820d69b29b2c495b2ae580d1e143146c309941760/pandas-3.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:5fdbfa05931071aba28b408e59226186b01eb5e92bea2ab78b65863ca3228d84", size = 9047156, upload-time = "2026-03-31T06:47:18.595Z" },
{ url = "https://files.pythonhosted.org/packages/72/20/7defa8b27d4f330a903bb68eea33be07d839c5ea6bdda54174efcec0e1d2/pandas-3.0.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:dbc20dea3b9e27d0e66d74c42b2d0c1bed9c2ffe92adea33633e3bedeb5ac235", size = 10756238, upload-time = "2026-03-31T06:47:22.012Z" },
{ url = "https://files.pythonhosted.org/packages/e9/95/49433c14862c636afc0e9b2db83ff16b3ad92959364e52b2955e44c8e94c/pandas-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b75c347eff42497452116ce05ef461822d97ce5b9ff8df6edacb8076092c855d", size = 10408520, upload-time = "2026-03-31T06:47:25.197Z" },
{ url = "https://files.pythonhosted.org/packages/3b/f8/462ad2b5881d6b8ec8e5f7ed2ea1893faa02290d13870a1600fe72ad8efc/pandas-3.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1478075142e83a5571782ad007fb201ed074bdeac7ebcc8890c71442e96adf7", size = 10324154, upload-time = "2026-03-31T06:47:28.097Z" },
{ url = "https://files.pythonhosted.org/packages/0a/65/d1e69b649cbcddda23ad6e4c40ef935340f6f652a006e5cbc3555ac8adb3/pandas-3.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5880314e69e763d4c8b27937090de570f1fb8d027059a7ada3f7f8e98bdcb677", size = 10714449, upload-time = "2026-03-31T06:47:30.85Z" },
{ url = "https://files.pythonhosted.org/packages/47/a4/85b59bc65b8190ea3689882db6cdf32a5003c0ccd5a586c30fdcc3ffc4fc/pandas-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b5329e26898896f06035241a626d7c335daa479b9bbc82be7c2742d048e41172", size = 11338475, upload-time = "2026-03-31T06:47:34.026Z" },
{ url = "https://files.pythonhosted.org/packages/1e/c4/bc6966c6e38e5d9478b935272d124d80a589511ed1612a5d21d36f664c68/pandas-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:81526c4afd31971f8b62671442a4b2b51e0aa9acc3819c9f0f12a28b6fcf85f1", size = 11786568, upload-time = "2026-03-31T06:47:36.941Z" },
{ url = "https://files.pythonhosted.org/packages/e8/74/09298ca9740beed1d3504e073d67e128aa07e5ca5ca2824b0c674c0b8676/pandas-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:7cadd7e9a44ec13b621aec60f9150e744cfc7a3dd32924a7e2f45edff31823b0", size = 10488652, upload-time = "2026-03-31T06:47:40.612Z" },
{ url = "https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b", size = 10326084, upload-time = "2026-03-31T06:47:43.834Z" },
{ url = "https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288", size = 9914146, upload-time = "2026-03-31T06:47:46.67Z" },
{ url = "https://files.pythonhosted.org/packages/8d/77/3a227ff3337aa376c60d288e1d61c5d097131d0ac71f954d90a8f369e422/pandas-3.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01f31a546acd5574ef77fe199bc90b55527c225c20ccda6601cf6b0fd5ed597c", size = 10444081, upload-time = "2026-03-31T06:47:49.681Z" },
{ url = "https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535", size = 10897535, upload-time = "2026-03-31T06:47:53.033Z" },
{ url = "https://files.pythonhosted.org/packages/06/9d/98cc7a7624f7932e40f434299260e2917b090a579d75937cb8a57b9d2de3/pandas-3.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f48afd9bb13300ffb5a3316973324c787054ba6665cda0da3fbd67f451995db", size = 11446992, upload-time = "2026-03-31T06:47:56.193Z" },
{ url = "https://files.pythonhosted.org/packages/9a/cd/19ff605cc3760e80602e6826ddef2824d8e7050ed80f2e11c4b079741dc3/pandas-3.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6c4d8458b97a35717b62469a4ea0e85abd5ed8687277f5ccfc67f8a5126f8c53", size = 11968257, upload-time = "2026-03-31T06:47:59.137Z" },
{ url = "https://files.pythonhosted.org/packages/db/60/aba6a38de456e7341285102bede27514795c1eaa353bc0e7638b6b785356/pandas-3.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:b35d14bb5d8285d9494fe93815a9e9307c0876e10f1e8e89ac5b88f728ec8dcf", size = 9865893, upload-time = "2026-03-31T06:48:02.038Z" },
{ url = "https://files.pythonhosted.org/packages/08/71/e5ec979dd2e8a093dacb8864598c0ff59a0cee0bbcdc0bfec16a51684d4f/pandas-3.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:63d141b56ef686f7f0d714cfb8de4e320475b86bf4b620aa0b7da89af8cbdbbb", size = 9188644, upload-time = "2026-03-31T06:48:05.045Z" },
{ url = "https://files.pythonhosted.org/packages/f1/6c/7b45d85db19cae1eb524f2418ceaa9d85965dcf7b764ed151386b7c540f0/pandas-3.0.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:140f0cffb1fa2524e874dde5b477d9defe10780d8e9e220d259b2c0874c89d9d", size = 10776246, upload-time = "2026-03-31T06:48:07.789Z" },
{ url = "https://files.pythonhosted.org/packages/a8/3e/7b00648b086c106e81766f25322b48aa8dfa95b55e621dbdf2fdd413a117/pandas-3.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae37e833ff4fed0ba352f6bdd8b73ba3ab3256a85e54edfd1ab51ae40cca0af8", size = 10424801, upload-time = "2026-03-31T06:48:10.897Z" },
{ url = "https://files.pythonhosted.org/packages/da/6e/558dd09a71b53b4008e7fc8a98ec6d447e9bfb63cdaeea10e5eb9b2dabe8/pandas-3.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d888a5c678a419a5bb41a2a93818e8ed9fd3172246555c0b37b7cc27027effd", size = 10345643, upload-time = "2026-03-31T06:48:13.7Z" },
{ url = "https://files.pythonhosted.org/packages/be/e3/921c93b4d9a280409451dc8d07b062b503bbec0531d2627e73a756e99a82/pandas-3.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b444dc64c079e84df91baa8bf613d58405645461cabca929d9178f2cd392398d", size = 10743641, upload-time = "2026-03-31T06:48:16.659Z" },
{ url = "https://files.pythonhosted.org/packages/56/ca/fd17286f24fa3b4d067965d8d5d7e14fe557dd4f979a0b068ac0deaf8228/pandas-3.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4544c7a54920de8eeacaa1466a6b7268ecfbc9bc64ab4dbb89c6bbe94d5e0660", size = 11361993, upload-time = "2026-03-31T06:48:19.475Z" },
{ url = "https://files.pythonhosted.org/packages/e4/a5/2f6ed612056819de445a433ca1f2821ac3dab7f150d569a59e9cc105de1d/pandas-3.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:734be7551687c00fbd760dc0522ed974f82ad230d4a10f54bf51b80d44a08702", size = 11815274, upload-time = "2026-03-31T06:48:22.695Z" },
{ url = "https://files.pythonhosted.org/packages/00/2f/b622683e99ec3ce00b0854bac9e80868592c5b051733f2cf3a868e5fea26/pandas-3.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:57a07209bebcbcf768d2d13c9b78b852f9a15978dac41b9e6421a81ad4cdd276", size = 10888530, upload-time = "2026-03-31T06:48:25.806Z" },
{ url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341, upload-time = "2026-03-31T06:48:28.418Z" },
]
[[package]]
name = "pyparsing"
version = "3.3.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" },
]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
]
[[package]]
name = "rdflib"
version = "7.6.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyparsing" },
]
sdist = { url = "https://files.pythonhosted.org/packages/98/f5/18bb77b7af9526add0c727a3b2048959847dc5fb030913e2918bf384fec3/rdflib-7.6.0.tar.gz", hash = "sha256:6c831288d5e4a5a7ece85d0ccde9877d512a3d0f02d7c06455d00d6d0ea379df", size = 4943826, upload-time = "2026-02-13T07:15:55.938Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/10/c2/6604a71269e0c1bd75656d5a001432d16f2cc5b8c057140ec797155c295e/rdflib-7.6.0-py3-none-any.whl", hash = "sha256:30c0a3ebf4c0e09215f066be7246794b6492e054e782d7ac2a34c9f70a15e0dd", size = 615416, upload-time = "2026-02-13T07:15:46.487Z" },
]
[[package]]
name = "requests"
version = "2.33.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" },
]
[[package]]
name = "six"
version = "1.17.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
]
[[package]]
name = "soupsieve"
version = "2.8.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" },
]
[[package]]
name = "sparqlwrapper"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "rdflib" },
]
sdist = { url = "https://files.pythonhosted.org/packages/4e/cc/453752fffa759ef41a3ceadb3f167e13dae1a74c1db057d9f6a7affa9240/SPARQLWrapper-2.0.0.tar.gz", hash = "sha256:3fed3ebcc77617a4a74d2644b86fd88e0f32e7f7003ac7b2b334c026201731f1", size = 98429, upload-time = "2022-03-13T23:14:00.671Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/31/89/176e3db96e31e795d7dfd91dd67749d3d1f0316bb30c6931a6140e1a0477/SPARQLWrapper-2.0.0-py3-none-any.whl", hash = "sha256:c99a7204fff676ee28e6acef327dc1ff8451c6f7217dcd8d49e8872f324a8a20", size = 28620, upload-time = "2022-03-13T23:13:58.969Z" },
]
[[package]]
name = "typing-extensions"
version = "4.15.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
]
[[package]]
name = "tzdata"
version = "2026.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" },
]
[[package]]
name = "urllib3"
version = "2.6.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
]