""" Curve data validation """ from typing import Dict def validate_schema(data: Dict) -> bool: """ Validate JSON data structure. Args: data: Parsed JSON data Returns: True if schema is valid, False otherwise """ # Check for required top-level keys if not isinstance(data, dict): return False if "meta" not in data or "shapes" not in data: return False # Check meta structure meta = data["meta"] if not isinstance(meta, dict): return False required_meta = ["version", "width", "height"] if not all(key in meta for key in required_meta): return False # Check shapes structure shapes = data["shapes"] if not isinstance(shapes, dict): return False # Validate each shape for shape_id, shape in shapes.items(): if not isinstance(shape, dict): return False if "name" not in shape or "frames" not in shape: return False frames = shape["frames"] if not isinstance(frames, dict): return False # Validate curves in each frame for frame_num, curves in frames.items(): if not isinstance(curves, list): return False for curve in curves: if not validate_curve(curve): return False return True def validate_curve(curve: Dict) -> bool: """ Validate a single curve structure. Args: curve: Curve dictionary Returns: True if curve is valid, False otherwise """ if not isinstance(curve, dict): return False required_keys = ["id", "closed", "points"] if not all(key in curve for key in required_keys): return False # Check points array points = curve["points"] if not isinstance(points, list): return False # Must have at least 2 points for a valid polygon # For closed shapes, need at least 3 points if len(points) < 2: return False if curve.get("closed", False) and len(points) < 3: return False # Each point must be [x, y] pair for point in points: if not isinstance(point, (list, tuple)) or len(point) != 2: return False if not all(isinstance(coord, (int, float)) for coord in point): return False # Validate optional pointTypes array if "pointTypes" in curve: point_types = curve["pointTypes"] if not isinstance(point_types, list): return False # pointTypes length must match points length if len(point_types) != len(points): return False # All values must be "smooth" or "hard" valid_types = {"smooth", "hard"} if not all(pt in valid_types for pt in point_types): return False return True