From 98e6077ddbd7b7c1530eb0e0581a94c1bd13878b Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Fri, 22 May 2026 10:57:29 +0200 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=E2=9C=A8=20Remove=20time=20suffixe?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datapackage.json | 733 ++------------------------- scripts/redcap_dict_to_properties.py | 84 ++- 2 files changed, 134 insertions(+), 683 deletions(-) diff --git a/datapackage.json b/datapackage.json index c04aefd..4065cb0 100644 --- a/datapackage.json +++ b/datapackage.json @@ -27060,10 +27060,10 @@ } }, { - "name": "vas_120_min", - "path": "resources/vas_120_min/data.parquet", - "title": "vas_120_min", - "description": "vas_120_min", + "name": "vas", + "path": "resources/vas/data.parquet", + "title": "vas", + "description": "vas", "schema": { "fields": [ { @@ -27095,753 +27095,124 @@ ] }, { - "name": "vas_hunger_120min", - "title": "vas_hunger_120min", - "type": "number", - "description": "Visual analogue scale. Hunger at time 120 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", - "constraints": { - "required": true - } - }, - { - "name": "vas_satisfaction_120min", - "title": "vas_satisfaction_120min", - "type": "number", - "description": "Visual analogue scale. Satisfaction at time 120 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", - "constraints": { - "required": true - } - }, - { - "name": "vas_full_120min", - "title": "vas_full_120min", - "type": "number", - "description": "Visual analogue scale. Fullness at time 120 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", - "constraints": { - "required": true - } - }, - { - "name": "vas_how_much_120min", - "title": "vas_how_much_120min", - "type": "number", - "description": "Visual analogue scale. How much to eat at time 120 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_comfort_120min", - "title": "vas_comfort_120min", - "type": "number", - "description": "Visual analogue scale. Comfort at time 120 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", - "constraints": { - "required": true - } - }, - { - "name": "vas_nausea_120min", - "title": "vas_nausea_120min", - "type": "number", - "description": "Visual analogue scale. Nausea at time 120min Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", - "constraints": { - "required": true - } - }, - { - "name": "vas_thirst_120min", - "title": "vas_thirst_120min", - "type": "number", - "description": "Visual analogue scale. Thirst at time 120 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_sweet_120min", - "title": "vas_sweet_120min", - "type": "number", - "description": "Visual analogue scale. Sweet at time 120 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_salt_120min", - "title": "vas_salt_120min", - "type": "number", - "description": "Visual analogue scale. Salt at time 120 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_fat_120min", - "title": "vas_fat_120min", - "type": "number", - "description": "Visual analogue scale. Fat at time 120 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - } - ], - "primaryKey": [ - "event" - ] - } - }, - { - "name": "vas_180_min", - "path": "resources/vas_180_min/data.parquet", - "title": "vas_180_min", - "description": "vas_180_min", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", + "name": "time", + "title": "Time", + "type": "integer", + "description": "The time in minutes after the meal when the VAS was recorded.", "constraints": { "required": true, "enum": [ - "Copenhagen", - "Aarhus", - "Odense" + 30, + 60, + 90, + 120, + 180, + 240 ] }, "categories": [ - "Copenhagen", - "Aarhus", - "Odense" + 30, + 60, + 90, + 120, + 180, + 240 ] }, { - "name": "vas_hunger_180min", - "title": "vas_hunger_180min", + "name": "vas_hunger", + "title": "vas_hunger", "type": "number", - "description": "Visual analogue scale. Hunger at time 180 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", + "description": "Visual analogue scale. Hunger Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", "constraints": { "required": true } }, { - "name": "vas_satisfaction_180min", - "title": "vas_satisfaction_180min", + "name": "vas_satisfaction", + "title": "vas_satisfaction", "type": "number", - "description": "Visual analogue scale. Satisfaction at time 180 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", + "description": "Visual analogue scale. Satisfaction Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", "constraints": { "required": true } }, { - "name": "vas_full_180min", - "title": "vas_full_180min", + "name": "vas_full", + "title": "vas_full", "type": "number", - "description": "Visual analogue scale. Fullness at time 180 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", + "description": "Visual analogue scale. Fullness Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", "constraints": { "required": true } }, { - "name": "vas_how_much_180min", - "title": "vas_how_much_180min", + "name": "vas_how_much", + "title": "vas_how_much", "type": "number", - "description": "Visual analogue scale. How much to eat at time 180 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", + "description": "Visual analogue scale. How much to eat Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", "constraints": { "required": true } }, { - "name": "vas_comfort_180min", - "title": "vas_comfort_180min", + "name": "vas_comfort", + "title": "vas_comfort", "type": "number", - "description": "Visual analogue scale. Comfort at time 180 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", + "description": "Visual analogue scale. Comfort Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", "constraints": { "required": true } }, { - "name": "vas_nausea_180min", - "title": "vas_nausea_180min", + "name": "vas_nausea", + "title": "vas_nausea", "type": "number", - "description": "Visual analogue scale. Nausea at time 180min Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", + "description": "Visual analogue scale. Nausea Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", "constraints": { "required": true } }, { - "name": "vas_thirst_180min", - "title": "vas_thirst_180min", + "name": "vas_thirst", + "title": "vas_thirst", "type": "number", - "description": "Visual analogue scale. Thirst at time 180 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", + "description": "Visual analogue scale. Thirst Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", "constraints": { "required": true } }, { - "name": "vas_sweet_180min", - "title": "vas_sweet_180min", + "name": "vas_sweet", + "title": "vas_sweet", "type": "number", - "description": "Visual analogue scale. Sweet at time 180 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", + "description": "Visual analogue scale. Sweet Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", "constraints": { "required": true } }, { - "name": "vas_salt_180min", - "title": "vas_salt_180min", + "name": "vas_salt", + "title": "vas_salt", "type": "number", - "description": "Visual analogue scale. Salt at time 180 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", + "description": "Visual analogue scale. Salt Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", "constraints": { "required": true } }, { - "name": "vas_fat_180min", - "title": "vas_fat_180min", + "name": "vas_fat", + "title": "vas_fat", "type": "number", - "description": "Visual analogue scale. Fat at time 180 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", + "description": "Visual analogue scale. Fat Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", "constraints": { "required": true } } ], "primaryKey": [ - "event" - ] - } - }, - { - "name": "vas_240_min", - "path": "resources/vas_240_min/data.parquet", - "title": "vas_240_min", - "description": "vas_240_min", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "vas_hunger_240min", - "title": "vas_hunger_240min", - "type": "number", - "description": "Visual analogue scale. Hunger at time 240 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", - "constraints": { - "required": true - } - }, - { - "name": "vas_satisfaction_240min", - "title": "vas_satisfaction_240min", - "type": "number", - "description": "Visual analogue scale. Satisfaction at time 240 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", - "constraints": { - "required": true - } - }, - { - "name": "vas_full_240min", - "title": "vas_full_240min", - "type": "number", - "description": "Visual analogue scale. Fullness at time 240 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", - "constraints": { - "required": true - } - }, - { - "name": "vas_how_much_240min", - "title": "vas_how_much_240min", - "type": "number", - "description": "Visual analogue scale. How much to eat at time 240 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_comfort_240min", - "title": "vas_comfort_240min", - "type": "number", - "description": "Visual analogue scale. Comfort at time 240 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", - "constraints": { - "required": true - } - }, - { - "name": "vas_nausea_240min", - "title": "vas_nausea_240min", - "type": "number", - "description": "Visual analogue scale. Nausea at time 240min Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", - "constraints": { - "required": true - } - }, - { - "name": "vas_thirst_240min", - "title": "vas_thirst_240min", - "type": "number", - "description": "Visual analogue scale. Thirst at time 240 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_sweet_240min", - "title": "vas_sweet_240min", - "type": "number", - "description": "Visual analogue scale. Sweet at time 240 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_salt_240min", - "title": "vas_salt_240min", - "type": "number", - "description": "Visual analogue scale. Salt at time 240 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_fat_240min", - "title": "vas_fat_240min", - "type": "number", - "description": "Visual analogue scale. Fat at time 240 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - } - ], - "primaryKey": [ - "event" - ] - } - }, - { - "name": "vas_30min", - "path": "resources/vas_30min/data.parquet", - "title": "vas_30min", - "description": "vas_30min", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "vas_hunger_30min", - "title": "vas_hunger_30min", - "type": "number", - "description": "Visual analogue scale. Hunger at time 30 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", - "constraints": { - "required": true - } - }, - { - "name": "vas_satisfaction_30min", - "title": "vas_satisfaction_30min", - "type": "number", - "description": "Visual analogue scale. Satisfaction at time 30 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", - "constraints": { - "required": true - } - }, - { - "name": "vas_full_30min", - "title": "vas_full_30min", - "type": "number", - "description": "Visual analogue scale. Fullness at time 30 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", - "constraints": { - "required": true - } - }, - { - "name": "vas_how_much_30min", - "title": "vas_how_much_30min", - "type": "number", - "description": "Visual analogue scale. How much to eat at time 30 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_comfort_30min", - "title": "vas_comfort_30min", - "type": "number", - "description": "Visual analogue scale. Comfort at time 30 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", - "constraints": { - "required": true - } - }, - { - "name": "vas_nausea_30min", - "title": "vas_nausea_30min", - "type": "number", - "description": "Visual analogue scale. Nausea at time 30 min Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", - "constraints": { - "required": true - } - }, - { - "name": "vas_thirst_30min", - "title": "vas_thirst_30min", - "type": "number", - "description": "Visual analogue scale. Thirst at time 30 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_sweet_30min", - "title": "vas_sweet_30min", - "type": "number", - "description": "Visual analogue scale. Sweet at time 30 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_salt_30min", - "title": "vas_salt_30min", - "type": "number", - "description": "Visual analogue scale. Salt at time 30 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_fat_30min", - "title": "vas_fat_30min", - "type": "number", - "description": "Visual analogue scale. Fat at time 30 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - } - ], - "primaryKey": [ - "event" - ] - } - }, - { - "name": "vas_60min", - "path": "resources/vas_60min/data.parquet", - "title": "vas_60min", - "description": "vas_60min", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "vas_hunger_60min", - "title": "vas_hunger_60min", - "type": "number", - "description": "Visual analogue scale. Hunger at time 60 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", - "constraints": { - "required": true - } - }, - { - "name": "vas_satisfaction_60min", - "title": "vas_satisfaction_60min", - "type": "number", - "description": "Visual analogue scale. Satisfaction at time 60 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", - "constraints": { - "required": true - } - }, - { - "name": "vas_full_60min", - "title": "vas_full_60min", - "type": "number", - "description": "Visual analogue scale. Fullness at time 60 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", - "constraints": { - "required": true - } - }, - { - "name": "vas_how_much_60min", - "title": "vas_how_much_60min", - "type": "number", - "description": "Visual analogue scale. How much to eat at time 60 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_comfort_60min", - "title": "vas_comfort_60min", - "type": "number", - "description": "Visual analogue scale. Comfort at time 60 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", - "constraints": { - "required": true - } - }, - { - "name": "vas_nausea_60min", - "title": "vas_nausea_60min", - "type": "number", - "description": "Visual analogue scale. Nausea at time 60 min Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", - "constraints": { - "required": true - } - }, - { - "name": "vas_thirst_60min", - "title": "vas_thirst_60min", - "type": "number", - "description": "Visual analogue scale. Thirst at time 60 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_sweet_60min", - "title": "vas_sweet_60min", - "type": "number", - "description": "Visual analogue scale. Sweet at time 60 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_salt_60min", - "title": "vas_salt_60min", - "type": "number", - "description": "Visual analogue scale. Salt at time 60 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_fat_60min", - "title": "vas_fat_60min", - "type": "number", - "description": "Visual analogue scale. Fat at time 60 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - } - ], - "primaryKey": [ - "event" - ] - } - }, - { - "name": "vas_90_min", - "path": "resources/vas_90_min/data.parquet", - "title": "vas_90_min", - "description": "vas_90_min", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "vas_hunger_90min", - "title": "vas_hunger_90min", - "type": "number", - "description": "Visual analogue scale. Hunger at time 90 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", - "constraints": { - "required": true - } - }, - { - "name": "vas_satisfaction_90min", - "title": "vas_satisfaction_90min", - "type": "number", - "description": "Visual analogue scale. Satisfaction at time 90 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", - "constraints": { - "required": true - } - }, - { - "name": "vas_full_90min", - "title": "vas_full_90min", - "type": "number", - "description": "Visual analogue scale. Fullness at time 90 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", - "constraints": { - "required": true - } - }, - { - "name": "vas_how_much_90min", - "title": "vas_how_much_90min", - "type": "number", - "description": "Visual analogue scale. How much to eat at time 90 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_comfort_90min", - "title": "vas_comfort_90min", - "type": "number", - "description": "Visual analogue scale. Comfort at time 90 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", - "constraints": { - "required": true - } - }, - { - "name": "vas_nausea_90min", - "title": "vas_nausea_90min", - "type": "number", - "description": "Visual analogue scale. Nausea at time 90 min Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", - "constraints": { - "required": true - } - }, - { - "name": "vas_thirst_90min", - "title": "vas_thirst_90min", - "type": "number", - "description": "Visual analogue scale. Thirst at time 90 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_sweet_90min", - "title": "vas_sweet_90min", - "type": "number", - "description": "Visual analogue scale. Sweet at time 90 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_salt_90min", - "title": "vas_salt_90min", - "type": "number", - "description": "Visual analogue scale. Salt at time 90 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_fat_90min", - "title": "vas_fat_90min", - "type": "number", - "description": "Visual analogue scale. Fat at time 90 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", - "constraints": { - "required": true - } - } - ], - "primaryKey": [ - "event" + "event", + "time" ] } }, diff --git a/scripts/redcap_dict_to_properties.py b/scripts/redcap_dict_to_properties.py index a22d0e5..643e0ee 100644 --- a/scripts/redcap_dict_to_properties.py +++ b/scripts/redcap_dict_to_properties.py @@ -1,5 +1,6 @@ import json import re +from functools import reduce from itertools import chain, groupby from operator import itemgetter from pathlib import Path @@ -9,6 +10,9 @@ In = TypeVar("In") Out = TypeVar("Out") +VAS_TIMEPOINTS = [30, 60, 90, 120, 180, 240] +VAS_TIME_FORM_PATTERN = re.compile(r"^vas_(30|60|90|120|180|240)_?min$") +VAS_TIME_FIELD_PATTERN = re.compile(r"_(30|60|90|120|180|240)min$") def _map(x: Iterable[In], fn: Callable[[In], Out]) -> list[Out]: @@ -34,6 +38,7 @@ def dictionary_to_properties( redcap_fields: list[dict[str, str]], ) -> list[sp.ResourceProperties]: """Converts REDCap data dictionary to Data Package resources.""" + redcap_fields = _join_vas_time_resources(redcap_fields) sorted_by_form = sorted(redcap_fields, key=lambda field: field["form_name"]) grouped_by_form = groupby(sorted_by_form, key=lambda field: field["form_name"]) return _map( @@ -42,6 +47,64 @@ def dictionary_to_properties( ) +def _join_vas_time_resources( + redcap_fields: list[dict[str, str]], +) -> list[dict[str, str]]: + """Combines REDCap VAS timepoint forms into one resource schema.""" + return _deduplicate_vas_fields( + _map(redcap_fields, _normalise_vas_time_resource_field) + ) + + +def _normalise_vas_time_resource_field(field: dict[str, str]) -> dict[str, str]: + if not _is_vas_time_resource_field(field): + return field + + return { + **field, + "field_name": VAS_TIME_FIELD_PATTERN.sub("", field["field_name"]), + "form_name": "vas", + "field_annotation": _remove_vas_time_from_annotation(field["field_annotation"]), + } + + +def _is_vas_time_resource_field(field: dict[str, str]) -> bool: + return bool(VAS_TIME_FORM_PATTERN.match(field["form_name"])) + + +def _deduplicate_vas_fields(fields: list[dict[str, str]]) -> list[dict[str, str]]: + deduplicated_fields, _ = reduce( + _append_if_new_vas_field, + fields, + ([], set()), + ) + return deduplicated_fields + + +def _append_if_new_vas_field( + result: tuple[list[dict[str, str]], set[str]], field: dict[str, str] +) -> tuple[list[dict[str, str]], set[str]]: + fields, seen_vas_fields = result + field_name = field["field_name"] + + if field["form_name"] != "vas": + return fields + [field], seen_vas_fields + + if field_name in seen_vas_fields: + return result + + return fields + [field], seen_vas_fields | {field_name} + + +def _remove_vas_time_from_annotation(annotation: str) -> str: + return re.sub( + r"\s+at time\s+\d+\s*min", + "", + annotation, + flags=re.IGNORECASE, + ).strip() + + def _form_to_resource( form_name: str, fields: list[dict[str, str]] ) -> sp.ResourceProperties: @@ -65,6 +128,23 @@ def _form_to_resource( enum=["Copenhagen", "Aarhus", "Odense"], ), ) + default_fields = [event_field, center_field] + primary_key = ["event"] + + if form_name == "vas": + time_field = sp.FieldProperties( + name="time", + title="Time", + type="integer", + description="The time in minutes after the meal when the VAS was recorded.", + categories=VAS_TIMEPOINTS, + constraints=sp.ConstraintsProperties( + required=True, + enum=VAS_TIMEPOINTS, + ), + ) + default_fields.append(time_field) + primary_key.append("time") # Discard fields displayed for information only form_redcap_fields = _filter( @@ -101,8 +181,8 @@ def _form_to_resource( title=form_name, description=form_name, schema=sp.TableSchemaProperties( - primary_key=["event"], - fields=[event_field, center_field] + form_fields + checkbox_fields, + primary_key=primary_key, + fields=default_fields + form_fields + checkbox_fields, ), ) From c8c7a9d8b5701bbf65b7167dca6d1ffef622238b Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Wed, 27 May 2026 11:09:58 +0200 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=E2=9C=A8=20Include=20pre-meal=20VA?= =?UTF-8?q?S=20timepoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Join vas_minus10 into the combined VAS resource using minutes_from_meal so negative and positive meal-relative timepoints share one schema. --- datapackage.json | 161 +++------------------------ scripts/redcap_dict_to_properties.py | 19 ++-- 2 files changed, 27 insertions(+), 153 deletions(-) diff --git a/datapackage.json b/datapackage.json index a3e1023..d0741ca 100644 --- a/datapackage.json +++ b/datapackage.json @@ -27104,13 +27104,14 @@ ] }, { - "name": "time", - "title": "Time", + "name": "minutes_from_meal", + "title": "Minutes from meal", "type": "integer", - "description": "The time in minutes after the meal when the VAS was recorded.", + "description": "The time in minutes from the meal when the specific VAS measurement was recorded. Negative values are before the meal.", "constraints": { "required": true, "enum": [ + -10, 30, 60, 90, @@ -27120,6 +27121,7 @@ ] }, "categories": [ + -10, 30, 60, 90, @@ -27132,7 +27134,7 @@ "name": "vas_hunger", "title": "vas_hunger", "type": "number", - "description": "Visual analogue scale. Hunger Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | Jeg har aldrig været mere sulten", + "description": "Visual analogue scale. How hungry do you feel Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | | Jeg har aldrig været mere sulten", "constraints": { "required": true } @@ -27141,7 +27143,7 @@ "name": "vas_satisfaction", "title": "vas_satisfaction", "type": "number", - "description": "Visual analogue scale. Satisfaction Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | Jeg kan ikke få en bid mere ned", + "description": "Visual analogue scale. How satiated do you feel Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | | Jeg kan ikke få en bid mere ned", "constraints": { "required": true } @@ -27150,7 +27152,7 @@ "name": "vas_full", "title": "vas_full", "type": "number", - "description": "Visual analogue scale. Fullness Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | Fyldt totalt op", + "description": "Visual analogue scale. How full do you feel Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | | Fyldt totalt op", "constraints": { "required": true } @@ -27159,7 +27161,7 @@ "name": "vas_how_much", "title": "vas_how_much", "type": "number", - "description": "Visual analogue scale. How much to eat Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | Virkelig meget", + "description": "Visual analogue scale. How much do you think you can eat Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | | Virkelig meget", "constraints": { "required": true } @@ -27168,7 +27170,7 @@ "name": "vas_comfort", "title": "vas_comfort", "type": "number", - "description": "Visual analogue scale. Comfort Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | Virkelig godt", + "description": "Visual analogue scale. Level of comfort Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | | Virkelig godt", "constraints": { "required": true } @@ -27177,7 +27179,7 @@ "name": "vas_nausea", "title": "vas_nausea", "type": "number", - "description": "Visual analogue scale. Nausea Question: Har du kvalme?. Slider scale labels: Ja, meget | Nej, slet ikke", + "description": "Visual analogue scale. Any nausea Question: Har du kvalme?. Slider scale labels: Ja, meget | | Nej, slet ikke", "constraints": { "required": true } @@ -27186,7 +27188,7 @@ "name": "vas_thirst", "title": "vas_thirst", "type": "number", - "description": "Visual analogue scale. Thirst Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | Virkelig meget", + "description": "Visual analogue scale. How thirsty do you feel Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | | Virkelig meget", "constraints": { "required": true } @@ -27195,7 +27197,7 @@ "name": "vas_sweet", "title": "vas_sweet", "type": "number", - "description": "Visual analogue scale. Sweet Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | Ja, meget", + "description": "Visual analogue scale. Would you like something sweet Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | | Ja, meget", "constraints": { "required": true } @@ -27204,7 +27206,7 @@ "name": "vas_salt", "title": "vas_salt", "type": "number", - "description": "Visual analogue scale. Salt Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | Ja, meget", + "description": "Visual analogue scale. Would you like something savoury Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | | Ja, meget", "constraints": { "required": true } @@ -27213,7 +27215,7 @@ "name": "vas_fat", "title": "vas_fat", "type": "number", - "description": "Visual analogue scale. Fat Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | Ja, meget", + "description": "Visual analogue scale. Would you like something fatty Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | | Ja, meget", "constraints": { "required": true } @@ -27221,138 +27223,7 @@ ], "primaryKey": [ "event", - "time" - ] - } - }, - { - "name": "vas_minus10", - "path": "resources/vas_minus10/data.parquet", - "title": "vas_minus10", - "description": "vas_minus10", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "vas_hunger_fasted_minus10min", - "title": "vas_hunger_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. How hungry do you feel, at time minus 10 min Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | | Jeg har aldrig været mere sulten", - "constraints": { - "required": true - } - }, - { - "name": "vas_satisfaction_fasted_minus10min", - "title": "vas_satisfaction_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. How satiated do you feel, at time minus 10 min Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | | Jeg kan ikke få en bid mere ned", - "constraints": { - "required": true - } - }, - { - "name": "vas_full_fasted_minus10min", - "title": "vas_full_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. How full do you feel, at time minus 10 min Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | | Fyldt totalt op", - "constraints": { - "required": true - } - }, - { - "name": "vas_how_much_fasted_minus10min", - "title": "vas_how_much_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. How much do you think you can eat, at time minus 10 min Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_comfort_fasted_minus10min", - "title": "vas_comfort_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. Level of comfort, at time minus 10 min Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | | Virkelig godt", - "constraints": { - "required": true - } - }, - { - "name": "vas_nausea_fasted_minus10min", - "title": "vas_nausea_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. Any nausea, at time minus 10 min Question: Har du kvalme?. Slider scale labels: Ja, meget | | Nej, slet ikke", - "constraints": { - "required": true - } - }, - { - "name": "vas_thirst_fasted_minus10min", - "title": "vas_thirst_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. How thirsty do you feel, at time minus 10 min Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | | Virkelig meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_sweet_fasted_minus10min", - "title": "vas_sweet_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. Would you like something sweet, at time minus 10 min Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_salt_fasted_minus10min", - "title": "vas_salt_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. Would you like something savoury, at time minus 10 min Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | | Ja, meget", - "constraints": { - "required": true - } - }, - { - "name": "vas_fat_fasted_minus10min", - "title": "vas_fat_fasted_minus10min", - "type": "number", - "description": "Visual analogue scale. Would you like something fatty, at time minus 10 min Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | | Ja, meget", - "constraints": { - "required": true - } - } - ], - "primaryKey": [ - "event" + "minutes_from_meal" ] } }, diff --git a/scripts/redcap_dict_to_properties.py b/scripts/redcap_dict_to_properties.py index 643e0ee..e77c8c6 100644 --- a/scripts/redcap_dict_to_properties.py +++ b/scripts/redcap_dict_to_properties.py @@ -10,9 +10,9 @@ In = TypeVar("In") Out = TypeVar("Out") -VAS_TIMEPOINTS = [30, 60, 90, 120, 180, 240] -VAS_TIME_FORM_PATTERN = re.compile(r"^vas_(30|60|90|120|180|240)_?min$") -VAS_TIME_FIELD_PATTERN = re.compile(r"_(30|60|90|120|180|240)min$") +VAS_TIMEPOINTS = [-10, 30, 60, 90, 120, 180, 240] +VAS_TIME_FORM_PATTERN = re.compile(r"^vas_(minus10|(30|60|90|120|180|240)_?min)$") +VAS_TIME_FIELD_PATTERN = re.compile(r"(_fasted)?_(minus10|30|60|90|120|180|240)min$") def _map(x: Iterable[In], fn: Callable[[In], Out]) -> list[Out]: @@ -98,7 +98,7 @@ def _append_if_new_vas_field( def _remove_vas_time_from_annotation(annotation: str) -> str: return re.sub( - r"\s+at time\s+\d+\s*min", + r",?\s+at time\s+(minus\s+10|\d+)\s*min", "", annotation, flags=re.IGNORECASE, @@ -133,10 +133,13 @@ def _form_to_resource( if form_name == "vas": time_field = sp.FieldProperties( - name="time", - title="Time", + name="minutes_from_meal", + title="Minutes from meal", type="integer", - description="The time in minutes after the meal when the VAS was recorded.", + description=( + "The time in minutes from the meal when the specific VAS " + "measurement was recorded. Negative values are before the meal." + ), categories=VAS_TIMEPOINTS, constraints=sp.ConstraintsProperties( required=True, @@ -144,7 +147,7 @@ def _form_to_resource( ), ) default_fields.append(time_field) - primary_key.append("time") + primary_key.append("minutes_from_meal") # Discard fields displayed for information only form_redcap_fields = _filter( From 52f5360dbb00a147c750d4d9b73fbef773eac8ec Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Wed, 27 May 2026 11:10:48 +0200 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E2=9C=A8=20Simplify=20VAS=20field?= =?UTF-8?q?=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the redundant vas_ prefix from variables after they are moved into the combined VAS resource. --- datapackage.json | 40 ++++++++++++++-------------- scripts/redcap_dict_to_properties.py | 6 ++++- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/datapackage.json b/datapackage.json index d0741ca..61c23f5 100644 --- a/datapackage.json +++ b/datapackage.json @@ -27131,8 +27131,8 @@ ] }, { - "name": "vas_hunger", - "title": "vas_hunger", + "name": "hunger", + "title": "hunger", "type": "number", "description": "Visual analogue scale. How hungry do you feel Question: Hvor sulten er du?. Slider scale labels: Jeg er slet ikke sulten | | Jeg har aldrig været mere sulten", "constraints": { @@ -27140,8 +27140,8 @@ } }, { - "name": "vas_satisfaction", - "title": "vas_satisfaction", + "name": "satisfaction", + "title": "satisfaction", "type": "number", "description": "Visual analogue scale. How satiated do you feel Question: Hvor mæt er du?. Slider scale labels: Jeg har et stort hul i maven | | Jeg kan ikke få en bid mere ned", "constraints": { @@ -27149,8 +27149,8 @@ } }, { - "name": "vas_full", - "title": "vas_full", + "name": "full", + "title": "full", "type": "number", "description": "Visual analogue scale. How full do you feel Question: Hvor fyldt op føler du dig?. Slider scale labels: Slet ikke fyldt op | | Fyldt totalt op", "constraints": { @@ -27158,8 +27158,8 @@ } }, { - "name": "vas_how_much", - "title": "vas_how_much", + "name": "how_much", + "title": "how_much", "type": "number", "description": "Visual analogue scale. How much do you think you can eat Question: Hvor meget tror du, at du kan spise?. Slider scale labels: Slet ingenting | | Virkelig meget", "constraints": { @@ -27167,8 +27167,8 @@ } }, { - "name": "vas_comfort", - "title": "vas_comfort", + "name": "comfort", + "title": "comfort", "type": "number", "description": "Visual analogue scale. Level of comfort Question: Hvordan føler du dig tilpas?. Slider scale labels: Virkelig dårligt | | Virkelig godt", "constraints": { @@ -27176,8 +27176,8 @@ } }, { - "name": "vas_nausea", - "title": "vas_nausea", + "name": "nausea", + "title": "nausea", "type": "number", "description": "Visual analogue scale. Any nausea Question: Har du kvalme?. Slider scale labels: Ja, meget | | Nej, slet ikke", "constraints": { @@ -27185,8 +27185,8 @@ } }, { - "name": "vas_thirst", - "title": "vas_thirst", + "name": "thirst", + "title": "thirst", "type": "number", "description": "Visual analogue scale. How thirsty do you feel Question: Hvor tørstig føler du dig?. Slider scale labels: Overhovedet ikke | | Virkelig meget", "constraints": { @@ -27194,8 +27194,8 @@ } }, { - "name": "vas_sweet", - "title": "vas_sweet", + "name": "sweet", + "title": "sweet", "type": "number", "description": "Visual analogue scale. Would you like something sweet Question: Har du lyst til at spise noget sødt?. Slider scale labels: Nej, slet ikke | | Ja, meget", "constraints": { @@ -27203,8 +27203,8 @@ } }, { - "name": "vas_salt", - "title": "vas_salt", + "name": "salt", + "title": "salt", "type": "number", "description": "Visual analogue scale. Would you like something savoury Question: Har du lyst til at spise noget salt?. Slider scale labels: Nej, slet ikke | | Ja, meget", "constraints": { @@ -27212,8 +27212,8 @@ } }, { - "name": "vas_fat", - "title": "vas_fat", + "name": "fat", + "title": "fat", "type": "number", "description": "Visual analogue scale. Would you like something fatty Question: Har du lyst til at spise noget fedtrigt?. Slider scale labels: Nej, slet ikke | | Ja, meget", "constraints": { diff --git a/scripts/redcap_dict_to_properties.py b/scripts/redcap_dict_to_properties.py index e77c8c6..a02139f 100644 --- a/scripts/redcap_dict_to_properties.py +++ b/scripts/redcap_dict_to_properties.py @@ -62,12 +62,16 @@ def _normalise_vas_time_resource_field(field: dict[str, str]) -> dict[str, str]: return { **field, - "field_name": VAS_TIME_FIELD_PATTERN.sub("", field["field_name"]), + "field_name": _normalise_vas_field_name(field["field_name"]), "form_name": "vas", "field_annotation": _remove_vas_time_from_annotation(field["field_annotation"]), } +def _normalise_vas_field_name(field_name: str) -> str: + return re.sub(r"^vas_", "", VAS_TIME_FIELD_PATTERN.sub("", field_name)) + + def _is_vas_time_resource_field(field: dict[str, str]) -> bool: return bool(VAS_TIME_FORM_PATTERN.match(field["form_name"])) From 83da6737c6a3c9fa421794fd06220ad056942939 Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Wed, 27 May 2026 11:17:54 +0200 Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20Clarify=20?= =?UTF-8?q?VAS=20resource=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use descriptive title and description values for the combined VAS resource and make VAS field deduplication easier to read. --- datapackage.json | 4 ++-- scripts/redcap_dict_to_properties.py | 26 ++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/datapackage.json b/datapackage.json index 61c23f5..6504081 100644 --- a/datapackage.json +++ b/datapackage.json @@ -27071,8 +27071,8 @@ { "name": "vas", "path": "resources/vas/data.parquet", - "title": "vas", - "description": "vas", + "title": "Visual analogue scale measurements", + "description": "Visual analogue scale measurements recorded at multiple timepoints relative to the meal.", "schema": { "fields": [ { diff --git a/scripts/redcap_dict_to_properties.py b/scripts/redcap_dict_to_properties.py index a02139f..672e30a 100644 --- a/scripts/redcap_dict_to_properties.py +++ b/scripts/redcap_dict_to_properties.py @@ -97,7 +97,7 @@ def _append_if_new_vas_field( if field_name in seen_vas_fields: return result - return fields + [field], seen_vas_fields | {field_name} + return (fields + [field], seen_vas_fields.union({field_name})) def _remove_vas_time_from_annotation(annotation: str) -> str: @@ -181,12 +181,13 @@ def _form_to_resource( fields, lambda field: field["field_type"] == "checkbox" ) checkbox_fields = _flat_map(checkbox_redcap_fields, _expand_checkbox_field) + resource_title = _get_resource_title(form_name) + resource_description = _get_resource_description(form_name) return sp.ResourceProperties( name=form_name, - # TODO: fill in title and description - title=form_name, - description=form_name, + title=resource_title, + description=resource_description, schema=sp.TableSchemaProperties( primary_key=primary_key, fields=default_fields + form_fields + checkbox_fields, @@ -194,6 +195,23 @@ def _form_to_resource( ) +def _get_resource_title(form_name: str) -> str: + if form_name == "vas": + return "Visual analogue scale measurements" + + return form_name + + +def _get_resource_description(form_name: str) -> str: + if form_name == "vas": + return ( + "Visual analogue scale measurements recorded at multiple timepoints " + "relative to the meal." + ) + + return form_name + + def _get_error_message(field: dict[str, str], key: str) -> str: return ( f"Unexpected value {field[key]!r} for `{key}` in field {field['field_name']!r} " From e03cb3ea271df3d25e404e32f4f720840e3de275 Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Wed, 27 May 2026 11:34:14 +0200 Subject: [PATCH 5/7] =?UTF-8?q?chore:=20=F0=9F=94=A7=20just=20run=20all?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uv.lock | 193 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 97 insertions(+), 96 deletions(-) diff --git a/uv.lock b/uv.lock index 37239ff..5ad587f 100644 --- a/uv.lock +++ b/uv.lock @@ -31,11 +31,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.4.22" +version = "2026.5.20" 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" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" } 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" }, + { url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" }, ] [[package]] @@ -171,7 +171,7 @@ wheels = [ [[package]] name = "cyclopts" -version = "4.14.1" +version = "4.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, @@ -179,9 +179,9 @@ dependencies = [ { name = "rich" }, { name = "rich-rst" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/75/c7988cb0b90ab9d6728d4c444f09256cfdc97606c1638d8a8090eeb57f7e/cyclopts-4.14.1.tar.gz", hash = "sha256:5d01fc3a940a0e4e872a81ed533a10c1892b5baaa4121fe69528a2b8c17fc9d0", size = 177281, upload-time = "2026-05-19T19:49:22.312Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/07/bf61d13de86d96a4c46aff00c9ca0eced44bcc8c3e16280605c1253e5720/cyclopts-4.16.1.tar.gz", hash = "sha256:8aa47bf92a5fb33abca5af05e576eecdb0d2f79893ad29238046df78370fc4a8", size = 181196, upload-time = "2026-05-25T15:29:08.518Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/1d/f6c80f82a42c69ff5a86c2580e789133de387d067210c7c46677618a2ca7/cyclopts-4.14.1-py3-none-any.whl", hash = "sha256:b705fdaa3277554a5da03e9bb5ff96a44d204a1afe3099f1b56e1586488bbfd4", size = 214925, upload-time = "2026-05-19T19:49:23.559Z" }, + { url = "https://files.pythonhosted.org/packages/00/8d/7f362c2fb8ef4decd2160bc24d4292c6ca658cc6d9a161b89ca5122bbdbf/cyclopts-4.16.1-py3-none-any.whl", hash = "sha256:617795392c4113a2c2cc7af716f20244900e87f23daa05442d1268d81472a592", size = 219020, upload-time = "2026-05-25T15:29:09.646Z" }, ] [[package]] @@ -309,11 +309,11 @@ wheels = [ [[package]] name = "idna" -version = "3.15" +version = "3.16" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/88/bcf9709822fe69d02c2a6a77956c98ce6ea8ca8767a9aadcedc7eb6a2390/idna-3.16.tar.gz", hash = "sha256:d7a6da03db833450fca25d2358ac9ff06cd624577a4aea3a596d5c0f77b8e03d", size = 203770, upload-time = "2026-05-22T00:16:18.781Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" }, + { url = "https://files.pythonhosted.org/packages/94/16/70255075a9859a0e3adb789b68ceb0e210dec03934245fd98d248226572f/idna-3.16-py3-none-any.whl", hash = "sha256:cc246e3a3f89580c3a951b5ad298ca4638078b2cdd4f115654332b5c26daded5", size = 74165, upload-time = "2026-05-22T00:16:16.698Z" }, ] [[package]] @@ -857,27 +857,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.13" +version = "0.15.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", hash = "sha256:f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7", size = 4678180, upload-time = "2026-05-14T13:44:37.869Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/8a/8bce2894573e9dae6ff4d77fe34ad727d79b9e6238ad288c5638990d90f6/ruff-0.15.14.tar.gz", hash = "sha256:48e866b165be4a9bdbf310f7d3c9a07edef2fe8cd63ffeb4e00bb590506ebf9f", size = 4700910, upload-time = "2026-05-21T14:34:55.177Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", hash = "sha256:444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8", size = 10738279, upload-time = "2026-05-14T13:44:18.7Z" }, - { url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7", size = 11124798, upload-time = "2026-05-14T13:44:06.427Z" }, - { url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629", size = 10460761, upload-time = "2026-05-14T13:44:04.375Z" }, - { url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5", size = 10804451, upload-time = "2026-05-14T13:44:25.221Z" }, - { url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22", size = 10534285, upload-time = "2026-05-14T13:44:08.888Z" }, - { url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9", size = 11312063, upload-time = "2026-05-14T13:44:11.274Z" }, - { url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55", size = 12183079, upload-time = "2026-05-14T13:44:01.634Z" }, - { url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6", size = 11440833, upload-time = "2026-05-14T13:43:59.043Z" }, - { url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca", size = 11434486, upload-time = "2026-05-14T13:44:27.761Z" }, - { url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd", size = 11385189, upload-time = "2026-05-14T13:44:13.704Z" }, - { url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6", size = 10781380, upload-time = "2026-05-14T13:43:56.734Z" }, - { url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51", size = 10540605, upload-time = "2026-05-14T13:44:20.748Z" }, - { url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2", size = 11036554, upload-time = "2026-05-14T13:44:16.256Z" }, - { url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b", size = 11528133, upload-time = "2026-05-14T13:44:22.808Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", hash = "sha256:4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41", size = 10721455, upload-time = "2026-05-14T13:44:35.697Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", hash = "sha256:7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4", size = 11900409, upload-time = "2026-05-14T13:44:30.389Z" }, - { url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", hash = "sha256:2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21", size = 11179336, upload-time = "2026-05-14T13:44:33.026Z" }, + { url = "https://files.pythonhosted.org/packages/b9/c8/74a92c6ff9fcfb4f1f947126d3ebee8389276e161ecc85de5bda7cda51bd/ruff-0.15.14-py3-none-linux_armv6l.whl", hash = "sha256:8dd2db9416e487c8d4b01fa7056bb02c4d05969d4f8d17a08c229c2f4ff3c108", size = 10739177, upload-time = "2026-05-21T14:34:37.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/254a35c20acc38a7223c9d2d594af12e794432464f2cdeb52af1dc4a892d/ruff-0.15.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:be4ff55af755bd71a00ab3dc6bd7ffc467bd76e0df6881e286c2e3d23e8fb43b", size = 11144969, upload-time = "2026-05-21T14:34:43.978Z" }, + { url = "https://files.pythonhosted.org/packages/56/9e/d13e40f83b8d0a94430e6778ce1d94a43b38cf2efe63278bdd2b4c65abbf/ruff-0.15.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:48d5909d7d06276ce7dde6d32bfa4b0d4cb2651145cd8ee4b440722cbc77832f", size = 10478207, upload-time = "2026-05-21T14:34:48.378Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f1/b15a7839fa4f332f8acec78e20564f26bb2d866e3d21710b877fd0263000/ruff-0.15.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca8cbfa94c4f90984a67561978602746d4cd27103568f745fa90eee3f0d4107d", size = 10818459, upload-time = "2026-05-21T14:34:22.318Z" }, + { url = "https://files.pythonhosted.org/packages/45/33/53d651177f84f94b400a0e27f8824eeada3dddc9d5ee8aeb048f4352a520/ruff-0.15.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a6bbc0333f1ab053423bcbf6226477d266ca7cec7738c4c8e3f55647803f3c4", size = 10541800, upload-time = "2026-05-21T14:34:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a6/868f87e0bf9786ed24b5d0d0ad8676b8a94fd1912f42cddf9cfc7857818a/ruff-0.15.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a24a4f7605d7003a6674d4387651effd939dead3fddd0f36561eb77a9a2e542", size = 11342149, upload-time = "2026-05-21T14:34:46.365Z" }, + { url = "https://files.pythonhosted.org/packages/a7/8b/38cd5c19faffdcc05a408d2b78edccc69492ab9720eadb49ea15ef80d768/ruff-0.15.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:049b5326e53ed80978f2fc041a280603f69dd6b0c95464342a2bb4572d9d9e2f", size = 12212563, upload-time = "2026-05-21T14:34:28.579Z" }, + { url = "https://files.pythonhosted.org/packages/3e/4d/a3c5b874a556d5731e3e657aaf04311bb76f0a5c3ec220ed43051be6b64b/ruff-0.15.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4ed42e6696c8dfa5f06728e6441993901f548eb92d73bc472cb5a38d1395fbf", size = 11493299, upload-time = "2026-05-21T14:34:41.836Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c0/56472c251d09858a53e51efbd485b09e1995d8731668b76d52e5dd6ee0f1/ruff-0.15.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715c543cf450c4888251f91c52f1942a800541d9bddd7ac060aa4e6b77ae7cba", size = 11455931, upload-time = "2026-05-21T14:34:57.276Z" }, + { url = "https://files.pythonhosted.org/packages/2c/4a/e2e7b4d8dbf233d4eace59c75bc3435fa6d8bd3bae82d351d4e4300c0fd1/ruff-0.15.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ebab6013ec887d439d8b7593737a0a4ffb06d45d209d4e4bf2e92813082d3f", size = 11400794, upload-time = "2026-05-21T14:34:39.773Z" }, + { url = "https://files.pythonhosted.org/packages/97/c7/83c0539fe34c3e09136204d1e75d6052492364e0b3cb05e9465423f567d7/ruff-0.15.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:49072d36abdbe97a8dd7f480afe9c675699c0c495d4c84076e2c1203c4550581", size = 10804759, upload-time = "2026-05-21T14:34:31.045Z" }, + { url = "https://files.pythonhosted.org/packages/86/a6/18f2bfc095a2ab4a78745644e428205532ce6653a5d0fa8501572891534d/ruff-0.15.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:958522aee105068640c2c2ceae08f413ae44d922f52a1374ac13d6a96032fc93", size = 10539517, upload-time = "2026-05-21T14:34:53.064Z" }, + { url = "https://files.pythonhosted.org/packages/54/3a/5a8b3b69c654d4e4bf1d246ac5b49cbcdac6eaab6905925f8915f31e3b80/ruff-0.15.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f3707da619a143a2e8830e2abab8224478d69ace2d28cb6c20543ae97c36bf61", size = 11065169, upload-time = "2026-05-21T14:34:24.484Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c5/8864e4e7925b836ea354b31d57641ec03830564e281a8b6f061f8c3e0ec1/ruff-0.15.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bb01d645694e3ec0102105d07ef2d53703970407d59c04e59d3ba0b7a1d53553", size = 11560214, upload-time = "2026-05-21T14:34:50.975Z" }, + { url = "https://files.pythonhosted.org/packages/36/38/012bf76752e1f89ed50b77b99532d90f3a3e287bc7918e1fc0948ac866ac/ruff-0.15.14-py3-none-win32.whl", hash = "sha256:6d0c1ad2a0ab718d39b6d8fd2217981ce4d625cd96a720095f798fb47d8b13e6", size = 10805548, upload-time = "2026-05-21T14:34:33.453Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/4ea2c170f10ad760fff2a5250beb18897719dc8b52b53a24cddbb9dd3f19/ruff-0.15.14-py3-none-win_amd64.whl", hash = "sha256:802342981e056db3851a7836e5b070f8f15f67d4a685ae2a6160939d364b2902", size = 11939523, upload-time = "2026-05-21T14:34:18.077Z" }, + { url = "https://files.pythonhosted.org/packages/62/d5/bc97ff895ec35cf3925d4bd60f3b39d822f377a446906ec9bcc87405e59b/ruff-0.15.14-py3-none-win_arm64.whl", hash = "sha256:ff47b90a9ef6a40c9e2f3b479c1fb78531adf055b94c1eba0a7ba04b31951826", size = 11208607, upload-time = "2026-05-21T14:34:26.525Z" }, ] [[package]] @@ -1008,18 +1008,19 @@ wheels = [ [[package]] name = "typos" -version = "1.46.2" +version = "1.46.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/f2/821dfcf25b3790acad8df3edbc11b178c0f026b657ac69768475621ee25e/typos-1.46.2.tar.gz", hash = "sha256:23e73e079e3a3b01f27b8239b36aa9eb03bcf7b98c87dbc984266c2e25f1dae9", size = 1822489, upload-time = "2026-05-16T17:43:35.153Z" } +sdist = { url = "https://files.pythonhosted.org/packages/36/53/f133630b6a8b39c686f0dfc02ca4844ac6a2016f504670040d0415c56a91/typos-1.46.3.tar.gz", hash = "sha256:f4e870d8bd4ebb699a2a08c25d62e0a059f707be65cb4d5025272fe2e78871a5", size = 1822838, upload-time = "2026-05-23T16:59:37.149Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/1d/1180b7e8e9bf169fec2c63fc3ff330e2dcf2f057633c0f67c4fe13d20951/typos-1.46.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:345977d2ee671ab53e8dd4bbed41c81f63849a6b7f114c99a9dd40584045007c", size = 3475696, upload-time = "2026-05-16T17:43:20.924Z" }, - { url = "https://files.pythonhosted.org/packages/7f/6f/0dae07b8c38f64f284a2d92cebf15fd38b3b2291ca5721120da078db948d/typos-1.46.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:426a899fa041457ff2b2cc83889ae17549cf8b1150646bb5f4d62a87e3cd2a5f", size = 3378450, upload-time = "2026-05-16T17:43:22.814Z" }, - { url = "https://files.pythonhosted.org/packages/ac/7e/a073bdfd99810d2b7796054677a351f37b87d5c607a8c1cd222cdb2dfb48/typos-1.46.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4c48409f04212d9ab4cd2f5cef19a553422a7953d32e3de8cbe9e4cb9e502e0", size = 8238091, upload-time = "2026-05-16T17:43:24.508Z" }, - { url = "https://files.pythonhosted.org/packages/8c/fa/0ae898d83f270cf355db94e51ae21646927ce0e413161081126757891b88/typos-1.46.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:443d2ebde8157397277d7b61652521b0982d15717a75be151a84d6a21b2603e4", size = 7332994, upload-time = "2026-05-16T17:43:26.445Z" }, - { url = "https://files.pythonhosted.org/packages/e6/90/01054b2282a4c03ac6bf30ad5412dfd875a3cbceba86886ea124621ba080/typos-1.46.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4612b8e93d4c3be490135c34f0341ee6ac271be569aa2803c8d52a4e2392244", size = 7745813, upload-time = "2026-05-16T17:43:28.151Z" }, - { url = "https://files.pythonhosted.org/packages/df/14/8f583f23308673005df154cccd24bb7620a34b8cb045560f9af3ee317636/typos-1.46.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af01d1c00f5245c25dfd0127c7fbe824e26fedd4826a0042a247be62d1dc2e91", size = 8131978, upload-time = "2026-05-16T17:43:30.061Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c6/535785d9916c71ed9cc969e1324a6252656c5cfe3f178af489b5c2274770/typos-1.46.2-py3-none-win32.whl", hash = "sha256:11c3c1a7bd8606c690ee0fcac8620af9c7fe59b919fed664f98f0140f8de9881", size = 3138217, upload-time = "2026-05-16T17:43:32.028Z" }, - { url = "https://files.pythonhosted.org/packages/50/57/f7c2b3c8865306ee8de50d47c55af12890a2bd0cce62c152062a30a4b988/typos-1.46.2-py3-none-win_amd64.whl", hash = "sha256:b10a771378b7ccd25a856db6ae2291d1b79293007ce322fcb7c576d73db00231", size = 3313690, upload-time = "2026-05-16T17:43:33.631Z" }, + { url = "https://files.pythonhosted.org/packages/56/a1/a1e9134a4bfcd15cf814f1aadc190a1b8526dc9530edfd42c6e6f1e1339b/typos-1.46.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:193d68afca7ae256f05ee9258eda2f041734952477d1f6aa32d439643ccb38db", size = 3479539, upload-time = "2026-05-23T16:59:19.03Z" }, + { url = "https://files.pythonhosted.org/packages/ef/3c/0e52f64b77aba0cd8827758e23b990af2f6ecdcf2432678b1b17b19ddd13/typos-1.46.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9acbe779c08baef59d08fc0366d0ae7a35190c8e4f57ad6dc121ca9b3a583344", size = 3380031, upload-time = "2026-05-23T16:59:21.265Z" }, + { url = "https://files.pythonhosted.org/packages/0e/c7/ab304f0ceea6b78fd07b643ca7bab624c688e0614b74809a74e814037667/typos-1.46.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf8897f3945530a83c213b759e915648eeba2e4eaa798455f565f78f2c12035b", size = 8237302, upload-time = "2026-05-23T16:59:23.026Z" }, + { url = "https://files.pythonhosted.org/packages/9b/42/45996c9ad2736e0cc1f771f60d1ed7ce8e472cd6fa2ec2b402cea44d030a/typos-1.46.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:922452006c37ca4f4760761a2ddcad02276a642a69c841f96136c3f17a59debf", size = 7331280, upload-time = "2026-05-23T16:59:24.813Z" }, + { url = "https://files.pythonhosted.org/packages/ee/14/5b2eec7093f8be01790412c74c4d350a641c4237cd6405ce48d31c6a50ce/typos-1.46.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3baf33ff3bc21feb254e83f8dbbbbf34eb339b47b3582508cfdc59609081d069", size = 7750163, upload-time = "2026-05-23T16:59:27.327Z" }, + { url = "https://files.pythonhosted.org/packages/92/ce/e9b4c9a7f620848ef1ddd563abcccf61815b11dacb43b5014721d63605e9/typos-1.46.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:abf65f93de75317eab8fd44a3790f272d04b6a7e6b6a006365f3a9ef323a7991", size = 7099717, upload-time = "2026-05-23T16:59:29.464Z" }, + { url = "https://files.pythonhosted.org/packages/d9/52/8ff928671fea1af4137ac88b708cb0b876121f3d5f03be494e3f928265a1/typos-1.46.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b17069c36a54358ead62cc6016ab547d9ae7dc44415dcfbcf4472bee5f099f54", size = 8136986, upload-time = "2026-05-23T16:59:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/19/3b/7c7a628ddf6ab89e98a1e81fb53ed81ab1bad17401c7fd8ba8d33e7f53b0/typos-1.46.3-py3-none-win32.whl", hash = "sha256:e73e39b46eef13947b58be1a7770fe46268b57e1575db56f7934f2f9959bda68", size = 3137646, upload-time = "2026-05-23T16:59:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/02/58/d94d28ebc500fb79a8f52e47cfe5a2d71949bc7394e08d0a0a36c9c04b65/typos-1.46.3-py3-none-win_amd64.whl", hash = "sha256:9646c7cce10a0cd628b1e3b543135e013d9db71a6aeab8f0b0a1f77128a8e63e", size = 3313518, upload-time = "2026-05-23T16:59:35.006Z" }, ] [[package]] @@ -1057,64 +1058,64 @@ wheels = [ [[package]] name = "wrapt" -version = "2.1.2" +version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2e/64/925f213fdcbb9baeb1530449ac71a4d57fc361c053d06bf78d0c5c7cd80c/wrapt-2.1.2.tar.gz", hash = "sha256:3996a67eecc2c68fd47b4e3c564405a5777367adfd9b8abb58387b63ee83b21e", size = 81678, upload-time = "2026-03-06T02:53:25.134Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/9f/06263fcd8ad6c405f05a3905fd7a84dd3176eb5ad46e44bccc0cd16348bb/wrapt-2.2.1.tar.gz", hash = "sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9", size = 127620, upload-time = "2026-05-22T14:49:43.056Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/b6/1db817582c49c7fcbb7df6809d0f515af29d7c2fbf57eb44c36e98fb1492/wrapt-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff2aad9c4cda28a8f0653fc2d487596458c2a3f475e56ba02909e950a9efa6a9", size = 61255, upload-time = "2026-03-06T02:52:45.663Z" }, - { url = "https://files.pythonhosted.org/packages/a2/16/9b02a6b99c09227c93cd4b73acc3678114154ec38da53043c0ddc1fba0dc/wrapt-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6433ea84e1cfacf32021d2a4ee909554ade7fd392caa6f7c13f1f4bf7b8e8748", size = 61848, upload-time = "2026-03-06T02:53:48.728Z" }, - { url = "https://files.pythonhosted.org/packages/af/aa/ead46a88f9ec3a432a4832dfedb84092fc35af2d0ba40cd04aea3889f247/wrapt-2.1.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c20b757c268d30d6215916a5fa8461048d023865d888e437fab451139cad6c8e", size = 121433, upload-time = "2026-03-06T02:54:40.328Z" }, - { url = "https://files.pythonhosted.org/packages/3a/9f/742c7c7cdf58b59085a1ee4b6c37b013f66ac33673a7ef4aaed5e992bc33/wrapt-2.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79847b83eb38e70d93dc392c7c5b587efe65b3e7afcc167aa8abd5d60e8761c8", size = 123013, upload-time = "2026-03-06T02:53:26.58Z" }, - { url = "https://files.pythonhosted.org/packages/e8/44/2c3dd45d53236b7ed7c646fcf212251dc19e48e599debd3926b52310fafb/wrapt-2.1.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f8fba1bae256186a83d1875b2b1f4e2d1242e8fac0f58ec0d7e41b26967b965c", size = 117326, upload-time = "2026-03-06T02:53:11.547Z" }, - { url = "https://files.pythonhosted.org/packages/74/e2/b17d66abc26bd96f89dec0ecd0ef03da4a1286e6ff793839ec431b9fae57/wrapt-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e3d3b35eedcf5f7d022291ecd7533321c4775f7b9cd0050a31a68499ba45757c", size = 121444, upload-time = "2026-03-06T02:54:09.5Z" }, - { url = "https://files.pythonhosted.org/packages/3c/62/e2977843fdf9f03daf1586a0ff49060b1b2fc7ff85a7ea82b6217c1ae36e/wrapt-2.1.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:6f2c5390460de57fa9582bc8a1b7a6c86e1a41dfad74c5225fc07044c15cc8d1", size = 116237, upload-time = "2026-03-06T02:54:03.884Z" }, - { url = "https://files.pythonhosted.org/packages/88/dd/27fc67914e68d740bce512f11734aec08696e6b17641fef8867c00c949fc/wrapt-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7dfa9f2cf65d027b951d05c662cc99ee3bd01f6e4691ed39848a7a5fffc902b2", size = 120563, upload-time = "2026-03-06T02:53:20.412Z" }, - { url = "https://files.pythonhosted.org/packages/ec/9f/b750b3692ed2ef4705cb305bd68858e73010492b80e43d2a4faa5573cbe7/wrapt-2.1.2-cp312-cp312-win32.whl", hash = "sha256:eba8155747eb2cae4a0b913d9ebd12a1db4d860fc4c829d7578c7b989bd3f2f0", size = 58198, upload-time = "2026-03-06T02:53:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/8e/b2/feecfe29f28483d888d76a48f03c4c4d8afea944dbee2b0cd3380f9df032/wrapt-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1c51c738d7d9faa0b3601708e7e2eda9bf779e1b601dce6c77411f2a1b324a63", size = 60441, upload-time = "2026-03-06T02:52:47.138Z" }, - { url = "https://files.pythonhosted.org/packages/44/e1/e328f605d6e208547ea9fd120804fcdec68536ac748987a68c47c606eea8/wrapt-2.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:c8e46ae8e4032792eb2f677dbd0d557170a8e5524d22acc55199f43efedd39bf", size = 58836, upload-time = "2026-03-06T02:53:22.053Z" }, - { url = "https://files.pythonhosted.org/packages/4c/7a/d936840735c828b38d26a854e85d5338894cda544cb7a85a9d5b8b9c4df7/wrapt-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787fd6f4d67befa6fe2abdffcbd3de2d82dfc6fb8a6d850407c53332709d030b", size = 61259, upload-time = "2026-03-06T02:53:41.922Z" }, - { url = "https://files.pythonhosted.org/packages/5e/88/9a9b9a90ac8ca11c2fdb6a286cb3a1fc7dd774c00ed70929a6434f6bc634/wrapt-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4bdf26e03e6d0da3f0e9422fd36bcebf7bc0eeb55fdf9c727a09abc6b9fe472e", size = 61851, upload-time = "2026-03-06T02:52:48.672Z" }, - { url = "https://files.pythonhosted.org/packages/03/a9/5b7d6a16fd6533fed2756900fc8fc923f678179aea62ada6d65c92718c00/wrapt-2.1.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bbac24d879aa22998e87f6b3f481a5216311e7d53c7db87f189a7a0266dafffb", size = 121446, upload-time = "2026-03-06T02:54:14.013Z" }, - { url = "https://files.pythonhosted.org/packages/45/bb/34c443690c847835cfe9f892be78c533d4f32366ad2888972c094a897e39/wrapt-2.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16997dfb9d67addc2e3f41b62a104341e80cac52f91110dece393923c0ebd5ca", size = 123056, upload-time = "2026-03-06T02:54:10.829Z" }, - { url = "https://files.pythonhosted.org/packages/93/b9/ff205f391cb708f67f41ea148545f2b53ff543a7ac293b30d178af4d2271/wrapt-2.1.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:162e4e2ba7542da9027821cb6e7c5e068d64f9a10b5f15512ea28e954893a267", size = 117359, upload-time = "2026-03-06T02:53:03.623Z" }, - { url = "https://files.pythonhosted.org/packages/1f/3d/1ea04d7747825119c3c9a5e0874a40b33594ada92e5649347c457d982805/wrapt-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f29c827a8d9936ac320746747a016c4bc66ef639f5cd0d32df24f5eacbf9c69f", size = 121479, upload-time = "2026-03-06T02:53:45.844Z" }, - { url = "https://files.pythonhosted.org/packages/78/cc/ee3a011920c7a023b25e8df26f306b2484a531ab84ca5c96260a73de76c0/wrapt-2.1.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:a9dd9813825f7ecb018c17fd147a01845eb330254dff86d3b5816f20f4d6aaf8", size = 116271, upload-time = "2026-03-06T02:54:46.356Z" }, - { url = "https://files.pythonhosted.org/packages/98/fd/e5ff7ded41b76d802cf1191288473e850d24ba2e39a6ec540f21ae3b57cb/wrapt-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f8dbdd3719e534860d6a78526aafc220e0241f981367018c2875178cf83a413", size = 120573, upload-time = "2026-03-06T02:52:50.163Z" }, - { url = "https://files.pythonhosted.org/packages/47/c5/242cae3b5b080cd09bacef0591691ba1879739050cc7c801ff35c8886b66/wrapt-2.1.2-cp313-cp313-win32.whl", hash = "sha256:5c35b5d82b16a3bc6e0a04349b606a0582bc29f573786aebe98e0c159bc48db6", size = 58205, upload-time = "2026-03-06T02:53:47.494Z" }, - { url = "https://files.pythonhosted.org/packages/12/69/c358c61e7a50f290958809b3c61ebe8b3838ea3e070d7aac9814f95a0528/wrapt-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f8bc1c264d8d1cf5b3560a87bbdd31131573eb25f9f9447bb6252b8d4c44a3a1", size = 60452, upload-time = "2026-03-06T02:53:30.038Z" }, - { url = "https://files.pythonhosted.org/packages/8e/66/c8a6fcfe321295fd8c0ab1bd685b5a01462a9b3aa2f597254462fc2bc975/wrapt-2.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:3beb22f674550d5634642c645aba4c72a2c66fb185ae1aebe1e955fae5a13baf", size = 58842, upload-time = "2026-03-06T02:52:52.114Z" }, - { url = "https://files.pythonhosted.org/packages/da/55/9c7052c349106e0b3f17ae8db4b23a691a963c334de7f9dbd60f8f74a831/wrapt-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fc04bc8664a8bc4c8e00b37b5355cffca2535209fba1abb09ae2b7c76ddf82b", size = 63075, upload-time = "2026-03-06T02:53:19.108Z" }, - { url = "https://files.pythonhosted.org/packages/09/a8/ce7b4006f7218248dd71b7b2b732d0710845a0e49213b18faef64811ffef/wrapt-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a9b9d50c9af998875a1482a038eb05755dfd6fe303a313f6a940bb53a83c3f18", size = 63719, upload-time = "2026-03-06T02:54:33.452Z" }, - { url = "https://files.pythonhosted.org/packages/e4/e5/2ca472e80b9e2b7a17f106bb8f9df1db11e62101652ce210f66935c6af67/wrapt-2.1.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2d3ff4f0024dd224290c0eabf0240f1bfc1f26363431505fb1b0283d3b08f11d", size = 152643, upload-time = "2026-03-06T02:52:42.721Z" }, - { url = "https://files.pythonhosted.org/packages/36/42/30f0f2cefca9d9cbf6835f544d825064570203c3e70aa873d8ae12e23791/wrapt-2.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3278c471f4468ad544a691b31bb856374fbdefb7fee1a152153e64019379f015", size = 158805, upload-time = "2026-03-06T02:54:25.441Z" }, - { url = "https://files.pythonhosted.org/packages/bb/67/d08672f801f604889dcf58f1a0b424fe3808860ede9e03affc1876b295af/wrapt-2.1.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8914c754d3134a3032601c6984db1c576e6abaf3fc68094bb8ab1379d75ff92", size = 145990, upload-time = "2026-03-06T02:53:57.456Z" }, - { url = "https://files.pythonhosted.org/packages/68/a7/fd371b02e73babec1de6ade596e8cd9691051058cfdadbfd62a5898f3295/wrapt-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ff95d4264e55839be37bafe1536db2ab2de19da6b65f9244f01f332b5286cfbf", size = 155670, upload-time = "2026-03-06T02:54:55.309Z" }, - { url = "https://files.pythonhosted.org/packages/86/2d/9fe0095dfdb621009f40117dcebf41d7396c2c22dca6eac779f4c007b86c/wrapt-2.1.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:76405518ca4e1b76fbb1b9f686cff93aebae03920cc55ceeec48ff9f719c5f67", size = 144357, upload-time = "2026-03-06T02:54:24.092Z" }, - { url = "https://files.pythonhosted.org/packages/0e/b6/ec7b4a254abbe4cde9fa15c5d2cca4518f6b07d0f1b77d4ee9655e30280e/wrapt-2.1.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c0be8b5a74c5824e9359b53e7e58bef71a729bacc82e16587db1c4ebc91f7c5a", size = 150269, upload-time = "2026-03-06T02:53:31.268Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6b/2fabe8ebf148f4ee3c782aae86a795cc68ffe7d432ef550f234025ce0cfa/wrapt-2.1.2-cp313-cp313t-win32.whl", hash = "sha256:f01277d9a5fc1862f26f7626da9cf443bebc0abd2f303f41c5e995b15887dabd", size = 59894, upload-time = "2026-03-06T02:54:15.391Z" }, - { url = "https://files.pythonhosted.org/packages/ca/fb/9ba66fc2dedc936de5f8073c0217b5d4484e966d87723415cc8262c5d9c2/wrapt-2.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:84ce8f1c2104d2f6daa912b1b5b039f331febfeee74f8042ad4e04992bd95c8f", size = 63197, upload-time = "2026-03-06T02:54:41.943Z" }, - { url = "https://files.pythonhosted.org/packages/c0/1c/012d7423c95d0e337117723eb8ecf73c622ce15a97847e84cf3f8f26cd7e/wrapt-2.1.2-cp313-cp313t-win_arm64.whl", hash = "sha256:a93cd767e37faeddbe07d8fc4212d5cba660af59bdb0f6372c93faaa13e6e679", size = 60363, upload-time = "2026-03-06T02:54:48.093Z" }, - { url = "https://files.pythonhosted.org/packages/39/25/e7ea0b417db02bb796182a5316398a75792cd9a22528783d868755e1f669/wrapt-2.1.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1370e516598854e5b4366e09ce81e08bfe94d42b0fd569b88ec46cc56d9164a9", size = 61418, upload-time = "2026-03-06T02:53:55.706Z" }, - { url = "https://files.pythonhosted.org/packages/ec/0f/fa539e2f6a770249907757eaeb9a5ff4deb41c026f8466c1c6d799088a9b/wrapt-2.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6de1a3851c27e0bd6a04ca993ea6f80fc53e6c742ee1601f486c08e9f9b900a9", size = 61914, upload-time = "2026-03-06T02:52:53.37Z" }, - { url = "https://files.pythonhosted.org/packages/53/37/02af1867f5b1441aaeda9c82deed061b7cd1372572ddcd717f6df90b5e93/wrapt-2.1.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:de9f1a2bbc5ac7f6012ec24525bdd444765a2ff64b5985ac6e0692144838542e", size = 120417, upload-time = "2026-03-06T02:54:30.74Z" }, - { url = "https://files.pythonhosted.org/packages/c3/b7/0138a6238c8ba7476c77cf786a807f871672b37f37a422970342308276e7/wrapt-2.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:970d57ed83fa040d8b20c52fe74a6ae7e3775ae8cff5efd6a81e06b19078484c", size = 122797, upload-time = "2026-03-06T02:54:51.539Z" }, - { url = "https://files.pythonhosted.org/packages/e1/ad/819ae558036d6a15b7ed290d5b14e209ca795dd4da9c58e50c067d5927b0/wrapt-2.1.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3969c56e4563c375861c8df14fa55146e81ac11c8db49ea6fb7f2ba58bc1ff9a", size = 117350, upload-time = "2026-03-06T02:54:37.651Z" }, - { url = "https://files.pythonhosted.org/packages/8b/2d/afc18dc57a4600a6e594f77a9ae09db54f55ba455440a54886694a84c71b/wrapt-2.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:57d7c0c980abdc5f1d98b11a2aa3bb159790add80258c717fa49a99921456d90", size = 121223, upload-time = "2026-03-06T02:54:35.221Z" }, - { url = "https://files.pythonhosted.org/packages/b9/5b/5ec189b22205697bc56eb3b62aed87a1e0423e9c8285d0781c7a83170d15/wrapt-2.1.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:776867878e83130c7a04237010463372e877c1c994d449ca6aaafeab6aab2586", size = 116287, upload-time = "2026-03-06T02:54:19.654Z" }, - { url = "https://files.pythonhosted.org/packages/f7/2d/f84939a7c9b5e6cdd8a8d0f6a26cabf36a0f7e468b967720e8b0cd2bdf69/wrapt-2.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fab036efe5464ec3291411fabb80a7a39e2dd80bae9bcbeeca5087fdfa891e19", size = 119593, upload-time = "2026-03-06T02:54:16.697Z" }, - { url = "https://files.pythonhosted.org/packages/0b/fe/ccd22a1263159c4ac811ab9374c061bcb4a702773f6e06e38de5f81a1bdc/wrapt-2.1.2-cp314-cp314-win32.whl", hash = "sha256:e6ed62c82ddf58d001096ae84ce7f833db97ae2263bff31c9b336ba8cfe3f508", size = 58631, upload-time = "2026-03-06T02:53:06.498Z" }, - { url = "https://files.pythonhosted.org/packages/65/0a/6bd83be7bff2e7efaac7b4ac9748da9d75a34634bbbbc8ad077d527146df/wrapt-2.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:467e7c76315390331c67073073d00662015bb730c566820c9ca9b54e4d67fd04", size = 60875, upload-time = "2026-03-06T02:53:50.252Z" }, - { url = "https://files.pythonhosted.org/packages/6c/c0/0b3056397fe02ff80e5a5d72d627c11eb885d1ca78e71b1a5c1e8c7d45de/wrapt-2.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:da1f00a557c66225d53b095a97eace0fc5349e3bfda28fa34ffae238978ee575", size = 59164, upload-time = "2026-03-06T02:53:59.128Z" }, - { url = "https://files.pythonhosted.org/packages/71/ed/5d89c798741993b2371396eb9d4634f009ff1ad8a6c78d366fe2883ea7a6/wrapt-2.1.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:62503ffbc2d3a69891cf29beeaccdb4d5e0a126e2b6a851688d4777e01428dbb", size = 63163, upload-time = "2026-03-06T02:52:54.873Z" }, - { url = "https://files.pythonhosted.org/packages/c6/8c/05d277d182bf36b0a13d6bd393ed1dec3468a25b59d01fba2dd70fe4d6ae/wrapt-2.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c7e6cd120ef837d5b6f860a6ea3745f8763805c418bb2f12eeb1fa6e25f22d22", size = 63723, upload-time = "2026-03-06T02:52:56.374Z" }, - { url = "https://files.pythonhosted.org/packages/f4/27/6c51ec1eff4413c57e72d6106bb8dec6f0c7cdba6503d78f0fa98767bcc9/wrapt-2.1.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3769a77df8e756d65fbc050333f423c01ae012b4f6731aaf70cf2bef61b34596", size = 152652, upload-time = "2026-03-06T02:53:23.79Z" }, - { url = "https://files.pythonhosted.org/packages/db/4c/d7dd662d6963fc7335bfe29d512b02b71cdfa23eeca7ab3ac74a67505deb/wrapt-2.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a76d61a2e851996150ba0f80582dd92a870643fa481f3b3846f229de88caf044", size = 158807, upload-time = "2026-03-06T02:53:35.742Z" }, - { url = "https://files.pythonhosted.org/packages/b4/4d/1e5eea1a78d539d346765727422976676615814029522c76b87a95f6bcdd/wrapt-2.1.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6f97edc9842cf215312b75fe737ee7c8adda75a89979f8e11558dfff6343cc4b", size = 146061, upload-time = "2026-03-06T02:52:57.574Z" }, - { url = "https://files.pythonhosted.org/packages/89/bc/62cabea7695cd12a288023251eeefdcb8465056ddaab6227cb78a2de005b/wrapt-2.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4006c351de6d5007aa33a551f600404ba44228a89e833d2fadc5caa5de8edfbf", size = 155667, upload-time = "2026-03-06T02:53:39.422Z" }, - { url = "https://files.pythonhosted.org/packages/e9/99/6f2888cd68588f24df3a76572c69c2de28287acb9e1972bf0c83ce97dbc1/wrapt-2.1.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a9372fc3639a878c8e7d87e1556fa209091b0a66e912c611e3f833e2c4202be2", size = 144392, upload-time = "2026-03-06T02:54:22.41Z" }, - { url = "https://files.pythonhosted.org/packages/40/51/1dfc783a6c57971614c48e361a82ca3b6da9055879952587bc99fe1a7171/wrapt-2.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3144b027ff30cbd2fca07c0a87e67011adb717eb5f5bd8496325c17e454257a3", size = 150296, upload-time = "2026-03-06T02:54:07.848Z" }, - { url = "https://files.pythonhosted.org/packages/6c/38/cbb8b933a0201076c1f64fc42883b0023002bdc14a4964219154e6ff3350/wrapt-2.1.2-cp314-cp314t-win32.whl", hash = "sha256:3b8d15e52e195813efe5db8cec156eebe339aaf84222f4f4f051a6c01f237ed7", size = 60539, upload-time = "2026-03-06T02:54:00.594Z" }, - { url = "https://files.pythonhosted.org/packages/82/dd/e5176e4b241c9f528402cebb238a36785a628179d7d8b71091154b3e4c9e/wrapt-2.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:08ffa54146a7559f5b8df4b289b46d963a8e74ed16ba3687f99896101a3990c5", size = 63969, upload-time = "2026-03-06T02:54:39Z" }, - { url = "https://files.pythonhosted.org/packages/5c/99/79f17046cf67e4a95b9987ea129632ba8bcec0bc81f3fb3d19bdb0bd60cd/wrapt-2.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:72aaa9d0d8e4ed0e2e98019cea47a21f823c9dd4b43c7b77bba6679ffcca6a00", size = 60554, upload-time = "2026-03-06T02:53:14.132Z" }, - { url = "https://files.pythonhosted.org/packages/1a/c7/8528ac2dfa2c1e6708f647df7ae144ead13f0a31146f43c7264b4942bf12/wrapt-2.1.2-py3-none-any.whl", hash = "sha256:b8fd6fa2b2c4e7621808f8c62e8317f4aae56e59721ad933bac5239d913cf0e8", size = 43993, upload-time = "2026-03-06T02:53:12.905Z" }, + { url = "https://files.pythonhosted.org/packages/89/0c/bfae7b9401583b6d05938cd16dedc43857d96da2f8a3d50d78cc515bf6ff/wrapt-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0", size = 81021, upload-time = "2026-05-22T14:48:00.313Z" }, + { url = "https://files.pythonhosted.org/packages/26/58/80f6a6599f933f4caecc1cb3ee88a04faf81e8b9bddbd6109c688dd63e0f/wrapt-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8", size = 81692, upload-time = "2026-05-22T14:48:01.49Z" }, + { url = "https://files.pythonhosted.org/packages/17/93/fb357cc7847c58a8ae790be718903afa81a28d23e642c843dc4129e8a0b2/wrapt-2.2.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e", size = 169364, upload-time = "2026-05-22T14:48:02.791Z" }, + { url = "https://files.pythonhosted.org/packages/aa/0b/76b601ee309a8bd556af0eecb184394c20b3c49aa9c8e085aa1ffacc2568/wrapt-2.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926", size = 171079, upload-time = "2026-05-22T14:48:04.22Z" }, + { url = "https://files.pythonhosted.org/packages/cd/87/ee3f32d5658e3e26d3e0e457922b47a36dd3bfbdfee7f97bb3e802344a66/wrapt-2.2.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624", size = 160205, upload-time = "2026-05-22T14:48:05.553Z" }, + { url = "https://files.pythonhosted.org/packages/b1/d0/ae2fd64277a67f5d7bffcf2d05eea1e476263fb2a072baf0b0129ab85984/wrapt-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710", size = 168922, upload-time = "2026-05-22T14:48:07.132Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f3/2d541a060c5bbafb9400bca4917e4d78bfd1f239f404782c86831a8f6b29/wrapt-2.2.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f", size = 158388, upload-time = "2026-05-22T14:48:08.629Z" }, + { url = "https://files.pythonhosted.org/packages/1d/68/8d92c8800c57e93cb116ae9e9d6cbafc34fade5ee9f9107b6f203fb4dc35/wrapt-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797", size = 167682, upload-time = "2026-05-22T14:48:10.042Z" }, + { url = "https://files.pythonhosted.org/packages/30/72/83ea3790ea352439442349388e29ff07b76e0686265f9088bbb505d1608d/wrapt-2.2.1-cp312-cp312-win32.whl", hash = "sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052", size = 77857, upload-time = "2026-05-22T14:48:11.782Z" }, + { url = "https://files.pythonhosted.org/packages/ef/cb/99450668dd3502d62a54a1c8aa56e44f34cb8c1261b381cfe2e7926c3b75/wrapt-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5", size = 80825, upload-time = "2026-05-22T14:48:13.046Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3a/87512881be64e743f9ee4c66f4cbe8e884974bef2a5989af71f999653ac7/wrapt-2.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579", size = 79087, upload-time = "2026-05-22T14:48:14.323Z" }, + { url = "https://files.pythonhosted.org/packages/88/d1/a1b08f8f4fac8cbb156fa51cf64ee2c7f7f74f9875ba3cf70b3c58368694/wrapt-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb", size = 80831, upload-time = "2026-05-22T14:48:15.598Z" }, + { url = "https://files.pythonhosted.org/packages/54/ce/57890814991446a845e09b3445ce8b694f27eb0577004f2c2a36a9772ed4/wrapt-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80", size = 81375, upload-time = "2026-05-22T14:48:17.071Z" }, + { url = "https://files.pythonhosted.org/packages/38/65/08d7a6c76ac4493bdb668205ee9c1de1bd5daca61717c3e9aa49b4c01499/wrapt-2.2.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a", size = 167417, upload-time = "2026-05-22T14:48:18.303Z" }, + { url = "https://files.pythonhosted.org/packages/62/ce/f1ccbee7a1bfe5cdc6b3da6bab4b45713d628b9294da32a39f563d648140/wrapt-2.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474", size = 166948, upload-time = "2026-05-22T14:48:19.768Z" }, + { url = "https://files.pythonhosted.org/packages/86/2a/f85d48d1cd4869aee6704028d257d740a47c1c467b457ce396b4b5b55d07/wrapt-2.2.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143", size = 158148, upload-time = "2026-05-22T14:48:21.96Z" }, + { url = "https://files.pythonhosted.org/packages/fe/5c/93939ad11d4a12358ab1aab219a2ef5efa5612e0db6b9fc65af8af1a891b/wrapt-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a", size = 165905, upload-time = "2026-05-22T14:48:23.373Z" }, + { url = "https://files.pythonhosted.org/packages/e0/22/b8c2aa89862ff58605934d7abf4b70e6a5a1c33df96656f49035ccdf1c8a/wrapt-2.2.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9", size = 156712, upload-time = "2026-05-22T14:48:24.767Z" }, + { url = "https://files.pythonhosted.org/packages/5d/78/bf00a7b02239c12bb02ddcc3c0b971bfcc36e578c5a44f1ccfef5b458545/wrapt-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31", size = 166560, upload-time = "2026-05-22T14:48:26.83Z" }, + { url = "https://files.pythonhosted.org/packages/fe/93/6390ca9c5b787683cef588d04f57c8d41b9a2323b5597a65f18638c90ef2/wrapt-2.2.1-cp313-cp313-win32.whl", hash = "sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337", size = 77817, upload-time = "2026-05-22T14:48:28.221Z" }, + { url = "https://files.pythonhosted.org/packages/97/73/ce10f0e71c0cfaa1a65faadb8efd4852028b3bb9ba28932b8889df769d38/wrapt-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215", size = 80736, upload-time = "2026-05-22T14:48:30.139Z" }, + { url = "https://files.pythonhosted.org/packages/c7/4c/89f4a6818fafbbd840330e4fa3873073e1bfc166133a64cac7f8fde7a5e3/wrapt-2.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f", size = 79099, upload-time = "2026-05-22T14:48:31.405Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f2/9a8741c46f8c208ac0a45b25ba170bcb4fb72a2781d5fb97dbd7b6be73cb/wrapt-2.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8", size = 82802, upload-time = "2026-05-22T14:48:33.307Z" }, + { url = "https://files.pythonhosted.org/packages/9c/0d/e9c855716a3705eef1416456bdf062b60620726fdc59428ff670fc3c60dc/wrapt-2.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8", size = 83329, upload-time = "2026-05-22T14:48:34.593Z" }, + { url = "https://files.pythonhosted.org/packages/3b/d6/a88f1c13112b7831adac75cea65d8310e0d696d570c8961844c90a57b865/wrapt-2.2.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d", size = 202937, upload-time = "2026-05-22T14:48:35.859Z" }, + { url = "https://files.pythonhosted.org/packages/42/65/e29d54aef06a4d898a5b8a25589a0b3769bde454f922fad8f6f89fbfb650/wrapt-2.2.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27", size = 209997, upload-time = "2026-05-22T14:48:38.153Z" }, + { url = "https://files.pythonhosted.org/packages/2a/91/e4454263516cf0e12640912fbca9a83654e424f0a6ddb79f5cd7ce14bf33/wrapt-2.2.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440", size = 194856, upload-time = "2026-05-22T14:48:39.69Z" }, + { url = "https://files.pythonhosted.org/packages/de/d0/fe0ee202286afdf4a7f77dd29f195703145764d572aec209c5086e57d924/wrapt-2.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e", size = 205654, upload-time = "2026-05-22T14:48:43.456Z" }, + { url = "https://files.pythonhosted.org/packages/23/b6/87d860dfc6460c246af70b1fd5c8b76df77571b42a493459423ded94fd7d/wrapt-2.2.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b", size = 192206, upload-time = "2026-05-22T14:48:44.858Z" }, + { url = "https://files.pythonhosted.org/packages/df/46/3eea8cde077d985f239a38c0257087b8064fd9ee9b1a99e282d2c86da4ef/wrapt-2.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394", size = 198428, upload-time = "2026-05-22T14:48:46.319Z" }, + { url = "https://files.pythonhosted.org/packages/18/dc/b927ee9c7fc67adc3a5658f246a0d275425eb840ba36e7b702e70f18bde8/wrapt-2.2.1-cp313-cp313t-win32.whl", hash = "sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562", size = 79448, upload-time = "2026-05-22T14:48:47.901Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b3/fd30b473fe498c70e6b9a5f328b8d3fbaf1b8c3c481465f59724bba8eb70/wrapt-2.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53", size = 83021, upload-time = "2026-05-22T14:48:49.201Z" }, + { url = "https://files.pythonhosted.org/packages/ee/f3/96c39153a8737a6e9aa85adef254ac4195bea3f2d24efc60472ccc3c9e2e/wrapt-2.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e", size = 80295, upload-time = "2026-05-22T14:48:50.479Z" }, + { url = "https://files.pythonhosted.org/packages/0a/a3/11d7f34ebbf3231bc907a3e6d5ee051b14d034c1bc7b65a97d5cc00516df/wrapt-2.2.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab", size = 80879, upload-time = "2026-05-22T14:48:51.802Z" }, + { url = "https://files.pythonhosted.org/packages/13/3c/b74cfd984cef560b900fb1a727af20352d89e1f06bf2e1114dd3f00f5f5a/wrapt-2.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c", size = 81462, upload-time = "2026-05-22T14:48:53.18Z" }, + { url = "https://files.pythonhosted.org/packages/15/a3/7c8f704b8dc07dfe0a5d01c2edbfd88317aa8e5e3fa7c743eb7a085ae767/wrapt-2.2.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c", size = 167251, upload-time = "2026-05-22T14:48:54.562Z" }, + { url = "https://files.pythonhosted.org/packages/80/85/a34d1888d97247da6c2ff6118c3a721c73ed8cc4dd198c00208bb73b6f80/wrapt-2.2.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e", size = 166316, upload-time = "2026-05-22T14:48:56.065Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d7/72ffaeb01eebc704afe3fb99e840480f4bda45f0fa66e3381b6a39251c8f/wrapt-2.2.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f", size = 157952, upload-time = "2026-05-22T14:48:57.924Z" }, + { url = "https://files.pythonhosted.org/packages/24/5b/36f5d6b024e4edfdd90b140742d11ebcf7836daf5c9daf326c55c24db412/wrapt-2.2.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508", size = 166130, upload-time = "2026-05-22T14:48:59.384Z" }, + { url = "https://files.pythonhosted.org/packages/81/06/9296d9e97bfdef5483dfcc859d57b095b257144b2bc5300ab521e06f4bc7/wrapt-2.2.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5", size = 156604, upload-time = "2026-05-22T14:49:00.921Z" }, + { url = "https://files.pythonhosted.org/packages/53/37/16953929ed6776175720e58fc966e779926d8d71e2c7b2273230590ca71f/wrapt-2.2.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283", size = 166007, upload-time = "2026-05-22T14:49:02.332Z" }, + { url = "https://files.pythonhosted.org/packages/b9/73/20ee58c0612dae7c31131a7095345812ed2c7b389019e175f68cde34e5b4/wrapt-2.2.1-cp314-cp314-win32.whl", hash = "sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243", size = 78327, upload-time = "2026-05-22T14:49:03.722Z" }, + { url = "https://files.pythonhosted.org/packages/22/b3/ef7c3295d02e0448a71c639a36a057f46d524d057c9486291a7a3039e65c/wrapt-2.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b", size = 81144, upload-time = "2026-05-22T14:49:05.093Z" }, + { url = "https://files.pythonhosted.org/packages/ac/dc/7bdf336953f99f4ceb0a584bb8870e42c8f26f93ea10c87834dad62f1668/wrapt-2.2.1-cp314-cp314-win_arm64.whl", hash = "sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36", size = 79569, upload-time = "2026-05-22T14:49:06.413Z" }, + { url = "https://files.pythonhosted.org/packages/6a/6d/6dfae80150ff1919c356d1dd528f049bcdfaae29b4d284bc957e022caef4/wrapt-2.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188", size = 82892, upload-time = "2026-05-22T14:49:07.925Z" }, + { url = "https://files.pythonhosted.org/packages/82/7b/4e34766a7d7804ffce9e71befe47e9b3225dc350c49c94493c4ab39fd3a5/wrapt-2.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199", size = 83333, upload-time = "2026-05-22T14:49:09.257Z" }, + { url = "https://files.pythonhosted.org/packages/9d/57/0b34db3e8de44ccfece62d7b337abd1631dd810f5adc5f3db571727836b5/wrapt-2.2.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413", size = 202899, upload-time = "2026-05-22T14:49:10.572Z" }, + { url = "https://files.pythonhosted.org/packages/e5/45/ac0c459f154b99d92789a6cba7ca727185b83513b986f8ec7fe2aacddcbf/wrapt-2.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956", size = 209986, upload-time = "2026-05-22T14:49:12.229Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e4/77e37ff33ad018fa81ade52c25fa327b80b56f81d734279a63614fcb4cbc/wrapt-2.2.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e", size = 194893, upload-time = "2026-05-22T14:49:14.139Z" }, + { url = "https://files.pythonhosted.org/packages/dd/9d/7ea651d1ab032fc5fa222fbec91d0f8a1397f6ae04ebb93fa7219aa921d7/wrapt-2.2.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85", size = 205636, upload-time = "2026-05-22T14:49:15.714Z" }, + { url = "https://files.pythonhosted.org/packages/09/af/8e88031a701275b9085c54e64bc88c0b1cd55c77eadd400691c371cd76c4/wrapt-2.2.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181", size = 192267, upload-time = "2026-05-22T14:49:17.283Z" }, + { url = "https://files.pythonhosted.org/packages/bf/a8/e657ca876b06710194f243d81c4b0896ade646e244bdbec2d87c8c56a8bd/wrapt-2.2.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a", size = 198378, upload-time = "2026-05-22T14:49:18.785Z" }, + { url = "https://files.pythonhosted.org/packages/c8/59/822efe4ea722a3961331bfa35b7d90937790d2c20f0616de1997ccc3aebd/wrapt-2.2.1-cp314-cp314t-win32.whl", hash = "sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85", size = 80226, upload-time = "2026-05-22T14:49:20.264Z" }, + { url = "https://files.pythonhosted.org/packages/ab/31/2a7dc5f6abb2fca0b6e1610e120419f603650aceb4f1d3ac4cae0354e162/wrapt-2.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50", size = 83835, upload-time = "2026-05-22T14:49:21.634Z" }, + { url = "https://files.pythonhosted.org/packages/9f/c0/782b86e28d1ceebeb74cccea12d2cd3d2ba0bd68e3dec20b1bc5873f6127/wrapt-2.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00", size = 80722, upload-time = "2026-05-22T14:49:23.59Z" }, + { url = "https://files.pythonhosted.org/packages/53/46/29ac9daf11a86c22a8c38cd9236c62928ccae83f7ceb06bd3b0467cf9d05/wrapt-2.2.1-py3-none-any.whl", hash = "sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f", size = 61000, upload-time = "2026-05-22T14:49:41.593Z" }, ] From f451a23586c2ddcde0555bb74ce6920520693ef5 Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Wed, 27 May 2026 12:17:35 +0200 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=E2=9C=A8=20Join=20SEFNC=20week=20r?= =?UTF-8?q?esources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Normalize the SEFNC visit-specific REDCap forms into one resource schema with a week field so repeated measurements are represented by rows instead of suffixed columns. --- scripts/redcap_dict_to_properties.py | 106 ++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/scripts/redcap_dict_to_properties.py b/scripts/redcap_dict_to_properties.py index 672e30a..a682c70 100644 --- a/scripts/redcap_dict_to_properties.py +++ b/scripts/redcap_dict_to_properties.py @@ -13,6 +13,13 @@ VAS_TIMEPOINTS = [-10, 30, 60, 90, 120, 180, 240] VAS_TIME_FORM_PATTERN = re.compile(r"^vas_(minus10|(30|60|90|120|180|240)_?min)$") VAS_TIME_FIELD_PATTERN = re.compile(r"(_fasted)?_(minus10|30|60|90|120|180|240)min$") +SEFNC_WEEKS = [0, 12, 52] +SEFNC_FORM_WEEKS = { + "sefnc_baseline_v4": 0, + "sefnc_week12_v6": 12, + "selfefficacy_for_nutrition_change_sefnc_week_52": 52, +} +SEFNC_WEEK_FIELD_PATTERN = re.compile(r"_v(6|10)$") def _map(x: Iterable[In], fn: Callable[[In], Out]) -> list[Out]: @@ -38,7 +45,7 @@ def dictionary_to_properties( redcap_fields: list[dict[str, str]], ) -> list[sp.ResourceProperties]: """Converts REDCap data dictionary to Data Package resources.""" - redcap_fields = _join_vas_time_resources(redcap_fields) + redcap_fields = _join_sefnc_week_resources(_join_vas_time_resources(redcap_fields)) sorted_by_form = sorted(redcap_fields, key=lambda field: field["form_name"]) grouped_by_form = groupby(sorted_by_form, key=lambda field: field["form_name"]) return _map( @@ -109,6 +116,79 @@ def _remove_vas_time_from_annotation(annotation: str) -> str: ).strip() +def _join_sefnc_week_resources( + redcap_fields: list[dict[str, str]], +) -> list[dict[str, str]]: + """Combines SEFNC week-specific forms into one resource schema.""" + return _deduplicate_sefnc_fields( + _map(redcap_fields, _normalise_sefnc_week_resource_field) + ) + + +def _normalise_sefnc_week_resource_field(field: dict[str, str]) -> dict[str, str]: + if not _is_sefnc_week_resource_field(field): + return field + + return { + **field, + "field_name": _normalise_sefnc_field_name(field["field_name"]), + "form_name": "sefnc", + "field_annotation": _remove_sefnc_week_from_annotation( + field["field_annotation"] + ), + } + + +def _normalise_sefnc_field_name(field_name: str) -> str: + return SEFNC_WEEK_FIELD_PATTERN.sub("", field_name).replace( + "sefnc_ubusy_schedule", "sefnc_busy_schedule" + ) + + +def _is_sefnc_week_resource_field(field: dict[str, str]) -> bool: + return field["form_name"] in SEFNC_FORM_WEEKS + + +def _deduplicate_sefnc_fields(fields: list[dict[str, str]]) -> list[dict[str, str]]: + deduplicated_fields, _ = reduce( + _append_if_new_sefnc_field, + fields, + ([], set()), + ) + return deduplicated_fields + + +def _append_if_new_sefnc_field( + result: tuple[list[dict[str, str]], set[str]], field: dict[str, str] +) -> tuple[list[dict[str, str]], set[str]]: + fields, seen_sefnc_fields = result + field_name = field["field_name"] + + if field["form_name"] != "sefnc": + return fields + [field], seen_sefnc_fields + + if field_name in seen_sefnc_fields: + return result + + return (fields + [field], seen_sefnc_fields.union({field_name})) + + +def _remove_sefnc_week_from_annotation(annotation: str) -> str: + annotation = re.sub( + r"\s+Repeated at baseline \(V4\), week 12 \(V6\) and week 52 \(V10\)\.?", + "", + annotation, + flags=re.IGNORECASE, + ) + + return re.sub( + r"\s+(Baseline|Week 12|Week 52)\s*\((V4|V6|V?10)\)\.?", + "", + annotation, + flags=re.IGNORECASE, + ).strip() + + def _form_to_resource( form_name: str, fields: list[dict[str, str]] ) -> sp.ResourceProperties: @@ -153,6 +233,21 @@ def _form_to_resource( default_fields.append(time_field) primary_key.append("minutes_from_meal") + if form_name == "sefnc": + week_field = sp.FieldProperties( + name="week", + title="Week", + type="integer", + description="The study week when the SEFNC measurement was recorded.", + categories=SEFNC_WEEKS, + constraints=sp.ConstraintsProperties( + required=True, + enum=SEFNC_WEEKS, + ), + ) + default_fields.append(week_field) + primary_key.append("week") + # Discard fields displayed for information only form_redcap_fields = _filter( fields, lambda field: field["field_type"] not in ["descriptive", "checkbox"] @@ -199,6 +294,9 @@ def _get_resource_title(form_name: str) -> str: if form_name == "vas": return "Visual analogue scale measurements" + if form_name == "sefnc": + return "Self-efficacy for nutrition change" + return form_name @@ -209,6 +307,12 @@ def _get_resource_description(form_name: str) -> str: "relative to the meal." ) + if form_name == "sefnc": + return ( + "Self-efficacy for nutrition change measurements recorded across " + "study weeks." + ) + return form_name From 401527c7cb0422aad8c39e3c6c7ca452a0b3d89a Mon Sep 17 00:00:00 2001 From: Joel Ostblom Date: Wed, 27 May 2026 12:17:54 +0200 Subject: [PATCH 7/7] =?UTF-8?q?build:=20=F0=9F=93=A6=20Regenerate=20SEFNC?= =?UTF-8?q?=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the generated data package metadata so SEFNC has one resource with week values 0, 12, and 52 and no visit-suffixed duplicate fields. --- datapackage.json | 760 +++-------------------------------------------- 1 file changed, 34 insertions(+), 726 deletions(-) diff --git a/datapackage.json b/datapackage.json index 6504081..baf83e8 100644 --- a/datapackage.json +++ b/datapackage.json @@ -23778,10 +23778,10 @@ } }, { - "name": "sefnc_baseline_v4", - "path": "resources/sefnc_baseline_v4/data.parquet", - "title": "sefnc_baseline_v4", - "description": "sefnc_baseline_v4", + "name": "sefnc", + "path": "resources/sefnc/data.parquet", + "title": "Self-efficacy for nutrition change", + "description": "Self-efficacy for nutrition change measurements recorded across study weeks.", "schema": { "fields": [ { @@ -23812,11 +23812,30 @@ "Odense" ] }, + { + "name": "week", + "title": "Week", + "type": "integer", + "description": "The study week when the SEFNC measurement was recorded.", + "constraints": { + "required": true, + "enum": [ + 0, + 12, + 52 + ] + }, + "categories": [ + 0, + 12, + 52 + ] + }, { "name": "sefnc_when_tired", "title": "sefnc_when_tired", "type": "string", - "description": "Participant's confidence in following their diet when feeling tired. Self-reported by participant. Baseline (V4).", + "description": "Participant's confidence in following their diet when feeling tired. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -23851,7 +23870,7 @@ "name": "sefnc_during_crisis", "title": "sefnc_during_crisis", "type": "string", - "description": "Participant's confidence in following their diet during or after a personal crisis. Baseline (V4).", + "description": "Participant's confidence in following their diet during or after a personal crisis.", "constraints": { "required": true, "enum": [ @@ -23886,7 +23905,7 @@ "name": "sefnc_when_depressed", "title": "sefnc_when_depressed", "type": "string", - "description": "Participant's confidence in following their diet when feeling depressed. Self-reported by participant. Baseline (V4).", + "description": "Participant's confidence in following their diet when feeling depressed. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -23921,7 +23940,7 @@ "name": "sefnc_when_anxious", "title": "sefnc_when_anxious", "type": "string", - "description": "Participant's confidence in following their diet when feeling anxious. Self-reported by participant. Baseline (V4).", + "description": "Participant's confidence in following their diet when feeling anxious. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -23956,7 +23975,7 @@ "name": "sefnc_on_vacation", "title": "sefnc_on_vacation", "type": "string", - "description": "Participant's confidence in following their diet while on vacation. Self-reported by participant. Repeated at baseline (V4), week 12 (V6) and week 52 (V10).", + "description": "Participant's confidence in following their diet while on vacation. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -23991,7 +24010,7 @@ "name": "sefnc_when_busy", "title": "sefnc_when_busy", "type": "string", - "description": "Participant's confidence in following their diet when they have a heavy workload. Self-reported by participant. Repeated at baseline (V4), week 12 (V6) and week 52 (V10).", + "description": "Participant's confidence in following their diet when they have a heavy workload. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -24026,7 +24045,7 @@ "name": "sefnc_when_missed_goals", "title": "sefnc_when_missed_goals", "type": "string", - "description": "Participant's confidence in following their diet when they have not met their dietary goals. Self-reported by participant. Baseline (V4).", + "description": "Participant's confidence in following their diet when they have not met their dietary goals. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -24061,7 +24080,7 @@ "name": "sefnc_no_support", "title": "sefnc_no_support", "type": "string", - "description": "Participant's confidence in following their diet when lacking support from family or friends. Baseline (V4).", + "description": "Participant's confidence in following their diet when lacking support from family or friends.", "constraints": { "required": true, "enum": [ @@ -24096,7 +24115,7 @@ "name": "sefnc_busy_schedule", "title": "sefnc_busy_schedule", "type": "string", - "description": "Participant's confidence in following their diet when their schedule is busy or resource- and/or time-demanding. Self-reported by participant. Baseline (V4).", + "description": "Participant's confidence in following their diet when their schedule is busy or resource- and/or time-demanding. Self-reported by participant.", "constraints": { "required": true, "enum": [ @@ -24129,719 +24148,8 @@ } ], "primaryKey": [ - "event" - ] - } - }, - { - "name": "sefnc_week12_v6", - "path": "resources/sefnc_week12_v6/data.parquet", - "title": "sefnc_week12_v6", - "description": "sefnc_week12_v6", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "sefnc_when_tired_v6", - "title": "sefnc_when_tired_v6", - "type": "string", - "description": "Participant's confidence in following their diet when feeling tired. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_during_crisis_v6", - "title": "sefnc_during_crisis_v6", - "type": "string", - "description": "Participant's confidence in following their diet during or after a personal crisis. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_depressed_v6", - "title": "sefnc_when_depressed_v6", - "type": "string", - "description": "Participant's confidence in following their diet when feeling depressed. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_anxious_v6", - "title": "sefnc_when_anxious_v6", - "type": "string", - "description": "Participant's confidence in following their diet when feeling anxious. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_on_vacation_v6", - "title": "sefnc_on_vacation_v6", - "type": "string", - "description": "Participant's confidence in following their diet while on vacation. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_busy_v6", - "title": "sefnc_when_busy_v6", - "type": "string", - "description": "Participant's confidence in following their diet when they have a heavy workload. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_missed_goals_v6", - "title": "sefnc_when_missed_goals_v6", - "type": "string", - "description": "Participant's confidence in following their diet when they have not met their dietary goals. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_no_support_v6", - "title": "sefnc_no_support_v6", - "type": "string", - "description": "Participant's confidence in following their diet when lacking support from family or friends. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_ubusy_schedule_v6", - "title": "sefnc_ubusy_schedule_v6", - "type": "string", - "description": "Participant's confidence in following their diet when their schedule is busy or resource- and/or time-demanding. Self-reported by participant. Week 12 (V6).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - } - ], - "primaryKey": [ - "event" - ] - } - }, - { - "name": "selfefficacy_for_nutrition_change_sefnc_week_52", - "path": "resources/selfefficacy_for_nutrition_change_sefnc_week_52/data.parquet", - "title": "selfefficacy_for_nutrition_change_sefnc_week_52", - "description": "selfefficacy_for_nutrition_change_sefnc_week_52", - "schema": { - "fields": [ - { - "name": "event", - "title": "The unique name of the event", - "type": "string", - "description": "The unique name identifying the event when the form was filled in.", - "constraints": { - "required": true - } - }, - { - "name": "center", - "title": "Research center", - "type": "string", - "description": "The research center where the data item was recorded.", - "constraints": { - "required": true, - "enum": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - "categories": [ - "Copenhagen", - "Aarhus", - "Odense" - ] - }, - { - "name": "sefnc_when_tired_v10", - "title": "sefnc_when_tired_v10", - "type": "string", - "description": "Participant's confidence in following their diet when feeling tired. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_during_crisis_v10", - "title": "sefnc_during_crisis_v10", - "type": "string", - "description": "Participant's confidence in following their diet during or after a personal crisis. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_depressed_v10", - "title": "sefnc_when_depressed_v10", - "type": "string", - "description": "Participant's confidence in following their diet when feeling depressed. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_anxious_v10", - "title": "sefnc_when_anxious_v10", - "type": "string", - "description": "Participant's confidence in following their diet when feeling anxious. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_on_vacation_v10", - "title": "sefnc_on_vacation_v10", - "type": "string", - "description": "Participant's confidence in following their diet while on vacation. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_busy_v10", - "title": "sefnc_when_busy_v10", - "type": "string", - "description": "Participant's confidence in following their diet when they have a heavy workload. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_when_missed_goals_v10", - "title": "sefnc_when_missed_goals_v10", - "type": "string", - "description": "Participant's confidence in following their diet when they have not met their dietary goals. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_no_support_v10", - "title": "sefnc_no_support_v10", - "type": "string", - "description": "Participant's confidence in following their diet when lacking support from family or friends. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - { - "name": "sefnc_ubusy_schedule_v10", - "title": "sefnc_ubusy_schedule_v10", - "type": "string", - "description": "Participant's confidence in following their diet when their schedule is busy or resource- and/or time-demanding. Self-reported by participant. Week 52 (10).", - "constraints": { - "required": true, - "enum": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - }, - "categories": [ - "0%", - "10%", - "20%", - "30%", - "40%", - "50%", - "60%", - "70%", - "80%", - "90%", - "100%" - ] - } - ], - "primaryKey": [ - "event" + "event", + "week" ] } },