소스 검색

feat(api-v13): related_paragraphs 重建工具链与第一版导出

从 wbw_templates 的 .ctl. 锚点重放 related_paragraphs,取代已失效的
cs6_para.csv 导入链路。原则是「查不到优于查到错」:任何一处判不定就留 cs=0
不赋值,绝不沿用上一个 cs——旧链路翻车的地方全在这条原则上。

工具链按「导出 → 检测 → 归因 → 改规则」迭代设计,脚本留在 scripts/ 而不是
app/Console/Commands/,稳定后再收编成 artisan command。

第一版成绩(related_paragraphs_v1,638076 行,与旧表逐段落 91.8% 相同):
- E1 cs 乱码 1242 行 → 0
- E3 kn10 家族 0 行 → 25506 行,kn10_A/kn10_B 清零
- E6 覆盖缺口 3464 段 → 1 段
- E7 缩写区间丢失 1292 段 + 225 段废值 → 0 + 0
- E8 书边界污染平铺 1499 行 → 0
- 区间标记展开不符 1611 → 0,镜像判据四组保持
- 零错误信号的书 128 本 → 148 本

迭代中查实的、与设计文档不符之处:
- cs6_para.csv 并未丢失(clove 仓库里,523283 行),是现表来源且含全部历史错误,
  故只作 diff 基线与 book 129 的回填源,不作生成源
- 段落全集应取 pali_texts(523284 段)而非 wbw_templates,后者少 7171 段
- para504-407 型倒序区间是高位笔误,低位可还原(504-507),前后邻标记可验证;
  其丢段发生在导入环节的 for ($i=504; $i<=407; $i++) 空转,不在生成环节
- E8 判据过宽:按 cs 值种类判会把章回绕误报成污染,真污染只有 book 207 一段
- book 107 整本属 kn10(para 2146 标题为「(Dutiyo bhāgo) Therāpadānaṃ」,
  是第二卷而非 therī),已记入 book_config.json 的 overrides
- book 177 内含四部书,仅首部为 abhi8

生产表已备份为 related_paragraphs_bak_20260909,本次不改动任何现有表。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcQqZgKWhw5HKRj2GDn21h
visuddhinanda 1 개월 전
부모
커밋
6e63b04ded

+ 3 - 0
api-v13/scripts/related/.gitignore

@@ -0,0 +1,3 @@
+report/
+data/cs6_para.csv
+data/backup/

+ 103 - 0
api-v13/scripts/related/backup.php

@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * 备份生产 related_paragraphs:库内快照表 + 库外 csv 存档 + 清单。
+ *
+ * 用法:
+ *   php scripts/related/backup.php                 # 表名自动带当天日期
+ *   php scripts/related/backup.php --tag=20260909  # 指定后缀
+ *   php scripts/related/backup.php --force         # 快照表已存在时覆盖
+ *
+ * 这是整个重建工程唯一允许写生产库的脚本,而且只做 CREATE TABLE AS,不改原表。
+ */
+
+require __DIR__.'/lib/boot.php';
+
+use Illuminate\Support\Facades\DB;
+
+[$options] = rp_args($argv);
+
+$source = 'related_paragraphs';
+$tag = $options['tag'] ?? date('Ymd');
+$snapshot = rp_assert_table("related_paragraphs_bak_$tag");
+$log = new RpLogger('backup', rp_report_dir());
+
+$log->info("源表:$source");
+$log->info("快照表:$snapshot");
+
+$sourceCount = DB::table($source)->count();
+$log->info("源表行数:$sourceCount");
+if ($sourceCount === 0) {
+    $log->error('源表为空,拒绝备份——这几乎一定是连错库了。');
+    $log->finish();
+    exit(1);
+}
+
+$exists = DB::selectOne('select to_regclass(?) as reg', [$snapshot])->reg !== null;
+if ($exists) {
+    if (! isset($options['force'])) {
+        $existing = DB::table($snapshot)->count();
+        $log->error("快照表已存在($existing 行)。要覆盖请加 --force。");
+        $log->finish();
+        exit(1);
+    }
+    $log->warn('快照表已存在,--force 生效,先 DROP。');
+    DB::statement("drop table $snapshot");
+}
+
+$log->info('建快照表中…');
+DB::statement("create table $snapshot as select * from $source");
+$snapshotCount = DB::table($snapshot)->count();
+$log->info("快照表行数:$snapshotCount");
+
+if ($snapshotCount !== $sourceCount) {
+    $log->error("行数不一致:源 $sourceCount vs 快照 $snapshotCount");
+    $log->finish();
+    exit(1);
+}
+
+// 快照表只用于比对,建最小索引即可(按 book/para 定位、按 book_name+cs_para 配对)。
+$log->info('建索引中…');
+DB::statement("create index on $snapshot (book, para)");
+DB::statement("create index on $snapshot (book_name, cs_para)");
+
+// 库外存档:库没了也能拿回数据。
+$archiveDir = rp_data_dir().'/backup';
+if (! is_dir($archiveDir)) {
+    mkdir($archiveDir, 0o755, true);
+}
+$csvPath = "$archiveDir/$snapshot.csv";
+$log->info("导出 csv:$csvPath");
+
+$handle = fopen($csvPath, 'w');
+fputcsv($handle, ['book', 'para', 'book_id', 'cs_para', 'book_name']);
+$rows = 0;
+DB::table($source)->orderBy('book')->orderBy('para')->orderBy('cs_para')->orderBy('id')
+    ->select('book', 'para', 'book_id', 'cs_para', 'book_name')
+    ->chunk(20000, function ($chunk) use ($handle, &$rows, $log) {
+        foreach ($chunk as $row) {
+            fputcsv($handle, [$row->book, $row->para, $row->book_id, $row->cs_para, $row->book_name]);
+            $rows++;
+        }
+        if ($rows % 200000 === 0) {
+            $log->info("  已导出 $rows 行");
+        }
+    });
+fclose($handle);
+$log->info("csv 行数:$rows");
+
+$manifest = [
+    'created_at' => date('c'),
+    'database' => DB::connection()->getDatabaseName(),
+    'source_table' => $source,
+    'snapshot_table' => $snapshot,
+    'rows' => $sourceCount,
+    'csv_path' => $csvPath,
+    'csv_sha256' => hash_file('sha256', $csvPath),
+    'csv_bytes' => filesize($csvPath),
+];
+rp_json_write("$archiveDir/$snapshot.manifest.json", $manifest);
+$log->info("清单:$archiveDir/$snapshot.manifest.json");
+$log->info('sha256: '.$manifest['csv_sha256']);
+
+$log->finish();

+ 3036 - 0
api-v13/scripts/related/baseline.json

@@ -0,0 +1,3036 @@
+{
+    "frozen_at": "2026-09-09T12:45:03+00:00",
+    "source_table": "related_paragraphs_bak_20260909",
+    "database": "visuddhinanda_20260311",
+    "purpose": "旧表的实测基线。clean_books 是零错误信号的书,重建后这些书一本都不许掉出来;detectors 是各探测器的旧表读数,用于回答「错误是否减少」。",
+    "clean_books": [
+        2,
+        3,
+        4,
+        5,
+        6,
+        7,
+        8,
+        10,
+        12,
+        13,
+        14,
+        15,
+        16,
+        17,
+        18,
+        19,
+        20,
+        22,
+        23,
+        24,
+        25,
+        26,
+        27,
+        28,
+        29,
+        30,
+        31,
+        32,
+        33,
+        34,
+        35,
+        36,
+        37,
+        38,
+        39,
+        40,
+        41,
+        42,
+        43,
+        44,
+        45,
+        46,
+        47,
+        48,
+        49,
+        50,
+        51,
+        52,
+        53,
+        54,
+        55,
+        56,
+        57,
+        58,
+        59,
+        60,
+        61,
+        62,
+        63,
+        64,
+        65,
+        66,
+        67,
+        68,
+        74,
+        75,
+        77,
+        82,
+        83,
+        84,
+        85,
+        86,
+        87,
+        88,
+        89,
+        90,
+        91,
+        92,
+        93,
+        94,
+        95,
+        99,
+        105,
+        106,
+        110,
+        115,
+        117,
+        118,
+        129,
+        131,
+        133,
+        134,
+        135,
+        136,
+        141,
+        149,
+        155,
+        156,
+        157,
+        158,
+        159,
+        160,
+        161,
+        162,
+        163,
+        164,
+        165,
+        166,
+        167,
+        168,
+        169,
+        170,
+        171,
+        177,
+        180,
+        181,
+        187,
+        188,
+        196,
+        197,
+        198,
+        204,
+        212,
+        213,
+        214,
+        215,
+        216,
+        217
+    ],
+    "detectors": {
+        "E1_cs_garbage": {
+            "rows": 1242,
+            "books": 24
+        },
+        "E2_chapter_wrap": {
+            "wrap_points": 429,
+            "books": 70
+        },
+        "E3_kn10_missing": {
+            "kn10_rows": 0,
+            "kn10_a_rows": 16926,
+            "kn10_b_rows": 12489
+        },
+        "E4_empty_book_name": {
+            "rows": 112965,
+            "books": 60
+        },
+        "E5_book_id_zero": {
+            "rows": 354,
+            "books": 201
+        },
+        "E6_coverage_gap": {
+            "segments": 3464,
+            "books": 44
+        },
+        "E7_abbrev_interval_lost": {
+            "marker_segments": 1519,
+            "books": 44,
+            "segments_without_rows": 1292,
+            "segments_with_garbage": 225
+        },
+        "E8_flat_pollution": {
+            "groups": 1,
+            "rows": 1499
+        },
+        "E9_no_marker_books": {
+            "books": 16,
+            "book_list": [
+                8,
+                15,
+                16,
+                25,
+                37,
+                39,
+                40,
+                41,
+                42,
+                44,
+                45,
+                47,
+                48,
+                56,
+                61,
+                129
+            ]
+        },
+        "E10_selfmade_names": {
+            "nk_rows": 986,
+            "subo_rows": 4258,
+            "dict_rows": 7041
+        },
+        "D_continuity": {
+            "broken_groups": 9026,
+            "books": 69,
+            "extra_segments": 30204
+        },
+        "D_mirror_alignment": {
+            "deviations": 0,
+            "detail": []
+        },
+        "D_interval_expansion": {
+            "interval_markers": 3615,
+            "mismatched_markers": 1611,
+            "empty_markers": 1611
+        }
+    },
+    "scorecard": [
+        {
+            "book": 1,
+            "rows": 986,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 3,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 3
+        },
+        {
+            "book": 2,
+            "rows": 845,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 845,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 3,
+            "rows": 316,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 316,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 4,
+            "rows": 597,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 597,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 5,
+            "rows": 1025,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1025,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 6,
+            "rows": 302,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 302,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 7,
+            "rows": 526,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 526,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 8,
+            "rows": 2458,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2458,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 9,
+            "rows": 3109,
+            "names": 1,
+            "garbage_rows": 31,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 32
+        },
+        {
+            "book": 10,
+            "rows": 1320,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 11,
+            "rows": 2938,
+            "names": 1,
+            "garbage_rows": 96,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 2,
+            "gap_segments": 3,
+            "flat_groups": 0,
+            "signals": 101
+        },
+        {
+            "book": 12,
+            "rows": 847,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 847,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 13,
+            "rows": 3262,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 3262,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 14,
+            "rows": 3486,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 3486,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 15,
+            "rows": 2980,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2980,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 16,
+            "rows": 3401,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 3401,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 17,
+            "rows": 4055,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 4055,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 18,
+            "rows": 1579,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1579,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 19,
+            "rows": 2493,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2493,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 20,
+            "rows": 318,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 318,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 21,
+            "rows": 3963,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 31,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 22,
+            "rows": 6144,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 6144,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 23,
+            "rows": 1498,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 24,
+            "rows": 442,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 25,
+            "rows": 249,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 249,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 26,
+            "rows": 1960,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1960,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 27,
+            "rows": 1347,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1347,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 28,
+            "rows": 243,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 243,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 29,
+            "rows": 1333,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1333,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 30,
+            "rows": 1283,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1283,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 31,
+            "rows": 876,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 876,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 32,
+            "rows": 266,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 266,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 33,
+            "rows": 545,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 545,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 34,
+            "rows": 552,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 552,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 35,
+            "rows": 1847,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1847,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 36,
+            "rows": 2457,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2457,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 37,
+            "rows": 433,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 433,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 38,
+            "rows": 2613,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2613,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 39,
+            "rows": 349,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 349,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 40,
+            "rows": 688,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 688,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 41,
+            "rows": 1256,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 1256,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 42,
+            "rows": 907,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 907,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 43,
+            "rows": 1554,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 1554,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 44,
+            "rows": 296,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 296,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 45,
+            "rows": 503,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 503,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 46,
+            "rows": 1240,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 47,
+            "rows": 1640,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 1640,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 48,
+            "rows": 1095,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 1095,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 49,
+            "rows": 83,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 83,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 50,
+            "rows": 494,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 494,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 51,
+            "rows": 3057,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 3057,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 52,
+            "rows": 1703,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 1703,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 53,
+            "rows": 709,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 709,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 54,
+            "rows": 1642,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 1642,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 55,
+            "rows": 118,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 118,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 56,
+            "rows": 491,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 491,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 57,
+            "rows": 364,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 364,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 58,
+            "rows": 1649,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 1649,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 59,
+            "rows": 9907,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 9907,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 60,
+            "rows": 501,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 501,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 61,
+            "rows": 152,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 152,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 62,
+            "rows": 971,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 971,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 63,
+            "rows": 15944,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 15944,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 64,
+            "rows": 2240,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 65,
+            "rows": 2192,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 66,
+            "rows": 1613,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 67,
+            "rows": 1851,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 68,
+            "rows": 2701,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2701,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 69,
+            "rows": 4241,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 16,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 16
+        },
+        {
+            "book": 70,
+            "rows": 6004,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 9,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 9
+        },
+        {
+            "book": 71,
+            "rows": 8046,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 20,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 20
+        },
+        {
+            "book": 72,
+            "rows": 5169,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 19,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 19
+        },
+        {
+            "book": 73,
+            "rows": 2436,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 2
+        },
+        {
+            "book": 74,
+            "rows": 3427,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 75,
+            "rows": 673,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 76,
+            "rows": 561,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 77,
+            "rows": 3460,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 78,
+            "rows": 4774,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 4,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 4
+        },
+        {
+            "book": 79,
+            "rows": 3859,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 2
+        },
+        {
+            "book": 80,
+            "rows": 5586,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 81,
+            "rows": 4301,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 4,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 4
+        },
+        {
+            "book": 82,
+            "rows": 3141,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 83,
+            "rows": 1889,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 84,
+            "rows": 957,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 85,
+            "rows": 485,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 86,
+            "rows": 1938,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 87,
+            "rows": 3439,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 88,
+            "rows": 16266,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 89,
+            "rows": 2377,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 1,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 90,
+            "rows": 14831,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 91,
+            "rows": 2604,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 92,
+            "rows": 1504,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 93,
+            "rows": 1074,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 94,
+            "rows": 1559,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 95,
+            "rows": 1910,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 96,
+            "rows": 3551,
+            "names": 1,
+            "garbage_rows": 3,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 2,
+            "gap_segments": 30,
+            "flat_groups": 0,
+            "signals": 36
+        },
+        {
+            "book": 97,
+            "rows": 2423,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 2,
+            "gap_segments": 9,
+            "flat_groups": 0,
+            "signals": 11
+        },
+        {
+            "book": 98,
+            "rows": 17589,
+            "names": 5,
+            "garbage_rows": 40,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 17,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 57
+        },
+        {
+            "book": 99,
+            "rows": 2078,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 100,
+            "rows": 3738,
+            "names": 3,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 2,
+            "gap_segments": 4,
+            "flat_groups": 0,
+            "signals": 6
+        },
+        {
+            "book": 101,
+            "rows": 1162,
+            "names": 3,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 102,
+            "rows": 950,
+            "names": 4,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 103,
+            "rows": 1976,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 1,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 104,
+            "rows": 1731,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 4,
+            "flat_groups": 0,
+            "signals": 5
+        },
+        {
+            "book": 105,
+            "rows": 1131,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 106,
+            "rows": 4548,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 107,
+            "rows": 4096,
+            "names": 2,
+            "garbage_rows": 47,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 22,
+            "abbrev_lost": 22,
+            "gap_segments": 48,
+            "flat_groups": 0,
+            "signals": 139
+        },
+        {
+            "book": 108,
+            "rows": 4194,
+            "names": 1,
+            "garbage_rows": 80,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 25,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 105
+        },
+        {
+            "book": 109,
+            "rows": 2136,
+            "names": 1,
+            "garbage_rows": 80,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 6,
+            "gap_segments": 10,
+            "flat_groups": 0,
+            "signals": 98
+        },
+        {
+            "book": 110,
+            "rows": 3117,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 111,
+            "rows": 2997,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 112,
+            "rows": 4892,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 5,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 5
+        },
+        {
+            "book": 113,
+            "rows": 7714,
+            "names": 1,
+            "garbage_rows": 21,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 5,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 26
+        },
+        {
+            "book": 114,
+            "rows": 5079,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 0,
+            "empty_name_rows": 0,
+            "wrap_points": 4,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 4
+        },
+        {
+            "book": 115,
+            "rows": 3688,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 116,
+            "rows": 1235,
+            "names": 1,
+            "garbage_rows": 26,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 4,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 30
+        },
+        {
+            "book": 117,
+            "rows": 6463,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 118,
+            "rows": 1833,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 119,
+            "rows": 765,
+            "names": 1,
+            "garbage_rows": 18,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 2,
+            "flat_groups": 0,
+            "signals": 21
+        },
+        {
+            "book": 120,
+            "rows": 2718,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 3,
+            "abbrev_lost": 1,
+            "gap_segments": 6,
+            "flat_groups": 0,
+            "signals": 10
+        },
+        {
+            "book": 121,
+            "rows": 1096,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 122,
+            "rows": 5231,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 123,
+            "rows": 1688,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 124,
+            "rows": 1766,
+            "names": 1,
+            "garbage_rows": 7,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 7
+        },
+        {
+            "book": 125,
+            "rows": 2505,
+            "names": 1,
+            "garbage_rows": 1,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 114,
+            "gap_segments": 306,
+            "flat_groups": 0,
+            "signals": 421
+        },
+        {
+            "book": 126,
+            "rows": 3973,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 36,
+            "gap_segments": 87,
+            "flat_groups": 0,
+            "signals": 124
+        },
+        {
+            "book": 127,
+            "rows": 3281,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 46,
+            "gap_segments": 98,
+            "flat_groups": 0,
+            "signals": 145
+        },
+        {
+            "book": 128,
+            "rows": 5390,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 2,
+            "gap_segments": 22,
+            "flat_groups": 0,
+            "signals": 24
+        },
+        {
+            "book": 129,
+            "rows": 6605,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 130,
+            "rows": 2906,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 2,
+            "gap_segments": 6,
+            "flat_groups": 0,
+            "signals": 9
+        },
+        {
+            "book": 131,
+            "rows": 1369,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 132,
+            "rows": 1105,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 2,
+            "flat_groups": 0,
+            "signals": 3
+        },
+        {
+            "book": 133,
+            "rows": 1480,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 134,
+            "rows": 1228,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 135,
+            "rows": 2850,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 136,
+            "rows": 1862,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 137,
+            "rows": 2840,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 5,
+            "abbrev_lost": 9,
+            "gap_segments": 52,
+            "flat_groups": 0,
+            "signals": 66
+        },
+        {
+            "book": 138,
+            "rows": 2805,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 26,
+            "gap_segments": 218,
+            "flat_groups": 0,
+            "signals": 244
+        },
+        {
+            "book": 139,
+            "rows": 1349,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 32,
+            "gap_segments": 147,
+            "flat_groups": 0,
+            "signals": 179
+        },
+        {
+            "book": 140,
+            "rows": 944,
+            "names": 1,
+            "garbage_rows": 6,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 6,
+            "gap_segments": 18,
+            "flat_groups": 0,
+            "signals": 30
+        },
+        {
+            "book": 141,
+            "rows": 670,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 142,
+            "rows": 717,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 1,
+            "flat_groups": 0,
+            "signals": 2
+        },
+        {
+            "book": 143,
+            "rows": 14646,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 41,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 41
+        },
+        {
+            "book": 144,
+            "rows": 10673,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 17,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 17
+        },
+        {
+            "book": 145,
+            "rows": 3282,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 28,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 28
+        },
+        {
+            "book": 146,
+            "rows": 1199,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 2
+        },
+        {
+            "book": 147,
+            "rows": 11528,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 5,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 5
+        },
+        {
+            "book": 148,
+            "rows": 10506,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 15,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 15
+        },
+        {
+            "book": 149,
+            "rows": 2927,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 150,
+            "rows": 2771,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 151,
+            "rows": 2044,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 3,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 3
+        },
+        {
+            "book": 152,
+            "rows": 2493,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 22,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 22
+        },
+        {
+            "book": 153,
+            "rows": 1624,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 154,
+            "rows": 276,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 6,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 6
+        },
+        {
+            "book": 155,
+            "rows": 1217,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 156,
+            "rows": 1394,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 157,
+            "rows": 965,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 158,
+            "rows": 1194,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 159,
+            "rows": 4051,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 160,
+            "rows": 3279,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 161,
+            "rows": 2655,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 162,
+            "rows": 4669,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 163,
+            "rows": 1785,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 164,
+            "rows": 1797,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 165,
+            "rows": 1690,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 166,
+            "rows": 1463,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 167,
+            "rows": 3498,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 168,
+            "rows": 1427,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 169,
+            "rows": 3165,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 170,
+            "rows": 2225,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 171,
+            "rows": 5900,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 172,
+            "rows": 1366,
+            "names": 1,
+            "garbage_rows": 7,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 1,
+            "gap_segments": 4,
+            "flat_groups": 0,
+            "signals": 14
+        },
+        {
+            "book": 173,
+            "rows": 2315,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 7,
+            "gap_segments": 20,
+            "flat_groups": 0,
+            "signals": 28
+        },
+        {
+            "book": 174,
+            "rows": 10905,
+            "names": 5,
+            "garbage_rows": 39,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 12,
+            "abbrev_lost": 2,
+            "gap_segments": 6,
+            "flat_groups": 0,
+            "signals": 59
+        },
+        {
+            "book": 175,
+            "rows": 1275,
+            "names": 1,
+            "garbage_rows": 9,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 11
+        },
+        {
+            "book": 176,
+            "rows": 11901,
+            "names": 5,
+            "garbage_rows": 43,
+            "no_book_id_rows": 3,
+            "empty_name_rows": 0,
+            "wrap_points": 13,
+            "abbrev_lost": 0,
+            "gap_segments": 3,
+            "flat_groups": 0,
+            "signals": 59
+        },
+        {
+            "book": 177,
+            "rows": 15499,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 10695,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 178,
+            "rows": 1838,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 17,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 17
+        },
+        {
+            "book": 179,
+            "rows": 2403,
+            "names": 2,
+            "garbage_rows": 55,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 418,
+            "gap_segments": 805,
+            "flat_groups": 0,
+            "signals": 1279
+        },
+        {
+            "book": 180,
+            "rows": 2826,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 2826,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 181,
+            "rows": 1451,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 182,
+            "rows": 3328,
+            "names": 3,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 3,
+            "abbrev_lost": 10,
+            "gap_segments": 46,
+            "flat_groups": 0,
+            "signals": 59
+        },
+        {
+            "book": 183,
+            "rows": 2094,
+            "names": 3,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 4,
+            "abbrev_lost": 10,
+            "gap_segments": 45,
+            "flat_groups": 0,
+            "signals": 59
+        },
+        {
+            "book": 184,
+            "rows": 6356,
+            "names": 4,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 5,
+            "abbrev_lost": 1,
+            "gap_segments": 4,
+            "flat_groups": 0,
+            "signals": 10
+        },
+        {
+            "book": 185,
+            "rows": 1588,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 17,
+            "gap_segments": 54,
+            "flat_groups": 0,
+            "signals": 71
+        },
+        {
+            "book": 186,
+            "rows": 1509,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 13,
+            "flat_groups": 0,
+            "signals": 14
+        },
+        {
+            "book": 187,
+            "rows": 1132,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 188,
+            "rows": 1781,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 189,
+            "rows": 1572,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 10,
+            "gap_segments": 37,
+            "flat_groups": 0,
+            "signals": 47
+        },
+        {
+            "book": 190,
+            "rows": 764,
+            "names": 1,
+            "garbage_rows": 1,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 2
+        },
+        {
+            "book": 191,
+            "rows": 1670,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 192,
+            "rows": 2397,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 3,
+            "gap_segments": 3,
+            "flat_groups": 0,
+            "signals": 8
+        },
+        {
+            "book": 193,
+            "rows": 936,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 3,
+            "flat_groups": 0,
+            "signals": 4
+        },
+        {
+            "book": 194,
+            "rows": 856,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 1,
+            "gap_segments": 2,
+            "flat_groups": 0,
+            "signals": 3
+        },
+        {
+            "book": 195,
+            "rows": 1709,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 196,
+            "rows": 1328,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 197,
+            "rows": 3276,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 198,
+            "rows": 1928,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 199,
+            "rows": 2837,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 7,
+            "abbrev_lost": 7,
+            "gap_segments": 28,
+            "flat_groups": 0,
+            "signals": 42
+        },
+        {
+            "book": 200,
+            "rows": 13281,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 201,
+            "rows": 4584,
+            "names": 2,
+            "garbage_rows": 452,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 256,
+            "gap_segments": 566,
+            "flat_groups": 0,
+            "signals": 1275
+        },
+        {
+            "book": 202,
+            "rows": 2989,
+            "names": 4,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 3,
+            "abbrev_lost": 10,
+            "gap_segments": 55,
+            "flat_groups": 0,
+            "signals": 68
+        },
+        {
+            "book": 203,
+            "rows": 3404,
+            "names": 2,
+            "garbage_rows": 81,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 84,
+            "gap_segments": 294,
+            "flat_groups": 0,
+            "signals": 460
+        },
+        {
+            "book": 204,
+            "rows": 1659,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 205,
+            "rows": 1926,
+            "names": 1,
+            "garbage_rows": 5,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 3,
+            "gap_segments": 4,
+            "flat_groups": 0,
+            "signals": 14
+        },
+        {
+            "book": 206,
+            "rows": 2862,
+            "names": 4,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 3,
+            "abbrev_lost": 4,
+            "gap_segments": 10,
+            "flat_groups": 0,
+            "signals": 17
+        },
+        {
+            "book": 207,
+            "rows": 2713,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 12,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 1,
+            "signals": 13
+        },
+        {
+            "book": 208,
+            "rows": 1673,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 1
+        },
+        {
+            "book": 209,
+            "rows": 2562,
+            "names": 5,
+            "garbage_rows": 70,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 1,
+            "abbrev_lost": 85,
+            "gap_segments": 255,
+            "flat_groups": 0,
+            "signals": 411
+        },
+        {
+            "book": 210,
+            "rows": 3901,
+            "names": 5,
+            "garbage_rows": 24,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 4,
+            "abbrev_lost": 46,
+            "gap_segments": 132,
+            "flat_groups": 0,
+            "signals": 206
+        },
+        {
+            "book": 211,
+            "rows": 2413,
+            "names": 2,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 2,
+            "abbrev_lost": 1,
+            "gap_segments": 1,
+            "flat_groups": 0,
+            "signals": 4
+        },
+        {
+            "book": 212,
+            "rows": 2517,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 1,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 213,
+            "rows": 2477,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 214,
+            "rows": 3690,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 215,
+            "rows": 2759,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 216,
+            "rows": 2821,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        },
+        {
+            "book": 217,
+            "rows": 3645,
+            "names": 1,
+            "garbage_rows": 0,
+            "no_book_id_rows": 2,
+            "empty_name_rows": 0,
+            "wrap_points": 0,
+            "abbrev_lost": 0,
+            "gap_segments": 0,
+            "flat_groups": 0,
+            "signals": 0
+        }
+    ]
+}

+ 6374 - 0
api-v13/scripts/related/book_config.json

@@ -0,0 +1,6374 @@
+{
+    "generated_at": "2026-09-09T15:01:15+00:00",
+    "baseline_table": "related_paragraphs_bak_20260909",
+    "purpose": "每本 VRI 文件的类型与书名分段。导出器优先用 wbw 现场证据,此表只在文件本身没有书名信息时兜底。overrides 是人工修正区,重跑不覆盖。",
+    "books": {
+        "1": {
+            "max_paragraph": 981,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 1,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "namakkāra",
+                        "añña",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "namakkārapāḷi"
+                    ]
+                },
+                {
+                    "book_id": 2,
+                    "from_paragraph": 159,
+                    "type": "tika",
+                    "tags": [
+                        "namakkāraṭīkā",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "añña",
+                        "ṭīkā",
+                        "namakkāra"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 981,
+                    "book_name": "NK"
+                }
+            ]
+        },
+        "2": {
+            "max_paragraph": 845,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 3,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "mahāpaṇāmapāṭha"
+                    ]
+                },
+                {
+                    "book_id": 4,
+                    "from_paragraph": 428,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "mahāpaṇāmapāṭha",
+                        "buddha-vandanā ganthasaṅgaha"
+                    ]
+                },
+                {
+                    "book_id": 5,
+                    "from_paragraph": 479,
+                    "type": "unknown",
+                    "tags": [
+                        "mahāpaṇāmapāṭha",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 845,
+                    "book_name": ""
+                }
+            ]
+        },
+        "3": {
+            "max_paragraph": 316,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 6,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "lakkhaṇāto",
+                        "buddha-vandanā ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 316,
+                    "book_name": ""
+                }
+            ]
+        },
+        "4": {
+            "max_paragraph": 597,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 7,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "suttavandanā",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 597,
+                    "book_name": ""
+                }
+            ]
+        },
+        "5": {
+            "max_paragraph": 1025,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 8,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "jinālaṅkāra",
+                        "añña",
+                        "buddha-vandanā ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1025,
+                    "book_name": ""
+                }
+            ]
+        },
+        "6": {
+            "max_paragraph": 302,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 9,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "kamalāñjali"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 302,
+                    "book_name": ""
+                }
+            ]
+        },
+        "7": {
+            "max_paragraph": 526,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 10,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "pajjamadhu",
+                        "buddha-vandanā ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 526,
+                    "book_name": ""
+                }
+            ]
+        },
+        "8": {
+            "max_paragraph": 2458,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 11,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "buddha-vandanā ganthasaṅgaha",
+                        "buddhaguṇagāthāvalī",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2458,
+                    "book_name": ""
+                }
+            ]
+        },
+        "9": {
+            "max_paragraph": 2714,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 12,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "abhidhānappadīpikāṭīkā",
+                        "nirutti",
+                        "abhidhānappadīpikā",
+                        "byākaraṇa ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2714,
+                    "book_name": "dict"
+                }
+            ]
+        },
+        "10": {
+            "max_paragraph": 1320,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 13,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "byākaraṇa ganthasaṅgaha",
+                        "subodhālaṅkāra",
+                        "nirutti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1320,
+                    "book_name": "subo"
+                }
+            ]
+        },
+        "11": {
+            "max_paragraph": 2885,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 14,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "subodhālaṅkāra",
+                        "nirutti",
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña",
+                        "subodhālaṅkāraṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2885,
+                    "book_name": "subo"
+                }
+            ]
+        },
+        "12": {
+            "max_paragraph": 847,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 15,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "avatāra",
+                        "nirutti",
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña",
+                        "bālāvatāra"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 847,
+                    "book_name": ""
+                }
+            ]
+        },
+        "13": {
+            "max_paragraph": 3262,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 16,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "moggallānasuttapāṭha",
+                        "añña",
+                        "byākaraṇa ganthasaṅgaha",
+                        "nirutti"
+                    ]
+                },
+                {
+                    "book_id": 17,
+                    "from_paragraph": 1105,
+                    "type": "unknown",
+                    "tags": [
+                        "moggallānabyākaraṇa",
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña",
+                        "nirutti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3262,
+                    "book_name": ""
+                }
+            ]
+        },
+        "14": {
+            "max_paragraph": 3486,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 18,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "byākaraṇa ganthasaṅgaha",
+                        "kaccāyanabyākaraṇa",
+                        "nirutti",
+                        "añña"
+                    ]
+                },
+                {
+                    "book_id": 19,
+                    "from_paragraph": 715,
+                    "type": "unknown",
+                    "tags": [
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña",
+                        "nirutti",
+                        "kaccāyanabyākaraṇa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3486,
+                    "book_name": ""
+                }
+            ]
+        },
+        "15": {
+            "max_paragraph": 2980,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 20,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "padamālā",
+                        "saddanītippakaraṇa",
+                        "nirutti",
+                        "byākaraṇa ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2980,
+                    "book_name": ""
+                }
+            ]
+        },
+        "16": {
+            "max_paragraph": 3401,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 21,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "dhātumālā",
+                        "saddanītippakaraṇa",
+                        "nirutti",
+                        "byākaraṇa ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3401,
+                    "book_name": ""
+                }
+            ]
+        },
+        "17": {
+            "max_paragraph": 4055,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 22,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "padarūpasiddhi",
+                        "byākaraṇa ganthasaṅgaha",
+                        "nirutti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4055,
+                    "book_name": ""
+                }
+            ]
+        },
+        "18": {
+            "max_paragraph": 1579,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 23,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "moggallāna pañcikā ṭīkā",
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña",
+                        "nirutti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1579,
+                    "book_name": ""
+                }
+            ]
+        },
+        "19": {
+            "max_paragraph": 2493,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 24,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "nirutti",
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña",
+                        "payogasiddhipāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2493,
+                    "book_name": ""
+                }
+            ]
+        },
+        "20": {
+            "max_paragraph": 318,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 25,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "vuttodaya",
+                        "nirutti",
+                        "byākaraṇa ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 318,
+                    "book_name": ""
+                }
+            ]
+        },
+        "21": {
+            "max_paragraph": 3963,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 26,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "byākaraṇa ganthasaṅgaha",
+                        "abhidhānappadīpikā",
+                        "nirutti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3932,
+                    "book_name": "dict"
+                },
+                {
+                    "para_from": 3933,
+                    "para_to": 3963,
+                    "book_name": ""
+                }
+            ]
+        },
+        "22": {
+            "max_paragraph": 6144,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 27,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "niruttidīpanīpāṭha",
+                        "añña",
+                        "nirutti",
+                        "leḍī sayādo"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 6144,
+                    "book_name": ""
+                }
+            ]
+        },
+        "23": {
+            "max_paragraph": 1498,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 28,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "paramatthadīpanī",
+                        "abhidhammatthasaṅgaha",
+                        "abhidhamma",
+                        "leḍī sayādo",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1498,
+                    "book_name": "abhi9"
+                }
+            ]
+        },
+        "24": {
+            "max_paragraph": 434,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 29,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "abhidhamma",
+                        "abhidhammatthasaṅgaha",
+                        "anudīpanīpāṭha",
+                        "leḍī sayādo",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 434,
+                    "book_name": "abhi9"
+                }
+            ]
+        },
+        "25": {
+            "max_paragraph": 249,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 30,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "paṭṭhānuddesa dīpanīpāṭha",
+                        "abhidhamma",
+                        "leḍī sayādo",
+                        "añña",
+                        "paṭṭhāna"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 249,
+                    "book_name": ""
+                }
+            ]
+        },
+        "26": {
+            "max_paragraph": 1960,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 31,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "dīpanī",
+                        "añña",
+                        "nīti-ganthasaṅgaha",
+                        "caturārakkhadīpanī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1960,
+                    "book_name": ""
+                }
+            ]
+        },
+        "27": {
+            "max_paragraph": 1347,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 32,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "kavidappaṇanīti",
+                        "nīti-ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1347,
+                    "book_name": ""
+                }
+            ]
+        },
+        "28": {
+            "max_paragraph": 243,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 33,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "nītimañjarī",
+                        "nīti-ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 243,
+                    "book_name": ""
+                }
+            ]
+        },
+        "29": {
+            "max_paragraph": 1333,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 34,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "dhammanīti",
+                        "nīti-ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1333,
+                    "book_name": ""
+                }
+            ]
+        },
+        "30": {
+            "max_paragraph": 1283,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 35,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "nīti-ganthasaṅgaha",
+                        "mahārahanīti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1283,
+                    "book_name": ""
+                }
+            ]
+        },
+        "31": {
+            "max_paragraph": 876,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 36,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "lokanīti",
+                        "nīti-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 876,
+                    "book_name": ""
+                }
+            ]
+        },
+        "32": {
+            "max_paragraph": 266,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 37,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "suttantanīti",
+                        "nīti-ganthasaṅgaha"
+                    ]
+                },
+                {
+                    "book_id": 38,
+                    "from_paragraph": 134,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "nīti-ganthasaṅgaha",
+                        "suttantanīti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 266,
+                    "book_name": ""
+                }
+            ]
+        },
+        "33": {
+            "max_paragraph": 545,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 39,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "sūrassatīnīti",
+                        "nīti-ganthasaṅgaha",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 545,
+                    "book_name": ""
+                }
+            ]
+        },
+        "34": {
+            "max_paragraph": 552,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 40,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "nīti-ganthasaṅgaha",
+                        "cāṇakyanītipāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 552,
+                    "book_name": ""
+                }
+            ]
+        },
+        "35": {
+            "max_paragraph": 1847,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 41,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "naradakkhadīpanī",
+                        "añña",
+                        "nīti-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1847,
+                    "book_name": ""
+                }
+            ]
+        },
+        "36": {
+            "max_paragraph": 2457,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 42,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "rasavāhinī",
+                        "añña",
+                        "pakiṇṇaka-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2457,
+                    "book_name": ""
+                }
+            ]
+        },
+        "37": {
+            "max_paragraph": 433,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 43,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "sīmavisodhanī",
+                        "pakiṇṇaka",
+                        "pakiṇṇaka-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 433,
+                    "book_name": ""
+                }
+            ]
+        },
+        "38": {
+            "max_paragraph": 2613,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 44,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "pakiṇṇaka-ganthasaṅgaha",
+                        "vessantarāgīti",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2613,
+                    "book_name": ""
+                }
+            ]
+        },
+        "39": {
+            "max_paragraph": 349,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 45,
+                    "from_paragraph": 3,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "dīghanikāya",
+                        "sutta",
+                        "saṅgayana-puccha vissajjanā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 349,
+                    "book_name": ""
+                }
+            ]
+        },
+        "40": {
+            "max_paragraph": 688,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 46,
+                    "from_paragraph": 3,
+                    "type": "unknown",
+                    "tags": [
+                        "sutta",
+                        "saṅgayana-puccha vissajjanā",
+                        "añña",
+                        "majjhimanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 688,
+                    "book_name": ""
+                }
+            ]
+        },
+        "41": {
+            "max_paragraph": 1256,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 47,
+                    "from_paragraph": 3,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "saṅgayana-puccha vissajjanā",
+                        "saṃyuttanikāya",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1256,
+                    "book_name": ""
+                }
+            ]
+        },
+        "42": {
+            "max_paragraph": 907,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 48,
+                    "from_paragraph": 3,
+                    "type": "unknown",
+                    "tags": [
+                        "saṅgayana-puccha vissajjanā",
+                        "añña",
+                        "sutta",
+                        "aṅguttaranikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 907,
+                    "book_name": ""
+                }
+            ]
+        },
+        "43": {
+            "max_paragraph": 1554,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 49,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "vinaya",
+                        "saṅgayana-puccha vissajjanā",
+                        "añña",
+                        "vinayapiṭaka"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1554,
+                    "book_name": ""
+                }
+            ]
+        },
+        "44": {
+            "max_paragraph": 296,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 50,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "abhidhammapiṭaka",
+                        "abhidhamma",
+                        "añña",
+                        "saṅgayana-puccha vissajjanā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 296,
+                    "book_name": ""
+                }
+            ]
+        },
+        "45": {
+            "max_paragraph": 503,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 51,
+                    "from_paragraph": 2,
+                    "type": "atthakatha",
+                    "tags": [
+                        "saṅgayana-puccha vissajjanā",
+                        "añña",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 503,
+                    "book_name": ""
+                }
+            ]
+        },
+        "46": {
+            "max_paragraph": 1240,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 52,
+                    "from_paragraph": 1,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "milidaṭīkā",
+                        "sihaḷa-ganthasaṅgaha",
+                        "milindapañha",
+                        "añña",
+                        "khuddakanikāya",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1240,
+                    "book_name": "kn18"
+                }
+            ]
+        },
+        "47": {
+            "max_paragraph": 1640,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 53,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "padamañjarī",
+                        "nirutti",
+                        "sihaḷa-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1640,
+                    "book_name": ""
+                }
+            ]
+        },
+        "48": {
+            "max_paragraph": 1095,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 54,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "nirutti",
+                        "padasādhana"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1095,
+                    "book_name": ""
+                }
+            ]
+        },
+        "49": {
+            "max_paragraph": 83,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 55,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "nirutti",
+                        "saddabindupakaraṇa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 83,
+                    "book_name": ""
+                }
+            ]
+        },
+        "50": {
+            "max_paragraph": 494,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 56,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "kaccāyanadhātumañjūsā",
+                        "añña",
+                        "nirutti",
+                        "sihaḷa-ganthasaṅgaha",
+                        "kaccāyana"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 494,
+                    "book_name": ""
+                }
+            ]
+        },
+        "51": {
+            "max_paragraph": 3057,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 57,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "samantakūṭavaṇṇanā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3057,
+                    "book_name": ""
+                }
+            ]
+        },
+        "52": {
+            "max_paragraph": 1703,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 58,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "moggallāna vuttivivaraṇapañcikā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1703,
+                    "book_name": ""
+                }
+            ]
+        },
+        "53": {
+            "max_paragraph": 709,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 59,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "sihaḷa-ganthasaṅgaha",
+                        "thupavaṃsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 709,
+                    "book_name": ""
+                }
+            ]
+        },
+        "54": {
+            "max_paragraph": 1642,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 60,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "dāṭhāvaṃsa",
+                        "añña",
+                        "sihaḷa-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1642,
+                    "book_name": ""
+                }
+            ]
+        },
+        "55": {
+            "max_paragraph": 118,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 61,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "dhātupāṭha vilāsiniyā",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 118,
+                    "book_name": ""
+                }
+            ]
+        },
+        "56": {
+            "max_paragraph": 491,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 62,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "dhātuvaṃsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 491,
+                    "book_name": ""
+                }
+            ]
+        },
+        "57": {
+            "max_paragraph": 364,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 63,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "hatthavanagallavihāravaṃsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 364,
+                    "book_name": ""
+                }
+            ]
+        },
+        "58": {
+            "max_paragraph": 1649,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 64,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "jinacaritaya",
+                        "añña",
+                        "sihaḷa-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1649,
+                    "book_name": ""
+                }
+            ]
+        },
+        "59": {
+            "max_paragraph": 9907,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 65,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "sihaḷa-ganthasaṅgaha",
+                        "jinavaṃsadīpa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 9907,
+                    "book_name": ""
+                }
+            ]
+        },
+        "60": {
+            "max_paragraph": 501,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 66,
+                    "from_paragraph": 1,
+                    "type": "unknown",
+                    "tags": [
+                        "sihaḷa-ganthasaṅgaha",
+                        "añña",
+                        "telakaṭāhagāthā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 501,
+                    "book_name": ""
+                }
+            ]
+        },
+        "61": {
+            "max_paragraph": 152,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 67,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "cūḷaganthavaṃsapāḷi",
+                        "vaṃsa ganthasaṅgaha",
+                        "añña",
+                        "vaṃsa-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 152,
+                    "book_name": ""
+                }
+            ]
+        },
+        "62": {
+            "max_paragraph": 971,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 68,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "añña",
+                        "vaṃsa ganthasaṅgaha",
+                        "vaṃsa-ganthasaṅgaha",
+                        "sāsanavaṃsappadīpikā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 971,
+                    "book_name": ""
+                }
+            ]
+        },
+        "63": {
+            "max_paragraph": 15944,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 69,
+                    "from_paragraph": 2,
+                    "type": "unknown",
+                    "tags": [
+                        "mahāvaṃsapāḷi",
+                        "vaṃsa ganthasaṅgaha",
+                        "añña",
+                        "vaṃsa-ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 15944,
+                    "book_name": ""
+                }
+            ]
+        },
+        "64": {
+            "max_paragraph": 2240,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 70,
+                    "from_paragraph": 2,
+                    "type": "atthakatha",
+                    "tags": [
+                        "visuddhimagga",
+                        "aṭṭhakathā",
+                        "paṭhamo bhāgo",
+                        "añña"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2240,
+                    "book_name": "vism"
+                }
+            ]
+        },
+        "65": {
+            "max_paragraph": 2192,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 71,
+                    "from_paragraph": 2,
+                    "type": "atthakatha",
+                    "tags": [
+                        "visuddhimagga",
+                        "dutiyo bhāgo",
+                        "añña",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2192,
+                    "book_name": "vism"
+                }
+            ]
+        },
+        "66": {
+            "max_paragraph": 1613,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 72,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "paṭhamo bhāgo",
+                        "mahāṭīkā",
+                        "añña",
+                        "visuddhimagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1613,
+                    "book_name": "vism"
+                }
+            ]
+        },
+        "67": {
+            "max_paragraph": 1851,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 73,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "añña",
+                        "mahāṭīkā",
+                        "dutiyo bhāgo",
+                        "visuddhimagga",
+                        "ṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1851,
+                    "book_name": "vism"
+                }
+            ]
+        },
+        "68": {
+            "max_paragraph": 981,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 74,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "visuddhimagga",
+                        "añña",
+                        "ṭīkā",
+                        "nidānakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 981,
+                    "book_name": ""
+                }
+            ]
+        },
+        "69": {
+            "max_paragraph": 4241,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 75,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "abhidhamma",
+                        "paṭṭhāna",
+                        "paṭṭhānapāḷi",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4241,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "70": {
+            "max_paragraph": 6004,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 76,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "abhidhamma",
+                        "mūla",
+                        "paṭṭhāna",
+                        "paṭṭhānapāḷi",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 6004,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "71": {
+            "max_paragraph": 8046,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 77,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "paṭṭhānapāḷi",
+                        "paṭṭhāna",
+                        "abhidhamma",
+                        "mūla",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 8046,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "72": {
+            "max_paragraph": 5169,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 78,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "paṭṭhānapāḷi",
+                        "abhidhamma",
+                        "mūla",
+                        "paṭṭhāna",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 5169,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "73": {
+            "max_paragraph": 2436,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 79,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "dhammasaṅgaṇī",
+                        "mūla",
+                        "pāḷi",
+                        "abhidhamma"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2436,
+                    "book_name": "abhi1"
+                }
+            ]
+        },
+        "74": {
+            "max_paragraph": 3427,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 80,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "abhidhamma",
+                        "vibhaṅga",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3427,
+                    "book_name": "abhi2"
+                }
+            ]
+        },
+        "75": {
+            "max_paragraph": 673,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 81,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "abhidhamma",
+                        "pāḷi",
+                        "mūla",
+                        "dhātukathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 673,
+                    "book_name": "abhi3"
+                }
+            ]
+        },
+        "76": {
+            "max_paragraph": 561,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 82,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "puggalapaññatti",
+                        "abhidhamma",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 561,
+                    "book_name": "abhi4"
+                }
+            ]
+        },
+        "77": {
+            "max_paragraph": 3460,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 83,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "kathāvatthu",
+                        "mūla",
+                        "abhidhamma"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3460,
+                    "book_name": "abhi5"
+                }
+            ]
+        },
+        "78": {
+            "max_paragraph": 4774,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 84,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "yamakapāḷi",
+                        "pāḷi",
+                        "mūla",
+                        "abhidhamma",
+                        "yamaka"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4774,
+                    "book_name": "abhi6"
+                }
+            ]
+        },
+        "79": {
+            "max_paragraph": 3859,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 85,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "yamaka",
+                        "abhidhamma",
+                        "mūla",
+                        "pāḷi",
+                        "yamakapāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3859,
+                    "book_name": "abhi6"
+                }
+            ]
+        },
+        "80": {
+            "max_paragraph": 5586,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 86,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "yamaka",
+                        "abhidhamma",
+                        "mūla",
+                        "pāḷi",
+                        "yamakapāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 5586,
+                    "book_name": "abhi6"
+                }
+            ]
+        },
+        "81": {
+            "max_paragraph": 4301,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 87,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "paṭṭhāna",
+                        "abhidhamma",
+                        "pāḷi",
+                        "paṭṭhānapāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4301,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "82": {
+            "max_paragraph": 1604,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 88,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "sutta",
+                        "nipāta",
+                        "mūla",
+                        "pāḷi",
+                        "dasakanipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1604,
+                    "book_name": "an10"
+                }
+            ]
+        },
+        "83": {
+            "max_paragraph": 245,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 89,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "sutta",
+                        "ekādasakanipāta",
+                        "pāḷi",
+                        "aṅguttaranikāya",
+                        "nipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 245,
+                    "book_name": "an11"
+                }
+            ]
+        },
+        "84": {
+            "max_paragraph": 400,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 90,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "nipāta",
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "aṅguttaranikāya",
+                        "ekakanipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 400,
+                    "book_name": "an1"
+                }
+            ]
+        },
+        "85": {
+            "max_paragraph": 318,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 91,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "pāḷi",
+                        "dukanipāta",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 318,
+                    "book_name": "an2"
+                }
+            ]
+        },
+        "86": {
+            "max_paragraph": 1336,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 92,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "tikanipāta",
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "mūla",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1336,
+                    "book_name": "an3"
+                }
+            ]
+        },
+        "87": {
+            "max_paragraph": 1950,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 93,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "nipāta",
+                        "catukkanipāta",
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "aṅguttaranikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1950,
+                    "book_name": "an4"
+                }
+            ]
+        },
+        "88": {
+            "max_paragraph": 1632,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 94,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "sutta",
+                        "mūla",
+                        "aṅguttaranikāya",
+                        "nipāta",
+                        "pañcakanipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1632,
+                    "book_name": "an5"
+                }
+            ]
+        },
+        "89": {
+            "max_paragraph": 857,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 95,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "nipāta",
+                        "chakkanipāta",
+                        "mūla",
+                        "sutta",
+                        "pāḷi",
+                        "aṅguttaranikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 857,
+                    "book_name": "an6"
+                }
+            ]
+        },
+        "90": {
+            "max_paragraph": 791,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 96,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "sattakanipāta",
+                        "aṅguttaranikāya",
+                        "nipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 791,
+                    "book_name": "an7"
+                }
+            ]
+        },
+        "91": {
+            "max_paragraph": 1041,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 97,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "aṭṭhakanipāta",
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1041,
+                    "book_name": "an8"
+                }
+            ]
+        },
+        "92": {
+            "max_paragraph": 502,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 98,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "nipāta",
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "aṅguttaranikāya",
+                        "navakanipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 502,
+                    "book_name": "an9"
+                }
+            ]
+        },
+        "93": {
+            "max_paragraph": 1074,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 99,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sīlakkhandhavagga",
+                        "dīghanikāya",
+                        "pāḷi",
+                        "mūla",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1074,
+                    "book_name": "dn1"
+                }
+            ]
+        },
+        "94": {
+            "max_paragraph": 1559,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 100,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mahāvagga",
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "dīghanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1559,
+                    "book_name": "dn2"
+                }
+            ]
+        },
+        "95": {
+            "max_paragraph": 1910,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 101,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "dīghanikāya",
+                        "pāthikavagga",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1910,
+                    "book_name": "dn3"
+                }
+            ]
+        },
+        "96": {
+            "max_paragraph": 2489,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 102,
+                    "from_paragraph": 4,
+                    "type": "atthakatha",
+                    "tags": [
+                        "abhidhamma",
+                        "aṭṭhasālinī",
+                        "aṭṭhakathā",
+                        "dhammasaṅgaṇī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2489,
+                    "book_name": "abhi1"
+                }
+            ]
+        },
+        "97": {
+            "max_paragraph": 2346,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 103,
+                    "from_paragraph": 4,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "sammohavinodanī",
+                        "abhidhamma",
+                        "vibhaṅga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2346,
+                    "book_name": "abhi2"
+                }
+            ]
+        },
+        "98": {
+            "max_paragraph": 2611,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 104,
+                    "from_paragraph": 4,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "abhidhamma",
+                        "pañcapakaraṇa",
+                        "dhātukathā"
+                    ]
+                },
+                {
+                    "book_id": 105,
+                    "from_paragraph": 173,
+                    "type": "atthakatha",
+                    "tags": [
+                        "puggalapaññatti",
+                        "pañcapakaraṇa",
+                        "abhidhamma",
+                        "aṭṭhakathā"
+                    ]
+                },
+                {
+                    "book_id": 106,
+                    "from_paragraph": 474,
+                    "type": "atthakatha",
+                    "tags": [
+                        "kathāvatthu",
+                        "abhidhamma",
+                        "aṭṭhakathā",
+                        "pañcapakaraṇa"
+                    ]
+                },
+                {
+                    "book_id": 107,
+                    "from_paragraph": 1623,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "abhidhamma",
+                        "pañcapakaraṇa",
+                        "yamaka"
+                    ]
+                },
+                {
+                    "book_id": 108,
+                    "from_paragraph": 1880,
+                    "type": "atthakatha",
+                    "tags": [
+                        "paṭṭhāna",
+                        "aṭṭhakathā",
+                        "abhidhamma",
+                        "pañcapakaraṇa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 172,
+                    "book_name": "abhi3"
+                },
+                {
+                    "para_from": 173,
+                    "para_to": 473,
+                    "book_name": "abhi4"
+                },
+                {
+                    "para_from": 474,
+                    "para_to": 1622,
+                    "book_name": "abhi5"
+                },
+                {
+                    "para_from": 1623,
+                    "para_to": 1879,
+                    "book_name": "abhi6"
+                },
+                {
+                    "para_from": 1880,
+                    "para_to": 2611,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "99": {
+            "max_paragraph": 1624,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 109,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "sutta",
+                        "ekakanipāta",
+                        "manorathapūraṇī",
+                        "aṅguttaranikāya",
+                        "nipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 49,
+                    "book_name": "an1_A"
+                },
+                {
+                    "para_from": 50,
+                    "para_to": 1624,
+                    "book_name": "an1"
+                }
+            ]
+        },
+        "100": {
+            "max_paragraph": 1722,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 110,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "aṭṭhakathā",
+                        "manorathapūraṇī",
+                        "sutta",
+                        "dukanipāta"
+                    ]
+                },
+                {
+                    "book_id": 111,
+                    "from_paragraph": 325,
+                    "type": "atthakatha",
+                    "tags": [
+                        "manorathapūraṇī",
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "tikanipāta"
+                    ]
+                },
+                {
+                    "book_id": 112,
+                    "from_paragraph": 997,
+                    "type": "atthakatha",
+                    "tags": [
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "manorathapūraṇī",
+                        "catukkanipāta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 322,
+                    "book_name": "an2"
+                },
+                {
+                    "para_from": 323,
+                    "para_to": 994,
+                    "book_name": "an3"
+                },
+                {
+                    "para_from": 995,
+                    "para_to": 1722,
+                    "book_name": "an4"
+                }
+            ]
+        },
+        "101": {
+            "max_paragraph": 985,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 113,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "manorathapūraṇī",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "aṅguttaranikāya",
+                        "nipāta",
+                        "pañcakanipāta"
+                    ]
+                },
+                {
+                    "book_id": 114,
+                    "from_paragraph": 503,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "manorathapūraṇī",
+                        "chakkanipāta",
+                        "nipāta"
+                    ]
+                },
+                {
+                    "book_id": 115,
+                    "from_paragraph": 792,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sattakanipāta",
+                        "nipāta",
+                        "manorathapūraṇī",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "aṅguttaranikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 500,
+                    "book_name": "an5"
+                },
+                {
+                    "para_from": 501,
+                    "para_to": 789,
+                    "book_name": "an6"
+                },
+                {
+                    "para_from": 790,
+                    "para_to": 985,
+                    "book_name": "an7"
+                }
+            ]
+        },
+        "102": {
+            "max_paragraph": 796,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 116,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "sutta",
+                        "aṭṭhakanipāta",
+                        "manorathapūraṇī",
+                        "nipāta",
+                        "aṅguttaranikāya"
+                    ]
+                },
+                {
+                    "book_id": 117,
+                    "from_paragraph": 275,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "manorathapūraṇī",
+                        "navakanipāta",
+                        "nipāta",
+                        "aṭṭhakathā",
+                        "sutta"
+                    ]
+                },
+                {
+                    "book_id": 118,
+                    "from_paragraph": 409,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "dasakanipāta",
+                        "aṭṭhakathā",
+                        "nipāta",
+                        "manorathapūraṇī",
+                        "sutta"
+                    ]
+                },
+                {
+                    "book_id": 119,
+                    "from_paragraph": 706,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "nipāta",
+                        "ekādasakanipāta",
+                        "manorathapūraṇī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 272,
+                    "book_name": "an8"
+                },
+                {
+                    "para_from": 273,
+                    "para_to": 406,
+                    "book_name": "an9"
+                },
+                {
+                    "para_from": 407,
+                    "para_to": 703,
+                    "book_name": "an10"
+                },
+                {
+                    "para_from": 704,
+                    "para_to": 796,
+                    "book_name": "an11"
+                }
+            ]
+        },
+        "103": {
+            "max_paragraph": 1507,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 120,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "sumaṅgalavilāsinī",
+                        "sīlakkhandhavagga",
+                        "dīghanikāya",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 198,
+                    "book_name": "dn1_A"
+                },
+                {
+                    "para_from": 199,
+                    "para_to": 1507,
+                    "book_name": "dn1"
+                }
+            ]
+        },
+        "104": {
+            "max_paragraph": 1712,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 121,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "dīghanikāya",
+                        "mahāvagga",
+                        "sumaṅgalavilāsinī",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1712,
+                    "book_name": "dn2"
+                }
+            ]
+        },
+        "105": {
+            "max_paragraph": 1131,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 122,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "pāthikavagga",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "dīghanikāya",
+                        "sumaṅgalavilāsinī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1131,
+                    "book_name": "dn3"
+                }
+            ]
+        },
+        "106": {
+            "max_paragraph": 4548,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 123,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "khuddakanikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "therīgāthā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4548,
+                    "book_name": "kn9"
+                }
+            ]
+        },
+        "107": {
+            "max_paragraph": 3875,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 124,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "apadāna",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "therāpadāna",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2141,
+                    "book_name": "kn10_A"
+                },
+                {
+                    "para_from": 2142,
+                    "para_to": 3875,
+                    "book_name": "kn10_B"
+                }
+            ]
+        },
+        "108": {
+            "max_paragraph": 4137,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 125,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "vaṃsa ganthasaṅgaha",
+                        "buddhavaṃsa",
+                        "khuddakanikāya",
+                        "aṭṭhakathā",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4137,
+                    "book_name": "kn12"
+                }
+            ]
+        },
+        "109": {
+            "max_paragraph": 2126,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 126,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "carita",
+                        "cariyāpiṭaka",
+                        "khuddakanikāya",
+                        "aṭṭhakathā",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2126,
+                    "book_name": "kn13"
+                }
+            ]
+        },
+        "110": {
+            "max_paragraph": 3117,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 127,
+                    "from_paragraph": 4,
+                    "type": "atthakatha",
+                    "tags": [
+                        "jātaka",
+                        "aṭṭhakathā",
+                        "khuddakanikāya",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3117,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "111": {
+            "max_paragraph": 2997,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 128,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "khuddakanikāya",
+                        "sutta",
+                        "jātaka",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2997,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "112": {
+            "max_paragraph": 4868,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 129,
+                    "from_paragraph": 4,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "sutta",
+                        "khuddakanikāya",
+                        "jātaka"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4868,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "113": {
+            "max_paragraph": 6738,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 130,
+                    "from_paragraph": 4,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "aṭṭhakathā",
+                        "khuddakanikāya",
+                        "jātaka"
+                    ]
+                },
+                {
+                    "book_id": 131,
+                    "from_paragraph": 5312,
+                    "type": "atthakatha",
+                    "tags": [
+                        "jātaka",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 6738,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "114": {
+            "max_paragraph": 5079,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 132,
+                    "from_paragraph": 1,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "jātaka",
+                        "khuddakanikāya",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 5079,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "115": {
+            "max_paragraph": 3688,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 133,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "khuddakanikāya",
+                        "jātaka",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3688,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "116": {
+            "max_paragraph": 1235,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 134,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "khuddakapāṭha",
+                        "paramatthajotika",
+                        "khuddakanikāya",
+                        "aṭṭhakathā",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1235,
+                    "book_name": "kn1"
+                }
+            ]
+        },
+        "117": {
+            "max_paragraph": 6463,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 135,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "jātaka",
+                        "khuddakanikāya",
+                        "aṭṭhakathā",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 6463,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "118": {
+            "max_paragraph": 1833,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 136,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "niddesa",
+                        "mahāniddesa",
+                        "khuddakanikāya",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1833,
+                    "book_name": "kn15"
+                }
+            ]
+        },
+        "119": {
+            "max_paragraph": 753,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 137,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "sutta",
+                        "cūḷaniddesa",
+                        "niddesa",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 753,
+                    "book_name": "kn16"
+                }
+            ]
+        },
+        "120": {
+            "max_paragraph": 2526,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 138,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "khuddakanikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "paṭisambhidāmagga",
+                        "saddhammappakāsinī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2526,
+                    "book_name": "kn17"
+                }
+            ]
+        },
+        "121": {
+            "max_paragraph": 1096,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 139,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "khuddakanikāya",
+                        "nettippakaraṇa",
+                        "netti",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1096,
+                    "book_name": "kn19"
+                }
+            ]
+        },
+        "122": {
+            "max_paragraph": 5231,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 140,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "dhammapada",
+                        "khuddakanikāya",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 5231,
+                    "book_name": "kn2"
+                }
+            ]
+        },
+        "123": {
+            "max_paragraph": 1688,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 141,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "khuddakanikāya",
+                        "udāna",
+                        "sutta",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1688,
+                    "book_name": "kn3"
+                }
+            ]
+        },
+        "124": {
+            "max_paragraph": 1759,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 142,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "khuddakanikāya",
+                        "itivuttaka",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1759,
+                    "book_name": "kn4"
+                }
+            ]
+        },
+        "125": {
+            "max_paragraph": 2689,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 143,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "suttanipāta",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "khuddakanikāya",
+                        "nipāta",
+                        "paramatthajotika"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2689,
+                    "book_name": "kn5"
+                }
+            ]
+        },
+        "126": {
+            "max_paragraph": 4017,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 144,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "khuddakanikāya",
+                        "vimānavatthu",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4017,
+                    "book_name": "kn6"
+                }
+            ]
+        },
+        "127": {
+            "max_paragraph": 3236,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 145,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "petavatthu",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3236,
+                    "book_name": "kn7"
+                }
+            ]
+        },
+        "128": {
+            "max_paragraph": 5412,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 146,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "khuddakanikāya",
+                        "theragāthā",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 5412,
+                    "book_name": "kn8"
+                }
+            ]
+        },
+        "129": {
+            "max_paragraph": 6607,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 147,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "theragāthā",
+                        "sutta",
+                        "aṭṭhakathā",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 6607,
+                    "book_name": "kn8"
+                }
+            ]
+        },
+        "130": {
+            "max_paragraph": 2912,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 148,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "mūlapaṇṇāsa",
+                        "aṭṭhakathā",
+                        "majjhimanikāya",
+                        "papañcasūdanī",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 46,
+                    "book_name": "mn1_A"
+                },
+                {
+                    "para_from": 47,
+                    "para_to": 2912,
+                    "book_name": "mn1"
+                }
+            ]
+        },
+        "131": {
+            "max_paragraph": 1339,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 149,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sutta",
+                        "aṭṭhakathā",
+                        "papañcasūdanī",
+                        "majjhimapaṇṇāsa",
+                        "majjhimanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1339,
+                    "book_name": "mn2"
+                }
+            ]
+        },
+        "132": {
+            "max_paragraph": 1107,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 150,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "majjhimanikāya",
+                        "aṭṭhakathā",
+                        "papañcasūdanī",
+                        "sutta",
+                        "uparipaṇṇāsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1107,
+                    "book_name": "mn3"
+                }
+            ]
+        },
+        "133": {
+            "max_paragraph": 1478,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 151,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "saṃyuttanikāya",
+                        "sagāthāvagga",
+                        "sāratthappakāsinī",
+                        "aṭṭhakathā",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 43,
+                    "book_name": "sn1_A"
+                },
+                {
+                    "para_from": 44,
+                    "para_to": 1478,
+                    "book_name": "sn1"
+                }
+            ]
+        },
+        "134": {
+            "max_paragraph": 978,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 152,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "sutta",
+                        "saṃyuttanikāya",
+                        "sāratthappakāsinī",
+                        "nidānavagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 978,
+                    "book_name": "sn2"
+                }
+            ]
+        },
+        "135": {
+            "max_paragraph": 491,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 153,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "saṃyuttanikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "sāratthappakāsinī",
+                        "khandhavagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 491,
+                    "book_name": "sn3"
+                }
+            ]
+        },
+        "136": {
+            "max_paragraph": 799,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 154,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "saḷāyatanavagga",
+                        "sāratthappakāsinī",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "saṃyuttanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 799,
+                    "book_name": "sn4"
+                }
+            ]
+        },
+        "137": {
+            "max_paragraph": 1016,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 155,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "sāratthappakāsinī",
+                        "saṃyuttanikāya",
+                        "aṭṭhakathā",
+                        "sutta",
+                        "mahāvagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1016,
+                    "book_name": "sn5"
+                }
+            ]
+        },
+        "138": {
+            "max_paragraph": 2974,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 156,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "pārājika",
+                        "vinaya",
+                        "aṭṭhakathā",
+                        "samantapāsādikā",
+                        "suttavibhaṅga",
+                        "mahāvibhaṅga",
+                        "pārājikakaṇḍa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2974,
+                    "book_name": "vin1"
+                }
+            ]
+        },
+        "139": {
+            "max_paragraph": 1466,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 157,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "mahāvibhaṅga",
+                        "suttavibhaṅga",
+                        "samantapāsādikā",
+                        "aṭṭhakathā",
+                        "vinaya",
+                        "pācittiya-aṭṭhakathā",
+                        "pācittiya"
+                    ]
+                },
+                {
+                    "book_id": 280,
+                    "from_paragraph": 925,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "samantapāsādikā",
+                        "vinaya",
+                        "bhikkhunīvibhaṅga",
+                        "pācittiya-aṭṭhakathā",
+                        "pācittiya",
+                        "suttavibhaṅga",
+                        "bhikkhunī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1466,
+                    "book_name": "vin2"
+                }
+            ]
+        },
+        "140": {
+            "max_paragraph": 923,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 158,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "aṭṭhakathā",
+                        "khandhaka",
+                        "samantapāsādikā",
+                        "mahāvagga",
+                        "vinaya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 923,
+                    "book_name": "vin3"
+                }
+            ]
+        },
+        "141": {
+            "max_paragraph": 669,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 159,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "samantapāsādikā",
+                        "cūḷavagga",
+                        "khandhaka",
+                        "vinaya",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 669,
+                    "book_name": "vin4"
+                }
+            ]
+        },
+        "142": {
+            "max_paragraph": 661,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 160,
+                    "from_paragraph": 3,
+                    "type": "atthakatha",
+                    "tags": [
+                        "samantapāsādikā",
+                        "parivāra",
+                        "parivārapāḷi",
+                        "vinaya",
+                        "aṭṭhakathā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 661,
+                    "book_name": "vin5"
+                }
+            ]
+        },
+        "143": {
+            "max_paragraph": 14646,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 161,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "apadāna",
+                        "therāpadāna",
+                        "khuddakanikāya",
+                        "sutta",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 14646,
+                    "book_name": "kn10"
+                }
+            ]
+        },
+        "144": {
+            "max_paragraph": 10673,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 162,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "khuddakanikāya",
+                        "therāpadāna",
+                        "apadāna",
+                        "pāḷi",
+                        "mūla",
+                        "sutta"
+                    ]
+                },
+                {
+                    "book_id": 163,
+                    "from_paragraph": 6534,
+                    "type": "mula",
+                    "tags": [
+                        "khuddakanikāya",
+                        "pāḷi",
+                        "apadāna",
+                        "therīapadāna",
+                        "sutta",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 6531,
+                    "book_name": "kn10"
+                },
+                {
+                    "para_from": 6532,
+                    "para_to": 10673,
+                    "book_name": "kn11"
+                }
+            ]
+        },
+        "145": {
+            "max_paragraph": 3282,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 164,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "sutta",
+                        "khuddakanikāya",
+                        "pāḷi",
+                        "buddhavaṃsa",
+                        "vaṃsa ganthasaṅgaha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 3282,
+                    "book_name": "kn12"
+                }
+            ]
+        },
+        "146": {
+            "max_paragraph": 1199,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 165,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "carita",
+                        "pāḷi",
+                        "cariyāpiṭaka",
+                        "mūla",
+                        "sutta",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1199,
+                    "book_name": "kn13"
+                }
+            ]
+        },
+        "147": {
+            "max_paragraph": 11528,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 166,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "sutta",
+                        "khuddakanikāya",
+                        "pāḷi",
+                        "jātaka"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 11528,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "148": {
+            "max_paragraph": 10506,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 167,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "khuddakanikāya",
+                        "mūla",
+                        "pāḷi",
+                        "jātaka",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 10506,
+                    "book_name": "kn14"
+                }
+            ]
+        },
+        "149": {
+            "max_paragraph": 2927,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 168,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "niddesa",
+                        "khuddakanikāya",
+                        "sutta",
+                        "mahāniddesa",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2927,
+                    "book_name": "kn15"
+                }
+            ]
+        },
+        "150": {
+            "max_paragraph": 2771,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 169,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "khuddakanikāya",
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "niddesa",
+                        "cūḷaniddesa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2771,
+                    "book_name": "kn16"
+                }
+            ]
+        },
+        "151": {
+            "max_paragraph": 2044,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 170,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "khuddakanikāya",
+                        "pāḷi",
+                        "mūla",
+                        "paṭisambhidāmagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2044,
+                    "book_name": "kn17"
+                }
+            ]
+        },
+        "152": {
+            "max_paragraph": 2493,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 171,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "milindapañha",
+                        "khuddakanikāya",
+                        "sutta",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2493,
+                    "book_name": "kn18"
+                }
+            ]
+        },
+        "153": {
+            "max_paragraph": 1624,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 172,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "sutta",
+                        "khuddakanikāya",
+                        "pāḷi",
+                        "nettippakaraṇa",
+                        "netti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1624,
+                    "book_name": "kn19"
+                }
+            ]
+        },
+        "154": {
+            "max_paragraph": 276,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 173,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "khuddakapāṭha",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 276,
+                    "book_name": "kn1"
+                }
+            ]
+        },
+        "155": {
+            "max_paragraph": 1217,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 174,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "peṭakopadesa",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1217,
+                    "book_name": "kn20"
+                }
+            ]
+        },
+        "156": {
+            "max_paragraph": 1394,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 175,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "dhammapada",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1394,
+                    "book_name": "kn2"
+                }
+            ]
+        },
+        "157": {
+            "max_paragraph": 965,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 176,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "khuddakanikāya",
+                        "sutta",
+                        "udāna",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 965,
+                    "book_name": "kn3"
+                }
+            ]
+        },
+        "158": {
+            "max_paragraph": 1194,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 177,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "itivuttaka",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1194,
+                    "book_name": "kn4"
+                }
+            ]
+        },
+        "159": {
+            "max_paragraph": 4051,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 178,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "suttanipāta",
+                        "nipāta",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 4051,
+                    "book_name": "kn5"
+                }
+            ]
+        },
+        "160": {
+            "max_paragraph": 3279,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 179,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "vimānavatthu",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 3279,
+                    "book_name": "kn6"
+                }
+            ]
+        },
+        "161": {
+            "max_paragraph": 2655,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 180,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "petavatthu",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2655,
+                    "book_name": "kn7"
+                }
+            ]
+        },
+        "162": {
+            "max_paragraph": 4669,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 181,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "sutta",
+                        "khuddakanikāya",
+                        "mūla",
+                        "theragāthā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 4669,
+                    "book_name": "kn8"
+                }
+            ]
+        },
+        "163": {
+            "max_paragraph": 1785,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 182,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "therīgāthā",
+                        "pāḷi",
+                        "mūla",
+                        "khuddakanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1785,
+                    "book_name": "kn9"
+                }
+            ]
+        },
+        "164": {
+            "max_paragraph": 1797,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 183,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūlapaṇṇāsa",
+                        "majjhimanikāya",
+                        "sutta",
+                        "mūla",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1797,
+                    "book_name": "mn1"
+                }
+            ]
+        },
+        "165": {
+            "max_paragraph": 1690,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 184,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "majjhimapaṇṇāsa",
+                        "mūla",
+                        "sutta",
+                        "majjhimanikāya",
+                        "pāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1690,
+                    "book_name": "mn2"
+                }
+            ]
+        },
+        "166": {
+            "max_paragraph": 1463,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 185,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "majjhimanikāya",
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "uparipaṇṇāsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1463,
+                    "book_name": "mn3"
+                }
+            ]
+        },
+        "167": {
+            "max_paragraph": 3498,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 186,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "sagāthāvagga",
+                        "saṃyuttanikāya",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 3498,
+                    "book_name": "sn1"
+                }
+            ]
+        },
+        "168": {
+            "max_paragraph": 1427,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 187,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "mūla",
+                        "nidānavagga",
+                        "saṃyuttanikāya",
+                        "pāḷi",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1427,
+                    "book_name": "sn2"
+                }
+            ]
+        },
+        "169": {
+            "max_paragraph": 1467,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 188,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "saṃyuttanikāya",
+                        "sutta",
+                        "khandhavagga",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1467,
+                    "book_name": "sn3"
+                }
+            ]
+        },
+        "170": {
+            "max_paragraph": 2020,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 189,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "mūla",
+                        "pāḷi",
+                        "saṃyuttanikāya",
+                        "saḷāyatanavagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2020,
+                    "book_name": "sn4"
+                }
+            ]
+        },
+        "171": {
+            "max_paragraph": 2852,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 190,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "sutta",
+                        "saṃyuttanikāya",
+                        "mahāvagga",
+                        "pāḷi",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2852,
+                    "book_name": "sn5"
+                }
+            ]
+        },
+        "172": {
+            "max_paragraph": 722,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 191,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhamma",
+                        "mūlaṭīkā",
+                        "ṭīkā",
+                        "dhammasaṅgaṇī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 722,
+                    "book_name": "abhi1"
+                }
+            ]
+        },
+        "173": {
+            "max_paragraph": 2219,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 192,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "vibhaṅga",
+                        "mūlaṭīkā",
+                        "abhidhamma",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 193,
+                    "from_paragraph": 1155,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "mūlaṭīkā",
+                        "abhidhamma",
+                        "vibhaṅga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2219,
+                    "book_name": "abhi2"
+                }
+            ]
+        },
+        "174": {
+            "max_paragraph": 1487,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 194,
+                    "from_paragraph": 4,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "abhidhamma",
+                        "dhātukathā",
+                        "pañcapakaraṇa",
+                        "mūlaṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 195,
+                    "from_paragraph": 100,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhamma",
+                        "pañcapakaraṇa",
+                        "puggalapaññatti",
+                        "mūlaṭīkā",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 196,
+                    "from_paragraph": 201,
+                    "type": "tika",
+                    "tags": [
+                        "pañcapakaraṇa",
+                        "abhidhamma",
+                        "ṭīkā",
+                        "mūlaṭīkā",
+                        "kathāvatthu"
+                    ]
+                },
+                {
+                    "book_id": 197,
+                    "from_paragraph": 865,
+                    "type": "tika",
+                    "tags": [
+                        "yamaka",
+                        "abhidhamma",
+                        "pañcapakaraṇa",
+                        "ṭīkā",
+                        "mūlaṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 198,
+                    "from_paragraph": 1059,
+                    "type": "tika",
+                    "tags": [
+                        "paṭṭhāna",
+                        "pañcapakaraṇa",
+                        "mūlaṭīkā",
+                        "ṭīkā",
+                        "abhidhamma"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 99,
+                    "book_name": "abhi3"
+                },
+                {
+                    "para_from": 100,
+                    "para_to": 200,
+                    "book_name": "abhi4"
+                },
+                {
+                    "para_from": 201,
+                    "para_to": 864,
+                    "book_name": "abhi5"
+                },
+                {
+                    "para_from": 865,
+                    "para_to": 1058,
+                    "book_name": "abhi6"
+                },
+                {
+                    "para_from": 1059,
+                    "para_to": 1487,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "175": {
+            "max_paragraph": 725,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 199,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "dhammasaṅgaṇī",
+                        "abhidhamma",
+                        "ṭīkā",
+                        "anuṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 725,
+                    "book_name": "abhi1"
+                }
+            ]
+        },
+        "176": {
+            "max_paragraph": 1511,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 200,
+                    "from_paragraph": 4,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhamma",
+                        "ṭīkā",
+                        "anuṭīkā",
+                        "dhātukathā",
+                        "pañcapakaraṇa"
+                    ]
+                },
+                {
+                    "book_id": 201,
+                    "from_paragraph": 117,
+                    "type": "tika",
+                    "tags": [
+                        "anuṭīkā",
+                        "ṭīkā",
+                        "abhidhamma",
+                        "puggalapaññatti",
+                        "pañcapakaraṇa"
+                    ]
+                },
+                {
+                    "book_id": 202,
+                    "from_paragraph": 213,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhamma",
+                        "ṭīkā",
+                        "anuṭīkā",
+                        "pañcapakaraṇa",
+                        "kathāvatthu"
+                    ]
+                },
+                {
+                    "book_id": 203,
+                    "from_paragraph": 917,
+                    "type": "tika",
+                    "tags": [
+                        "pañcapakaraṇa",
+                        "anuṭīkā",
+                        "yamaka",
+                        "abhidhamma",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 204,
+                    "from_paragraph": 1139,
+                    "type": "tika",
+                    "tags": [
+                        "anuṭīkā",
+                        "ṭīkā",
+                        "abhidhamma",
+                        "paṭṭhāna",
+                        "pañcapakaraṇa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 116,
+                    "book_name": "abhi3"
+                },
+                {
+                    "para_from": 117,
+                    "para_to": 212,
+                    "book_name": "abhi4"
+                },
+                {
+                    "para_from": 213,
+                    "para_to": 916,
+                    "book_name": "abhi5"
+                },
+                {
+                    "para_from": 917,
+                    "para_to": 1138,
+                    "book_name": "abhi6"
+                },
+                {
+                    "para_from": 1139,
+                    "para_to": 1511,
+                    "book_name": "abhi7"
+                }
+            ]
+        },
+        "177": {
+            "max_paragraph": 15499,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 205,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhamma",
+                        "ṭīkā",
+                        "abhidhammāvatāro",
+                        "abhidhammāvatāra"
+                    ]
+                },
+                {
+                    "book_id": 206,
+                    "from_paragraph": 4805,
+                    "type": "tika",
+                    "tags": [
+                        "nāmarūpapariccheda",
+                        "abhidhamma",
+                        "ṭīkā",
+                        "abhidhammāvatāro"
+                    ]
+                },
+                {
+                    "book_id": 207,
+                    "from_paragraph": 10627,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhammāvatāro",
+                        "abhidhamma",
+                        "ṭīkā",
+                        "paramatthavinicchaya"
+                    ]
+                },
+                {
+                    "book_id": 208,
+                    "from_paragraph": 14272,
+                    "type": "tika",
+                    "tags": [
+                        "saccasaṅkhepa",
+                        "ṭīkā",
+                        "abhidhamma",
+                        "abhidhammāvatāro"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 4804,
+                    "book_name": "abhi8"
+                },
+                {
+                    "para_from": 4805,
+                    "para_to": 15499,
+                    "book_name": ""
+                }
+            ]
+        },
+        "178": {
+            "max_paragraph": 1838,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 209,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhammatthasaṅgaha",
+                        "abhidhamma",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 210,
+                    "from_paragraph": 875,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhammatthasaṅgaha",
+                        "ṭīkā",
+                        "abhidhamma"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1838,
+                    "book_name": "abhi9"
+                }
+            ]
+        },
+        "179": {
+            "max_paragraph": 2598,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 211,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhammāvatāra",
+                        "avatāra",
+                        "ṭīkā",
+                        "purāṇaṭīkā",
+                        "abhidhamma"
+                    ]
+                },
+                {
+                    "book_id": 212,
+                    "from_paragraph": 872,
+                    "type": "tika",
+                    "tags": [
+                        "abhidhammāvatāra",
+                        "ṭīkā",
+                        "avatāra",
+                        "abhidhamma",
+                        "abhinavaṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2572,
+                    "book_name": "abhi8"
+                },
+                {
+                    "para_from": 2573,
+                    "para_to": 2598,
+                    "book_name": "abhi8_A"
+                }
+            ]
+        },
+        "180": {
+            "max_paragraph": 2826,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 213,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "mātikā",
+                        "abhidhammamātikā",
+                        "pāḷi",
+                        "abhidhamma",
+                        "ṭīkā",
+                        "abhidhammamātikāpāḷi"
+                    ]
+                },
+                {
+                    "book_id": 214,
+                    "from_paragraph": 1221,
+                    "type": "tika",
+                    "tags": [
+                        "pāḷi",
+                        "abhidhamma",
+                        "ṭīkā",
+                        "abhidhammamātikā",
+                        "mohavicchedanī",
+                        "mātikā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2826,
+                    "book_name": ""
+                }
+            ]
+        },
+        "181": {
+            "max_paragraph": 1173,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 215,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "aṅguttaranikāya",
+                        "ekakanipāta",
+                        "sāratthamañjūsā",
+                        "nipāta",
+                        "ṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 138,
+                    "book_name": "an1_A"
+                },
+                {
+                    "para_from": 139,
+                    "para_to": 1173,
+                    "book_name": "an1"
+                }
+            ]
+        },
+        "182": {
+            "max_paragraph": 1925,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 216,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "ṭīkā",
+                        "dukanipāta",
+                        "sāratthamañjūsā",
+                        "nipāta",
+                        "sutta"
+                    ]
+                },
+                {
+                    "book_id": 217,
+                    "from_paragraph": 324,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "sāratthamañjūsā",
+                        "tikanipāta",
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 218,
+                    "from_paragraph": 1023,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "aṅguttaranikāya",
+                        "ṭīkā",
+                        "nipāta",
+                        "catukkanipāta",
+                        "sāratthamañjūsā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 321,
+                    "book_name": "an2"
+                },
+                {
+                    "para_from": 322,
+                    "para_to": 1020,
+                    "book_name": "an3"
+                },
+                {
+                    "para_from": 1021,
+                    "para_to": 1925,
+                    "book_name": "an4"
+                }
+            ]
+        },
+        "183": {
+            "max_paragraph": 1026,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 219,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "nipāta",
+                        "sāratthamañjūsā",
+                        "pañcakanipāta",
+                        "aṅguttaranikāya",
+                        "sutta"
+                    ]
+                },
+                {
+                    "book_id": 220,
+                    "from_paragraph": 470,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "ṭīkā",
+                        "aṅguttaranikāya",
+                        "nipāta",
+                        "chakkanipāta",
+                        "sāratthamañjūsā"
+                    ]
+                },
+                {
+                    "book_id": 221,
+                    "from_paragraph": 793,
+                    "type": "tika",
+                    "tags": [
+                        "nipāta",
+                        "sutta",
+                        "aṅguttaranikāya",
+                        "ṭīkā",
+                        "sattakanipāta",
+                        "sāratthamañjūsā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 467,
+                    "book_name": "an5"
+                },
+                {
+                    "para_from": 468,
+                    "para_to": 790,
+                    "book_name": "an6"
+                },
+                {
+                    "para_from": 791,
+                    "para_to": 1026,
+                    "book_name": "an7"
+                }
+            ]
+        },
+        "184": {
+            "max_paragraph": 868,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 222,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "aṭṭhakanipāta",
+                        "ṭīkā",
+                        "sāratthamañjūsā",
+                        "nipāta",
+                        "sutta"
+                    ]
+                },
+                {
+                    "book_id": 223,
+                    "from_paragraph": 278,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "sāratthamañjūsā",
+                        "navakanipāta",
+                        "nipāta",
+                        "aṅguttaranikāya",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 224,
+                    "from_paragraph": 466,
+                    "type": "tika",
+                    "tags": [
+                        "nipāta",
+                        "ṭīkā",
+                        "sutta",
+                        "aṅguttaranikāya",
+                        "dasakanipāta",
+                        "sāratthamañjūsā"
+                    ]
+                },
+                {
+                    "book_id": 225,
+                    "from_paragraph": 776,
+                    "type": "tika",
+                    "tags": [
+                        "aṅguttaranikāya",
+                        "ṭīkā",
+                        "sutta",
+                        "nipāta",
+                        "ekādasakanipāta",
+                        "sāratthamañjūsā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 275,
+                    "book_name": "an8"
+                },
+                {
+                    "para_from": 276,
+                    "para_to": 463,
+                    "book_name": "an9"
+                },
+                {
+                    "para_from": 464,
+                    "para_to": 773,
+                    "book_name": "an10"
+                },
+                {
+                    "para_from": 774,
+                    "para_to": 868,
+                    "book_name": "an11"
+                }
+            ]
+        },
+        "185": {
+            "max_paragraph": 1391,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 226,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "dīghanikāya",
+                        "ṭīkā",
+                        "sīlakkhandhavaggaṭīkā",
+                        "līnatthappakāsanā",
+                        "sīlakkhandhavagga",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 120,
+                    "book_name": "dn1_A"
+                },
+                {
+                    "para_from": 121,
+                    "para_to": 1391,
+                    "book_name": "dn1"
+                }
+            ]
+        },
+        "186": {
+            "max_paragraph": 1495,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 227,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "mahāvagga",
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "dīghanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1495,
+                    "book_name": "dn2"
+                }
+            ]
+        },
+        "187": {
+            "max_paragraph": 1132,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 228,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "pāthikavagga",
+                        "sutta",
+                        "dīghanikāya",
+                        "ṭīkā",
+                        "līnatthappakāsanā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1132,
+                    "book_name": "dn3"
+                }
+            ]
+        },
+        "188": {
+            "max_paragraph": 1574,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 229,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "abhinavaṭīkā",
+                        "sādhuvilāsinī",
+                        "sutta",
+                        "ṭīkā",
+                        "dīghanikāya",
+                        "sīlakkhandhavagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 458,
+                    "book_name": "dn1_A"
+                },
+                {
+                    "para_from": 459,
+                    "para_to": 1574,
+                    "book_name": "dn1"
+                }
+            ]
+        },
+        "189": {
+            "max_paragraph": 1366,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 230,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "sādhuvilāsinī",
+                        "abhinavaṭīkā",
+                        "dīghanikāya",
+                        "sutta",
+                        "ṭīkā",
+                        "sīlakkhandhavagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1366,
+                    "book_name": "dn1"
+                }
+            ]
+        },
+        "190": {
+            "max_paragraph": 764,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 231,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "netti",
+                        "khuddakanikāya",
+                        "ṭīkā",
+                        "sutta",
+                        "nettippakaraṇa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 764,
+                    "book_name": "kn19"
+                }
+            ]
+        },
+        "191": {
+            "max_paragraph": 1670,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 232,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "nettivibhāvinī",
+                        "ṭīkā",
+                        "sutta",
+                        "khuddakanikāya",
+                        "netti"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1670,
+                    "book_name": "kn19"
+                }
+            ]
+        },
+        "192": {
+            "max_paragraph": 2388,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 233,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "mūlapaṇṇāsa",
+                        "majjhimanikāya",
+                        "sutta",
+                        "ṭīkā",
+                        "līnatthappakāsanā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 89,
+                    "book_name": "mn1_A"
+                },
+                {
+                    "para_from": 90,
+                    "para_to": 2388,
+                    "book_name": "mn1"
+                }
+            ]
+        },
+        "193": {
+            "max_paragraph": 906,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 234,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "sutta",
+                        "majjhimanikāya",
+                        "majjhimapaṇṇāsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 906,
+                    "book_name": "mn2"
+                }
+            ]
+        },
+        "194": {
+            "max_paragraph": 858,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 235,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "sutta",
+                        "majjhimanikāya",
+                        "uparipaṇṇāsa"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 858,
+                    "book_name": "mn3"
+                }
+            ]
+        },
+        "195": {
+            "max_paragraph": 1705,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 236,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "līnatthappakāsanā",
+                        "sagāthāvagga",
+                        "saṃyuttanikāya",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1705,
+                    "book_name": "sn1"
+                }
+            ]
+        },
+        "196": {
+            "max_paragraph": 1027,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 237,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "saṃyuttanikāya",
+                        "nidānavagga",
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "sutta"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 1027,
+                    "book_name": "sn2"
+                }
+            ]
+        },
+        "197": {
+            "max_paragraph": 520,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 238,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "khandhavagga",
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "saṃyuttanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 520,
+                    "book_name": "sn3"
+                }
+            ]
+        },
+        "198": {
+            "max_paragraph": 729,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 239,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "saḷāyatanavagga",
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "saṃyuttanikāya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 729,
+                    "book_name": "sn4"
+                }
+            ]
+        },
+        "199": {
+            "max_paragraph": 850,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 240,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "sutta",
+                        "saṃyuttanikāya",
+                        "līnatthappakāsanā",
+                        "ṭīkā",
+                        "mahāvagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 850,
+                    "book_name": "sn5"
+                }
+            ]
+        },
+        "200": {
+            "max_paragraph": 13281,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 241,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "vinicchaya",
+                        "vinayavinicchaya",
+                        "vinaya",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 242,
+                    "from_paragraph": 10176,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "uttaravinicchaya",
+                        "vinicchaya",
+                        "vinaya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 10175,
+                    "book_name": "vin8"
+                },
+                {
+                    "para_from": 10176,
+                    "para_to": 13281,
+                    "book_name": "vin9"
+                }
+            ]
+        },
+        "201": {
+            "max_paragraph": 5124,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 243,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "vinayavinicchayaṭīkā",
+                        "ṭīkā",
+                        "vinaya",
+                        "vinayavinicchaya",
+                        "vinicchaya"
+                    ]
+                },
+                {
+                    "book_id": 244,
+                    "from_paragraph": 4270,
+                    "type": "tika",
+                    "tags": [
+                        "uttaravinicchayaṭīkā",
+                        "ṭīkā",
+                        "vinaya",
+                        "uttaravinicchaya",
+                        "vinicchaya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1,
+                    "book_name": "vin9"
+                },
+                {
+                    "para_from": 2,
+                    "para_to": 4269,
+                    "book_name": "vin8"
+                },
+                {
+                    "para_from": 4270,
+                    "para_to": 5124,
+                    "book_name": "vin9"
+                }
+            ]
+        },
+        "202": {
+            "max_paragraph": 2992,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 245,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "pācityādiyojanā",
+                        "yojanā",
+                        "pācittiyapāḷi",
+                        "ṭīkā",
+                        "vinaya",
+                        "suttavibhaṅga",
+                        "uttaravinicchayaṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1005,
+                    "book_name": "vin2"
+                },
+                {
+                    "para_from": 1006,
+                    "para_to": 1850,
+                    "book_name": "vin3"
+                },
+                {
+                    "para_from": 1851,
+                    "para_to": 2423,
+                    "book_name": "vin4"
+                },
+                {
+                    "para_from": 2424,
+                    "para_to": 2992,
+                    "book_name": "vin5"
+                }
+            ]
+        },
+        "203": {
+            "max_paragraph": 3631,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 246,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "vinaya",
+                        "khuddasikkhā",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 247,
+                    "from_paragraph": 1620,
+                    "type": "tika",
+                    "tags": [
+                        "vinaya",
+                        "khuddasikkhā",
+                        "purāṇaṭīkā",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 248,
+                    "from_paragraph": 2361,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "vinaya",
+                        "abhinavaṭīkā",
+                        "khuddasikkhā"
+                    ]
+                },
+                {
+                    "book_id": 249,
+                    "from_paragraph": 3100,
+                    "type": "tika",
+                    "tags": [
+                        "vinaya",
+                        "ṭīkā",
+                        "mūlasikkhā"
+                    ]
+                },
+                {
+                    "book_id": 250,
+                    "from_paragraph": 3481,
+                    "type": "tika",
+                    "tags": [
+                        "mūlasikkhā",
+                        "ṭīkā",
+                        "vinaya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 3104,
+                    "book_name": "vin10"
+                },
+                {
+                    "para_from": 3105,
+                    "para_to": 3631,
+                    "book_name": "vin11"
+                }
+            ]
+        },
+        "204": {
+            "max_paragraph": 1659,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 251,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "paṭhamo bhāgo",
+                        "ṭīkā",
+                        "dīpanī",
+                        "vinaya",
+                        "suttavibhaṅga",
+                        "mahāvibhaṅga",
+                        "sāratthadīpanī",
+                        "pārājikapāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1659,
+                    "book_name": "vin1"
+                }
+            ]
+        },
+        "205": {
+            "max_paragraph": 1660,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 252,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "mahāvibhaṅga",
+                        "pārājikapāḷi",
+                        "sāratthadīpanī",
+                        "ṭīkā",
+                        "dīpanī",
+                        "vinaya",
+                        "dutiyo bhāgo",
+                        "suttavibhaṅga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1660,
+                    "book_name": "vin1"
+                }
+            ]
+        },
+        "206": {
+            "max_paragraph": 2401,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 253,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "dīpanī",
+                        "ṭīkā",
+                        "vinaya",
+                        "suttavibhaṅga",
+                        "mahāvibhaṅga",
+                        "pācittiyapāḷi",
+                        "sāratthadīpanī",
+                        "tatiyo bhāgo"
+                    ]
+                },
+                {
+                    "book_id": 254,
+                    "from_paragraph": 717,
+                    "type": "tika",
+                    "tags": [
+                        "sāratthadīpanī",
+                        "vinaya",
+                        "khandhaka",
+                        "mahāvagga",
+                        "ṭīkā",
+                        "dīpanī"
+                    ]
+                },
+                {
+                    "book_id": 255,
+                    "from_paragraph": 1753,
+                    "type": "tika",
+                    "tags": [
+                        "cūḷavagga",
+                        "ṭīkā",
+                        "dīpanī",
+                        "vinaya",
+                        "khandhaka",
+                        "sāratthadīpanī"
+                    ]
+                },
+                {
+                    "book_id": 256,
+                    "from_paragraph": 2154,
+                    "type": "tika",
+                    "tags": [
+                        "sāratthadīpanī",
+                        "ṭīkā",
+                        "dīpanī",
+                        "vinaya",
+                        "parivāra",
+                        "parivārapāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 716,
+                    "book_name": "vin2"
+                },
+                {
+                    "para_from": 717,
+                    "para_to": 1752,
+                    "book_name": "vin3"
+                },
+                {
+                    "para_from": 1753,
+                    "para_to": 2153,
+                    "book_name": "vin4"
+                },
+                {
+                    "para_from": 2154,
+                    "para_to": 2401,
+                    "book_name": "vin5"
+                }
+            ]
+        },
+        "207": {
+            "max_paragraph": 2713,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 257,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "dvemātikāpāḷi",
+                        "bhikkhupātimokkha",
+                        "pāḷi",
+                        "vinaya",
+                        "ṭīkā",
+                        "pātimokkha"
+                    ]
+                },
+                {
+                    "book_id": 258,
+                    "from_paragraph": 524,
+                    "type": "tika",
+                    "tags": [
+                        "dvemātikāpāḷi",
+                        "ṭīkā",
+                        "vinaya",
+                        "pāḷi",
+                        "bhikkhunī",
+                        "bhikkhupātimokkha",
+                        "pātimokkha"
+                    ]
+                },
+                {
+                    "book_id": 259,
+                    "from_paragraph": 1215,
+                    "type": "tika",
+                    "tags": [
+                        "dvemātikāpāḷi",
+                        "pātimokkha",
+                        "vinaya",
+                        "ṭīkā",
+                        "kaṅkhāvitaraṇī"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2713,
+                    "book_name": "vin6"
+                }
+            ]
+        },
+        "208": {
+            "max_paragraph": 1673,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 260,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "vinayasaṅgaha",
+                        "ṭīkā",
+                        "vinaya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1673,
+                    "book_name": "vin7"
+                }
+            ]
+        },
+        "209": {
+            "max_paragraph": 2673,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 261,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "vajirabuddhi",
+                        "vinaya",
+                        "ṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 991,
+                    "book_name": "vin1"
+                },
+                {
+                    "para_from": 992,
+                    "para_to": 1714,
+                    "book_name": "vin2"
+                },
+                {
+                    "para_from": 1715,
+                    "para_to": 2216,
+                    "book_name": "vin3"
+                },
+                {
+                    "para_from": 2217,
+                    "para_to": 2427,
+                    "book_name": "vin4"
+                },
+                {
+                    "para_from": 2428,
+                    "para_to": 2673,
+                    "book_name": "vin5"
+                }
+            ]
+        },
+        "210": {
+            "max_paragraph": 3137,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 267,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "vinaya",
+                        "suttavibhaṅga",
+                        "mahāvibhaṅga",
+                        "pārājikapāḷi",
+                        "vimativinodanī"
+                    ]
+                },
+                {
+                    "book_id": 268,
+                    "from_paragraph": 1658,
+                    "type": "tika",
+                    "tags": [
+                        "ṭīkā",
+                        "vimativinodanī",
+                        "pācittiyapāḷi",
+                        "bhikkhunī",
+                        "bhikkhunīvibhaṅga",
+                        "suttavibhaṅga",
+                        "vinaya"
+                    ]
+                },
+                {
+                    "book_id": 269,
+                    "from_paragraph": 1779,
+                    "type": "tika",
+                    "tags": [
+                        "vinaya",
+                        "mahāvagga",
+                        "khandhaka",
+                        "vimativinodanī",
+                        "ṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 270,
+                    "from_paragraph": 2431,
+                    "type": "tika",
+                    "tags": [
+                        "khandhaka",
+                        "cūḷavagga",
+                        "vimativinodanī",
+                        "ṭīkā",
+                        "vinaya"
+                    ]
+                },
+                {
+                    "book_id": 271,
+                    "from_paragraph": 2792,
+                    "type": "tika",
+                    "tags": [
+                        "vinaya",
+                        "parivārapāḷi",
+                        "parivāra",
+                        "vimativinodanī",
+                        "ṭīkā"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1182,
+                    "book_name": "vin1"
+                },
+                {
+                    "para_from": 1183,
+                    "para_to": 1778,
+                    "book_name": "vin2"
+                },
+                {
+                    "para_from": 1779,
+                    "para_to": 2430,
+                    "book_name": "vin3"
+                },
+                {
+                    "para_from": 2431,
+                    "para_to": 2791,
+                    "book_name": "vin4"
+                },
+                {
+                    "para_from": 2792,
+                    "para_to": 3137,
+                    "book_name": "vin5"
+                }
+            ]
+        },
+        "211": {
+            "max_paragraph": 2414,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 272,
+                    "from_paragraph": 3,
+                    "type": "tika",
+                    "tags": [
+                        "vinayālaṅkāra",
+                        "ṭīkā",
+                        "vinaya"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 1934,
+                    "book_name": "vin7"
+                },
+                {
+                    "para_from": 1935,
+                    "para_to": 2414,
+                    "book_name": "vin7_A"
+                }
+            ]
+        },
+        "212": {
+            "max_paragraph": 2517,
+            "name_source": "old_table",
+            "file_types": [
+                {
+                    "book_id": 273,
+                    "from_paragraph": 2,
+                    "type": "tika",
+                    "tags": [
+                        "vinaya",
+                        "pātimokkha",
+                        "kaṅkhāvitaraṇī",
+                        "ṭīkā",
+                        "purāṇaṭīkā"
+                    ]
+                },
+                {
+                    "book_id": 274,
+                    "from_paragraph": 671,
+                    "type": "tika",
+                    "tags": [
+                        "abhinavaṭīkā",
+                        "vinaya",
+                        "ṭīkā",
+                        "kaṅkhāvitaraṇī",
+                        "pātimokkha"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 2517,
+                    "book_name": "vin6"
+                }
+            ]
+        },
+        "213": {
+            "max_paragraph": 2477,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 275,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pārājika",
+                        "vinaya",
+                        "mūla",
+                        "pāḷi",
+                        "suttavibhaṅga",
+                        "mahāvibhaṅga",
+                        "pārājikapāḷi"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2477,
+                    "book_name": "vin1"
+                }
+            ]
+        },
+        "214": {
+            "max_paragraph": 3690,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 276,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pācittiyapāḷi",
+                        "mūla",
+                        "vinaya",
+                        "pāḷi",
+                        "mahāvibhaṅga",
+                        "suttavibhaṅga"
+                    ]
+                },
+                {
+                    "book_id": 281,
+                    "from_paragraph": 2162,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "suttavibhaṅga",
+                        "pācittiyapāḷi",
+                        "bhikkhunī",
+                        "bhikkhunīvibhaṅga",
+                        "vinaya",
+                        "mūla"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 3690,
+                    "book_name": "vin2"
+                }
+            ]
+        },
+        "215": {
+            "max_paragraph": 2759,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 277,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "mūla",
+                        "vinaya",
+                        "khandhaka",
+                        "mahāvagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2759,
+                    "book_name": "vin3"
+                }
+            ]
+        },
+        "216": {
+            "max_paragraph": 2821,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 278,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "khandhaka",
+                        "vinaya",
+                        "mūla",
+                        "pāḷi",
+                        "cūḷavagga"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 2821,
+                    "book_name": "vin4"
+                }
+            ]
+        },
+        "217": {
+            "max_paragraph": 3645,
+            "name_source": "wbw_book_tag",
+            "file_types": [
+                {
+                    "book_id": 279,
+                    "from_paragraph": 3,
+                    "type": "mula",
+                    "tags": [
+                        "pāḷi",
+                        "mūla",
+                        "vinaya",
+                        "parivāra"
+                    ]
+                }
+            ],
+            "segments": [
+                {
+                    "para_from": 3,
+                    "para_to": 3645,
+                    "book_name": "vin5"
+                }
+            ]
+        }
+    },
+    "overrides": {
+        "107": {
+            "reason": "旧表把 book 107(apadāna-aṭṭhakathā)切成 kn10_A(para 3-2141)与 kn10_B(para 2142-3875),并声称后者对应 therī。实测标题证伪:para 2146 的标题是「(Dutiyo bhāgo) Therāpadānaṃ」——那是 therāpadāna 的第二卷而非 therīapadāna;全书只有一个 level-1 标题「Apadāna-aṭṭhakathā」,vagga 编到 56(Yasavaggo)也正是 therāpadāna 的范围,书内无任何 therī 标题。therīapadāna 另在 book 144 para 6534 起(level-1「Therīapadānapāḷi」,wbw 标记 kn11@6532)。故 book 107 整本归 kn10,与 mūla 侧 books 143/144 的 kn10 对齐。",
+            "segments": [
+                {
+                    "para_from": 1,
+                    "para_to": 999999,
+                    "book_name": "kn10"
+                }
+            ]
+        }
+    }
+}

+ 264 - 0
api-v13/scripts/related/build_book_config.php

@@ -0,0 +1,264 @@
+<?php
+
+/**
+ * 生成书级配置表 book_config.json:每本 VRI 文件的类型(mūla/义注/复注)与
+ * 书名分段(哪一段段落属于哪个 book_name)。
+ *
+ * 为什么需要:123 本文件的 wbw 标记里完全没有书名信息(只有裸 paraN),书名要从
+ * 别处来。证据按可信度排序:
+ *   1. wbw 的 book_tag 标记(dn1@3、an3@323)——文件自带的书界,最硬
+ *   2. wbw 的 paraN_xxx 后缀——逐段自带书名
+ *   3. 旧表的主导书名——最后兜底。旧表的错在 cs 值不在书名上,唯一例外是
+ *      kn10_A/kn10_B,而那两本恰好有 book_tag 证据,会被 1 覆盖掉。
+ *
+ * overrides 区是人工修正区,脚本不动它,每次重跑都保留。
+ *
+ * 用法:php scripts/related/build_book_config.php [--baseline=related_paragraphs_bak_20260909]
+ */
+
+require __DIR__.'/lib/boot.php';
+
+use Illuminate\Support\Facades\DB;
+
+[$options] = rp_args($argv);
+$baseline = rp_assert_table($options['baseline'] ?? 'related_paragraphs_bak_20260909');
+$markers = $options['markers'] ?? 'rp_markers';
+$configPath = __DIR__.'/book_config.json';
+
+$log = new RpLogger('build_book_config', rp_report_dir());
+$log->info("书名兜底基线:$baseline");
+
+// 已有的人工修正区必须原样带过来,否则每次重跑都把人的判断冲掉。
+$overrides = new stdClass;
+if (file_exists($configPath)) {
+    $existing = rp_json_read($configPath)['overrides'] ?? [];
+    $overrides = $existing === [] ? new stdClass : (object) $existing;
+    $log->info('保留已有 overrides:'.count((array) $overrides).' 条');
+}
+
+// ── 文件类型:按 level-1 段落的 tag 判定,粒度是 book_id 不是 VRI 文件 ──────
+// book 207 一个文件里既有 pāḷi 又有 ṭīkā,按文件判会判错。
+$typeRows = DB::select("
+    select p.book, p.paragraph, bt.sn as book_id, string_agg(t.name, ',') as tags
+    from pali_texts p
+    join tag_maps m on m.anchor_id = p.uid and m.table_name = 'pali_texts'
+    join tags t on t.id = m.tag_id
+    left join book_titles bt on bt.book = p.book and bt.paragraph = p.paragraph
+    where p.level = 1
+    group by p.book, p.paragraph, bt.sn
+    order by p.book, p.paragraph
+");
+
+$fileTypes = [];
+foreach ($typeRows as $row) {
+    $tags = explode(',', $row->tags);
+    $type = match (true) {
+        (bool) array_intersect($tags, ['ṭīkā', 'mūlaṭīkā', 'anuṭīkā', 'abhinavaṭīkā', 'purāṇaṭīkā']) => 'tika',
+        in_array('aṭṭhakathā', $tags, true) => 'atthakatha',
+        (bool) array_intersect($tags, ['mūla', 'pāḷi']) => 'mula',
+        default => 'unknown',
+    };
+    $fileTypes[$row->book][] = [
+        'book_id' => $row->book_id,
+        'from_paragraph' => $row->paragraph,
+        'type' => $type,
+        'tags' => $tags,
+    ];
+    $log->count("file_type.$type");
+    if ($type === 'unknown') {
+        $log->unresolved('file_type_unknown', [
+            'book' => $row->book, 'paragraph' => $row->paragraph, 'tags' => $row->tags,
+        ]);
+    }
+}
+
+// ── 书名证据 ─────────────────────────────────────────────────────────────
+$books = DB::select('select distinct book from pali_texts order by book');
+$config = [];
+
+foreach ($books as $b) {
+    $book = $b->book;
+    $maxPara = (int) DB::table('pali_texts')->where('book', $book)->max('paragraph');
+
+    // 证据 1:book_tag 标记,给出文件内的书界切换点
+    $tagMarks = DB::select(
+        "select paragraph, book_name from $markers where book = ? and kind = 'book_tag' order by paragraph",
+        [$book]
+    );
+
+    // 证据 2:paraN_xxx 后缀,逐段自带书名
+    $suffixMarks = DB::select(
+        "select paragraph, book_name from $markers
+         where book = ? and kind in ('single','interval') and book_name is not null
+         order by paragraph, wid",
+        [$book]
+    );
+
+    // 证据 3:旧表逐段落的名字,按连续段压缩。
+    // 空书名也必须成段——book 177 一个文件里装了四部书,只有头一部是 abhi8,
+    // 后三部(nāmarūpaparicchedo 等)本来就没有 SC 书名。早先过滤掉空名,
+    // 结果 abhi8 越过书界铺满全文件,把 10695 行错配进了 abhi8 的注释链。
+    $oldNames = DB::select(
+        "select para, max(book_name) as book_name from $baseline where book = ?
+         group by para order by para",
+        [$book]
+    );
+
+    $source = match (true) {
+        $tagMarks !== [] => 'wbw_book_tag',
+        $suffixMarks !== [] => 'wbw_suffix',
+        $oldNames !== [] => 'old_table',
+        default => 'none',
+    };
+
+    $points = [];   // paragraph => book_name 的切换点
+    if ($source === 'wbw_book_tag') {
+        foreach ($tagMarks as $m) {
+            $points[(int) $m->paragraph] = $m->book_name;
+        }
+        // book_tag 只给书界,段内若还有后缀且与之矛盾,记下来复核
+        foreach ($suffixMarks as $m) {
+            $expected = null;
+            foreach ($points as $p => $n) {
+                if ($p <= $m->paragraph) {
+                    $expected = $n;
+                }
+            }
+            if ($expected !== null && $expected !== $m->book_name) {
+                $log->count('name_conflict.tag_vs_suffix');
+                $log->unresolved('name_conflict_tag_vs_suffix', [
+                    'book' => $book, 'paragraph' => (int) $m->paragraph,
+                    'book_tag_says' => $expected, 'suffix_says' => $m->book_name,
+                ]);
+            }
+        }
+    } elseif ($source === 'wbw_suffix') {
+        $prev = null;
+        foreach ($suffixMarks as $m) {
+            if ($m->book_name !== $prev) {
+                $points[(int) $m->paragraph] = $m->book_name;
+                $prev = $m->book_name;
+            }
+        }
+    } elseif ($source === 'old_table') {
+        $prev = null;
+        foreach ($oldNames as $m) {
+            // 序言名 dn1_A 是义注开头的正常设计,保留;其余同名连续段合并
+            if ($m->book_name !== $prev) {
+                $points[(int) $m->para] = $m->book_name;
+                $prev = $m->book_name;
+            }
+        }
+    }
+
+    // 义注/复注开头的序言段用 {book}_A 命名(dn1_A 型,全库 12 本)。wbw 里带
+    // {mula}_0 章标记的书(99/103/130/133)导出器能自己认出来,但另有 6 本
+    // (181/185/188/192 及 179/211 的文件中段)wbw 完全没有痕迹,序言范围只存在于
+    // 旧表里。这里把旧表的 _A 连续段叠加进切换点,免得序言被并进正文名下。
+    if ($source !== 'old_table') {
+        // 注意:序言段里出现 paraN_mula 标记是正常的,不能拿首个 cs 标记当序言终点。
+        // book 130 的序言(mn1_0@5)里就有 para1_mn1@40,序言真正的终点是章标记
+        // mn1_1@47;book 192 同样。序言段照旧表原样叠加即可。
+        $runName = null;
+        $runFrom = null;
+        $flushRun = function (int $endPara) use (&$points, &$runName, &$runFrom, $log, $book, $oldNames) {
+            if ($runName === null) {
+                return;
+            }
+            $base = preg_replace('/_A$/', '', $runName);
+
+            // 真序言的后面一定跟着正文(基名)。book 143 的 kn10_A 铺满整个文件、
+            // 后面根本没有 kn10——那是 E3 的错名而不是序言,绝不能叠加进来。
+            $baseFollows = false;
+            foreach ($oldNames as $row) {
+                if ((int) $row->para > $endPara && $row->book_name === $base) {
+                    $baseFollows = true;
+                    break;
+                }
+            }
+            if (! $baseFollows) {
+                $log->count('prologue_overlay.rejected');
+                $log->info("book $book 拒绝叠加 $runName@$runFrom-{$endPara}:其后无 $base 正文,判为错名而非序言");
+                $runName = null;
+                $runFrom = null;
+
+                return;
+            }
+            // 序言区间内的旧切换点要清掉:book_tag 的 dn1@3 落在 dn1_A@1-198 中间,
+            // 不清就会把序言从 para 3 截断,只剩两段。
+            $base = $points[$endPara + 1] ?? $base;
+            foreach (array_keys($points) as $existing) {
+                if ($existing > $runFrom && $existing <= $endPara) {
+                    unset($points[$existing]);
+                }
+            }
+            $points[$runFrom] = $runName;
+            if (! isset($points[$endPara + 1])) {
+                $points[$endPara + 1] = $base;
+            }
+            $log->count('prologue_overlay');
+            $log->info("book $book 叠加序言段 $runName@$runFrom-$endPara");
+            $runName = null;
+            $runFrom = null;
+        };
+        $lastPara = null;
+        foreach ($oldNames as $m) {
+            $para = (int) $m->para;
+            $isPrologue = str_ends_with((string) $m->book_name, '_A');
+            if ($isPrologue && $m->book_name === $runName && $para === $lastPara + 1) {
+                $lastPara = $para;
+
+                continue;
+            }
+            if ($runName !== null) {
+                $flushRun($lastPara);
+            }
+            if ($isPrologue) {
+                $runName = $m->book_name;
+                $runFrom = $para;
+            }
+            $lastPara = $para;
+        }
+        if ($runName !== null) {
+            $flushRun($lastPara);
+        }
+        ksort($points);
+    }
+
+    // 切换点 → 区间
+    $segments = [];
+    $keys = array_keys($points);
+    foreach ($keys as $i => $from) {
+        $segments[] = [
+            'para_from' => $from,
+            'para_to' => isset($keys[$i + 1]) ? $keys[$i + 1] - 1 : $maxPara,
+            'book_name' => $points[$from],
+        ];
+    }
+
+    $config[(string) $book] = [
+        'max_paragraph' => $maxPara,
+        'name_source' => $source,
+        'file_types' => $fileTypes[$book] ?? [],
+        'segments' => $segments,
+    ];
+    $log->count("name_source.$source");
+    if ($source === 'none') {
+        $log->unresolved('book_name_unknown', ['book' => $book]);
+    }
+    if (count($segments) > 1) {
+        $log->info(sprintf('book %-3d %-14s %d 段:%s', $book, $source, count($segments),
+            implode(' ', array_map(fn ($s) => "{$s['book_name']}@{$s['para_from']}", $segments))));
+    }
+}
+
+rp_json_write($configPath, [
+    'generated_at' => date('c'),
+    'baseline_table' => $baseline,
+    'purpose' => '每本 VRI 文件的类型与书名分段。导出器优先用 wbw 现场证据,此表只在文件本身没有书名信息时兜底。overrides 是人工修正区,重跑不覆盖。',
+    'books' => $config,
+    'overrides' => $overrides,
+]);
+$log->info("配置表:{$configPath}(".count($config).' 本)');
+
+$log->finish();

+ 129 - 0
api-v13/scripts/related/build_markers.php

@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * 把 wbw_templates 里的 .ctl. 锚点解析成工作表 rp_markers。
+ *
+ * 导出器和检测器都要按标记做集合运算,逐次在 PHP 里重解析 33 万行既慢又容易两边
+ * 规则跑偏,所以物化一次、共用一份。改了 MarkerParser 就要重跑这个脚本。
+ *
+ * 用法:php scripts/related/build_markers.php [--table=rp_markers]
+ */
+
+require __DIR__.'/lib/boot.php';
+require __DIR__.'/lib/MarkerParser.php';
+
+use Illuminate\Support\Facades\DB;
+
+[$options] = rp_args($argv);
+$table = $options['table'] ?? 'rp_markers';
+if (! preg_match('/^rp_[a-z0-9_]+$/', $table)) {
+    throw new InvalidArgumentException("工作表名必须以 rp_ 开头:$table");
+}
+
+$log = new RpLogger('build_markers', rp_report_dir());
+$log->info("目标工作表:$table");
+
+DB::statement("drop table if exists $table");
+DB::statement("
+    create table $table (
+        book        integer not null,
+        paragraph   integer not null,
+        wid         integer not null,
+        word        varchar(1024) not null,
+        kind        varchar(16) not null,
+        book_name   varchar(64),
+        cs_from     integer,
+        cs_to       integer,
+        cs_count    integer not null default 0,
+        numbers     varchar(64),
+        is_abbrev   boolean not null default false,
+        repaired    text,
+        error       text
+    )
+");
+
+$total = DB::table('wbw_templates')->where('type', '.ctl.')->where('style', '#a#')->count();
+$log->info("待解析锚点:$total 行");
+
+$buffer = [];
+$written = 0;
+
+$flush = function () use (&$buffer, &$written, $table, $log) {
+    if ($buffer === []) {
+        return;
+    }
+    DB::table($table)->insert($buffer);
+    $written += count($buffer);
+    $buffer = [];
+    if ($written % 50000 === 0) {
+        $log->info("  已写入 $written 行");
+    }
+};
+
+DB::table('wbw_templates')
+    ->where('type', '.ctl.')
+    ->where('style', '#a#')
+    ->select('book', 'paragraph', 'wid', 'word')
+    ->orderBy('book')->orderBy('paragraph')->orderBy('wid')
+    ->chunk(20000, function ($chunk) use (&$buffer, $flush, $log) {
+        foreach ($chunk as $row) {
+            $parsed = MarkerParser::parse($row->word);
+            $log->count('kind.'.$parsed['kind']);
+
+            // 缩写区间:右端位数少于左端,正是旧生成器翻车的那一类,单独打标以便统计。
+            $isAbbrev = false;
+            if ($parsed['kind'] === MarkerParser::KIND_INTERVAL
+                && preg_match('/^para([0-9]+)-([0-9]+)/', $row->word, $m)
+                && strlen($m[2]) < strlen($m[1])) {
+                $isAbbrev = true;
+                $log->count('interval.abbrev');
+            }
+
+            if ($parsed['error']) {
+                $log->unresolved('marker_parse_failed', [
+                    'book' => $row->book, 'paragraph' => $row->paragraph,
+                    'word' => $row->word, 'detail' => $parsed['error'],
+                ]);
+            }
+            if ($parsed['repaired']) {
+                $log->warn("修补标记 book={$row->book} para={$row->paragraph}: {$parsed['repaired']}");
+                $log->unresolved('marker_repaired', [
+                    'book' => $row->book, 'paragraph' => $row->paragraph,
+                    'word' => $row->word, 'detail' => $parsed['repaired'],
+                ]);
+            }
+
+            $buffer[] = [
+                'book' => $row->book,
+                'paragraph' => $row->paragraph,
+                'wid' => $row->wid,
+                'word' => $row->word,
+                'kind' => $parsed['kind'],
+                'book_name' => $parsed['book_name'],
+                'cs_from' => $parsed['cs'] === [] ? null : $parsed['cs'][0],
+                'cs_to' => $parsed['cs'] === [] ? null : end($parsed['cs']),
+                'cs_count' => count($parsed['cs']),
+                'numbers' => $parsed['numbers'] ? implode('.', $parsed['numbers']) : null,
+                'is_abbrev' => $isAbbrev,
+                'repaired' => $parsed['repaired'],
+                'error' => $parsed['error'],
+            ];
+            if (count($buffer) >= 5000) {
+                $flush();
+            }
+        }
+    });
+$flush();
+
+$log->info("写入完成:$written 行");
+if ($written !== $total) {
+    $log->error("行数不符:源 $total vs 写入 $written");
+}
+
+$log->info('建索引中…');
+DB::statement("create index on $table (book, paragraph)");
+DB::statement("create index on $table (kind)");
+DB::statement("create index on $table (book_name)");
+DB::statement("create index on $table (is_abbrev) where is_abbrev");
+
+$log->finish();

+ 345 - 0
api-v13/scripts/related/check.php

@@ -0,0 +1,345 @@
+<?php
+
+/**
+ * related_paragraphs 记分卡:按 known_issues.json 的探测器给任意一张 related 表打分。
+ *
+ * 这是整个重建工程的标尺——每一轮「导出 → 检测 → 交给模型评估 → 改规则」都靠它
+ * 回答两个问题:错误变少了没有?本来正确的书有没有被搞坏?
+ *
+ * 用法:
+ *   php scripts/related/check.php --table=related_paragraphs_bak_20260909 --save-baseline
+ *   php scripts/related/check.php --table=related_paragraphs_v1
+ *
+ * 依赖 rp_markers(先跑 build_markers.php)。
+ */
+
+require __DIR__.'/lib/boot.php';
+
+use Illuminate\Support\Facades\DB;
+
+[$options] = rp_args($argv);
+$table = rp_assert_table($options['table'] ?? 'related_paragraphs');
+$markers = $options['markers'] ?? 'rp_markers';
+$saveBaseline = isset($options['save-baseline']);
+
+$known = rp_json_read(__DIR__.'/known_issues.json');
+$params = $known['params'];
+$log = new RpLogger('check.'.$table, rp_report_dir());
+$log->info("被检表:$table");
+$log->info("标记表:$markers");
+
+$one = fn (string $sql, array $bind = []) => (array) DB::selectOne($sql, $bind);
+$all = fn (string $sql, array $bind = []) => array_map(fn ($r) => (array) $r, DB::select($sql, $bind));
+
+$results = [];
+
+/** 记一条探测结果,并与 known_issues.json 的基线对照。 */
+$record = function (string $id, array $measured, ?string $note = null) use (&$results, $known, $log) {
+    $spec = null;
+    foreach ($known['detectors'] as $d) {
+        if ($d['id'] === $id) {
+            $spec = $d;
+            break;
+        }
+    }
+    $results[$id] = [
+        'title' => $spec['title'] ?? $id,
+        'severity' => $spec['severity'] ?? 'unknown',
+        'baseline' => $spec['baseline'] ?? null,
+        'target_v1' => $spec['target_v1'] ?? null,
+        'measured' => $measured,
+        'note' => $note,
+    ];
+    $log->info(sprintf('[%-24s] %s', $id, json_encode($measured, JSON_UNESCAPED_UNICODE)));
+    if ($note) {
+        $log->info('  '.$note);
+    }
+};
+
+// ── E1 cs 乱码值 ──────────────────────────────────────────────────────────
+$threshold = $params['cs_garbage_threshold'];
+$record('E1_cs_garbage', $one(
+    "select count(*)::int as rows, count(distinct book)::int as books from $table where cs_para > ?",
+    [$threshold]
+));
+
+// ── E2 章回绕:同 (book, book_name) 内 cs 从大值回到 1 ────────────────────
+$record('E2_chapter_wrap', $one("
+    with s as (
+        select book, book_name, cs_para,
+               lag(cs_para) over (partition by book, book_name order by para, cs_para) as prev
+        from $table where cs_para > 0 and book_name <> ''
+    )
+    select count(*)::int as wrap_points, count(distinct book)::int as books
+    from s where cs_para = 1 and prev > 1
+"));
+
+// ── E3 kn10 家族 ─────────────────────────────────────────────────────────
+$record('E3_kn10_missing', $one("
+    select
+        count(*) filter (where book_name = 'kn10')::int   as kn10_rows,
+        count(*) filter (where book_name = 'kn10_A')::int as kn10_a_rows,
+        count(*) filter (where book_name = 'kn10_B')::int as kn10_b_rows
+    from $table
+"));
+
+// ── E4 空 book_name(预期保留) ───────────────────────────────────────────
+$record('E4_empty_book_name', $one(
+    "select count(*)::int as rows, count(distinct book)::int as books from $table where book_name = ''"
+));
+
+// ── E5 book_id 未赋值 ────────────────────────────────────────────────────
+$record('E5_book_id_zero', $one(
+    "select count(*)::int as rows, count(distinct book)::int as books from $table where book_id = 0"
+));
+
+// ── E6 覆盖缺口:wbw 有这个段落,related 没有任何行 ────────────────────────
+$record('E6_coverage_gap', $one("
+    with wbw as (select distinct book, paragraph from pali_texts),
+         rel as (select distinct book, para from $table)
+    select count(*)::int as segments, count(distinct w.book)::int as books
+    from wbw w left join rel r on r.book = w.book and r.para = w.paragraph
+    where r.book is null
+"));
+
+// ── E7 缩写区间:旧生成器在这里丢段或产废值 ────────────────────────────────
+$record('E7_abbrev_interval_lost', $one("
+    with seg as (select distinct book, paragraph from $markers where is_abbrev),
+         hit as (
+            select s.book, s.paragraph,
+                   count(r.id)::int as rows,
+                   count(r.id) filter (where r.cs_para > $threshold)::int as garbage
+            from seg s left join $table r on r.book = s.book and r.para = s.paragraph
+            group by 1, 2
+         )
+    select
+        count(*)::int as marker_segments,
+        count(distinct book)::int as books,
+        count(*) filter (where rows = 0)::int as segments_without_rows,
+        count(*) filter (where rows > 0 and garbage > 0)::int as segments_with_garbage
+    from hit
+"));
+
+// ── E8 书边界污染平铺 ─────────────────────────────────────────────────────
+// 污染的准确签名是「整段一个 cs 标记都没有,却被写进了非零 cs」——那个值只能是
+// 从上一本沿用下来的。早先按「cs 值种类少、行数多」判会把章回绕误判成污染
+// (book 152 有 516 个标记却只 24 个 cs 值,那是 22 次回绕),按标记判才分得开。
+// cs 恒为 0 的整段不算污染:0 是「未赋值」,不是编造出来的值。
+$flat = $all("
+    with seg as (
+        select bt.book, bt.sn as book_id, bt.paragraph as p_from,
+               coalesce(lead(bt.paragraph) over (partition by bt.book order by bt.paragraph) - 1, 2147483647) as p_to
+        from book_titles bt
+    ),
+    book_marks as (
+        select book, count(*) as n from $markers where kind in ('single','interval') group by 1
+    )
+    select s.book, s.book_id, s.p_from, x.rows, x.max_cs, x.vals
+    from seg s
+    join book_marks bm on bm.book = s.book
+    cross join lateral (
+        select count(*)::int as rows, coalesce(max(cs_para), 0)::int as max_cs,
+               count(distinct cs_para)::int as vals
+        from $table r where r.book = s.book and r.para between s.p_from and s.p_to
+    ) x
+    where x.rows > 0 and x.max_cs > 0
+      and not exists (
+        select 1 from $markers m
+        where m.book = s.book and m.paragraph between s.p_from and s.p_to
+          and m.kind in ('single','interval')
+      )
+    order by x.rows desc
+");
+$record('E8_flat_pollution', [
+    'groups' => count($flat),
+    'rows' => array_sum(array_column($flat, 'rows')),
+], $flat === [] ? null : '污染段:'.json_encode($flat, JSON_UNESCAPED_UNICODE));
+
+// ── E9 全书无标记:related 有行但 wbw 无 para 标记 ─────────────────────────
+$noMarker = $all("
+    with rel as (select book, count(*)::int as rows from $table group by 1),
+         mk  as (select book, count(*)::int as markers from $markers
+                 where kind in ('single', 'interval') group by 1)
+    select rel.book, rel.rows from rel left join mk on mk.book = rel.book
+    where coalesce(mk.markers, 0) = 0 order by rel.book
+");
+$record('E9_no_marker_books', [
+    'books' => count($noMarker),
+    'book_list' => array_column($noMarker, 'book'),
+], $noMarker === [] ? null : '各本行数:'.json_encode($noMarker, JSON_UNESCAPED_UNICODE));
+
+// ── E10 自造名(预期保留) ────────────────────────────────────────────────
+$record('E10_selfmade_names', $one("
+    select
+        count(*) filter (where book_name = 'NK')::int   as nk_rows,
+        count(*) filter (where book_name like 'subo%')::int as subo_rows,
+        count(*) filter (where book_name = 'dict')::int as dict_rows
+    from $table
+"));
+
+// ── D 连续性:同 (book, book_name, cs_para) 的 para 应构成连续区间 ──────────
+$record('D_continuity', $one("
+    with g as (
+        select book, book_name, cs_para, para,
+               para - row_number() over (partition by book, book_name, cs_para order by para) as grp
+        from $table where cs_para > 0 and book_name <> ''
+    ), seg as (
+        select book, book_name, cs_para, count(distinct grp)::int as segments
+        from g group by 1, 2, 3
+    )
+    select count(*)::int as broken_groups, count(distinct book)::int as books,
+           coalesce(sum(segments - 1), 0)::int as extra_segments
+    from seg where segments > 1
+"));
+
+// ── D 镜像对齐:注释链条两侧同名书的 cs 上界应一致 ─────────────────────────
+$watch = ['dn1', 'kn6', 'kn9', 'abhi5', 'abhi3', 'abhi4', 'abhi6', 'abhi7'];
+$mirror = [];
+foreach ($watch as $name) {
+    // 必须排除乱码值:旧表里 abhi4/5/6/7 的 max 全是六位废值(44022 等),
+    // 不滤掉就看不出真实的跨侧对齐情况。
+    $perFile = $all(
+        "select book, max(cs_para)::int as max_cs, count(*)::int as rows
+         from $table where book_name = ? and cs_para <= ? group by 1 order by 1",
+        [$name, $threshold]
+    );
+    $mirror[$name] = [
+        'overall_max' => $perFile === [] ? null : max(array_column($perFile, 'max_cs')),
+        'per_file' => $perFile,
+    ];
+}
+$aligned = $known['detectors'];
+$expectedMax = [];
+foreach ($aligned as $d) {
+    if ($d['id'] === 'D_mirror_alignment') {
+        $expectedMax = $d['baseline']['aligned'];
+    }
+}
+$deviations = [];
+foreach ($expectedMax as $name => $expected) {
+    if (($mirror[$name]['overall_max'] ?? null) !== $expected) {
+        $deviations[$name] = ['expected' => $expected, 'actual' => $mirror[$name]['overall_max'] ?? null];
+    }
+}
+$record('D_mirror_alignment', [
+    'deviations' => count($deviations),
+    'detail' => $deviations,
+], '各名 max(cs_para):'.json_encode(
+    array_map(fn ($m) => $m['overall_max'], $mirror),
+    JSON_UNESCAPED_UNICODE
+));
+$results['D_mirror_alignment']['per_file'] = $mirror;
+
+// ── D 区间展开:区间标记的展开行数必须等于 cs_to − cs_from + 1 ──────────────
+$record('D_interval_expansion', $one("
+    with mk as (
+        select book, paragraph, min(cs_from)::int as cs_from, max(cs_to)::int as cs_to,
+               max(cs_to) - min(cs_from) + 1 as expect
+        from $markers where kind = 'interval' group by 1, 2
+    ), got as (
+        select mk.book, mk.paragraph, mk.expect,
+               count(distinct r.cs_para)::int as actual
+        from mk left join $table r on r.book = mk.book and r.para = mk.paragraph
+             and r.cs_para between mk.cs_from and mk.cs_to
+        group by 1, 2, 3
+    )
+    select count(*)::int as interval_markers,
+           count(*) filter (where actual <> expect)::int as mismatched_markers,
+           count(*) filter (where actual = 0)::int as empty_markers
+    from got
+"));
+
+// ── 逐本记分卡:把 book 级错误信号汇总,零信号的书即基线冻结对象 ─────────────
+$log->info('生成逐本记分卡…');
+$scorecard = $all("
+    with rel as (
+        select book,
+               count(*)::int as rows,
+               count(distinct book_name)::int as names,
+               count(*) filter (where cs_para > $threshold)::int as garbage_rows,
+               count(*) filter (where book_id = 0)::int as no_book_id_rows,
+               count(*) filter (where book_name = '')::int as empty_name_rows
+        from $table group by 1
+    ),
+    wrap as (
+        select book, count(*)::int as wrap_points from (
+            select book, book_name, cs_para,
+                   lag(cs_para) over (partition by book, book_name order by para, cs_para) as prev
+            from $table where cs_para > 0 and book_name <> ''
+        ) s where cs_para = 1 and prev > 1 group by 1
+    ),
+    abbrev as (
+        select s.book, count(*) filter (where h.rows = 0)::int as abbrev_lost from (
+            select distinct book, paragraph from $markers where is_abbrev
+        ) s join lateral (
+            select count(r.id)::int as rows from $table r where r.book = s.book and r.para = s.paragraph
+        ) h on true group by 1
+    ),
+    gap as (
+        select w.book, count(*)::int as gap_segments
+        from (select distinct book, paragraph from wbw_templates) w
+        left join (select distinct book, para from $table) r on r.book = w.book and r.para = w.paragraph
+        where r.book is null group by 1
+    )
+    select rel.book, rel.rows, rel.names, rel.garbage_rows, rel.no_book_id_rows, rel.empty_name_rows,
+           coalesce(wrap.wrap_points, 0) as wrap_points,
+           coalesce(abbrev.abbrev_lost, 0) as abbrev_lost,
+           coalesce(gap.gap_segments, 0) as gap_segments
+    from rel
+    left join wrap on wrap.book = rel.book
+    left join abbrev on abbrev.book = rel.book
+    left join gap on gap.book = rel.book
+    order by rel.book
+");
+
+$flatBooks = [];
+foreach ($flat as $f) {
+    $flatBooks[$f['book']] = ($flatBooks[$f['book']] ?? 0) + 1;
+}
+$clean = [];
+$dirty = [];
+foreach ($scorecard as &$row) {
+    $row['flat_groups'] = $flatBooks[$row['book']] ?? 0;
+    // 空 book_name 是 E4 的预期状态,不算错误信号;其余四类算。
+    $row['signals'] = $row['garbage_rows'] + $row['wrap_points']
+        + $row['abbrev_lost'] + $row['flat_groups'] + $row['gap_segments'];
+    if ($row['signals'] === 0) {
+        $clean[] = $row['book'];
+    } else {
+        $dirty[] = $row['book'];
+    }
+}
+unset($row);
+
+$log->info(sprintf('逐本记分:合格 %d 本,有信号 %d 本,共 %d 本',
+    count($clean), count($dirty), count($scorecard)));
+
+$summary = [
+    'checked_at' => date('c'),
+    'database' => DB::connection()->getDatabaseName(),
+    'table' => $table,
+    'markers_table' => $markers,
+    'total_rows' => DB::table($table)->count(),
+    'detectors' => $results,
+    'books' => ['clean' => $clean, 'dirty' => $dirty, 'scorecard' => $scorecard],
+];
+
+$reportPath = rp_report_dir()."/check.$table.json";
+rp_json_write($reportPath, $summary);
+$log->info("报告:$reportPath");
+
+if ($saveBaseline) {
+    $baselinePath = __DIR__.'/baseline.json';
+    rp_json_write($baselinePath, [
+        'frozen_at' => date('c'),
+        'source_table' => $table,
+        'database' => DB::connection()->getDatabaseName(),
+        'purpose' => '旧表的实测基线。clean_books 是零错误信号的书,重建后这些书一本都不许掉出来;detectors 是各探测器的旧表读数,用于回答「错误是否减少」。',
+        'clean_books' => $clean,
+        'detectors' => array_map(fn ($r) => $r['measured'], $results),
+        'scorecard' => $scorecard,
+    ]);
+    $log->info("基线已冻结:$baselinePath");
+}
+
+$log->finish();

+ 133 - 0
api-v13/scripts/related/diff.php

@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * 两张 related 表的逐段落差异报告。
+ *
+ * 迭代的收敛判据是「每一条 diff 都能归因」——要么是修好了,要么是已知留空,不允许
+ * 有说不清来源的差异。所以这里不只给总数,还按类型分桶并各留样本,供逐轮核对。
+ *
+ * 用法:
+ *   php scripts/related/diff.php --old=related_paragraphs_bak_20260909 --new=related_paragraphs_v1
+ *   php scripts/related/diff.php --new=related_paragraphs_v1 --book=98 --samples=40
+ */
+
+require __DIR__.'/lib/boot.php';
+
+use Illuminate\Support\Facades\DB;
+
+[$options] = rp_args($argv);
+$old = rp_assert_table($options['old'] ?? 'related_paragraphs_bak_20260909');
+$new = rp_assert_table($options['new'] ?? 'related_paragraphs_v1');
+$sampleLimit = (int) ($options['samples'] ?? 15);
+$onlyBooks = isset($options['book']) ? array_map('intval', explode(',', $options['book'])) : null;
+
+$log = new RpLogger('diff', rp_report_dir());
+$log->info("旧:$old");
+$log->info("新:$new");
+
+$bookFilter = $onlyBooks ? 'and book in ('.implode(',', $onlyBooks).')' : '';
+$log->info('比对范围:'.($onlyBooks ? implode(',', $onlyBooks) : '全库'));
+
+// 每个 (book, para) 压成一行「书名:cs 列表」的签名,逐段落比对。
+$sql = "
+    with o as (
+        select book, para,
+               string_agg(distinct book_name || ':' || cs_para, ',' order by book_name || ':' || cs_para) as sig,
+               count(*) as rows
+        from $old where true $bookFilter group by book, para
+    ),
+    n as (
+        select book, para,
+               string_agg(distinct book_name || ':' || cs_para, ',' order by book_name || ':' || cs_para) as sig,
+               count(*) as rows
+        from $new where true $bookFilter group by book, para
+    )
+    select
+        coalesce(o.book, n.book) as book,
+        coalesce(o.para, n.para) as para,
+        o.sig as old_sig, n.sig as new_sig,
+        coalesce(o.rows, 0) as old_rows, coalesce(n.rows, 0) as new_rows,
+        case
+            when o.book is null then 'only_in_new'
+            when n.book is null then 'only_in_old'
+            when o.sig = n.sig then 'same'
+            else 'changed'
+        end as verdict
+    from o full outer join n on n.book = o.book and n.para = o.para
+";
+
+$log->info('比对中…');
+$buckets = [];
+$samples = [];
+$perBook = [];
+$total = 0;
+
+foreach (DB::cursor($sql) as $row) {
+    $total++;
+    $verdict = $row->verdict;
+
+    if ($verdict === 'changed') {
+        // 细分:只是 cs 变了,还是书名也变了
+        $oldNames = [];
+        $newNames = [];
+        foreach (explode(',', (string) $row->old_sig) as $pair) {
+            $oldNames[substr($pair, 0, strrpos($pair, ':'))] = true;
+        }
+        foreach (explode(',', (string) $row->new_sig) as $pair) {
+            $newNames[substr($pair, 0, strrpos($pair, ':'))] = true;
+        }
+        $verdict = array_keys($oldNames) === array_keys($newNames) ? 'cs_changed' : 'name_changed';
+    }
+
+    $buckets[$verdict] = ($buckets[$verdict] ?? 0) + 1;
+    if ($verdict !== 'same') {
+        $perBook[$row->book][$verdict] = ($perBook[$row->book][$verdict] ?? 0) + 1;
+        if (count($samples[$verdict] ?? []) < $sampleLimit) {
+            $samples[$verdict][] = [
+                'book' => (int) $row->book, 'para' => (int) $row->para,
+                'old' => $row->old_sig, 'new' => $row->new_sig,
+            ];
+        }
+    }
+}
+
+ksort($buckets);
+$log->info('---- 差异分桶(按段落计) ----');
+foreach ($buckets as $verdict => $n) {
+    $log->info(sprintf('  %-14s %8d  %5.1f%%', $verdict, $n, $total ? $n / $total * 100 : 0));
+}
+
+foreach ($samples as $verdict => $items) {
+    $log->info("---- $verdict 样本 ----");
+    foreach ($items as $s) {
+        $log->info(sprintf('  book %-3d para %-6d 旧[%s] → 新[%s]',
+            $s['book'], $s['para'], $s['old'] ?? '—', $s['new'] ?? '—'));
+    }
+}
+
+// 差异最集中的书优先看
+$ranked = [];
+foreach ($perBook as $book => $b) {
+    $ranked[] = ['book' => (int) $book, 'total' => array_sum($b)] + $b;
+}
+usort($ranked, fn ($a, $b) => $b['total'] <=> $a['total']);
+
+$log->info('---- 差异最多的 20 本 ----');
+foreach (array_slice($ranked, 0, 20) as $r) {
+    $log->info(sprintf('  book %-3d 共 %-6d  %s', $r['book'], $r['total'],
+        json_encode(array_diff_key($r, ['book' => 1, 'total' => 1]), JSON_UNESCAPED_UNICODE)));
+}
+
+$path = rp_report_dir()."/diff.$new.json";
+rp_json_write($path, [
+    'generated_at' => date('c'),
+    'old_table' => $old, 'new_table' => $new,
+    'scope' => $onlyBooks ?? 'all',
+    'paragraphs_compared' => $total,
+    'buckets' => $buckets,
+    'per_book' => $ranked,
+    'samples' => $samples,
+]);
+$log->info("报告:$path");
+
+$log->finish();

+ 316 - 0
api-v13/scripts/related/export.php

@@ -0,0 +1,316 @@
+<?php
+
+/**
+ * 从 wbw_templates 的锚点标记重放 related_paragraphs 第一版。
+ *
+ * 原则是「查不到优于查到错」:任何一处判不定就留空、记 issue,绝不沿用上一个 cs 值。
+ * 旧生成链路(VRI html → cs6_para.csv → laravel import)翻车的地方全在这条原则上:
+ * 换书后无标记就把上一个 cs 一路铺下去(E8),缩写区间不认识就跳过或写成六位废值
+ * (E1/E7),倒序区间 begin>end 让导入的 for 循环空转(book 103 para 1464 的成因)。
+ *
+ * 本版不处理章回绕后缀(E2),那要看标题层级,留给下一批;先把确定性规则跑干净,
+ * 混在一起会看不出是哪条规则错了。
+ *
+ * 用法:
+ *   php scripts/related/export.php --to=related_paragraphs_v1
+ *   php scripts/related/export.php --to=related_paragraphs_v1 --book=136,98,207   # 样例验货
+ */
+
+require __DIR__.'/lib/boot.php';
+
+use Illuminate\Support\Facades\DB;
+
+[$options] = rp_args($argv);
+$target = rp_assert_table($options['to'] ?? 'related_paragraphs_v1');
+$markersTable = $options['markers'] ?? 'rp_markers';
+$onlyBooks = isset($options['book']) ? array_map('intval', explode(',', $options['book'])) : null;
+
+$log = new RpLogger('export', rp_report_dir());
+$log->info("目标表:$target");
+if ($onlyBooks) {
+    $log->info('只导出:'.implode(',', $onlyBooks));
+}
+
+$config = rp_json_read(__DIR__.'/book_config.json');
+$bookConfig = $config['books'];
+$overrides = $config['overrides'] ?? [];
+
+// ── 建表 ─────────────────────────────────────────────────────────────────
+if (! $onlyBooks) {
+    DB::statement("drop table if exists $target");
+}
+DB::statement("
+    create table if not exists $target (
+        id bigserial primary key,
+        book integer not null,
+        para integer not null,
+        book_id integer not null,
+        cs_para integer not null,
+        book_name varchar(64) not null,
+        created_at timestamp(0), updated_at timestamp(0)
+    )
+");
+if ($onlyBooks) {
+    DB::table($target)->whereIn('book', $onlyBooks)->delete();
+}
+
+// ── 预载 ─────────────────────────────────────────────────────────────────
+$log->info('预载 book_titles…');
+$titles = [];
+foreach (DB::select('select book, paragraph, sn from book_titles order by book, paragraph') as $t) {
+    $titles[$t->book][] = ['paragraph' => (int) $t->paragraph, 'sn' => (int) $t->sn];
+}
+
+$books = array_map(
+    fn ($r) => (int) $r->book,
+    DB::select('select distinct book from pali_texts order by book')
+);
+if ($onlyBooks) {
+    $books = array_values(array_intersect($books, $onlyBooks));
+}
+$log->info('待导出文件数:'.count($books));
+
+$buffer = [];
+$written = 0;
+$now = date('Y-m-d H:i:s');
+
+$flush = function () use (&$buffer, &$written, $target) {
+    if ($buffer === []) {
+        return;
+    }
+    foreach (array_chunk($buffer, 5000) as $chunk) {
+        DB::table($target)->insert($chunk);
+    }
+    $written += count($buffer);
+    $buffer = [];
+};
+
+/** 在配置分段里查某段落该用什么书名;段落早于首段时沿用首段的名。 */
+$configName = function (int $book, int $para) use ($bookConfig, $overrides): ?string {
+    // overrides 是人工判定区,优先级高于自动推导出来的分段。
+    $segments = $overrides[(string) $book]['segments']
+        ?? $bookConfig[(string) $book]['segments']
+        ?? [];
+    if ($segments === []) {
+        return null;
+    }
+    $name = $segments[0]['book_name'];
+    foreach ($segments as $s) {
+        if ($para >= $s['para_from']) {
+            $name = $s['book_name'];
+        }
+    }
+
+    return $name;
+};
+
+foreach ($books as $book) {
+    $bookTitles = $titles[$book] ?? [];
+
+    // 段落全集取 pali_texts 而不是 wbw_templates:pali_texts 是严格超集
+    // (523284 段 vs 516113 段),wbw 少的那 7171 段散在 21 本里,
+    // 按 wbw 取全集会白丢这些段落的行。wbw 只负责提供标记。
+    $paragraphs = array_map(
+        fn ($r) => (int) $r->paragraph,
+        DB::select('select distinct paragraph from pali_texts where book = ? order by paragraph', [$book])
+    );
+    if ($paragraphs === []) {
+        continue;
+    }
+
+    $markerRows = DB::select(
+        "select paragraph, wid, word, kind, book_name, cs_from, cs_to, numbers, error
+         from $markersTable where book = ? and kind <> 'page' order by paragraph, wid",
+        [$book]
+    );
+    $byParagraph = [];
+    foreach ($markerRows as $m) {
+        $byParagraph[(int) $m->paragraph][] = $m;
+    }
+
+    // ── book_id 分段:book_titles 的每个条目开一段,之前的段落是书前页 ────────
+    $segments = [];
+    if ($bookTitles === []) {
+        $segments[] = ['sn' => 0, 'from' => 1, 'to' => PHP_INT_MAX];
+    } else {
+        if ($bookTitles[0]['paragraph'] > 1) {
+            $segments[] = ['sn' => 0, 'from' => 1, 'to' => $bookTitles[0]['paragraph'] - 1];
+        }
+        foreach ($bookTitles as $i => $t) {
+            $segments[] = [
+                'sn' => $t['sn'],
+                'from' => $t['paragraph'],
+                'to' => $bookTitles[$i + 1]['paragraph'] ?? PHP_INT_MAX,
+            ];
+            if (isset($bookTitles[$i + 1])) {
+                $segments[count($segments) - 1]['to'] = $bookTitles[$i + 1]['paragraph'] - 1;
+            }
+        }
+    }
+
+    $bookName = null;
+    $prologue = false;
+
+    // 义注文件的开头几段(书前页)在 {mula}_0 序言标记之前,但内容上属于序言。
+    // 文件里首个章标记是 _0 时,起手就用 {mula}_A,免得前几段挂到正文名下。
+    foreach ($markerRows as $m) {
+        if ($m->kind === 'chapter') {
+            if ($m->numbers === '0') {
+                $bookName = $m->book_name.'_A';
+                $prologue = true;
+                $log->count('event.prologue_seeded');
+            }
+            break;
+        }
+    }
+    // 文件自身没有任何书名标记时,书名只能全程由配置表分段决定。
+    // 配置表在所有书里都当书名基线:它已经把 book_tag 书界、人工 override 和
+    // 序言段(dn1_A 型)合并成一份完整分段。标记仍然可以就地覆盖——paraN_xxx 后缀
+    // 是最贴身的证据,book_tag 是书界事件,两者都在下面的标记循环里生效。
+    $nameFromConfig = true;
+
+    foreach ($segments as $seg) {
+        $segParagraphs = array_values(array_filter(
+            $paragraphs,
+            fn ($p) => $p >= $seg['from'] && $p <= $seg['to']
+        ));
+        if ($segParagraphs === []) {
+            continue;
+        }
+
+        // ⭐ 防污染核心规则:整段没有任何 cs 标记,就不许给它任何非零 cs。
+        // 旧生成器在这里把换书前的 cs 一路铺下去,book 207 的 1499 行恒 cs=75 就是这么来的。
+        // 但也不能整段不输出:这些段落的行多半是 cs=0 的占位行(E4 的无注释体系书、
+        // 义注序言、书前页),下游 ParaInfoController 按段落取行,删掉就是白丢覆盖。
+        // 输出 cs=0 即可——index() 取锚点时要求 cs_para > 0,cs=0 行不会产生任何配对,
+        // 既保住覆盖又不编造关系。仍然记 issue,标出待 LLM 补齐的位置。
+        $segMarkerCount = 0;
+        foreach ($segParagraphs as $p) {
+            foreach ($byParagraph[$p] ?? [] as $m) {
+                if (in_array($m->kind, ['single', 'interval'], true)) {
+                    $segMarkerCount++;
+                }
+            }
+        }
+        if ($segMarkerCount === 0 && $seg['sn'] !== 0) {
+            $log->count('segment_without_markers');
+            $log->unresolved('segment_without_markers', [
+                'book' => $book, 'book_id' => $seg['sn'],
+                'para_from' => $segParagraphs[0], 'para_to' => end($segParagraphs),
+                'paragraphs' => count($segParagraphs),
+                'detail' => '整段无 cs 标记,全部输出 cs=0 占位,待补(E8/E9)',
+            ]);
+        }
+
+        // 段起点:cs 归零等待首个标记。
+        // 书名分两种来源:文件自带 book_tag/后缀标记的,交给标记驱动;没有任何现场
+        // 证据的(123 本,如 book 98 一个文件里装了 abhi3..abhi7),只能逐段落查配置表
+        // ——这类文件的书界在 wbw 里没有任何痕迹。
+        $csList = [0];
+        $bookName ??= $configName($book, $segParagraphs[0]);
+
+        foreach ($segParagraphs as $para) {
+            $skipParagraph = false;
+
+            $configNameHere = $configName($book, $para);
+            if ($nameFromConfig) {
+                $bookName = $configNameHere;
+            }
+
+            foreach ($byParagraph[$para] ?? [] as $m) {
+                switch ($m->kind) {
+                    case 'book_tag':
+                        // 文件内的书界切换(an2@1 an3@323…),新书从 cs=0 起算
+                        if ($bookName !== $m->book_name) {
+                            $log->count('event.book_switch');
+                        }
+                        $bookName = $m->book_name;
+                        $prologue = false;
+                        $csList = [0];
+                        break;
+
+                    case 'chapter':
+                        $numbers = $m->numbers === null ? [] : array_map('intval', explode('.', $m->numbers));
+                        if ($numbers === [0]) {
+                            // {mula}_0 = 义注开头的序言(Ganthārambhakathā),不对应原文段落
+                            $prologue = true;
+                            $bookName = $m->book_name.'_A';
+                            $csList = [0];
+                            $log->count('event.prologue_begin');
+                        } else {
+                            if ($prologue) {
+                                $prologue = false;
+                                $bookName = $m->book_name;
+                                $csList = [0];
+                                $log->count('event.prologue_end');
+                            }
+                            $log->count('event.chapter');
+                        }
+                        break;
+
+                    case 'single':
+                    case 'interval':
+                        // 序言段里的 paraN_mula 后缀不夺名:序言归 {mula}_A,
+                        // 后缀只说明它在注释哪一段,不表示它已经进入正文
+                        // (book 181 的 an1_A@1-138 内就有 para1_an1 起的一串)。
+                        if ($m->book_name !== null && $configNameHere !== $m->book_name.'_A') {
+                            $bookName = $m->book_name;
+                        }
+                        // cs 标记不结束序言:序言里带 paraN_mula 是正常体例
+                        // (book 130 的 mn1_0 序言内就有 para1_mn1),序言只由
+                        // {mula}_{N>0} 章标记结束。
+                        $csList = range((int) $m->cs_from, (int) $m->cs_to);
+                        $log->count($m->kind === 'interval' ? 'marker.interval' : 'marker.single');
+                        break;
+
+                    case 'truncated':
+                        // para179- 型:区间右端缺失,本段留空,上下文不变
+                        $skipParagraph = true;
+                        $log->unresolved('truncated_marker', [
+                            'book' => $book, 'paragraph' => $para, 'word' => $m->word,
+                            'detail' => $m->error ?? '区间右端缺失',
+                        ]);
+                        break;
+
+                    default:
+                        $log->count('marker.ignored.'.$m->kind);
+                }
+            }
+
+            if ($skipParagraph) {
+                continue;
+            }
+
+            if ($bookName === null) {
+                // 没有任何书名证据:E4 的无注释体系书走到这里是正常的,输出空名占位
+                $bookName = '';
+            }
+
+            foreach ($csList as $cs) {
+                $buffer[] = [
+                    'book' => $book, 'para' => $para, 'book_id' => $seg['sn'],
+                    'cs_para' => $cs, 'book_name' => $bookName,
+                    'created_at' => $now, 'updated_at' => $now,
+                ];
+            }
+            $log->count('rows.emitted', count($csList));
+        }
+    }
+
+    $flush();
+    $log->info(sprintf('book %-3d 完成,累计 %d 行', $book, $written));
+}
+
+$flush();
+$log->info("写入完成:$written 行");
+
+if (! $onlyBooks) {
+    $log->info('建索引中…');
+    DB::statement("create index on $target (book)");
+    DB::statement("create index on $target (para)");
+    DB::statement("create index on $target (book_name)");
+    DB::statement("create index on $target (book_name, cs_para)");
+    DB::statement("create index on $target (book, para, cs_para)");
+}
+
+$log->finish();

+ 347 - 0
api-v13/scripts/related/known_issues.json

@@ -0,0 +1,347 @@
+{
+  "version": 1,
+  "purpose": "related_paragraphs 重建工程的已知错误登记表:每条一个可机检的探测器,带旧表实测基线与各阶段目标。check.php 按此表给任意一张 related 表打分,用来回答『这一轮错误是不是变少了』。",
+  "doc_ref": "api-v13/documents/related-paragraphs-redesign.md",
+  "baseline_table": "related_paragraphs_bak_20260909",
+  "baseline_database": "visuddhinanda_20260311",
+  "baseline_measured_at": "2026-09-09",
+  "params": {
+    "cs_garbage_threshold": 5000,
+    "cs_observed_max_legit": 3183,
+    "flat_min_rows": 200,
+    "flat_max_distinct_ratio": 50
+  },
+  "notes": [
+    "cs6_para.csv 并未丢失(github.com/iapt-platform/clove/pali_title/cs6_para.csv,523283 行),与设计文档 §6.1 的表述不符。它是现表的来源,含全部历史错误,因此不作生成源,只作 baseline 与 book 129 的回填源。",
+    "逐本比对 csv 非零行 vs wbw 标记数:只有 book 129 是『csv 有 6580 非零行、wbw 零标记』。E9 其余 15 本 csv 里也是全零,源头就没有。",
+    "基线数字取自旧表实测,与文档 §4.3/§8 的差异已在各条 baseline_note 注明。",
+    "E8 判据在实测中收窄,详见该条 baseline_note;旧的「cs 值种类少」判法会把章回绕误报成污染。",
+    "MarkerParser 全库实跑:330267 个锚点 100% 归类,零 unknown。新发现两类文档未记录的形态——倒序区间 3 行(para504-407 / para706-608,高位笔误,按低位补齐还原为 504-507 / 706-708,已由前后邻标记验证)与多级章标记 247 行(an5_1_1 型,13 本,义注书 100-102 与 mūla 书 82-92 共用同一套编号,是跨文件章界对齐的抓手)。",
+    "para504-407 丢段的完整链路已查清:cs6_para.csv 原样写了 begin=504,end=407,旧 Laravel 命令的 for ($i=$begin; $i<=$end; $i++) 一圈没进——是导入环节静默吞掉的,不是生成环节。"
+  ],
+  "detectors": [
+    {
+      "id": "E1_cs_garbage",
+      "title": "cs 乱码值",
+      "doc_ref": "§4.3 E1",
+      "severity": "blocker",
+      "baseline": {
+        "rows": 1242,
+        "books": 24
+      },
+      "target_v1": {
+        "rows": 0
+      },
+      "target_final": {
+        "rows": 0
+      },
+      "root_cause": "旧生成器解析无后缀区间标记 para7-10 产生废值(如 44022)",
+      "fix_stage": "batch1 导出器:超值域拒绝输出 + issue"
+    },
+    {
+      "id": "E2_chapter_wrap",
+      "title": "章回绕(cs 从 1 重新计数)",
+      "doc_ref": "§4.3 E2",
+      "severity": "blocker",
+      "baseline": {
+        "wrap_points": 429,
+        "books": 70
+      },
+      "baseline_note": "文档写 430,实测 429,差异来自并列排序的 tie-break,不影响结论",
+      "target_v1": {
+        "wrap_points": "unchanged"
+      },
+      "target_final": {
+        "wrap_points": 0
+      },
+      "root_cause": "VRI 标记是章内局部编号,章界处重置,旧生成器照搬",
+      "fix_stage": "batch3 章后缀;v1 不处理,先让确定性规则跑干净"
+    },
+    {
+      "id": "E3_kn10_missing",
+      "title": "kn10 家族命名错乱,apadāna 注释链断裂",
+      "doc_ref": "§4.3 E3",
+      "severity": "blocker",
+      "baseline": {
+        "kn10_rows": 0,
+        "kn10_a_rows": 16787,
+        "kn10_b_rows": 12407
+      },
+      "baseline_note": "kn10_A/kn10_B 行数取自 csv album 统计,旧表同源",
+      "target_v1": {
+        "kn10_rows": ">6000"
+      },
+      "target_final": {
+        "kn10_rows": ">6000"
+      },
+      "root_cause": "therā/therī(book 143/144)被赋 kn10_A/kn10_B 且归属互相矛盾;wbw 中 paraN_kn10 标记 6533 行在 related 中映射丢失",
+      "fix_stage": "batch1 书级配置表"
+    },
+    {
+      "id": "E4_empty_book_name",
+      "title": "空 book_name(无注释体系书)",
+      "doc_ref": "§4.3 E4",
+      "severity": "expected",
+      "baseline": {
+        "rows": 112965
+      },
+      "target_v1": {
+        "rows": "~112965"
+      },
+      "target_final": {
+        "rows": "~112965"
+      },
+      "root_cause": "nīti/语法/词典类书无 cs 标记体系,不参与注释关系",
+      "fix_stage": "不修,维持现状(§6.7)"
+    },
+    {
+      "id": "E5_book_id_zero",
+      "title": "book_id 未赋值",
+      "doc_ref": "§4.3 E5",
+      "severity": "minor",
+      "baseline": {
+        "rows": 354,
+        "books": 201
+      },
+      "target_v1": {
+        "rows": "<=354"
+      },
+      "target_final": {
+        "rows": "<=354"
+      },
+      "root_cause": "各文件 para 1-2 书前页,语义正确;另 sn 280/281 整段归错前册",
+      "fix_stage": "batch1 book_id 层按 book_titles 重跑"
+    },
+    {
+      "id": "E6_coverage_gap",
+      "title": "覆盖缺口(wbw 有段落但 related 无行)",
+      "doc_ref": "§4.3 E6",
+      "severity": "major",
+      "baseline": {
+        "segments": 3466
+      },
+      "target_v1": {
+        "segments": "<500"
+      },
+      "target_final": {
+        "segments": "<100"
+      },
+      "root_cause": "主体为缩写区间丢失(E7),其余为 wbw_templates 整段缺失",
+      "fix_stage": "batch1 + batch4"
+    },
+    {
+      "id": "E7_abbrev_interval_lost",
+      "title": "缩写区间丢失(para292-3 型)",
+      "doc_ref": "§4.3 E7",
+      "severity": "blocker",
+      "baseline": {
+        "marker_segments": 1517,
+        "books": 44,
+        "segments_without_rows": 1292,
+        "segments_with_garbage": 225
+      },
+      "target_v1": {
+        "segments_without_rows": 0,
+        "segments_with_garbage": 0
+      },
+      "target_final": {
+        "segments_without_rows": 0,
+        "segments_with_garbage": 0
+      },
+      "root_cause": "VRI 缩写语法 para292-3(=292-293)旧生成器不识别:多数跳过,少数误解析为废值",
+      "fix_stage": "batch1 导出器缩写补齐规则"
+    },
+    {
+      "id": "E8_flat_pollution",
+      "title": "书边界污染平铺",
+      "doc_ref": "§4.3 E8",
+      "severity": "blocker",
+      "baseline": {
+        "groups": 1,
+        "rows": 1499
+      },
+      "baseline_note": "实测复核后收窄了判据:污染的准确签名是「整段零 cs 标记却被写进非零 cs」。按此判全库只有 book 207 / book_id 259 kaṅkhāvitaraṇī 一段(1499 行恒 cs=75)。文档 §4.3 原列的另外几组里,book 212/273(669 行)、book 180/213、book 209/261 都是 cs 恒 0,0 是「未赋值」不是编造值,不算污染;book 152/46/116/154/204 则是章回绕(E2)被误判——book 152 有 516 个标记却只 24 个 cs 值,正是 22 次回绕造成的。",
+      "target_v1": {
+        "groups": 0
+      },
+      "target_final": {
+        "groups": 0
+      },
+      "root_cause": "换书(book_id 切换)后无标记,旧生成器无限沿用上一个 cs 值",
+      "fix_stage": "batch1 留空 + batch4 LLM"
+    },
+    {
+      "id": "E9_no_marker_books",
+      "title": "全书无标记(related 有行但 wbw 零标记)",
+      "doc_ref": "§4.3 E9",
+      "severity": "major",
+      "baseline": {
+        "books": 16,
+        "book_list": [
+          8,
+          15,
+          16,
+          25,
+          37,
+          39,
+          40,
+          41,
+          42,
+          44,
+          45,
+          47,
+          48,
+          56,
+          61,
+          129
+        ]
+      },
+      "target_v1": {
+        "books": 16,
+        "note": "v1 只按 wbw 重放,这些书自然无行"
+      },
+      "target_final": {
+        "books": 15,
+        "note": "book 129 用 csv 回填(csv 有 6580 非零行),其余 15 本 csv 也是全零,源头没有"
+      },
+      "root_cause": "VRI 源文件无锚点",
+      "fix_stage": "batch4:129 用 csv,其余维持现状",
+      "baseline_note": ""
+    },
+    {
+      "id": "E10_selfmade_names",
+      "title": "自造名体系(NK / subo / dict)",
+      "doc_ref": "§4.3 E10",
+      "severity": "expected",
+      "baseline": {
+        "nk_rows": 985,
+        "subo_rows": 4256,
+        "dict_rows": 6646
+      },
+      "baseline_note": "行数为 csv album 口径的近似值,check.php 会实测回填",
+      "target_v1": {
+        "note": "保留不动,架构正确"
+      },
+      "target_final": {
+        "note": "保留不动"
+      },
+      "root_cause": "非 SC 体系书对的自造 album 名,与 dn1/dn1_A 同构",
+      "fix_stage": "不改名,仅修其中的乱码/缩写(§6.7)"
+    },
+    {
+      "id": "D_continuity",
+      "title": "同 (book, book_name, cs_para) 的 para 不连续",
+      "doc_ref": "§4.2 正确性判据",
+      "severity": "watch",
+      "baseline": {
+        "broken_groups": 9026,
+        "books": 69,
+        "extra_segments": 30204
+      },
+      "target_v1": {
+        "broken_groups": "decrease"
+      },
+      "target_final": {
+        "broken_groups": "decrease"
+      },
+      "root_cause": "部分为合法的回指补充(cs 小幅回退),部分为章回绕与污染导致的真错",
+      "fix_stage": "观察项,不做硬断言;batch3 后应显著下降"
+    },
+    {
+      "id": "D_mirror_alignment",
+      "title": "镜像型书对两侧 max(cs_para) 一致",
+      "doc_ref": "§4.2 / §8",
+      "severity": "blocker",
+      "baseline": {
+        "aligned": {
+          "dn1": 559,
+          "kn6": 1289,
+          "kn9": 524,
+          "abhi5": 918
+        },
+        "misaligned": [
+          "abhi3",
+          "abhi4",
+          "abhi6",
+          "abhi7"
+        ]
+      },
+      "target_v1": {
+        "note": "aligned 四组必须保持相等;misaligned 四组 batch3 处理"
+      },
+      "target_final": {
+        "note": "全部对齐"
+      },
+      "root_cause": "义注/复注段的标记即被注书段落号;abhidhamma 系自有编号导致跨侧错位",
+      "fix_stage": "batch1 出口断言 + batch3 补丁后缀"
+    },
+    {
+      "id": "D_interval_expansion",
+      "title": "区间标记展开行数 == M − N + 1",
+      "doc_ref": "§6.3 验收断言",
+      "severity": "blocker",
+      "baseline": {
+        "note": "旧表未做此断言,check.php 首跑回填实测值"
+      },
+      "target_v1": {
+        "mismatched_markers": 0
+      },
+      "target_final": {
+        "mismatched_markers": 0
+      },
+      "root_cause": "旧生成器对 151-152 型一对多展开不完整",
+      "fix_stage": "batch1"
+    },
+    {
+      "id": "D_book_regression",
+      "title": "基线合格书回归",
+      "doc_ref": "§5 汇总",
+      "severity": "blocker",
+      "baseline": {
+        "note": "首跑生成 baseline.json,冻结旧表中零错误信号的书"
+      },
+      "target_v1": {
+        "regressed_books": 0
+      },
+      "target_final": {
+        "regressed_books": 0
+      },
+      "root_cause": "重建可能破坏本来正确的书",
+      "fix_stage": "每轮必检"
+    }
+  ],
+  "rounds": [
+    {
+      "round": 1,
+      "date": "2026-09-09",
+      "table": "related_paragraphs_v1",
+      "rows": 638076,
+      "scripts": "build_markers.php → build_book_config.php → export.php → check.php → diff.php",
+      "result": {
+        "E1_cs_garbage": "1242 → 0",
+        "E3_kn10_missing": "0 → 25506(kn10_A/kn10_B 清零)",
+        "E6_coverage_gap": "3464 → 1(仅 book 11 para 1577 的截断标记)",
+        "E7_abbrev_interval_lost": "1292 段无行 + 225 段废值 → 0 + 0",
+        "E8_flat_pollution": "1499 行 → 0",
+        "D_interval_expansion": "1611 个区间标记展开不符 → 0",
+        "D_mirror_alignment": "四组镜像判据保持(dn1 559 / kn6 1289 / kn9 524 / abhi5 918)",
+        "clean_books": "128 → 148",
+        "E2_chapter_wrap": "429 → 677(未处理,留给章后缀批次;旧表的乱码与污染此前掩盖了部分真回绕)"
+      },
+      "diff_vs_old": {
+        "same": "480290 段 / 91.8%",
+        "only_in_old": "1 段(截断标记)",
+        "only_in_new": "3466 段(区间展开补回,与旧表的覆盖缺口数一致)",
+        "cs_changed": "10371 段 —— 8600 段新归零(防污染/防越界沿用)、528 段新赋值、1290 段两侧都非零而边界不同",
+        "name_changed": "29156 段 —— 29146 段是 kn10 家族修复(books 143/144/107),其余 10 段是各文件 book_tag 所在段本身"
+      },
+      "open": [
+        "book 129(6605 段)现为 cs=0 占位,待用 cs6_para.csv 回填(csv 有 6580 非零行)",
+        "20 段 segment_without_markers 已输出 cs=0 占位,待 LLM 归属",
+        "book 11 para 1577 的 para179- 截断标记待人工定",
+        "E2 章回绕 677 处未处理",
+        "1290 段两侧都非零而边界不同,需抽样复核(book 110 已查:旧表把 cs=5 边界提前 7 段,wbw 无依据,新值站得住)"
+      ]
+    }
+  ]
+}

+ 116 - 0
api-v13/scripts/related/lib/Logger.php

@@ -0,0 +1,116 @@
+<?php
+
+/**
+ * 重建工程专用日志器。
+ *
+ * 迭代流程是「脚本跑 → 日志和报告交给 LLM 评估 → 改规则 → 再跑」,所以日志的读者
+ * 是模型不是人:宁可啰嗦,但必须结构化。unresolved() 记录的是脚本自己判定
+ * 「我处理不了」的点,它们是下一轮规则迭代的输入,单独成文件。
+ */
+class RpLogger
+{
+    private $handle;
+
+    private array $counters = [];
+
+    /** @var array<int, array<string, mixed>> */
+    private array $unresolved = [];
+
+    private float $startedAt;
+
+    public function __construct(
+        private string $name,
+        private string $reportDir,
+        private bool $echoToStdout = true,
+    ) {
+        $this->startedAt = microtime(true);
+        $this->handle = fopen($this->reportDir."/{$name}.log", 'w');
+        $this->line('INFO', "==== $name 开始 ".date('Y-m-d H:i:s').' ====');
+    }
+
+    public function info(string $message): void
+    {
+        $this->line('INFO', $message);
+    }
+
+    public function warn(string $message): void
+    {
+        $this->line('WARN', $message);
+    }
+
+    public function error(string $message): void
+    {
+        $this->line('ERROR', $message);
+    }
+
+    /** 计数器:高频事件不逐条打印,只累计,收尾时汇总。 */
+    public function count(string $key, int $n = 1): void
+    {
+        $this->counters[$key] = ($this->counters[$key] ?? 0) + $n;
+    }
+
+    public function counters(): array
+    {
+        return $this->counters;
+    }
+
+    /**
+     * 脚本无法判定的点。type 是规则名,供下一轮按类型聚合决定要不要加规则。
+     */
+    public function unresolved(string $type, array $context): void
+    {
+        $this->unresolved[] = ['type' => $type] + $context;
+        $this->count("unresolved.$type");
+    }
+
+    /** 收尾:写计数汇总与 unresolved 清单,返回汇总数组。 */
+    public function finish(): array
+    {
+        $elapsed = round(microtime(true) - $this->startedAt, 1);
+        ksort($this->counters);
+
+        $this->line('INFO', '---- 计数汇总 ----');
+        foreach ($this->counters as $key => $value) {
+            $this->line('INFO', sprintf('  %-46s %10d', $key, $value));
+        }
+
+        $byType = [];
+        foreach ($this->unresolved as $item) {
+            $byType[$item['type']] = ($byType[$item['type']] ?? 0) + 1;
+        }
+        if ($byType !== []) {
+            $this->line('WARN', '---- 未决问题(按类型) ----');
+            foreach ($byType as $type => $n) {
+                $this->line('WARN', sprintf('  %-46s %10d', $type, $n));
+            }
+        }
+
+        $path = $this->reportDir."/{$this->name}.unresolved.json";
+        rp_json_write($path, [
+            'generated_at' => date('c'),
+            'total' => count($this->unresolved),
+            'by_type' => $byType,
+            'items' => $this->unresolved,
+        ]);
+
+        $this->line('INFO', "未决清单:$path");
+        $this->line('INFO', "==== {$this->name} 结束,耗时 {$elapsed}s ====");
+        fclose($this->handle);
+
+        return [
+            'counters' => $this->counters,
+            'unresolved_total' => count($this->unresolved),
+            'unresolved_by_type' => $byType,
+            'elapsed_seconds' => $elapsed,
+        ];
+    }
+
+    private function line(string $level, string $message): void
+    {
+        $row = sprintf('[%s] %-5s %s', date('H:i:s'), $level, $message);
+        fwrite($this->handle, $row."\n");
+        if ($this->echoToStdout) {
+            fwrite(STDOUT, $row."\n");
+        }
+    }
+}

+ 202 - 0
api-v13/scripts/related/lib/MarkerParser.php

@@ -0,0 +1,202 @@
+<?php
+
+/**
+ * wbw_templates 里 .ctl. 锚点标记的解析器。
+ *
+ * 这些标记来自 VRI html 的 <a name="..."> 锚点,是整个 related_paragraphs 的唯一
+ * 事实来源。旧生成器(cs6_para.csv 那条链路)在这里翻过车——缩写区间被跳过或
+ * 误解析成六位数废值——所以解析规则集中在这一个类里,导出器和检测器共用同一份,
+ * 不允许各写一遍。
+ *
+ * 形态实测(type='.ctl.' and style='#a#',330267 行):
+ *   pagemark 167647 / paraN 116921 / paraN_book 39998 / paraN-M 3611
+ *   / 书名·章标记 1096 / paraN-M_book 989 / 链式 4 / 截断 1
+ */
+class MarkerParser
+{
+    /** 解析结果超过此值一律视为废值,拒绝输出。实测合法上界 3183。 */
+    public const CS_MAX = 5000;
+
+    public const KIND_SINGLE = 'single';          // para4
+
+    public const KIND_INTERVAL = 'interval';      // para151-152 / para292-3 / para292-3-6
+
+    public const KIND_BOOK_TAG = 'book_tag';      // dn1
+
+    public const KIND_CHAPTER = 'chapter';        // dn1_9 / an5_1_1 —— 章标记或义注标记,同形歧义
+
+    public const KIND_PAGE = 'page';              // P1.0023
+
+    public const KIND_TRUNCATED = 'truncated';    // para179-
+
+    public const KIND_UNKNOWN = 'unknown';
+
+    /**
+     * @return array{
+     *   kind: string,
+     *   cs: list<int>,          解析出的 cs 值(已展开区间)
+     *   book_name: ?string,     标记自带的书名后缀
+     *   number: ?int,           chapter 形态的首级编号
+     *   numbers: ?list<int>,    chapter 形态的完整编号路径(an5_1_1 → [1,1])
+     *   repaired: ?string,      规则修补过的标记,须记 issue 复核
+     *   raw: string,
+     *   error: ?string,         非空表示拒绝输出,调用方须记 issue
+     * }
+     */
+    public static function parse(string $word): array
+    {
+        $base = [
+            'kind' => self::KIND_UNKNOWN,
+            'cs' => [],
+            'book_name' => null,
+            'number' => null,
+            'numbers' => null,
+            'repaired' => null,
+            'raw' => $word,
+            'error' => null,
+        ];
+
+        // 页码/卷标 P/M/V/T/O × 0-5:本轮一律忽略(§6.7)
+        if (preg_match('/^[A-Z][0-9]/', $word)) {
+            return ['kind' => self::KIND_PAGE] + $base;
+        }
+
+        if (! str_starts_with($word, 'para')) {
+            // 纯书名 dn1(书上下文事件)或 dn1_9(章标记 / 义注标记)
+            // 章标记,可带多级编号路径:dn1_9 是一级,an5_1_1 是两级(实测 13 本 247 行,
+            // 义注书 100-102 与 mūla 书 82-92 共用同一套编号,是跨文件章界对齐的抓手)。
+            if (preg_match('/^([a-z][a-z0-9]*)((?:_[0-9]+)+)$/', $word, $m)) {
+                $numbers = array_values(array_map('intval', array_filter(explode('_', $m[2]), 'strlen')));
+
+                return [
+                    'kind' => self::KIND_CHAPTER,
+                    'book_name' => $m[1],
+                    'number' => $numbers[0],
+                    'numbers' => $numbers,
+                ] + $base;
+            }
+            if (preg_match('/^[a-z][a-z0-9]*$/', $word)) {
+                return ['kind' => self::KIND_BOOK_TAG, 'book_name' => $word] + $base;
+            }
+
+            return $base;
+        }
+
+        $body = substr($word, 4);
+
+        // 尾部 _book 后缀。区间与单值都可能带,如 para1008-9_sn5(实测 989 行)。
+        $bookName = null;
+        if (preg_match('/^(.*?)_([a-z][a-z0-9_]*)$/', $body, $m)) {
+            $body = $m[1];
+            $bookName = $m[2];
+        }
+
+        if ($body === '' || ! preg_match('/^[0-9]/', $body)) {
+            return ['error' => '标记主体不是数字'] + $base;
+        }
+
+        // para179- :区间右端缺失,全库仅 book 11 para 1577 一处,留给人工。
+        if (str_ends_with($body, '-')) {
+            return ['kind' => self::KIND_TRUNCATED, 'book_name' => $bookName, 'error' => '区间右端缺失'] + $base;
+        }
+
+        $parts = explode('-', $body);
+        foreach ($parts as $part) {
+            if (! preg_match('/^[0-9]+$/', $part)) {
+                return ['error' => "区间片段非数字:$part"] + $base;
+            }
+        }
+
+        if (count($parts) === 1) {
+            $cs = (int) $parts[0];
+            if ($cs > self::CS_MAX) {
+                return ['book_name' => $bookName, 'error' => "cs 超值域:$cs"] + $base;
+            }
+
+            return ['kind' => self::KIND_SINGLE, 'cs' => [$cs], 'book_name' => $bookName] + $base;
+        }
+
+        // 链式 para292-3-6:逐段以前一个完整值补齐,取首尾展开(实测仅 4 行)。
+        $start = (int) $parts[0];
+        $current = $start;
+        for ($i = 1; $i < count($parts); $i++) {
+            $current = self::completePrefix($current, $parts[$i]);
+            if ($current === null) {
+                return ['book_name' => $bookName, 'error' => "区间右端无法补齐:$body"] + $base;
+            }
+        }
+        $end = $current;
+
+        $repaired = null;
+        if ($end < $start) {
+            // 倒序区间是 VRI 源里的高位笔误,低位是对的:实测 para504-407 前邻 502-503
+            // 后邻 508(真值 504-507)、para706-608 前邻 703-705 后邻 709(真值 706-708)。
+            // 丢掉右端高位、只用低位重新补齐即可还原。全库仅 3 行,一律记 issue 人工复核。
+            $tail = end($parts);
+            $end = self::repairReversedEnd($start, $tail);
+            if ($end === null) {
+                return ['book_name' => $bookName, 'error' => "区间倒序且无法修补:$body"] + $base;
+            }
+            $repaired = "倒序区间按低位补齐:$body → $start-$end";
+        }
+        if ($end > self::CS_MAX || $start > self::CS_MAX) {
+            return ['book_name' => $bookName, 'error' => "cs 超值域:$start-$end"] + $base;
+        }
+        if ($end - $start > 2000) {
+            return ['book_name' => $bookName, 'error' => "区间过宽:$start-$end"] + $base;
+        }
+
+        return [
+            'kind' => self::KIND_INTERVAL,
+            'cs' => range($start, $end),
+            'book_name' => $bookName,
+            'repaired' => $repaired,
+        ] + $base;
+    }
+
+    /**
+     * VRI 缩写区间语法:右端只写变化的低位,用左端补齐前缀。
+     *   292-3   → 293      (补 "29")
+     *   1008-9  → 1009     (补 "100")
+     *   15-8    → 18       (补 "1")
+     *   298-3   → 303      (补出来 293 < 298,进位加 10^1)
+     * 右端位数不少于左端时不是缩写,原样返回。
+     */
+    public static function completePrefix(int $left, string $rightDigits): ?int
+    {
+        $leftDigits = (string) $left;
+        $rightLen = strlen($rightDigits);
+
+        if ($rightLen >= strlen($leftDigits)) {
+            return (int) $rightDigits;
+        }
+
+        $prefix = substr($leftDigits, 0, strlen($leftDigits) - $rightLen);
+        $completed = (int) ($prefix.$rightDigits);
+
+        if ($completed <= $left) {
+            // 低位回绕,向上进一位:298-3 的 3 指的是 303 不是 293。
+            $completed += 10 ** $rightLen;
+        }
+
+        return $completed > $left ? $completed : null;
+    }
+
+    /**
+     * 倒序区间的还原:逐步丢弃右端高位,只保留低位再按前缀补齐,取第一个大于左端
+     * 且区间宽度合理的结果。
+     *   504-407 → 低两位 "07" 补成 507
+     *   706-608 → 低两位 "08" 补成 708
+     */
+    public static function repairReversedEnd(int $start, string $rightDigits): ?int
+    {
+        for ($keep = strlen($rightDigits) - 1; $keep >= 1; $keep--) {
+            $candidate = self::completePrefix($start, substr($rightDigits, -$keep));
+            if ($candidate !== null && $candidate > $start && $candidate - $start <= 20) {
+                return $candidate;
+            }
+        }
+
+        return null;
+    }
+}

+ 85 - 0
api-v13/scripts/related/lib/boot.php

@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * related_paragraphs 重建工程的公共引导。
+ *
+ * 这些脚本刻意留在 scripts/ 而不是 app/Console/Commands/:重建期间它们会被反复
+ * 改写、丢弃、重跑,不属于应用的常驻命令面。导出器稳定后再收编成 artisan command。
+ */
+
+use Illuminate\Contracts\Console\Kernel;
+
+require __DIR__.'/../../../vendor/autoload.php';
+
+$app = require __DIR__.'/../../../bootstrap/app.php';
+$app->make(Kernel::class)->bootstrap();
+
+require __DIR__.'/Logger.php';
+
+/** 本工程所有产物的落地目录。 */
+function rp_report_dir(): string
+{
+    $dir = __DIR__.'/../report';
+    if (! is_dir($dir)) {
+        mkdir($dir, 0o755, true);
+    }
+
+    return $dir;
+}
+
+function rp_data_dir(): string
+{
+    return __DIR__.'/../data';
+}
+
+/** 命令行参数:--key=value / --flag,返回 [$options, $positional]。 */
+function rp_args(array $argv): array
+{
+    $options = [];
+    $positional = [];
+    foreach (array_slice($argv, 1) as $arg) {
+        if (str_starts_with($arg, '--')) {
+            $body = substr($arg, 2);
+            if (str_contains($body, '=')) {
+                [$k, $v] = explode('=', $body, 2);
+                $options[$k] = $v;
+            } else {
+                $options[$body] = true;
+            }
+        } else {
+            $positional[] = $arg;
+        }
+    }
+
+    return [$options, $positional];
+}
+
+/**
+ * 表名白名单校验。这些脚本会把表名拼进 SQL(标识符不能用绑定参数),
+ * 所以只允许我们自己的表族,避免手滑打错表名时打到生产数据。
+ */
+function rp_assert_table(string $table): string
+{
+    if (! preg_match('/^related_paragraphs(_[a-z0-9_]+)?$/', $table)) {
+        throw new InvalidArgumentException("拒绝操作非 related_paragraphs 表族的表:$table");
+    }
+
+    return $table;
+}
+
+function rp_json_write(string $path, mixed $data): void
+{
+    file_put_contents(
+        $path,
+        json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."\n"
+    );
+}
+
+function rp_json_read(string $path): mixed
+{
+    if (! file_exists($path)) {
+        throw new RuntimeException("找不到文件:$path");
+    }
+
+    return json_decode(file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
+}