from __future__ import annotations from typing import Any try: from . import item_axis_policy from . import outercourse_action_policy as outercourse_policy except ImportError: # Allows local smoke tests with top-level imports. import item_axis_policy import outercourse_action_policy as outercourse_policy def _context_text(item_text: str, item_axis_values: dict[str, Any] | None) -> str: return item_axis_policy.context_text(item_text, axis_values=item_axis_values) def build_outercourse_role_graph( woman: str, man: str, item_text: str, item_axis_values: dict[str, Any] | None = None, pov_labels: list[str] | None = None, ) -> str: position_text = item_axis_policy.key_text(item_axis_values, "position") text = _context_text(item_text, item_axis_values) action_kind = outercourse_policy.infer_outercourse_action_kind(position_text) if action_kind == outercourse_policy.OUTERCOURSE_GENERIC: action_kind = outercourse_policy.infer_outercourse_action_kind(text) man_is_pov = man in set(pov_labels or []) if action_kind == outercourse_policy.OUTERCOURSE_BOOBJOB: if man_is_pov: return ( f"{woman} kneels low between the POV viewer's open thighs with her torso bent forward over his pelvis, " "both hands pushing her breasts inward around the POV viewer's penis, the penis held between her breasts in the lower foreground, " "her chin and lips directly above the glans at the tip." ) return ( f"{man} sits with legs apart while {woman} kneels low between his open thighs with her torso bent forward over his pelvis, " f"{woman}'s hands pushing her breasts inward around {man}'s penis, the penis held between her breasts, " "her chin and lips directly above the glans at the tip." ) if action_kind == outercourse_policy.OUTERCOURSE_TESTICLE: if man_is_pov: return ( f"{woman} bends forward and kneels very low between the POV viewer's open thighs with her shoulders between his knees, " "her face below the POV viewer's penis at testicle height, mouth and tongue on the POV viewer's balls, " "while his penis points upward in the lower foreground above her forehead." ) return ( f"{man} sits with legs apart while {woman} kneels very low between his open thighs with her torso bent forward and shoulders between his knees, " f"{woman}'s face below {man}'s penis at testicle height, mouth and tongue on his balls, while {man}'s penis points upward above her forehead." ) if action_kind == outercourse_policy.OUTERCOURSE_PENIS_LICKING: if man_is_pov: return ( f"{woman} bends forward between the POV viewer's open thighs with her head low under the POV viewer's penis, " "her face just under the penis while her tongue touches the underside from the base toward the glans at the tip, " "one hand steadying the base of the POV viewer's penis." ) return ( f"{woman} bends forward between {man}'s open thighs with her head low under {man}'s penis, " f"her face just under the penis while her tongue touches the underside from the base toward the glans at the tip, " f"one hand steadying the base of {man}'s penis." ) if action_kind == outercourse_policy.OUTERCOURSE_FOOTJOB: if man_is_pov: return ( f"{woman} faces the POV viewer with her hips back, torso visible behind her raised legs, and both knees bent open toward the camera, " "both soles wrapped around the POV viewer's penis shaft in the lower foreground." ) return ( f"{man} reclines with hips forward while {woman} faces him with her hips back and both knees bent open, " f"wrapping both soles around {man}'s penis shaft while the contact stays centered." ) if action_kind == outercourse_policy.OUTERCOURSE_HANDJOB: if man_is_pov: return ( f"{woman} kneels between the POV viewer's open thighs with her torso leaning forward and face visible behind the POV viewer's penis, " "one hand grips and strokes the POV viewer's penis in the lower foreground while the other hand steadies its base, " "thumb and fingers visible around the penis as she strokes toward the glans." ) return ( f"{woman} kneels between {man}'s open thighs with her torso leaning forward and face visible behind {man}'s penis, " f"one hand grips and strokes {man}'s penis while the other hand steadies its base, " "thumb and fingers visible around the penis as she strokes toward the glans." ) if man_is_pov: return ( f"{woman} kneels close to the POV viewer's hips and keeps the POV viewer's penis centered in clear non-penetrative contact, " "with her mouth, hands, breasts, or feet visibly working around the penis shaft." ) return ( f"{woman} kneels close to {man}'s hips and keeps {man}'s penis centered in clear non-penetrative contact, " "with her mouth, hands, breasts, or feet visibly working around the penis shaft." )