# FlowOps — Motor de Enrutamiento Inteligente
# Manim CE | manim -qh flowops_routing.py FlowOpsRouting
from manim import *
class FlowOpsRouting(Scene):
def construct(self):
# ── Paleta ─────────────────────────────────────────
BG = "#0F172A"
GREEN = "#22C55E"
AMBER = "#F59E0B"
BLUE = "#3B82F6"
MUTED = "#64748B"
self.camera.background_color = BG
# ── ESCENA 1: El caos ───────────────────────────────
tickets = VGroup(*[
RoundedRectangle(width=1.6, height=0.7, corner_radius=0.08,
color=BLUE, fill_color="#1E3A5F", fill_opacity=1)
for _ in range(4)
]).arrange(RIGHT, buff=0.3).to_edge(UP, buff=1)
labels = VGroup(*[
Text(f"#104{i+2}", font_size=18, color=MUTED).move_to(t)
for i, t in enumerate(tickets)
])
inbox = RoundedRectangle(width=8, height=1.2, corner_radius=0.15,
color=MUTED, fill_color="#1E293B", fill_opacity=1).to_edge(DOWN, buff=1.5)
inbox_txt = Text("BANDEJA DE ENTRADA", font_size=24, color=MUTED).move_to(inbox)
self.play(FadeIn(tickets, shift=DOWN*0.3), FadeIn(labels))
self.play(Create(inbox), Write(inbox_txt))
arrows_in = VGroup(*[Arrow(t.get_bottom(), inbox.get_top(), buff=0.1,
color=BLUE, stroke_width=2) for t in tickets])
self.play(Create(arrows_in))
self.wait(1)
self.play(*[FadeOut(m) for m in [tickets, labels, inbox, inbox_txt, arrows_in]])
# ── ESCENA 2: Detección ─────────────────────────────
ticket_in = RoundedRectangle(width=1.8, height=0.9, corner_radius=0.1,
color=BLUE, fill_color="#1E3A5F", fill_opacity=1).to_edge(LEFT, buff=1.2)
t_label = Text("#1046", font_size=22, color=BLUE).move_to(ticket_in)
detector = RoundedRectangle(width=2.4, height=1.6, corner_radius=0.15,
color=AMBER, fill_color="#1E293B", fill_opacity=1).move_to(ORIGIN)
det_txt = Text("DETECTOR", font_size=22, color=AMBER).move_to(detector)
tags = VGroup(
Text("🔴 Urgente", font_size=18, color="#EF4444"),
Text("🔧 Técnico", font_size=18, color=BLUE),
Text("💬 Chat", font_size=18, color=GREEN),
Text("⭐ Pro plan", font_size=18, color=AMBER),
).arrange(DOWN, buff=0.25).to_edge(RIGHT, buff=1.5)
self.play(FadeIn(ticket_in), FadeIn(t_label))
self.play(Create(detector), Write(det_txt))
arrow1 = Arrow(ticket_in.get_right(), detector.get_left(), color=BLUE, buff=0.1)
self.play(GrowArrow(arrow1))
for tag in tags:
self.play(FadeIn(tag, shift=RIGHT*0.2), run_time=0.4)
self.wait(0.8)
self.play(*[FadeOut(m) for m in [ticket_in, t_label, detector, det_txt, arrow1, tags]])
# ── ESCENA 3: Árbol de decisión ─────────────────────
# ... (ver repo completo) ...
# ── ESCENA 5: Asignación ─────────────────────────────
timer_val = ValueTracker(0)
timer_disp = always_redraw(lambda: DecimalNumber(
timer_val.get_value(), num_decimal_places=1,
color=GREEN, font_size=60).move_to(DOWN*1.5))
unit_txt = Text(" s", font_size=48, color=MUTED).next_to(timer_disp, RIGHT)
self.add(timer_disp)
self.play(FadeIn(unit_txt),
timer_val.animate.set_value(1.4), run_time=1.4)
flash_txt = Text("⚡ Asignado", font_size=40, color=GREEN).to_edge(UP)
self.play(FadeIn(flash_txt, scale=1.3))
self.wait(1)