Repository Analysis

3b1b/manim

Animation engine for explanatory math videos

15.2 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of 3b1b/manim, a Python project with 88,507 GitHub stars. SynthScan v2.0 examined 25,622 lines of code across 111 source files, recording 393 pattern matches distributed across 12 syntactic categories. The overall adjusted score of 15.2 places this repository in the Moderate AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

15.2
Adjusted Score
15.2
Raw Score
100%
Time Factor
2026-07-02
Last Push
88.5K
Stars
Python
Language
25.6K
Lines of Code
111
Files
393
Pattern Hits
2026-07-14
Scan Date
0.01
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 0HIGH 1MEDIUM 7LOW 385

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 393 distinct pattern matches across 12 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Unused Imports176 hits · 152 pts
SeverityFileLineSnippetContext
LOWexample_scenes.py1CODE
LOWmanimlib/config.py1CODE
LOWmanimlib/window.py1CODE
LOWmanimlib/constants.py1CODE
LOWmanimlib/__init__.py17CODE
LOWmanimlib/__init__.py19CODE
LOWmanimlib/__init__.py21CODE
LOWmanimlib/__init__.py22CODE
LOWmanimlib/__init__.py23CODE
LOWmanimlib/__init__.py24CODE
LOWmanimlib/__init__.py25CODE
LOWmanimlib/__init__.py26CODE
LOWmanimlib/__init__.py27CODE
LOWmanimlib/__init__.py28CODE
LOWmanimlib/__init__.py29CODE
LOWmanimlib/__init__.py30CODE
LOWmanimlib/__init__.py31CODE
LOWmanimlib/__init__.py32CODE
LOWmanimlib/__init__.py33CODE
LOWmanimlib/__init__.py35CODE
LOWmanimlib/__init__.py37CODE
LOWmanimlib/__init__.py38CODE
LOWmanimlib/__init__.py39CODE
LOWmanimlib/__init__.py40CODE
LOWmanimlib/__init__.py41CODE
LOWmanimlib/__init__.py42CODE
LOWmanimlib/__init__.py43CODE
LOWmanimlib/__init__.py44CODE
LOWmanimlib/__init__.py45CODE
LOWmanimlib/__init__.py46CODE
LOWmanimlib/__init__.py47CODE
LOWmanimlib/__init__.py48CODE
LOWmanimlib/__init__.py49CODE
LOWmanimlib/__init__.py50CODE
LOWmanimlib/__init__.py51CODE
LOWmanimlib/__init__.py52CODE
LOWmanimlib/__init__.py53CODE
LOWmanimlib/__init__.py54CODE
LOWmanimlib/__init__.py55CODE
LOWmanimlib/__init__.py56CODE
LOWmanimlib/__init__.py57CODE
LOWmanimlib/__init__.py58CODE
LOWmanimlib/__init__.py59CODE
LOWmanimlib/__init__.py60CODE
LOWmanimlib/__init__.py61CODE
LOWmanimlib/__init__.py62CODE
LOWmanimlib/__init__.py63CODE
LOWmanimlib/__init__.py64CODE
LOWmanimlib/__init__.py65CODE
LOWmanimlib/__init__.py67CODE
LOWmanimlib/__init__.py68CODE
LOWmanimlib/__init__.py70CODE
LOWmanimlib/__init__.py71CODE
LOWmanimlib/__init__.py72CODE
LOWmanimlib/__init__.py73CODE
LOWmanimlib/__init__.py74CODE
LOWmanimlib/__init__.py75CODE
LOWmanimlib/__init__.py76CODE
LOWmanimlib/__init__.py77CODE
LOWmanimlib/__init__.py78CODE
116 more matches not shown…
Hyper-Verbose Identifiers133 hits · 135 pts
SeverityFileLineSnippetContext
LOWmanimlib/config.py268def update_file_writer_config(config: Dict, args: Namespace):CODE
LOWmanimlib/window.py120 def pixel_coords_to_space_coords(CODE
LOWmanimlib/extract_scene.py146def insert_embed_line_to_module(module: Module, run_config: Dict) -> None:CODE
LOWmanimlib/module_loader.py53 def _exec_module_and_track_imports(spec, module: Module) -> set[str]:CODE
LOWmanimlib/camera/camera_frame.py97 def get_inverse_camera_rotation_matrix(self):CODE
LOWmanimlib/camera/camera_frame.py251 def get_implied_camera_location(self) -> np.ndarray:CODE
LOWmanimlib/animation/transform_matching_parts.py101 def find_pairs_with_matching_shapes(CODE
LOWmanimlib/animation/animation.py113 def get_all_mobjects_to_update(self) -> list[Mobject]:CODE
LOWmanimlib/animation/transform.py83 def check_target_mobject_validity(self) -> None:CODE
LOWmanimlib/animation/composition.py90 def build_animations_with_timings(self, lag_ratio: float) -> None:CODE
LOWmanimlib/utils/rate_functions.py48def there_and_back_with_pause(t: float, pause_ratio: float = 1. / 3) -> float:CODE
LOWmanimlib/utils/bezier.py75def partial_quadratic_bezier_points(CODE
LOWmanimlib/utils/bezier.py117def set_array_by_interpolation(CODE
LOWmanimlib/utils/bezier.py174def quadratic_bezier_points_for_arc(angle: float, n_components: int = 8):CODE
LOWmanimlib/utils/bezier.py184def approx_smooth_quadratic_bezier_handles(CODE
LOWmanimlib/utils/bezier.py257def get_smooth_cubic_bezier_handle_points(CODE
LOWmanimlib/utils/bezier.py343def get_quadratic_approximation_of_cubic(CODE
LOWmanimlib/utils/bezier.py415def get_smooth_quadratic_bezier_path_through(CODE
LOWmanimlib/utils/space_ops.py98def quaternion_from_angle_axis(CODE
LOWmanimlib/utils/space_ops.py105def angle_axis_from_quaternion(quat: Vect4) -> Tuple[float, Vect3]:CODE
LOWmanimlib/utils/space_ops.py132def rotation_matrix_transpose_from_quaternion(quat: Vect4) -> Matrix3x3:CODE
LOWmanimlib/utils/space_ops.py136def rotation_matrix_from_quaternion(quat: Vect4) -> Matrix3x3:CODE
LOWmanimlib/utils/space_ops.py147def rotation_matrix_transpose(angle: float, axis: Vect3) -> Matrix3x3:CODE
LOWmanimlib/utils/space_ops.py356def get_closest_point_on_line(a: VectN, b: VectN, p: VectN) -> VectN:CODE
LOWmanimlib/utils/images.py17def get_full_raster_image_path(image_file_name: str) -> str:CODE
LOWmanimlib/utils/images.py25def get_full_vector_image_path(image_file_name: str) -> str:CODE
LOWmanimlib/utils/images.py33def get_full_three_d_model_path(model_file_name: str) -> str:CODE
LOWmanimlib/utils/family_ops.py11def extract_mobject_family_members(CODE
LOWmanimlib/utils/iterables.py108def resize_with_interpolation(nparray: np.ndarray, length: int) -> np.ndarray:CODE
LOWmanimlib/utils/shaders.py80def get_shader_code_from_file(filename: str) -> str | None:CODE
LOWmanimlib/scene/scene_file_writer.py94 def init_partial_movie_directory(self):CODE
LOWmanimlib/scene/scene_file_writer.py121 def get_next_partial_movie_path(self) -> str:CODE
LOWmanimlib/scene/scene_file_writer.py270 def set_progress_display_description(self, file: str = "", sub_desc: str = "") -> None:CODE
LOWmanimlib/scene/scene.py297 def get_mobject_family_members(self) -> list[Mobject]:CODE
LOWmanimlib/scene/scene.py496 def get_animation_time_progression(CODE
LOWmanimlib/scene/scene.py508 def get_wait_time_progression(CODE
LOWmanimlib/scene/scene.py555 def progress_through_animations(self, animations: Iterable[Animation]) -> None:CODE
LOWmanimlib/scene/scene.py640 def revert_to_original_skipping_status(self):CODE
LOWmanimlib/scene/interactive_scene.py145 def update_selection_rectangle(self, rect: Rectangle):CODE
LOWmanimlib/scene/interactive_scene.py161 def update_selection_highlight(self, highlight: Mobject):CODE
LOWmanimlib/scene/interactive_scene.py263 def regenerate_selection_search_set(self):CODE
LOWmanimlib/scene/interactive_scene.py591 def handle_sweeping_selection(self, point: Vect3):CODE
LOWmanimlib/scene/scene_embed.py39 def get_ipython_shell_for_embedded_scene(self) -> InteractiveShellEmbed:CODE
LOWmanimlib/scene/scene_embed.py95 def ensure_frame_update_post_cell(self):CODE
LOWmanimlib/mobject/matrix.py154 def add_background_to_entries(self) -> Self:CODE
LOWmanimlib/mobject/matrix.py167 def swap_entries_for_ellipses(CODE
LOWmanimlib/mobject/vector_field.py34def get_vectorized_rgb_gradient_function(CODE
LOWmanimlib/mobject/vector_field.py57def get_rgb_gradient_function(CODE
LOWmanimlib/mobject/vector_field.py89def move_submobjects_along_vector_field(CODE
LOWmanimlib/mobject/vector_field.py103def move_points_along_vector_field(CODE
LOWmanimlib/mobject/vector_field.py231 def init_base_stroke_width_array(self, n_sample_points):CODE
LOWmanimlib/mobject/boolean_ops.py12def _convert_vmobject_to_skia_path(vmobject: VMobject) -> pathops.Path:CODE
LOWmanimlib/mobject/boolean_ops.py26def _convert_skia_path_to_vmobject(CODE
LOWmanimlib/mobject/numbers.py80 def set_submobjects_from_number(self, number: float | complex) -> None:CODE
LOWmanimlib/mobject/numbers.py217 def _handle_scale_side_effects(self, scale_factor: float) -> Self:CODE
LOWmanimlib/mobject/interactive.py520 def move_panel_and_controls_to_panel_opener(self) -> None:CODE
LOWmanimlib/mobject/interactive.py558 def panel_opener_on_mouse_drag(self, mob, event_data: dict[str, np.ndarray]) -> bool:CODE
LOWmanimlib/mobject/geometry.py116 def reset_endpoints_based_on_tip(self, tip: ArrowTip, at_start: bool) -> Self:CODE
LOWmanimlib/mobject/geometry.py798 def set_perpendicular_to_camera(self, camera_frame):CODE
LOWmanimlib/mobject/geometry.py996 def create_tip_with_stroke_width(self) -> Self:CODE
73 more matches not shown…
AI Structural Patterns33 hits · 32 pts
SeverityFileLineSnippetContext
LOWmanimlib/shader_wrapper.py233CODE
LOWmanimlib/camera/camera.py26CODE
LOWmanimlib/animation/animation.py24CODE
LOWmanimlib/animation/specialized.py17CODE
LOWmanimlib/utils/color.py163CODE
LOWmanimlib/scene/scene_file_writer.py29CODE
LOWmanimlib/scene/scene.py64CODE
LOWmanimlib/mobject/matrix.py25CODE
LOWmanimlib/mobject/vector_field.py52CODE
LOWmanimlib/mobject/vector_field.py142CODE
LOWmanimlib/mobject/vector_field.py338CODE
LOWmanimlib/mobject/numbers.py35CODE
LOWmanimlib/mobject/interactive.py383CODE
LOWmanimlib/mobject/geometry.py539CODE
LOWmanimlib/mobject/geometry.py1077CODE
LOWmanimlib/mobject/number_line.py28CODE
LOWmanimlib/mobject/number_line.py245CODE
LOWmanimlib/mobject/probability.py197CODE
LOWmanimlib/mobject/coordinate_systems.py363CODE
LOWmanimlib/mobject/coordinate_systems.py446CODE
LOWmanimlib/mobject/mobject.py538CODE
LOWmanimlib/mobject/svg/drawings.py189CODE
LOWmanimlib/mobject/svg/drawings.py358CODE
LOWmanimlib/mobject/svg/drawings.py594CODE
LOWmanimlib/mobject/svg/drawings.py688CODE
LOWmanimlib/mobject/svg/svg_mobject.py58CODE
LOWmanimlib/mobject/svg/string_mobject.py46CODE
LOWmanimlib/mobject/svg/text_mobject.py136CODE
LOWmanimlib/mobject/svg/old_tex_mobject.py23CODE
LOWmanimlib/mobject/svg/tex_mobject.py38CODE
LOWmanimlib/mobject/types/vectorized_mobject.py79CODE
LOWmanimlib/mobject/types/vectorized_mobject.py215CODE
LOWmanimlib/mobject/types/surface.py44CODE
Modern Structural Boilerplate20 hits · 20 pts
SeverityFileLineSnippetContext
LOWmanimlib/logger.py5__all__ = ["log"]CODE
LOWmanimlib/shader_wrapper.py144 def set_ctx_depth_test(self, enable: bool = True) -> None:CODE
LOWmanimlib/shader_wrapper.py150 def set_ctx_clip_plane(self, num_planes: int = 0) -> None:CODE
LOWmanimlib/animation/creation.py199 def update_submobject_list(self, index: int) -> None:CODE
LOWmanimlib/animation/creation.py212 def update_submobject_list(self, index: int) -> None:CODE
LOWmanimlib/animation/animation.py105 def update_mobjects(self, dt: float) -> None:CODE
LOWmanimlib/animation/transform.py95 def update_config(self, **kwargs) -> None:CODE
LOWmanimlib/animation/composition.py78 def update_mobjects(self, dt: float) -> None:CODE
LOWmanimlib/animation/composition.py141 def update_mobjects(self, dt: float) -> None:CODE
LOWmanimlib/scene/scene_file_writer.py270 def set_progress_display_description(self, file: str = "", sub_desc: str = "") -> None:CODE
LOWmanimlib/scene/scene.py236 def update_frame(self, dt: float = 0, force_draw: bool = False) -> None:CODE
LOWmanimlib/scene/scene.py264 def update_mobjects(self, dt: float) -> None:CODE
LOWmanimlib/scene/scene.py450 def update_skipping_status(self) -> None:CODE
LOWmanimlib/scene/scene.py876 def set_background_color(self, background_color, background_opacity=1) -> None:CODE
LOWmanimlib/mobject/numbers.py80 def set_submobjects_from_number(self, number: float | complex) -> None:CODE
LOWmanimlib/mobject/interactive.py124 def set_value_anim(self, value: bool) -> None:CODE
LOWmanimlib/mobject/interactive.py176 def set_value_anim(self, value: bool) -> None:CODE
LOWmanimlib/mobject/interactive.py257 def set_value_anim(self, value: float) -> None:CODE
LOWmanimlib/mobject/interactive.py419 def set_value_anim(self, value: str) -> None:CODE
LOWmanimlib/mobject/interactive.py422 def update_text(self, value: str) -> None:CODE
Self-Referential Comments5 hits · 16 pts
SeverityFileLineSnippetContext
MEDIUMmanimlib/__main__.py24 # Create a new dict to be able to upate withoutCOMMENT
MEDIUMmanimlib/__main__.py30 # Create a reusable windowCOMMENT
MEDIUMmanimlib/animation/indication.py235 # Create a gaussian such that 3 sigmas out on either sideCOMMENT
MEDIUMmanimlib/utils/tex_file_writing.py98 temp_dir.mkdir(exist_ok=True) # Create the directory if it does not already existCODE
MEDIUMmanimlib/mobject/numbers.py81 # Create the submobject listCOMMENT
Deep Nesting15 hits · 14 pts
SeverityFileLineSnippetContext
LOWmanimlib/module_loader.py139CODE
LOWmanimlib/event_handler/event_dispatcher.py37CODE
LOWmanimlib/scene/scene_file_writer.py349CODE
LOWmanimlib/scene/scene.py827CODE
LOWmanimlib/scene/interactive_scene.py413CODE
LOWmanimlib/scene/interactive_scene.py487CODE
LOWmanimlib/scene/interactive_scene.py560CODE
LOWmanimlib/mobject/boolean_ops.py26CODE
LOWmanimlib/mobject/interactive.py445CODE
LOWmanimlib/mobject/coordinate_systems.py363CODE
LOWmanimlib/mobject/svg/svg_mobject.py203CODE
LOWmanimlib/mobject/svg/text_mobject.py319CODE
LOWmanimlib/mobject/svg/old_tex_mobject.py153CODE
LOWmanimlib/mobject/svg/tex_mobject.py92CODE
LOWmanimlib/mobject/types/vectorized_mobject.py694CODE
Redundant / Tautological Comments4 hits · 6 pts
SeverityFileLineSnippetContext
LOWmanimlib/default_config.yml12 # Set this to true if you want the path to video filesCOMMENT
LOWmanimlib/utils/file_ops.py31 # Check if this is a file online first, and if so, downloadCOMMENT
LOWmanimlib/utils/file_ops.py44 # Check if what was passed in is already a valid path to a fileCOMMENT
LOWmanimlib/mobject/mobject.py907 # Check if mark as static or not for cameraCOMMENT
Docstring Block Structure1 hit · 5 pts
SeverityFileLineSnippetContext
HIGHmanimlib/utils/tex_file_writing.py58Convert LaTeX string to SVG string. Args: latex: LaTeX source code template: Path to a template LaTSTRING
Slop Phrases2 hits · 4 pts
SeverityFileLineSnippetContext
MEDIUMexample_scenes.py300 # If the argument itself might change, you can use f_always,STRING
MEDIUMmanimlib/mobject/svg/old_tex_mobject.py111 # tex == "\\frac", # you can use \\over as a alternativeCOMMENT
Excessive Try-Catch Wrapping2 hits · 2 pts
SeverityFileLineSnippetContext
LOWmanimlib/config.py260 except Exception as err:CODE
LOWmanimlib/scene/scene_embed.py135 except Exception as e:CODE
AI Slop Vocabulary1 hit · 2 pts
SeverityFileLineSnippetContext
LOWmanimlib/mobject/mobject.py1783 # If empty, simply add n point mobjectsCOMMENT
Over-Commented Block1 hit · 1 pts
SeverityFileLineSnippetContext
LOWmanimlib/default_config.yml1# This file determines the default configuration for how manim isCOMMENT