← back to doooooraku__video

Function bodies 28 total

All specs Real LLM only Function bodies
getDummyReports function · typescript · L405-L412 (8 LOC)
apps/Repolog/src/AppMockupVideo.tsx
function getDummyReports(locale: 'ja' | 'en', dummyDay: number): DummyReport[] {
  const allReports = locale === 'ja' ? jaReports : enReports;
  const target = allReports.find((r) => r.day === dummyDay);
  if (!target) return allReports.slice(0, 3);
  // Return the target + 2 surrounding reports for list views
  const idx = allReports.indexOf(target);
  return [target, ...allReports.filter((_, i) => i !== idx).slice(0, 2)];
}
withVariantB function · typescript · L5-L7 (3 LOC)
apps/Repolog/src/i18n/variants.ts
export function withVariantB<
  T extends { hookSubtitle: string; variant?: string },
>(props: T, hookSubtitle: string): T & { variant: 'B' } {
ratioToY function · typescript · L75-L77 (3 LOC)
packages/core/src/constants/design-tokens.ts
export function ratioToY(ratio: number): number {
  return Math.round(ratio * VIDEO_HEIGHT);
}
useLocale function · typescript · L3-L11 (9 LOC)
packages/core/src/hooks/useLocale.ts
export function useLocale(locale: Locale) {
  const isJapanese = locale === 'ja';
  return {
    locale,
    isJapanese,
    isEnglish: !isJapanese,
    fontWeight: isJapanese ? 700 : 800,
  };
}
useSceneTiming function · typescript · L18-L39 (22 LOC)
packages/core/src/hooks/useSceneTiming.ts
export function useSceneTiming(timing: SceneTiming): SceneFrames {
  return useMemo(() => {
    const fps = VIDEO_FPS;
    const hookDuration = secToFrames(timing.hookDurationSec, fps);
    const demoDuration = secToFrames(timing.demoDurationSec, fps);
    const resultsDuration = secToFrames(timing.resultsDurationSec, fps);
    const ctaDuration = secToFrames(timing.ctaDurationSec, fps);

    return {
      hookStart: 0,
      hookDuration,
      demoStart: hookDuration,
      demoDuration,
      resultsStart: hookDuration + demoDuration,
      resultsDuration,
      ctaStart: hookDuration + demoDuration + resultsDuration,
      ctaDuration,
      totalDuration:
        hookDuration + demoDuration + resultsDuration + ctaDuration,
    };
  }, [timing]);
}
useTransitionTiming function · typescript · L27-L40 (14 LOC)
packages/core/src/hooks/useTransitionTiming.ts
export function useTransitionTiming(timing: SceneTiming): TransitionFrames {
  const base = useSceneTiming(timing);
  return useMemo(() => {
    const tf = TRANSITIONS.durationFrames;
    return {
      ...base,
      transitionFrames: tf,
      hookVisualDuration: base.hookDuration + tf,
      demoVisualDuration: base.demoDuration + tf,
      resultsVisualDuration: base.resultsDuration + tf,
      ctaVisualDuration: base.ctaDuration,
    };
  }, [base]);
}
t function · typescript · L11-L13 (3 LOC)
packages/core/src/i18n/strings.ts
export function t(key: keyof typeof strings, locale: Locale): string {
  return strings[key][locale];
}
All rows scored by the Repobility analyzer (https://repobility.com)
useSlideIn function · typescript · L4-L24 (21 LOC)
packages/core/src/utils/animations.ts
export function useSlideIn(
  direction: 'left' | 'right' | 'up' | 'down' = 'up',
  delay: number = 0,
) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const progress = spring({ frame: frame - delay, fps, durationInFrames: 20 });
  const distance = 100;

  const offsets = {
    left: { x: interpolate(progress, [0, 1], [-distance, 0]), y: 0 },
    right: { x: interpolate(progress, [0, 1], [distance, 0]), y: 0 },
    up: { x: 0, y: interpolate(progress, [0, 1], [distance, 0]) },
    down: { x: 0, y: interpolate(progress, [0, 1], [-distance, 0]) },
  };

  return {
    transform: `translate(${offsets[direction].x}px, ${offsets[direction].y}px)`,
    opacity: progress,
  };
}
useFadeIn function · typescript · L26-L31 (6 LOC)
packages/core/src/utils/animations.ts
export function useFadeIn(delay: number = 0) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const opacity = spring({ frame: frame - delay, fps, durationInFrames: 15 });
  return { opacity };
}
useScale function · typescript · L33-L42 (10 LOC)
packages/core/src/utils/animations.ts
export function useScale(delay: number = 0) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const scale = spring({
    frame: frame - delay,
    fps,
    config: { damping: 12 },
  });
  return { transform: `scale(${scale})` };
}
useAnticipateScale function · typescript · L49-L82 (34 LOC)
packages/core/src/utils/animations.ts
export function useAnticipateScale(delay: number = 0) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const relFrame = frame - delay;

  const { scaleDip, durationFrames: dipDur } = ANIMATION.anticipation;

  // Phase 1: dip (0 → scaleDip over dipDur frames)
  const dipProgress = interpolate(relFrame, [0, dipDur], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });

  // Phase 2: spring from scaleDip to overshoot → 1.0
  const springProgress = spring({
    frame: relFrame - dipDur,
    fps,
    config: ANIMATION.spring.bouncy,
  });

  const scale =
    relFrame <= 0
      ? 0
      : relFrame <= dipDur
        ? interpolate(dipProgress, [0, 1], [0, scaleDip])
        : interpolate(springProgress, [0, 1], [scaleDip, 1]);

  const opacity = interpolate(relFrame, [0, 3], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });

  return { transform: `scale(${scale})`, opacity };
}
useStaggeredEntrance function · typescript · L87-L105 (19 LOC)
packages/core/src/utils/animations.ts
export function useStaggeredEntrance(
  index: number,
  staggerFrames: number = ANIMATION.stagger.default,
) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const delay = index * staggerFrames;
  const progress = spring({
    frame: frame - delay,
    fps,
    config: ANIMATION.spring.default,
  });
  const y = interpolate(progress, [0, 1], [ANIMATION.slideUp.distance, 0]);

  return {
    transform: `translateY(${y}px)`,
    opacity: progress,
  };
}
usePopIn function · typescript · L111-L125 (15 LOC)
packages/core/src/utils/animations.ts
export function usePopIn(delay: number = 0) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const progress = spring({
    frame: frame - delay,
    fps,
    config: ANIMATION.spring.snappy,
  });
  const scale = interpolate(progress, [0, 1], [0, 1]);

  return {
    transform: `scale(${scale})`,
    opacity: progress,
  };
}
secToFrames function · typescript · L3-L5 (3 LOC)
packages/core/src/utils/timing.ts
export function secToFrames(seconds: number, fps: number = VIDEO_FPS): number {
  return Math.round(seconds * fps);
}
framesToSec function · typescript · L7-L9 (3 LOC)
packages/core/src/utils/timing.ts
export function framesToSec(frames: number, fps: number = VIDEO_FPS): number {
  return frames / fps;
}
Repobility · MCP-ready · https://repobility.com
pickText function · typescript · L73-L79 (7 LOC)
scripts/convert-brief.ts
function pickText(
  ja: string,
  en: string | undefined,
  locale: 'ja' | 'en',
): string {
  return locale === 'en' && en ? en : ja;
}
buildProps function · typescript · L81-L155 (75 LOC)
scripts/convert-brief.ts
function buildProps(locale: 'ja' | 'en'): Record<string, unknown> {
  const sceneTiming = {
    hookDurationSec: brief.scenes.hook.duration_sec ?? 5,
    demoDurationSec: brief.scenes.demo.duration_sec ?? 13,
    resultsDurationSec: brief.scenes.results.duration_sec ?? 5,
    ctaDurationSec: brief.scenes.cta.duration_sec ?? 5,
  };

  return {
    appName: brief.app.name,
    appTagline: brief.app.tagline,
    locale,
    accentColor: brief.style?.accent_color ?? '#6366F1',
    backgroundColor: brief.style?.background_color ?? '#0F172A',
    appIconPath: brief.app.icon || undefined,
    screenRecordingPath: brief.assets.screen_recording ?? undefined,
    screenshotPaths: brief.assets.screenshots,
    hookSubtitle:
      variant === 'B'
        ? pickText(
            brief.scenes.hook.subtitle_variant_b ?? brief.scenes.hook.subtitle,
            brief.scenes.hook.subtitle_en_variant_b ??
              brief.scenes.hook.subtitle_en,
            locale,
          )
        : pickText(
  
withComment function · typescript · L192-L197 (6 LOC)
scripts/convert-brief.ts
function withComment(props: Record<string, unknown>): Record<string, unknown> {
  return {
    _comment: `DO NOT EDIT — auto-generated from video-brief.yaml. Run: npx tsx scripts/convert-brief.ts ${appName}`,
    ...props,
  };
}
generateProps function · typescript · L104-L195 (92 LOC)
scripts/generate-day-props.ts
function generateProps(locale: 'ja' | 'en'): string {
  const isJa = locale === 'ja';
  const varName = `day${dayPadded}${isJa ? 'Ja' : 'En'}Props`;

  const pick = (ja: string, en?: string) => (isJa ? ja : en || ja);

  const hookSubtitle = pick(
    brief.scenes.hook.subtitle,
    brief.scenes.hook.subtitle_en,
  );
  const demoSubtitles = brief.scenes.demo.steps.map((s) =>
    pick(s.subtitle, s.subtitle_en),
  );
  const resultsSubtitle = pick(
    brief.scenes.results.subtitle,
    brief.scenes.results.subtitle_en,
  );
  const ctaSubtitle = pick(
    brief.scenes.cta.subtitle,
    brief.scenes.cta.subtitle_en,
  );
  const demoIcons = brief.scenes.demo.steps.map((s) => s.icon || 'document');
  const hookIcon = brief.scenes.hook.icon || 'document';

  const hookVariantB = pick(
    brief.scenes.hook.subtitle_variant_b || '',
    brief.scenes.hook.subtitle_en_variant_b || '',
  );

  const accentColor = brief.style?.accent_color || '#39FF14';
  const bgColor = brief.style?.backgrou
escTs function · typescript · L197-L199 (3 LOC)
scripts/generate-day-props.ts
function escTs(s: string): string {
  return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
}
regenerateDayConfigs function · typescript · L218-L302 (85 LOC)
scripts/generate-day-props.ts
function regenerateDayConfigs() {
  const files = fs
    .readdirSync(i18nDir)
    .filter((f) => /^day\d+-ja\.ts$/.test(f))
    .sort();
  const days = files
    .map((f) => {
      const match = f.match(/^day(\d+)-ja\.ts$/);
      return match ? parseInt(match[1], 10) : 0;
    })
    .filter((d) => d > 0);

  const imports: string[] = [];
  const variantA: string[] = [];
  const variantB: string[] = [];

  for (const d of days) {
    const dp = String(d).padStart(2, '0');
    const jaVar = `day${dp}JaProps`;
    const enVar = `day${dp}EnProps`;

    imports.push(`import { ${jaVar} } from './day${dp}-ja';`);
    imports.push(`import { ${enVar} } from './day${dp}-en';`);

    variantA.push(`  { id: 'Day${dp}-JA', props: ${jaVar} },`);
    variantA.push(`  { id: 'Day${dp}-EN', props: ${enVar} },`);

    // Read variant B subtitle from YAML brief (source of truth)
    const dayBriefPath = path.join(appDir, 'briefs', `day${dp}.yaml`);
    let jaVariantB = '';
    let enVariantB = '';
    
load_model function · python · L96-L121 (26 LOC)
scripts/generate-narration.py
def load_model():
    """Qwen3-TTS モデルをロードする。"""
    from qwen_tts import Qwen3TTSModel

    print(f"[TTS] モデルをロード中: {MODEL_NAME}")

    try:
        import flash_attn  # noqa: F401
        attn_impl = "flash_attention_2"
        print("[TTS] FlashAttention 2 を使用します(高速モード)")
    except ImportError:
        attn_impl = "eager"
        print("[TTS] FlashAttention 2 未検出。eager モードで実行(やや低速)")

    model = Qwen3TTSModel.from_pretrained(
        MODEL_NAME,
        device_map="cuda:0",
        dtype=torch.bfloat16,
        attn_implementation=attn_impl,
    )

    print("[TTS] モデルロード完了")
    print(f"[TTS] 生成パラメータ: temperature={STABLE_GEN_KWARGS['temperature']}, "
          f"top_p={STABLE_GEN_KWARGS['top_p']}, top_k={STABLE_GEN_KWARGS['top_k']}, "
          f"repetition_penalty={STABLE_GEN_KWARGS['repetition_penalty']}")
    return model
generate_audio function · python · L124-L149 (26 LOC)
scripts/generate-narration.py
def generate_audio(model, text: str, locale: str, seed: int) -> tuple:
    """テキストから音声を生成する。

    引数:
        model:  Qwen3TTSModel インスタンス
        text:   読み上げるテキスト
        locale: "ja" または "en"
        seed:   乱数シード

    戻り値:
        (waveform, sample_rate): NumPy配列とサンプルレート
    """
    config = VOICE_CONFIG[locale]

    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)

    wavs, sr = model.generate_custom_voice(
        text=text,
        language=config["language"],
        speaker=config["speaker"],
        instruct=config["instruct"],
        **STABLE_GEN_KWARGS,
    )

    return wavs[0], sr
Repobility · code-quality intelligence · https://repobility.com
generate_audio_with_retry function · python · L152-L200 (49 LOC)
scripts/generate-narration.py
def generate_audio_with_retry(
    model, text: str, locale: str, max_duration_sec: float
) -> tuple:
    """リトライ付きで音声を生成する。

    音声がシーン尺の MAX_DURATION_MULTIPLIER 倍を超えた場合、
    異なるシードで再生成を試みる(最大 MAX_RETRIES 回)。

    引数:
        model:            Qwen3TTSModel インスタンス
        text:             読み上げるテキスト
        locale:           "ja" または "en"
        max_duration_sec: シーンの最大秒数

    戻り値:
        (waveform, sample_rate): 最も適切な音声
    """
    duration_limit = max_duration_sec * MAX_DURATION_MULTIPLIER
    best_waveform = None
    best_sr = None
    best_duration = float("inf")

    for attempt in range(MAX_RETRIES):
        seed = BASE_SEED + attempt
        waveform, sr = generate_audio(model, text, locale, seed)
        duration = len(waveform) / sr

        if duration <= duration_limit:
            # 許容範囲内ならそのまま返す
            if attempt > 0:
                print(f"    リトライ {attempt + 1}/{MAX_RETRIES}: {duration:.1f}秒 → OK")
            return waveform, sr

        # 範囲外でも、これまでで最短なら記録
   
get_audio_duration function · python · L203-L205 (3 LOC)
scripts/generate-narration.py
def get_audio_duration(waveform, sample_rate: int) -> float:
    """音声の長さ(秒)を計算する。"""
    return len(waveform) / sample_rate
save_audio function · python · L208-L214 (7 LOC)
scripts/generate-narration.py
def save_audio(waveform, sample_rate: int, output_path: str):
    """音声を WAV ファイルとして保存する。"""
    os.makedirs(os.path.dirname(output_path), exist_ok=True)
    sf.write(output_path, waveform, sample_rate)
    duration = get_audio_duration(waveform, sample_rate)
    print(f"  保存: {output_path} ({duration:.1f}秒)")
    return duration
extract_scenes_from_brief function · python · L217-L287 (71 LOC)
scripts/generate-narration.py
def extract_scenes_from_brief(brief: dict, locale: str, narration_dir: Path) -> list:
    """YAML ブリーフファイルからシーン情報を抽出する。

    引数:
        brief:         YAML をパースした辞書
        locale:        "ja" または "en"
        narration_dir: WAV ファイルの出力ディレクトリ

    戻り値:
        シーンのリスト(main() の scenes と同じ形式)
    """
    scenes_data = brief.get("scenes", {})
    scenes = []

    # ロケールに応じてナレーション/字幕フィールド名を決定
    narration_key = "narration" if locale == "ja" else "narration_en"
    subtitle_key = "subtitle" if locale == "ja" else "subtitle_en"

    # シーン1: Hook
    hook = scenes_data.get("hook", {})
    hook_text = hook.get(narration_key) or hook.get(subtitle_key)
    if hook_text:
        scenes.append({
            "name": "hook",
            "text": hook_text,
            "output": str(narration_dir / "hook.wav"),
            "props_key": "hookNarrationPath",
            "duration_sec": hook.get("duration_sec", 5),
        })

    # シーン2: Demo (複数ステップ)
    demo = scenes_data.get("demo", {})
    steps =
main function · python · L290-L501 (212 LOC)
scripts/generate-narration.py
def main():
    parser = argparse.ArgumentParser(
        description="Qwen3-TTS でナレーション音声を生成する"
    )
    parser.add_argument("app_name", help="アプリ名 (例: Repolog)")
    parser.add_argument(
        "--locale",
        choices=["ja", "en"],
        required=True,
        help="言語 (ja=日本語, en=英語)",
    )
    parser.add_argument(
        "--validate-timing",
        action="store_true",
        help="音声の長さとシーン尺のバリデーションを行う",
    )
    parser.add_argument(
        "--root-dir",
        default=None,
        help="プロジェクトルートディレクトリ (デフォルト: スクリプトの親ディレクトリ)",
    )
    parser.add_argument(
        "--brief",
        default=None,
        help=(
            "YAML ブリーフファイルのパス (例: briefs/day01.yaml)。"
            "指定時は JSON props の代わりに YAML からテキストを読み込む。"
            "相対パスはアプリディレクトリからの相対パスとして解決される。"
        ),
    )
    args = parser.parse_args()

    # パスの解決
    script_dir = Path(__file__).resolve().parent
    root_dir = Path(args.root_dir) if args.root_dir else script_dir.parent
    app_dir = root_