diff --git a/Makefile b/Makefile index a1ce332..8f46e68 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,13 @@ build: run: build ./bin/server -# 结构迁移为手动 SQL(无自动运行器):db/migrations/001-007(ingest/review 链) -# 与 scripts/sql/002-008(i18n/账号链)内容互补,按文件名顺序用 mysql 客户端执行,例如: -# mysql db_dev < db/migrations/001_create_street_snap.sql -# mysql db_dev < db/migrations/002_ingest.sql -# ... 两套链都跑完才是完整 schema +# 表结构由 GORM AutoMigrate 在 server 启动时幂等创建,无需手动 SQL。 +# 跨环境搬运全库数据(结构 + 数据)用 dbtool: +# go run ./cmd/dbtool dump -out db_dump.json +# go run ./cmd/dbtool import -in db_dump.json # 整机重建 +# go run ./cmd/dbtool import -in db_dump.json -data-only # 仅导数据(结构已由 AutoMigrate 建好) migrate: - @echo "Migrations are manual SQL. Apply db/migrations/001-007 then scripts/sql/002-008 via a mysql client." + @echo "Schema is auto-migrated by server on startup (GORM AutoMigrate). Use 'go run ./cmd/dbtool' to move data between environments." # 跑单测 test: diff --git a/README.md b/README.md index ec10fd4..cdabda9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Fashion API -秀场 / 品牌档案对外只读 API 服务(Go + Gin + GORM/MySQL)。 +秀场 / 品牌档案对外只读 API 服务(Go + Gin + GORM/PostgreSQL)。 本项目是从原 `admin/backend`(后台管理接口)中**剥离对外只读接口**后独立出的服务, 专门服务于前端项目 `test/test`(`D:\project\test\test`)。它只保留前端实际调用的公开接口, @@ -53,11 +53,11 @@ ``` cmd/ 组合根(Composition Root):只做依赖装配,不含业务逻辑 server/ 启动 HTTP 服务 - migrate/ 独立结构迁移命令 + dbtool/ 跨环境数据搬运(dump/import) internal/ 业务代码(不对外暴露) config/ 配置加载(yml + 环境变量覆盖 + 默认值) model/ 实体定义(gorm tag + json tag,PasswordHash 永不出参) - database/ MySQL 连接池 / 迁移 + database/ PostgreSQL 连接池 / 自动迁移(AutoMigrate) repository/ 数据访问(接口 + GORM 实现,查询条件用 Scope 安全组合) service/ 业务逻辑(JWT 签发、密码哈希、参数归一化、聚合) dto/ 请求/响应结构体与边界常量 @@ -75,8 +75,8 @@ internal/ 业务代码(不对外暴露) 避免原项目“复用同一个 `*gorm.DB` 实例导致 WHERE 串味”的隐患。 - **排序字段白名单**:`orderBy` 只允许白名单内的值,杜绝 SQL 注入。 - **配置统一收敛到 yml**:见第 3 节。 -- **迁移从启动流程剥离**:`auto_migrate` 默认 `false`,改用独立 `cmd/migrate` 命令显式执行, - 避免每次启动都对 `brand_runway_images`(89 万行)等大表隐式 `ALTER TABLE`。 +- **表结构由 GORM AutoMigrate 托管**:服务启动时幂等创建/更新全部表(替代原 `scripts/sql`、`db/migrations` 下的手写 MySQL 迁移脚本), + 跨环境数据搬运经 `cmd/dbtool`(dump/import)。如需避免大表启动期加列,可在部署流程中先行 `dbtool import` 建好结构。 - **修复原项目配置隐患**:原 `admin/backend` 代码只读 `DB_PASS`,而 docker-compose 注入的是 `DB_PASSWORD`,二者不一致;本项目同时兼容 `DB_PASSWORD` 与 `DB_PASS`,`DB_PASSWORD` 优先。 @@ -101,7 +101,7 @@ internal/ 业务代码(不对外暴露) | `GIN_MODE` | server.mode | | `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_NAME` | 数据库连接 | | `DB_PASSWORD`(或 `DB_PASS`) | database.password | -| `DB_LOG_LEVEL` / `DB_AUTO_MIGRATE` | GORM 日志 / 自动迁移开关 | +| `DB_LOG_LEVEL` | GORM 日志级别 | | `JWT_SECRET` / `JWT_EXPIRE_HOURS` | 令牌密钥 / 有效期 | | `UPLOAD_DIR` / `UPLOAD_URL_PREFIX` | 静态资源目录 / 前缀 | | `CONFIG_PATH` | 显式指定配置文件路径(优先级高于 `-config` 参数) | @@ -118,24 +118,26 @@ internal/ 业务代码(不对外暴露) ### 前置要求 - Go 1.26+ -- MySQL 8.x(本项目对接 WSL 1Panel 本地库:`127.0.0.1:3306`,库名 `db`,账号 `root/root`) +- PostgreSQL 16(+ pgvector,见 `scripts/pgvector` 的 Docker 一键起库):`127.0.0.1:5432`,库名 `fashion`,账号 `fashion/fashion_dev_2026` ### 构建 ```bash -# 两个可执行文件:server(API 服务)与 migrate(结构迁移) +# 主服务 go build -o bin/server ./cmd/server -go build -o bin/migrate ./cmd/migrate +# 跨环境数据搬运工具(dump / import) +go build -o bin/dbtool ./cmd/dbtool ``` -### 数据库迁移(可选,首次部署时执行一次) +### 数据库迁移(结构自动创建) -迁移默认**不**随服务启动执行(`auto_migrate: false`)。需建表/加字段时: +表结构**随服务启动自动执行** GORM AutoMigrate(幂等,仅增量变更,不重建已有表)。 +跨环境搬运全库数据(结构 + 数据)用 dbtool: ```bash -./bin/migrate # 读取 configs/config.yml -# 或指定配置文件 -./bin/migrate -config /path/to/config.yml +go run ./cmd/dbtool dump -out db_dump.json # 导出当前库 +go run ./cmd/dbtool import -in db_dump.json # 在目标环境重建并回灌 +go run ./cmd/dbtool import -in db_dump.json -data-only # 仅导数据(结构已由 AutoMigrate 建好) ``` ### 启动服务 @@ -228,11 +230,11 @@ backend/ │ └── config.yml # 唯一配置源 ├── cmd/ │ ├── server/main.go # 组合根:启动 HTTP 服务 + 优雅关闭 -│ └── migrate/main.go # 组合根:独立结构迁移 +│ └── dbtool/main.go # 组合根:跨环境数据搬运(dump/import) ├── internal/ │ ├── config/ # 配置加载(yml + env + 默认值) │ ├── model/ # 实体(brand / runway / runway_image / user) -│ ├── database/ # MySQL 连接池 + 迁移 +│ ├── database/ # PostgreSQL 连接池 + 自动迁移 │ ├── repository/ # 数据访问(接口 + GORM 实现) │ ├── service/ # 业务逻辑 │ ├── dto/ # 请求/响应结构体与边界常量 diff --git a/cmd/dbdiag/main.go b/cmd/dbdiag/main.go new file mode 100644 index 0000000..57b5b9d --- /dev/null +++ b/cmd/dbdiag/main.go @@ -0,0 +1,79 @@ +// 临时诊断:对照测试列元信息查询的"参数版"与"内联版",定位 42601。 +package main + +import ( + "database/sql" + "fmt" + "log" + "strings" + + _ "github.com/jackc/pgx/v5/stdlib" + + "fashionapi/internal/config" +) + +func main() { + cfg, err := config.Load("") + if err != nil { + log.Fatalf("load config: %v", err) + } + db, err := sql.Open("pgx", cfg.Database.DSN()) + if err != nil { + log.Fatalf("open: %v", err) + } + defer db.Close() + if err := db.Ping(); err != nil { + log.Fatalf("ping: %v", err) + } + + base := ` + SELECT c.column_name, + c.udt_name, + (c.is_nullable = 'YES'), + COALESCE(c.column_default, ''), + (c.column_default LIKE 'nextval(%') + FROM information_schema.columns c + WHERE c.table_schema = 'public' AND c.table_name = %s + ORDER BY c.ordinal_position` + + // (a) 参数版:用 $1 + paramQ := strings.Replace(base, "%s", "$1", 1) + fmt.Println("=== (a) 参数版 $1 ===") + testQ(db, paramQ, "brand") + + // (b) 内联版:把 'brand' 直接拼进 SQL(模拟 simple-protocol 内联) + inlineQ := strings.Replace(base, "%s", "'brand'", 1) + fmt.Println("=== (b) 内联版 'brand' ===") + testQ(db, inlineQ) + + // (c) 去掉 LIKE 表达式的版本(用 is_identity 代替) + noLike := ` + SELECT c.column_name, + c.udt_name, + (c.is_nullable = 'YES'), + COALESCE(c.column_default, ''), + (c.is_identity = 'YES') + FROM information_schema.columns c + WHERE c.table_schema = 'public' AND c.table_name = 'brand' + ORDER BY c.ordinal_position` + fmt.Println("=== (c) 去掉 LIKE 表达式版 ===") + testQ(db, noLike) +} + +func testQ(db *sql.DB, q string, args ...any) { + rows, err := db.Query(q, args...) + if err != nil { + fmt.Printf(" ERROR: %v\n", err) + // 尝试用 pgconn 解析 position + var pgErr interface{ Error() string } + _ = pgErr + fmt.Printf(" raw err: %s\n", err.Error()) + return + } + cnt := 0 + for rows.Next() { + cnt++ + } + fmt.Printf(" OK rows=%d err=%v\n", cnt, rows.Err()) + rows.Close() +} diff --git a/cmd/dbtool/db_dump.json b/cmd/dbtool/db_dump.json index 135d96b..e16b355 100644 --- a/cmd/dbtool/db_dump.json +++ b/cmd/dbtool/db_dump.json @@ -1,18 +1,51 @@ { "version": 1, - "generated_at": "2026-09-12T16:54:40Z", - "database": "db_dev", + "generated_at": "2026-09-17T14:50:49Z", + "database": "fashion", "tables": [ { "name": "brand", - "create": "CREATE TABLE `brand` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `created_at` int unsigned DEFAULT '0',\n `updated_at` int unsigned DEFAULT '0',\n `name_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `name_cn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `is_deleted` tinyint unsigned DEFAULT '0',\n PRIMARY KEY (`id`) USING BTREE,\n KEY `idx_name_en` (`name_en`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "created_at", - "updated_at", - "name_en", - "name_cn", - "is_deleted" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('brand_id_seq'::regclass)" + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "name_en", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "name_cn", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -171,23 +204,103 @@ }, { "name": "brand_runway", - "create": "CREATE TABLE `brand_runway` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `title_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `title_cn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `description_en` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `description_cn` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `created_at` int unsigned DEFAULT '0',\n `updated_at` int unsigned DEFAULT '0',\n `is_deleted` tinyint unsigned DEFAULT '0',\n `image_count` smallint unsigned DEFAULT '0',\n `brand_id` int unsigned NOT NULL DEFAULT '0',\n `year` smallint unsigned DEFAULT '0',\n `cover` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',\n `collection_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n `season` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,\n `season_code` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',\n PRIMARY KEY (`id`) USING BTREE,\n UNIQUE KEY `uk_brand_season` (`brand_id`,`season_code`,`collection_type`),\n KEY `idx_brand_id` (`brand_id`) USING BTREE,\n KEY `idx_year` (`year`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "title_en", - "title_cn", - "description_en", - "description_cn", - "created_at", - "updated_at", - "is_deleted", - "image_count", - "brand_id", - "year", - "cover", - "collection_type", - "season", - "season_code" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('brand_runway_id_seq'::regclass)" + }, + { + "name": "title_en", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "title_cn", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "description_en", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "description_cn", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image_count", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "brand_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "year", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "cover", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "collection_type", + "type": "varchar", + "is_nullable": false, + "is_identity": false, + "default": "''::character varying" + }, + { + "name": "season", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "season_code", + "type": "varchar", + "is_nullable": false, + "is_identity": false, + "default": "''::character varying" + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -279,27 +392,125 @@ }, { "name": "brand_runway_draft", - "create": "CREATE TABLE `brand_runway_draft` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `job_id` int unsigned NOT NULL DEFAULT '0',\n `brand_id` int unsigned NOT NULL DEFAULT '0',\n `title_en` varchar(512) NOT NULL DEFAULT '',\n `title_cn` varchar(512) NOT NULL DEFAULT '',\n `description_en` text,\n `description_cn` text,\n `year` smallint unsigned NOT NULL DEFAULT '0',\n `season` varchar(8) NOT NULL DEFAULT '',\n `collection_type` varchar(16) NOT NULL DEFAULT '',\n `season_code` varchar(8) NOT NULL DEFAULT '',\n `cover` varchar(1024) NOT NULL DEFAULT '',\n `image_count` smallint unsigned NOT NULL DEFAULT '0',\n `status` varchar(16) NOT NULL DEFAULT 'pending',\n `reviewer` varchar(64) NOT NULL DEFAULT '',\n `reject_reason` varchar(512) NOT NULL DEFAULT '',\n `is_deleted` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`),\n KEY `idx_status` (`status`),\n KEY `idx_job` (`job_id`)\n) ENGINE=InnoDB AUTO_INCREMENT=93 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", "columns": [ - "id", - "job_id", - "brand_id", - "title_en", - "title_cn", - "description_en", - "description_cn", - "year", - "season", - "collection_type", - "season_code", - "cover", - "image_count", - "status", - "reviewer", - "reject_reason", - "is_deleted", - "created_at", - "updated_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('brand_runway_draft_id_seq'::regclass)" + }, + { + "name": "job_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "brand_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "title_en", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "title_cn", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "description_en", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "description_cn", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "year", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "season", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "collection_type", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "season_code", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "cover", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image_count", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "status", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "reviewer", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "reject_reason", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -411,18 +622,89 @@ }, { "name": "brand_runway_draft_images", - "create": "CREATE TABLE `brand_runway_draft_images` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `draft_id` int unsigned NOT NULL DEFAULT '0',\n `image` varchar(1024) NOT NULL DEFAULT '',\n `name` varchar(255) NOT NULL DEFAULT '',\n `sort_order` int unsigned NOT NULL DEFAULT '0',\n `is_detail` tinyint unsigned NOT NULL DEFAULT '0',\n `look_index` int unsigned NOT NULL DEFAULT '0',\n `is_deleted` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`),\n KEY `idx_draft` (`draft_id`)\n) ENGINE=InnoDB AUTO_INCREMENT=3656 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", "columns": [ - "id", - "draft_id", - "image", - "name", - "sort_order", - "is_detail", - "look_index", - "is_deleted", - "created_at", - "updated_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('brand_runway_draft_images_id_seq'::regclass)" + }, + { + "name": "draft_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "name", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "sort_order", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "look_index", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_detail", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "phash", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_duplicate", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "dup_of", + "type": "text", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -431,11 +713,14 @@ "runway/3b9b7e07916b454ba93c56b4d2edc81614101e3c.jpg", "Look 1", "1", - "0", "1", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3101", @@ -447,7 +732,10 @@ "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3102", @@ -455,11 +743,14 @@ "runway/d93cf2bc50b36eb23f9dcccc33eeec30c32cadb5.jpg", "Look 2", "3", - "0", "2", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3103", @@ -467,11 +758,14 @@ "runway/50fa0a6bd295ef3c4f91273a9ac479d0f0ea5776.jpg", "Look 2 — Detail 1", "4", - "1", "2", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3104", @@ -479,11 +773,14 @@ "runway/ddcd6d9fd1250227b48b0df82bc3738a8f7d390a.jpg", "Look 2 — Detail 2", "5", - "1", "2", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3105", @@ -491,11 +788,14 @@ "runway/9169c35ad6a1aac7b5910d1296092c2dd8fff406.jpg", "Look 3", "6", - "0", "3", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3106", @@ -503,11 +803,14 @@ "runway/c8322d8c510ab7ac5e37242c32f888dda32b9dad.jpg", "Look 3 — Detail 1", "7", - "1", "3", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3107", @@ -515,11 +818,14 @@ "runway/a15402d14d4fe2bce43752010955237073530aeb.jpg", "Look 4", "8", - "0", "4", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3108", @@ -527,11 +833,14 @@ "runway/7d61cd76a0f4f0f2a28fd36365795863a3c2ae95.jpg", "Look 4 — Detail 1", "9", - "1", "4", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3109", @@ -539,11 +848,14 @@ "runway/8edd287a3a320672c3f17f9a3d7370ed5bc4ce82.jpg", "Look 4 — Detail 2", "10", - "1", "4", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3110", @@ -551,11 +863,14 @@ "runway/a4b6ca6e503334ee7a04cc7841432dc45ef312d1.jpg", "Look 5", "11", - "0", "5", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3111", @@ -563,11 +878,14 @@ "runway/103c3065584a23eaf2fdb3aa399b9b0d48a0530f.jpg", "Look 6", "12", - "0", "6", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3112", @@ -575,11 +893,14 @@ "runway/2fe145682980e8d318087c2f4aee953d1fc60caa.jpg", "Look 6 — Detail 1", "13", - "1", "6", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3113", @@ -587,11 +908,14 @@ "runway/6a6c56c8292c0c1f3b424797a94cb67411f20a4e.jpg", "Look 7", "14", - "0", "7", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3114", @@ -599,11 +923,14 @@ "runway/2aab80fee23ef969ad2ea3919f74b12318cddcbe.jpg", "Look 7 — Detail 1", "15", - "1", "7", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3115", @@ -611,11 +938,14 @@ "runway/8d9dae17557e4c85aa85bb2999594c3ed8f0b7bb.jpg", "Look 8", "16", - "0", "8", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3116", @@ -623,11 +953,14 @@ "runway/14b84b13a091dfb5b50ec58d183c1b802a1f2faa.jpg", "Look 8 — Detail 1", "17", - "1", "8", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3117", @@ -635,11 +968,14 @@ "runway/34073920cb75aaf9bab5b02e96a2810b2d2e6d0f.jpg", "Look 9", "18", - "0", "9", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3118", @@ -647,11 +983,14 @@ "runway/c4b3b179c09f0e6172053efc3877394d1031bf88.jpg", "Look 9 — Detail 1", "19", - "1", "9", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3119", @@ -659,11 +998,14 @@ "runway/2d11a281be9cd30d272e5739728e46906fe29646.jpg", "Look 10", "20", - "0", "10", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3120", @@ -671,11 +1013,14 @@ "runway/3a519d06c76abbe798d25d41f2e9e6b48f3076b4.jpg", "Look 11", "21", - "0", "11", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3121", @@ -683,11 +1028,14 @@ "runway/33c10c2a865c7774e1b99fa4e9dbd109306af972.jpg", "Look 11 — Detail 1", "22", - "1", "11", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3122", @@ -695,11 +1043,14 @@ "runway/0ed23849d1cc127d26dd48d43d0fd145bc0b9cd3.jpg", "Look 11 — Detail 2", "23", - "1", "11", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3123", @@ -707,11 +1058,14 @@ "runway/665f05c89a97f03489311abf30c0fb5bf91c8193.jpg", "Look 12", "24", - "0", "12", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3124", @@ -719,11 +1073,14 @@ "runway/45ff436b0235a2365a8ee6f26c7fbd4f39e33c41.jpg", "Look 12 — Detail 1", "25", - "1", "12", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3125", @@ -731,11 +1088,14 @@ "runway/e2127d87977bcc532ff9d39675be9809ef60a26f.jpg", "Look 13", "26", - "0", "13", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3126", @@ -743,11 +1103,14 @@ "runway/6a3b02f13ebbbbfd54248174d63b7b45f240b6de.jpg", "Look 13 — Detail 1", "27", - "1", "13", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3127", @@ -755,11 +1118,14 @@ "runway/dc5195062580363bb3e5d4d931fcabbc979e1085.jpg", "Look 13 — Detail 2", "28", - "1", "13", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3128", @@ -767,11 +1133,14 @@ "runway/84b3faff4ed7cad500823ae612d17c8981c1fba4.jpg", "Look 14", "29", - "0", "14", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3129", @@ -779,11 +1148,14 @@ "runway/a9c0348e2077a40511ded92dc37536f69310e6c5.jpg", "Look 14 — Detail 1", "30", - "1", "14", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3130", @@ -791,11 +1163,14 @@ "runway/f0b8f8bf35025c0e99b1a813bcb6c596446954dd.jpg", "Look 15", "31", - "0", "15", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3131", @@ -803,11 +1178,14 @@ "runway/8b1ad833497720cccfeb8353ecae43e1c6ba0de9.jpg", "Look 15 — Detail 1", "32", - "1", "15", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3132", @@ -815,11 +1193,14 @@ "runway/1ca07aa668dd4b9a2e6b1f3a18a348530d11d833.jpg", "Look 16", "33", - "0", "16", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3133", @@ -827,11 +1208,14 @@ "runway/e8ff2f9189cfcdbfe161a20b8ac6420673ba7be7.jpg", "Look 16 — Detail 1", "34", - "1", "16", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3134", @@ -839,11 +1223,14 @@ "runway/732e05988a821d74c522b0e0d2d633d334cf1d66.jpg", "Look 17", "35", - "0", "17", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3135", @@ -851,11 +1238,14 @@ "runway/41614ac8d4e7667865b5911c4a5493843b2d36fa.jpg", "Look 17 — Detail 1", "36", - "1", "17", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3136", @@ -863,11 +1253,14 @@ "runway/e43a4fc03661e19ba2eef049ca3e19db3809675c.jpg", "Look 18", "37", - "0", "18", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3137", @@ -875,11 +1268,14 @@ "runway/3b1f4ccbc965ef35184c5ae361a9ce96eb4acb9e.jpg", "Look 19", "38", - "0", "19", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3138", @@ -887,11 +1283,14 @@ "runway/90ae88137be6a58d770ecd5e5de5bd98de99c627.jpg", "Look 19 — Detail 1", "39", - "1", "19", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3139", @@ -899,11 +1298,14 @@ "runway/a501e0022ab59cf5339e42408875b942b341925d.jpg", "Look 20", "40", - "0", "20", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3140", @@ -911,11 +1313,14 @@ "runway/3eba3739a190b24ac33e4fc7cc35ededa3693830.jpg", "Look 20 — Detail 1", "41", - "1", "20", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3141", @@ -923,11 +1328,14 @@ "runway/ac922b339cb682c1d06029367509ddfdd872ad2b.jpg", "Look 20 — Detail 2", "42", - "1", "20", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3142", @@ -935,11 +1343,14 @@ "runway/84058a9f7c20ed82bc76b76d4b976b7a275259bd.jpg", "Look 21", "43", - "0", "21", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3143", @@ -947,11 +1358,14 @@ "runway/9ffcff1413804897b3a1205fe839d4a55f4fa74e.jpg", "Look 21 — Detail 1", "44", - "1", "21", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3144", @@ -959,11 +1373,14 @@ "runway/aa7f0f328ce2114748e7699481c13b20b21e9f72.jpg", "Look 22", "45", - "0", "22", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3145", @@ -971,11 +1388,14 @@ "runway/bf18bd7fab257fdefd3b067997dcf881ad8691ca.jpg", "Look 22 — Detail 1", "46", - "1", "22", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3146", @@ -983,11 +1403,14 @@ "runway/4dc8fb7d853b0fada8d769c1a9184b5a845134fa.jpg", "Look 23", "47", - "0", "23", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3147", @@ -995,11 +1418,14 @@ "runway/5bba200c123bc14ab24cb87901946b76eda75bd7.jpg", "Look 23 — Detail 1", "48", - "1", "23", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3148", @@ -1007,11 +1433,14 @@ "runway/eccf5d98e03fc424da9da6149dee411ab69868d5.jpg", "Look 24", "49", - "0", "24", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3149", @@ -1019,11 +1448,14 @@ "runway/33959ee00bc2a60a732c4b3f224aed57b29fe135.jpg", "Look 25", "50", - "0", "25", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3150", @@ -1031,11 +1463,14 @@ "runway/d717666f973a00f7a7f12bbd87f4557fa0cf4e7d.jpg", "Look 25 — Detail 1", "51", - "1", "25", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3151", @@ -1043,11 +1478,14 @@ "runway/0cfd3dfce2ad18c1818aff599c5c1d009a8a56c6.jpg", "Look 26", "52", - "0", "26", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3152", @@ -1055,11 +1493,14 @@ "runway/c6f13a5fc70b976a94cea6eb1e3712be07224ba6.jpg", "Look 27", "53", - "0", "27", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3153", @@ -1067,11 +1508,14 @@ "runway/ed08cd2fc3caff7ac35ba32ea7074031433642b3.jpg", "Look 28", "54", - "0", "28", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3154", @@ -1079,11 +1523,14 @@ "runway/0d50201e444a69fc4199589d21348b2553d70fc2.jpg", "Look 28 — Detail 1", "55", - "1", "28", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3155", @@ -1091,11 +1538,14 @@ "runway/2c04d9f6b9e27363f964a264838f0df762a61780.jpg", "Look 28 — Detail 2", "56", - "1", "28", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3156", @@ -1103,11 +1553,14 @@ "runway/5c6296f3b6964de5a1d66184bc209464a27b6350.jpg", "Look 29", "57", - "0", "29", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3157", @@ -1115,11 +1568,14 @@ "runway/336276ecae49d69727bc007120d3a6427b2e24b7.jpg", "Look 29 — Detail 1", "58", - "1", "29", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3158", @@ -1127,11 +1583,14 @@ "runway/db56ea5ce9657e0604e94cb3b966cc2c2bf4527f.jpg", "Look 30", "59", - "0", "30", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3159", @@ -1139,11 +1598,14 @@ "runway/f7f00879c90330f57f57d81c7a923707fb48d575.jpg", "Look 30 — Detail 1", "60", - "1", "30", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3160", @@ -1151,11 +1613,14 @@ "runway/443623ee48a87442c67d73a9c200b52923bae397.jpg", "Look 31", "61", - "0", "31", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3161", @@ -1163,11 +1628,14 @@ "runway/11323e5299690f14e4588d2fdbe6d72be62fce1c.jpg", "Look 31 — Detail 1", "62", - "1", "31", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3162", @@ -1175,11 +1643,14 @@ "runway/fb990a8d92917fa9fef8fa2f517ab36715a64794.jpg", "Look 32", "63", - "0", "32", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3163", @@ -1187,11 +1658,14 @@ "runway/01457d304ef9dd5a58e927b047d4870602231b2e.jpg", "Look 32 — Detail 1", "64", - "1", "32", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3164", @@ -1199,11 +1673,14 @@ "runway/01b944067c9e42b310c613d0b0859ae355a1a9e1.jpg", "Look 33", "65", - "0", "33", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3165", @@ -1211,11 +1688,14 @@ "runway/96cf74430117604bce4b9b63d89c3e4bbdb2f6e6.jpg", "Look 33 — Detail 1", "66", - "1", "33", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3166", @@ -1223,11 +1703,14 @@ "runway/8c6dd7c0a6563a0287da47731a5236eb57fd4469.jpg", "Look 34", "67", - "0", "34", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3167", @@ -1235,11 +1718,14 @@ "runway/e20fcd4ac355648db8cd19012dcaa76ac67e57cb.jpg", "Look 35", "68", - "0", "35", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3168", @@ -1247,11 +1733,14 @@ "runway/ea8baf19667e09e1727708a1dbf89a3fadaeeec9.jpg", "Look 35 — Detail 1", "69", - "1", "35", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3169", @@ -1259,11 +1748,14 @@ "runway/851140b110cf0246984149ac3a46e767c558e608.jpg", "Look 35 — Detail 2", "70", - "1", "35", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3170", @@ -1271,11 +1763,14 @@ "runway/e9f65aa2bf070f0401dec12ae0890657fe596cf9.jpg", "Look 36", "71", - "0", "36", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3171", @@ -1283,11 +1778,14 @@ "runway/fac700352f61dcfb36918e0c6a55737182339bfb.jpg", "Look 36 — Detail 1", "72", - "1", "36", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3172", @@ -1295,11 +1793,14 @@ "runway/9ab643a773ee4f093ffe7b978b3ebcbbad5f3d61.jpg", "Look 37", "73", - "0", "37", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3173", @@ -1307,11 +1808,14 @@ "runway/4895adfd63321a2a1713bbdda5b384e48beb6239.jpg", "Look 37 — Detail 1", "74", - "1", "37", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3174", @@ -1319,11 +1823,14 @@ "runway/65e71aa78986cec7d15a545d26c88d9e49a06710.jpg", "Look 38", "75", - "0", "38", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3175", @@ -1331,11 +1838,14 @@ "runway/46d46a49ce8dc5bcf8c8397faad8d6fb1705cd6a.jpg", "Look 38 — Detail 1", "76", - "1", "38", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3176", @@ -1343,11 +1853,14 @@ "runway/592fcd8310ac891e0c5c81fe9f29a065ebb43b25.jpg", "Look 38 — Detail 2", "77", - "1", "38", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3177", @@ -1355,11 +1868,14 @@ "runway/19a6948b7c8e6f47a752f6149eda441313487e78.jpg", "Look 39", "78", - "0", "39", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3178", @@ -1367,11 +1883,14 @@ "runway/0c08437bf4d41e4c9c0bc4a9e6c24ba867385790.jpg", "Look 39 — Detail 1", "79", - "1", "39", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3179", @@ -1379,11 +1898,14 @@ "runway/432e57ec4960c94399549e75a1f200e996734de0.jpg", "Look 39 — Detail 2", "80", - "1", "39", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3180", @@ -1391,11 +1913,14 @@ "runway/aa7529a481612b033dd5bcb795abaef6d6b0ff25.jpg", "Look 40", "81", - "0", "40", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3181", @@ -1403,11 +1928,14 @@ "runway/0f524235b301b477c1db0fbb9c8f34cf9b3ef450.jpg", "Look 40 — Detail 1", "82", - "1", "40", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3182", @@ -1415,11 +1943,14 @@ "runway/cf21eb59e38161fa84629d2764e4b171dbfca174.jpg", "Look 41", "83", - "0", "41", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3183", @@ -1427,11 +1958,14 @@ "runway/650d564fda1768298c299fe62c5fd70d5eccd371.jpg", "Look 41 — Detail 1", "84", - "1", "41", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3184", @@ -1439,11 +1973,14 @@ "runway/c94ba1964d3559b6490510dff747b281c86e82c9.jpg", "Look 41 — Detail 2", "85", - "1", "41", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3185", @@ -1451,11 +1988,14 @@ "runway/092ee3fcc8ad46d95c4d9827b65e73d2781c7d61.jpg", "Look 42", "86", - "0", "42", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3186", @@ -1463,11 +2003,14 @@ "runway/fb74adde31318e1307e2fdea8b032384e722897b.jpg", "Look 43", "87", - "0", "43", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3187", @@ -1475,11 +2018,14 @@ "runway/8f5730d7b684417bf421b4aa4e498bafe1ceb4b6.jpg", "Look 43 — Detail 1", "88", - "1", "43", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3188", @@ -1487,11 +2033,14 @@ "runway/deda0cc53ae8091bbfb3b6426c86fe0a3b3c280d.jpg", "Look 43 — Detail 2", "89", - "1", "43", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3189", @@ -1499,11 +2048,14 @@ "runway/b66cd176fdd6c4e843f9a268c201e91ba73a636e.jpg", "Look 44", "90", - "0", "44", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3190", @@ -1511,11 +2063,14 @@ "runway/e787c6781f05ae18de31d388605f3043927965c9.jpg", "Look 44 — Detail 1", "91", - "1", "44", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3191", @@ -1523,11 +2078,14 @@ "runway/e5c2d7f241209d9b0350bdfcc99dd2c78791edf1.jpg", "Look 45", "92", - "0", "45", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3192", @@ -1535,11 +2093,14 @@ "runway/a9847861e8288aeda1cb8795639ac55e7ac0b85c.jpg", "Look 45 — Detail 1", "93", - "1", "45", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3193", @@ -1547,11 +2108,14 @@ "runway/3ccc5ff70272a03a7bb7fe3aec744608f46ac0a5.jpg", "Look 46", "94", - "0", "46", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3194", @@ -1559,11 +2123,14 @@ "runway/9c13d470ef38b832058a9cf7cca147939afb84de.jpg", "Look 46 — Detail 1", "95", - "1", "46", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3195", @@ -1571,11 +2138,14 @@ "runway/13aee23b6ce1198818ec119b3b0e3147425c37a5.jpg", "Look 46 — Detail 2", "96", - "1", "46", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3196", @@ -1583,11 +2153,14 @@ "runway/2ea4c8371610ee9982e052118744c404574c21b5.jpg", "Look 47", "97", - "0", "47", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3197", @@ -1595,11 +2168,14 @@ "runway/280a4aafb38041c9d7857ef31edb9eb4d4a063c7.jpg", "Look 47 — Detail 1", "98", - "1", "47", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3198", @@ -1607,11 +2183,14 @@ "runway/ee6f26e87f68be48c370f83321c2d5ea0b67eba8.jpg", "Look 47 — Detail 2", "99", - "1", "47", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3199", @@ -1619,11 +2198,14 @@ "runway/04976a042c1ea845fc5b372fedbbfe53588caea5.jpg", "Look 48", "100", - "0", "48", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3200", @@ -1631,11 +2213,14 @@ "runway/4cb679695d2291bf27cddd69996a6c392085b6c9.jpg", "Look 48 — Detail 1", "101", - "1", "48", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3201", @@ -1643,11 +2228,14 @@ "runway/da95e17259c679d2843b3196dedcfc456213db2d.jpg", "Look 49", "102", - "0", "49", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3202", @@ -1655,11 +2243,14 @@ "runway/82612e513e27ce79b3af6719b1325fa1a883e8d4.jpg", "Look 49 — Detail 1", "103", - "1", "49", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3203", @@ -1667,11 +2258,14 @@ "runway/4929b63c4dc173fb6a6128072449160c5def9fe3.jpg", "Look 50", "104", - "0", "50", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3204", @@ -1679,11 +2273,14 @@ "runway/a389a7acb3a90d11ce2fb432c23a2711fe076ad2.jpg", "Look 50 — Detail 1", "105", - "1", "50", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3205", @@ -1691,11 +2288,14 @@ "runway/3863f2da28149db92f101a00fc57486a2fdd0d7f.jpg", "Look 51", "106", - "0", "51", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3206", @@ -1703,11 +2303,14 @@ "runway/551ed4a9cb5709d829a39a3e0942b39303d7baa5.jpg", "Look 51 — Detail 1", "107", - "1", "51", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3207", @@ -1715,11 +2318,14 @@ "runway/050e59a4cebf20025905d2e16667ea2441b6a239.jpg", "Look 52", "108", - "0", "52", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3208", @@ -1727,11 +2333,14 @@ "runway/c71605bb6c0797cfc957ae014def6463f4342a4c.jpg", "Look 52 — Detail 1", "109", - "1", "52", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3209", @@ -1739,11 +2348,14 @@ "runway/8c2a6b60b87b1db821c457c67d78becb925eca8d.jpg", "Look 52 — Detail 2", "110", - "1", "52", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3210", @@ -1751,11 +2363,14 @@ "runway/64560ccb4050d5008ab6f8dd8eb805e642bfce69.jpg", "Look 53", "111", - "0", "53", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3211", @@ -1763,11 +2378,14 @@ "runway/a147cff64aef1cb5ec4e94b9e34961ee422a860f.jpg", "Look 53 — Detail 1", "112", - "1", "53", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3212", @@ -1775,11 +2393,14 @@ "runway/c5b86556fbb955d8a46ad783e6a0bff50f4918da.jpg", "Look 54", "113", - "0", "54", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3213", @@ -1787,11 +2408,14 @@ "runway/11360e57033a19d2e87576c2eca0b6506869e560.jpg", "Look 54 — Detail 1", "114", - "1", "54", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3214", @@ -1799,11 +2423,14 @@ "runway/dedc0745eff27c35871dbf176031cb3c6bb399b7.jpg", "Look 55", "115", - "0", "55", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3215", @@ -1811,11 +2438,14 @@ "runway/5c6a6076eca199c4140d0d55a444630525e10133.jpg", "Look 55 — Detail 1", "116", - "1", "55", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3216", @@ -1823,11 +2453,14 @@ "runway/d3b3528ce9fc33d10a3a5f58ae75868e29a63cce.jpg", "Look 56", "117", - "0", "56", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3217", @@ -1835,11 +2468,14 @@ "runway/802a915bccbc3cbda3b49cb750f255485f952720.jpg", "Look 56 — Detail 1", "118", - "1", "56", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3218", @@ -1847,11 +2483,14 @@ "runway/aca5b86e5cb74555bca15e5f7690e99b0c1a4fa9.jpg", "Look 57", "119", - "0", "57", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3219", @@ -1859,11 +2498,14 @@ "runway/29bb31e5325343e3218049958149e7d8f3919999.jpg", "Look 57 — Detail 1", "120", - "1", "57", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3220", @@ -1871,11 +2513,14 @@ "runway/ec4a489b72bd150fea90fcb34f3d451896a208b0.jpg", "Look 57 — Detail 2", "121", - "1", "57", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3221", @@ -1883,11 +2528,14 @@ "runway/2f447c8bdf87a3007324425692794f6d96779313.jpg", "Look 58", "122", - "0", "58", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3222", @@ -1895,11 +2543,14 @@ "runway/7efa2cb6d6833941ff453db6bf55086bbb6bb017.jpg", "Look 58 — Detail 1", "123", - "1", "58", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3223", @@ -1907,11 +2558,14 @@ "runway/68439a900798601d55578c66957a34def1b5e8ea.jpg", "Look 58 — Detail 2", "124", - "1", "58", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3224", @@ -1919,11 +2573,14 @@ "runway/10150cb18221a510bc09b4297b5c917f80aed275.jpg", "Look 59", "125", - "0", "59", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3225", @@ -1931,11 +2588,14 @@ "runway/08c992c264b3fcd03f6caf2c9072f4081648c371.jpg", "Look 59 — Detail 1", "126", - "1", "59", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3226", @@ -1943,11 +2603,14 @@ "runway/6f4c350bf4c9d6a9806ab90ce78837a8e1c96099.jpg", "Look 60", "127", - "0", "60", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3227", @@ -1955,11 +2618,14 @@ "runway/8a807bedea0650ea2511b3f846c84a94cbfd710d.jpg", "Look 60 — Detail 1", "128", - "1", "60", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3228", @@ -1967,11 +2633,14 @@ "runway/e8c8339a09110f9a3d39bafa8f9d8e59a449e100.jpg", "Look 61", "129", - "0", "61", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3229", @@ -1979,11 +2648,14 @@ "runway/36449614d3c4a123c36315a7ec29beec99c77610.jpg", "Look 61 — Detail 1", "130", - "1", "61", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3230", @@ -1991,11 +2663,14 @@ "runway/c09ee8900ddb979bd42e07159a1f636e15650089.jpg", "Look 62", "131", - "0", "62", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3231", @@ -2003,11 +2678,14 @@ "runway/b1bb925c7eb5155eb74aad89e5689254b16161ed.jpg", "Look 62 — Detail 1", "132", - "1", "62", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3232", @@ -2015,11 +2693,14 @@ "runway/c5c0d7c434d89600541c9699ed1cd060a6c1c95b.jpg", "Look 63", "133", - "0", "63", "0", + "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3233", @@ -2027,11 +2708,14 @@ "runway/6d4cd5802283dbcb28d496e23d337299e0acc343.jpg", "Look 63 — Detail 1", "134", - "1", "63", + "1", "0", "1789137204", - "1789137204" + "1789137204", + null, + null, + null ], [ "3234", @@ -2039,11 +2723,14 @@ "runway/7a79af2f7d456b427cdb68d5330ba1b9decf5dce.jpg", "Look 1", "1", - "0", "1", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3235", @@ -2055,7 +2742,10 @@ "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3236", @@ -2067,7 +2757,10 @@ "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3237", @@ -2075,11 +2768,14 @@ "runway/3de4a8d19bc5acf61b58eb5d2f765e3cd13c0efb.jpg", "Look 2", "4", - "0", "2", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3238", @@ -2087,11 +2783,14 @@ "runway/2210635ae5420494bf37fddd59feb1a917396a00.jpg", "Look 2 — Detail 1", "5", - "1", "2", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3239", @@ -2099,11 +2798,14 @@ "runway/c0525730b986eee4db8e92bddbb5aa6e7d2eea71.jpg", "Look 2 — Detail 2", "6", - "1", "2", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3240", @@ -2111,11 +2813,14 @@ "runway/799a48f290908f4a43c73f12990791b61e91ef19.jpg", "Look 2 — Detail 3", "7", - "1", "2", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3241", @@ -2123,11 +2828,14 @@ "runway/add90692b7e5480ade8d9e9863efbf280d10ac21.jpg", "Look 3", "8", - "0", "3", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3242", @@ -2135,11 +2843,14 @@ "runway/edf39c509dd5c86d5480bdcf249472c759baad27.jpg", "Look 3 — Detail 1", "9", - "1", "3", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3243", @@ -2147,11 +2858,14 @@ "runway/442d14bab0f3847af9e9a7419313a8fa5156045c.jpg", "Look 3 — Detail 2", "10", - "1", "3", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3244", @@ -2159,11 +2873,14 @@ "runway/a40852020eeeb7d966e6b632b40b2a6b356c9f9e.jpg", "Look 4", "11", - "0", "4", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3245", @@ -2171,11 +2888,14 @@ "runway/4d8aecf46cd04fb6e237272814eaa9fc19e63ad8.jpg", "Look 4 — Detail 1", "12", - "1", "4", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3246", @@ -2183,11 +2903,14 @@ "runway/5192a953de7a3414a092c1b120d39a1b64c41710.jpg", "Look 4 — Detail 2", "13", - "1", "4", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3247", @@ -2195,11 +2918,14 @@ "runway/fef87d9b4d2d35480ce84ea961ab095f7f10bee7.jpg", "Look 4 — Detail 3", "14", - "1", "4", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3248", @@ -2207,11 +2933,14 @@ "runway/9c360f3253196f72b7f7abcaa0c9d4d5f3247725.jpg", "Look 5", "15", - "0", "5", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3249", @@ -2219,11 +2948,14 @@ "runway/80988d01741b8124f3139246d99890807edd2900.jpg", "Look 5 — Detail 1", "16", - "1", "5", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3250", @@ -2231,11 +2963,14 @@ "runway/6c23e857f873df88c6f092606e57a92dea8632b1.jpg", "Look 5 — Detail 2", "17", - "1", "5", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3251", @@ -2243,11 +2978,14 @@ "runway/f88d03fb1ca60ff7d05cc9cc0a0ddf8c1c004b9e.jpg", "Look 5 — Detail 3", "18", - "1", "5", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3252", @@ -2255,11 +2993,14 @@ "runway/5e3bca2f45fcc218fa88e4216fa19d9c6238ff29.jpg", "Look 6", "19", - "0", "6", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3253", @@ -2267,11 +3008,14 @@ "runway/38a7a3db5d99e114a98c28b6d5c07eae76f011fa.jpg", "Look 6 — Detail 1", "20", - "1", "6", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3254", @@ -2279,11 +3023,14 @@ "runway/268324cd990b53c7c958b71440b612a9edf89fcb.jpg", "Look 6 — Detail 2", "21", - "1", "6", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3255", @@ -2291,11 +3038,14 @@ "runway/2b5d90e769c1b7887ed60f9a1845e25113499a89.jpg", "Look 7", "22", - "0", "7", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3256", @@ -2303,11 +3053,14 @@ "runway/72538728aa126c4b5e8dc1afb86cc28d86d3f52f.jpg", "Look 7 — Detail 1", "23", - "1", "7", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3257", @@ -2315,11 +3068,14 @@ "runway/d7d4b06a66f63e7eb327872964c468d17e826288.jpg", "Look 8", "24", - "0", "8", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3258", @@ -2327,11 +3083,14 @@ "runway/bbf094bf5c04be8c790104429736b2d3e7c8f3ab.jpg", "Look 8 — Detail 1", "25", - "1", "8", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3259", @@ -2339,11 +3098,14 @@ "runway/bb1b1c219d5508de431c21922ec01b28ce8bddec.jpg", "Look 9", "26", - "0", "9", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3260", @@ -2351,11 +3113,14 @@ "runway/cb8ad812f3056e07e91a14f18e2f880787fd6573.jpg", "Look 9 — Detail 1", "27", - "1", "9", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3261", @@ -2363,11 +3128,14 @@ "runway/756cf31c3548788d92d938dabf158269875c5712.jpg", "Look 10", "28", - "0", "10", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3262", @@ -2375,11 +3143,14 @@ "runway/f53a2a15e359f7def3dd9244a0db1514c33b0ceb.jpg", "Look 10 — Detail 1", "29", - "1", "10", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3263", @@ -2387,11 +3158,14 @@ "runway/dda466b3ee589d4dba1fb3054abc559ba37856d8.jpg", "Look 10 — Detail 2", "30", - "1", "10", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3264", @@ -2399,11 +3173,14 @@ "runway/0fd2b408ca7a63247421e950e6f46d0486389afa.jpg", "Look 11", "31", - "0", "11", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3265", @@ -2411,11 +3188,14 @@ "runway/76b6bfa821b37bd23f68e748a4c8e4d9cbd67bb5.jpg", "Look 11 — Detail 1", "32", - "1", "11", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3266", @@ -2423,11 +3203,14 @@ "runway/0a77481a67f69a1d7a0027eacae97712d265fa9c.jpg", "Look 11 — Detail 2", "33", - "1", "11", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3267", @@ -2435,11 +3218,14 @@ "runway/1f69241c6f48cc4c7f613d3511364c1318dea16e.jpg", "Look 12", "34", - "0", "12", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3268", @@ -2447,11 +3233,14 @@ "runway/00f37781ea05fe384972094b5c1740bb3b7ec602.jpg", "Look 12 — Detail 1", "35", - "1", "12", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3269", @@ -2459,11 +3248,14 @@ "runway/b3e13eceb3af19eb7ec86a54df78dd544b72716a.jpg", "Look 12 — Detail 2", "36", - "1", "12", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3270", @@ -2471,11 +3263,14 @@ "runway/8c8bb262232ef3da58d54859f0c39f6902472501.jpg", "Look 12 — Detail 3", "37", - "1", "12", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3271", @@ -2483,11 +3278,14 @@ "runway/972f629cd66a37f4d60b59f175421a25606e596f.jpg", "Look 13", "38", - "0", "13", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3272", @@ -2495,11 +3293,14 @@ "runway/f19a9679f277e2a2c761323d57b9d363b1404f05.jpg", "Look 13 — Detail 1", "39", - "1", "13", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3273", @@ -2507,11 +3308,14 @@ "runway/551bf8b0a273c16da92fafc6a9cc1ba9afb2c73c.jpg", "Look 13 — Detail 2", "40", - "1", "13", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3274", @@ -2519,11 +3323,14 @@ "runway/1c0e9e7b1dfe785d628887eac500502431356d10.jpg", "Look 13 — Detail 3", "41", - "1", "13", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3275", @@ -2531,11 +3338,14 @@ "runway/ee25554956bec48bae9a1b202134181a2c5c92fa.jpg", "Look 14", "42", - "0", "14", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3276", @@ -2543,11 +3353,14 @@ "runway/74d3428c0c1dba4fe86b274465352adceb0cecff.jpg", "Look 15", "43", - "0", "15", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3277", @@ -2555,11 +3368,14 @@ "runway/771f1297b4b9ff5f1aa9cf58e15649b9f93f89cf.jpg", "Look 15 — Detail 1", "44", - "1", "15", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3278", @@ -2567,11 +3383,14 @@ "runway/cee08e6bb076a88c4f194ab75ab9c71916281127.jpg", "Look 15 — Detail 2", "45", - "1", "15", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3279", @@ -2579,11 +3398,14 @@ "runway/5b9915ab65f324548c5e8280cf1c3697b9607db4.jpg", "Look 16", "46", - "0", "16", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3280", @@ -2591,11 +3413,14 @@ "runway/9870e52f471394cd825d8199822a1354045e4b69.jpg", "Look 16 — Detail 1", "47", - "1", "16", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3281", @@ -2603,11 +3428,14 @@ "runway/1f28a2bedc8a1fb11b9aa8f28ad97e264bc99610.jpg", "Look 16 — Detail 2", "48", - "1", "16", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3282", @@ -2615,11 +3443,14 @@ "runway/3895d92a623b9f05ec2e711dfb756eddd4a7dbb0.jpg", "Look 17", "49", - "0", "17", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3283", @@ -2627,11 +3458,14 @@ "runway/570ef1dfd5125c9f52fa31b3b6754b9bdba2d851.jpg", "Look 17 — Detail 1", "50", - "1", "17", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3284", @@ -2639,11 +3473,14 @@ "runway/bdccd2b60ef2e51b44e81dbd723ee186a0f3915b.jpg", "Look 17 — Detail 2", "51", - "1", "17", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3285", @@ -2651,11 +3488,14 @@ "runway/695aaa9f2c3c333deb802cade4b2b21e4d521691.jpg", "Look 18", "52", - "0", "18", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3286", @@ -2663,11 +3503,14 @@ "runway/4e2ec1879bddd161498fdd25b11c0a0a45523c81.jpg", "Look 18 — Detail 1", "53", - "1", "18", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3287", @@ -2675,11 +3518,14 @@ "runway/b498e1417318bebf6086c2d41760dc6cb8b89053.jpg", "Look 18 — Detail 2", "54", - "1", "18", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3288", @@ -2687,11 +3533,14 @@ "runway/a42e5a0ab0e962697b6a09cc48f5c292da9dab9a.jpg", "Look 19", "55", - "0", "19", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3289", @@ -2699,11 +3548,14 @@ "runway/710d2e6bb458ba63dd1de72505dba18a134e9bad.jpg", "Look 19 — Detail 1", "56", - "1", "19", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3290", @@ -2711,11 +3563,14 @@ "runway/f74efa892acf558d54d244d0ee91b1d7ca6f10f3.jpg", "Look 19 — Detail 2", "57", - "1", "19", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3291", @@ -2723,11 +3578,14 @@ "runway/5baf7fe9345a8deb6a7e59432a2158ca9d4228bd.jpg", "Look 19 — Detail 3", "58", - "1", "19", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3292", @@ -2735,11 +3593,14 @@ "runway/0a161f5edf3b2fdd221087494ee79fbde9053708.jpg", "Look 20", "59", - "0", "20", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3293", @@ -2747,11 +3608,14 @@ "runway/d6c4bb92b1dd4faa5d40a41325c75585f1581d8f.jpg", "Look 20 — Detail 1", "60", - "1", "20", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3294", @@ -2759,11 +3623,14 @@ "runway/5f656cd7dd330f95a6edcfd13c2c1cced6b0241c.jpg", "Look 20 — Detail 2", "61", - "1", "20", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3295", @@ -2771,11 +3638,14 @@ "runway/a5bbeb33cede643b95eff85adfc5438ae5855e6c.jpg", "Look 20 — Detail 3", "62", - "1", "20", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3296", @@ -2783,11 +3653,14 @@ "runway/5349fa23f11e6231ee9e05f2c4cc54e3a154ed4d.jpg", "Look 21", "63", - "0", "21", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3297", @@ -2795,11 +3668,14 @@ "runway/ab13b8b0263277ba5015de56a87693ebe73f0ef1.jpg", "Look 21 — Detail 1", "64", - "1", "21", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3298", @@ -2807,11 +3683,14 @@ "runway/393dbd177ffc05e820b459e7568ab67e7fd084b4.jpg", "Look 21 — Detail 2", "65", - "1", "21", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3299", @@ -2819,11 +3698,14 @@ "runway/42a9d9fc6b2a2049bc3ed21fe6d045bd0120700a.jpg", "Look 21 — Detail 3", "66", - "1", "21", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3300", @@ -2831,11 +3713,14 @@ "runway/7ada5f030f95c0f23963eefd8c88ee9f9504fcc1.jpg", "Look 22", "67", - "0", "22", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3301", @@ -2843,11 +3728,14 @@ "runway/dafba17544c9490a673482fca6ec3e6cd009b4b0.jpg", "Look 22 — Detail 1", "68", - "1", "22", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3302", @@ -2855,11 +3743,14 @@ "runway/16d296921d97be5de722c10ddcd8d823b51f7db0.jpg", "Look 22 — Detail 2", "69", - "1", "22", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3303", @@ -2867,11 +3758,14 @@ "runway/f2eda5b44c16681bfd94c14f6207818911c4701e.jpg", "Look 23", "70", - "0", "23", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3304", @@ -2879,11 +3773,14 @@ "runway/61e1d377d650f21a35acb64135ed37bcf5328f6b.jpg", "Look 23 — Detail 1", "71", - "1", "23", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3305", @@ -2891,11 +3788,14 @@ "runway/79819c63bc5447cc44fe5da60eea7bfde92a8466.jpg", "Look 23 — Detail 2", "72", - "1", "23", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3306", @@ -2903,11 +3803,14 @@ "runway/a666131610d6f089f2e11649b80c950dc23bdea7.jpg", "Look 24", "73", - "0", "24", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3307", @@ -2915,11 +3818,14 @@ "runway/17b743da2bbb0345782604db3768de7fc739ba63.jpg", "Look 24 — Detail 1", "74", - "1", "24", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3308", @@ -2927,11 +3833,14 @@ "runway/4edf741c13b916844471f4afd12e0414c4810a24.jpg", "Look 25", "75", - "0", "25", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3309", @@ -2939,11 +3848,14 @@ "runway/8d170b443b4929c0e7af4b01b0da065390dec279.jpg", "Look 25 — Detail 1", "76", - "1", "25", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3310", @@ -2951,11 +3863,14 @@ "runway/d755437501c5aefaed371eb30b4f0a805f1d146a.jpg", "Look 25 — Detail 2", "77", - "1", "25", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3311", @@ -2963,11 +3878,14 @@ "runway/3e33c3b89340f4da7736be65b2a4fb38d5326136.jpg", "Look 25 — Detail 3", "78", - "1", "25", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3312", @@ -2975,11 +3893,14 @@ "runway/3ecbce60e4b63f922d3168bac2bfaf971ad32e01.jpg", "Look 26", "79", - "0", "26", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3313", @@ -2987,11 +3908,14 @@ "runway/612557c2d2570a76e556f7e90a90cc6eed187f47.jpg", "Look 26 — Detail 1", "80", - "1", "26", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3314", @@ -2999,11 +3923,14 @@ "runway/e7ab577b9f8dab03ca30860c450cfab72f32139a.jpg", "Look 26 — Detail 2", "81", - "1", "26", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3315", @@ -3011,11 +3938,14 @@ "runway/8f8e75d5db25072913052b04efc4ac30f8d7e356.jpg", "Look 26 — Detail 3", "82", - "1", "26", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3316", @@ -3023,11 +3953,14 @@ "runway/66db39fd428061e9b77fe9270eec2a2d102954d3.jpg", "Look 27", "83", - "0", "27", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3317", @@ -3035,11 +3968,14 @@ "runway/a82c4cf9e4c209fbc801bb7f5297d6ac16fe60b9.jpg", "Look 27 — Detail 1", "84", - "1", "27", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3318", @@ -3047,11 +3983,14 @@ "runway/a3df8ab000cc53d68dc09774861802dc21949f64.jpg", "Look 27 — Detail 2", "85", - "1", "27", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3319", @@ -3059,11 +3998,14 @@ "runway/7c0d458c9d545561c101c4b016adc5f139d2326b.jpg", "Look 28", "86", - "0", "28", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3320", @@ -3071,11 +4013,14 @@ "runway/b433b04be4027ef675de28579a93f8972377e835.jpg", "Look 28 — Detail 1", "87", - "1", "28", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3321", @@ -3083,11 +4028,14 @@ "runway/08ce917a268041f68c19aca1846fbab579407ed7.jpg", "Look 28 — Detail 2", "88", - "1", "28", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3322", @@ -3095,11 +4043,14 @@ "runway/5bc90ebc1aad1a3b53a4a427363507981e18e605.jpg", "Look 29", "89", - "0", "29", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3323", @@ -3107,11 +4058,14 @@ "runway/898fbc75971d5d28f8f5530462378bd26ec18cb8.jpg", "Look 29 — Detail 1", "90", - "1", "29", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3324", @@ -3119,11 +4073,14 @@ "runway/1e1705c780e21557543edbac51661f89013d5223.jpg", "Look 29 — Detail 2", "91", - "1", "29", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3325", @@ -3131,11 +4088,14 @@ "runway/ac71b3ea5cd681cc499e0e085f1777ee273b1977.jpg", "Look 29 — Detail 3", "92", - "1", "29", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3326", @@ -3143,11 +4103,14 @@ "runway/2ab2f47a81bb6f31c0edfcdc41071c5f89b36427.jpg", "Look 29 — Detail 4", "93", - "1", "29", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3327", @@ -3155,11 +4118,14 @@ "runway/59d6de8b4f6df60f85a2364208c2491bf59e88a8.jpg", "Look 30", "94", - "0", "30", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3328", @@ -3167,11 +4133,14 @@ "runway/00a7a2de6519697ad72685a982f932a106348b79.jpg", "Look 31", "95", - "0", "31", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3329", @@ -3179,11 +4148,14 @@ "runway/1c085c3d4d7cd4603e3707c0d2116aca4fcfb6aa.jpg", "Look 31 — Detail 1", "96", - "1", "31", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3330", @@ -3191,11 +4163,14 @@ "runway/350653ef6b32bff62d8a9acb7a906dea6ddd8b11.jpg", "Look 32", "97", - "0", "32", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3331", @@ -3203,11 +4178,14 @@ "runway/fbe20218b9ba6a77d34e0cfc9c6977408fd79b2e.jpg", "Look 32 — Detail 1", "98", - "1", "32", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3332", @@ -3215,11 +4193,14 @@ "runway/0233e86c83a4fc15234534a35e0aec99f902e234.jpg", "Look 32 — Detail 2", "99", - "1", "32", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3333", @@ -3227,11 +4208,14 @@ "runway/79599ff0eca5a9f40482c2df5f30b74556d784f2.jpg", "Look 33", "100", - "0", "33", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3334", @@ -3239,11 +4223,14 @@ "runway/028ec7463c6c03234eaee4412e43ac3cec5504d9.jpg", "Look 33 — Detail 1", "101", - "1", "33", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3335", @@ -3251,11 +4238,14 @@ "runway/b2773c2706a369dfd7157f1ec39975a5d0545738.jpg", "Look 34", "102", - "0", "34", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3336", @@ -3263,11 +4253,14 @@ "runway/7b03ae39f63030748b150a3bb067af227f5d473b.jpg", "Look 34 — Detail 1", "103", - "1", "34", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3337", @@ -3275,11 +4268,14 @@ "runway/1ab642861a5abc02667e2fd2b7f4b71380e3bc72.jpg", "Look 34 — Detail 2", "104", - "1", "34", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3338", @@ -3287,11 +4283,14 @@ "runway/a600b7cb3091ec80e88ce93e6dde8d24fa117633.jpg", "Look 34 — Detail 3", "105", - "1", "34", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3339", @@ -3299,11 +4298,14 @@ "runway/1e187213d18ff0fa42d9bcd9f32cbfe486ecbde5.jpg", "Look 35", "106", - "0", "35", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3340", @@ -3311,11 +4313,14 @@ "runway/309a0a197e2162b872a3e210d62d130af7de547e.jpg", "Look 35 — Detail 1", "107", - "1", "35", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3341", @@ -3323,11 +4328,14 @@ "runway/dccc30e60228e7b231c3214c5437d6a773dd6012.jpg", "Look 35 — Detail 2", "108", - "1", "35", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3342", @@ -3335,11 +4343,14 @@ "runway/ce2f8f835f1e5a2b10c42c7287b725805397f2ad.jpg", "Look 36", "109", - "0", "36", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3343", @@ -3347,11 +4358,14 @@ "runway/9440231b016623e783073628a352bbb0af851729.jpg", "Look 36 — Detail 1", "110", - "1", "36", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3344", @@ -3359,11 +4373,14 @@ "runway/d550e648f1a689a834f3a60b46b6f1a011a47136.jpg", "Look 36 — Detail 2", "111", - "1", "36", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3345", @@ -3371,11 +4388,14 @@ "runway/2ca7d2d54819f63aebfb4a99344071489505d204.jpg", "Look 37", "112", - "0", "37", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3346", @@ -3383,11 +4403,14 @@ "runway/4359ea83ebbf828a8039d09be1e115005a7498b5.jpg", "Look 37 — Detail 1", "113", - "1", "37", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3347", @@ -3395,11 +4418,14 @@ "runway/4fbfe716046b1af4253e487d156855fdf9069d13.jpg", "Look 37 — Detail 2", "114", - "1", "37", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3348", @@ -3407,11 +4433,14 @@ "runway/9974756fc9937f0b74e0af0c731ef5a9cb369a59.jpg", "Look 38", "115", - "0", "38", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3349", @@ -3419,11 +4448,14 @@ "runway/30d4988ce4e5d33b06ee079d2769a6b9b44c727e.jpg", "Look 38 — Detail 1", "116", - "1", "38", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3350", @@ -3431,11 +4463,14 @@ "runway/a0f8cec9e308f38c5cf7319cff2bc99990ab6f97.jpg", "Look 38 — Detail 2", "117", - "1", "38", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3351", @@ -3443,11 +4478,14 @@ "runway/1054ca15999e9cb68608315c6b745b0e4d88ab7e.jpg", "Look 39", "118", - "0", "39", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3352", @@ -3455,11 +4493,14 @@ "runway/e6350b959eaabc86e5ffdeb6614b80de10e86432.jpg", "Look 40", "119", - "0", "40", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3353", @@ -3467,11 +4508,14 @@ "runway/b42f2dc7fd5b0d9980ad30b4a93790c68f3a5e4b.jpg", "Look 40 — Detail 1", "120", - "1", "40", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3354", @@ -3479,11 +4523,14 @@ "runway/c56ae4f5966dc2bd59db39dd932d049385a941e7.jpg", "Look 40 — Detail 2", "121", - "1", "40", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3355", @@ -3491,11 +4538,14 @@ "runway/bb2349b90396d08f65e07bf8827ce4957b5655b6.jpg", "Look 40 — Detail 3", "122", - "1", "40", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3356", @@ -3503,11 +4553,14 @@ "runway/13434b4c4d6ae77155b204c78ee910d3df62f299.jpg", "Look 41", "123", - "0", "41", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3357", @@ -3515,11 +4568,14 @@ "runway/4a27f85ec07470e2c45f06ac4fa505eb4d54aa75.jpg", "Look 41 — Detail 1", "124", - "1", "41", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3358", @@ -3527,11 +4583,14 @@ "runway/8702bee39c9ba2c04fe5aeb84b7e7cc7b0e1a91b.jpg", "Look 41 — Detail 2", "125", - "1", "41", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3359", @@ -3539,11 +4598,14 @@ "runway/558e2c2c434aea72681dae98fe0fde8000fd9830.jpg", "Look 42", "126", - "0", "42", "0", + "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3360", @@ -3551,11 +4613,14 @@ "runway/062ba768b50b2dd6335ab5eeb3a136375180556b.jpg", "Look 42 — Detail 1", "127", - "1", "42", + "1", "0", "1789137277", - "1789137277" + "1789137277", + null, + null, + null ], [ "3361", @@ -3563,11 +4628,14 @@ "runway/cc1924c01b84613de52e4a1409f777ad04a880b5.jpg", "Look 1", "1", - "0", "1", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3362", @@ -3579,7 +4647,10 @@ "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3363", @@ -3591,7 +4662,10 @@ "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3364", @@ -3599,11 +4673,14 @@ "runway/cbfadf2d600afe2d34d88a5bd77118e806b1a81e.jpg", "Look 2", "4", - "0", "2", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3365", @@ -3611,11 +4688,14 @@ "runway/ae751d69fc5284d81e4d887b94bd1289fe2c0a72.jpg", "Look 2 — Detail 1", "5", - "1", "2", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3366", @@ -3623,11 +4703,14 @@ "runway/493621bd66a95c9f8f50cb2948b64d51b4b32a1e.jpg", "Look 3", "6", - "0", "3", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3367", @@ -3635,11 +4718,14 @@ "runway/a0f87693ad9128dcaabf7316cd9f7a2ba3d03ce5.jpg", "Look 4", "7", - "0", "4", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3368", @@ -3647,11 +4733,14 @@ "runway/adfecda1c106c7e0295d4137064044cab05c405b.jpg", "Look 5", "8", - "0", "5", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3369", @@ -3659,11 +4748,14 @@ "runway/7f2d60628f840aa12caef776a7678a7e921cbf97.jpg", "Look 5 — Detail 1", "9", - "1", "5", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3370", @@ -3671,11 +4763,14 @@ "runway/c7cb1f92454b8aff8de2456c7634dea5c2e59134.jpg", "Look 6", "10", - "0", "6", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3371", @@ -3683,11 +4778,14 @@ "runway/8b4aa5736dc0ec4cca0e920439f85c897b9df002.jpg", "Look 6 — Detail 1", "11", - "1", "6", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3372", @@ -3695,11 +4793,14 @@ "runway/c39d56e905156ae6307291e757ff2f321426c64d.jpg", "Look 7", "12", - "0", "7", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3373", @@ -3707,11 +4808,14 @@ "runway/770f948b812d1c586094822c36cf55272cea2012.jpg", "Look 7 — Detail 1", "13", - "1", "7", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3374", @@ -3719,11 +4823,14 @@ "runway/22b7c73cf38eb0a85878a0cdfbe638c5f6639382.jpg", "Look 7 — Detail 2", "14", - "1", "7", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3375", @@ -3731,11 +4838,14 @@ "runway/0b04a7c40cd6c9f80d8a5fc123016b86be1c291d.jpg", "Look 8", "15", - "0", "8", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3376", @@ -3743,11 +4853,14 @@ "runway/83723064aa5df62dece160cac0dfb127820d0e89.jpg", "Look 9", "16", - "0", "9", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3377", @@ -3755,11 +4868,14 @@ "runway/f923cb11228a9e81661815237168f065b3b612e1.jpg", "Look 9 — Detail 1", "17", - "1", "9", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3378", @@ -3767,11 +4883,14 @@ "runway/5004c0e0248845a1f96f6b15e61dcbff9fef9510.jpg", "Look 9 — Detail 2", "18", - "1", "9", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3379", @@ -3779,11 +4898,14 @@ "runway/d9dcbb9421f1fd5baaacb71944c6590e3b87245f.jpg", "Look 10", "19", - "0", "10", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3380", @@ -3791,11 +4913,14 @@ "runway/ad3f281243dc307fc6625c15ad1478520e8d49c3.jpg", "Look 11", "20", - "0", "11", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3381", @@ -3803,11 +4928,14 @@ "runway/2a37ff3abc2425531b56d822eed35f6f346313d1.jpg", "Look 11 — Detail 1", "21", - "1", "11", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3382", @@ -3815,11 +4943,14 @@ "runway/aab239dfe2186b6590bfd9a990708f3574b18434.jpg", "Look 12", "22", - "0", "12", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3383", @@ -3827,11 +4958,14 @@ "runway/22a4e29ce333a7b9ef2d71564b15fe5e22dda390.jpg", "Look 12 — Detail 1", "23", - "1", "12", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3384", @@ -3839,11 +4973,14 @@ "runway/ff447bf8a206cab6cb458513e474874fc1cc0c16.jpg", "Look 13", "24", - "0", "13", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3385", @@ -3851,11 +4988,14 @@ "runway/5b6ecac3f52c9167834b56295f67446a073b3823.jpg", "Look 13 — Detail 1", "25", - "1", "13", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3386", @@ -3863,11 +5003,14 @@ "runway/7e0cb3cd83be4674218c516e50e613934769be0b.jpg", "Look 14", "26", - "0", "14", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3387", @@ -3875,11 +5018,14 @@ "runway/5cb0d457517fa24cf69b04a7465b77971a30749a.jpg", "Look 15", "27", - "0", "15", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3388", @@ -3887,11 +5033,14 @@ "runway/45c348e8f4faa8e78eacfda14afbb4c835b6ddcb.jpg", "Look 15 — Detail 1", "28", - "1", "15", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3389", @@ -3899,11 +5048,14 @@ "runway/b965af9fca712ec4aea11f1b1190cb4cb2b5e4ab.jpg", "Look 16", "29", - "0", "16", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3390", @@ -3911,11 +5063,14 @@ "runway/c9e8dd148a9a26ec61cb355eb8ebe47ffc04e8fe.jpg", "Look 17", "30", - "0", "17", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3391", @@ -3923,11 +5078,14 @@ "runway/785ed4d1d6a250c2e8b5c8c088e160cfd050543f.jpg", "Look 17 — Detail 1", "31", - "1", "17", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3392", @@ -3935,11 +5093,14 @@ "runway/54c96d0a39004573b35a7e83b2789609ee602d10.jpg", "Look 18", "32", - "0", "18", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3393", @@ -3947,11 +5108,14 @@ "runway/c0c90b1fb5cb797e465accabdcbb54360d548f69.jpg", "Look 18 — Detail 1", "33", - "1", "18", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3394", @@ -3959,11 +5123,14 @@ "runway/b17ddecfe41da887f56f6c2903d8af8e361e4dc8.jpg", "Look 19", "34", - "0", "19", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3395", @@ -3971,11 +5138,14 @@ "runway/437268756eda3a4d0f12571d55baaede0b3c7ec3.jpg", "Look 19 — Detail 1", "35", - "1", "19", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3396", @@ -3983,11 +5153,14 @@ "runway/e91ab587584f63a668c0be7711e61804e7cba5e4.jpg", "Look 20", "36", - "0", "20", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3397", @@ -3995,11 +5168,14 @@ "runway/1fe22f3e5932a31491e6f838ca2fe570c9123f3d.jpg", "Look 21", "37", - "0", "21", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3398", @@ -4007,11 +5183,14 @@ "runway/58f1088a6c95bb4ba07b33558b038ed2c27be95a.jpg", "Look 21 — Detail 1", "38", - "1", "21", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3399", @@ -4019,11 +5198,14 @@ "runway/fcd2c6381b1af057bff187aef305cb74ed3d7be6.jpg", "Look 21 — Detail 2", "39", - "1", "21", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3400", @@ -4031,11 +5213,14 @@ "runway/eb3b2bb796c71212fd800012598352bb762a1206.jpg", "Look 22", "40", - "0", "22", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3401", @@ -4043,11 +5228,14 @@ "runway/159df703a3595622819deef06f9bddafff49d912.jpg", "Look 23", "41", - "0", "23", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3402", @@ -4055,11 +5243,14 @@ "runway/f4c5d84fc92728960d4e0d102afe154d6a110032.jpg", "Look 23 — Detail 1", "42", - "1", "23", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3403", @@ -4067,11 +5258,14 @@ "runway/2f8530b4944e9193677ac0bd511f8407444346a6.jpg", "Look 24", "43", - "0", "24", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3404", @@ -4079,11 +5273,14 @@ "runway/c5477d8edf0d24731ab1ffa2d72748646b5537cb.jpg", "Look 24 — Detail 1", "44", - "1", "24", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3405", @@ -4091,11 +5288,14 @@ "runway/3cd370d894c5c991e51cbf24494016f38d942612.jpg", "Look 25", "45", - "0", "25", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3406", @@ -4103,11 +5303,14 @@ "runway/a50d2afa54f93b27b957f88a72abb5a72a818cf1.jpg", "Look 26", "46", - "0", "26", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3407", @@ -4115,11 +5318,14 @@ "runway/9abcd9c2b825d8c3464ad8378103928e993b7f0d.jpg", "Look 27", "47", - "0", "27", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3408", @@ -4127,11 +5333,14 @@ "runway/3b1f24ecdc642703ed770908e0da4a33735842df.jpg", "Look 27 — Detail 1", "48", - "1", "27", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3409", @@ -4139,11 +5348,14 @@ "runway/f47097d792f91946015bfa7dd584926196991af2.jpg", "Look 28", "49", - "0", "28", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3410", @@ -4151,11 +5363,14 @@ "runway/d1a4c5b768cf63ad96be530abb386b45ea10500c.jpg", "Look 28 — Detail 1", "50", - "1", "28", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3411", @@ -4163,11 +5378,14 @@ "runway/4d3754055f0acb563d6741c9f20f9555844c5ddb.jpg", "Look 29", "51", - "0", "29", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3412", @@ -4175,11 +5393,14 @@ "runway/146171ceea506c3a2658ff1adbd801dd1af55177.jpg", "Look 29 — Detail 1", "52", - "1", "29", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3413", @@ -4187,11 +5408,14 @@ "runway/b0745a059ee385a40edb73199f2376f1dead1809.jpg", "Look 30", "53", - "0", "30", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3414", @@ -4199,11 +5423,14 @@ "runway/327f4c9fa3b4220b8e98401db1a5a80f10fc842f.jpg", "Look 31", "54", - "0", "31", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3415", @@ -4211,11 +5438,14 @@ "runway/e6f4cb990010281ffc424cc79b6502de51f593d0.jpg", "Look 31 — Detail 1", "55", - "1", "31", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3416", @@ -4223,11 +5453,14 @@ "runway/25acc2f0ee410076d4993d82b3fc3c925e523da7.jpg", "Look 31 — Detail 2", "56", - "1", "31", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3417", @@ -4235,11 +5468,14 @@ "runway/3883d97cb6d0c1f05a1e4c44490843f21fe8be32.jpg", "Look 32", "57", - "0", "32", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3418", @@ -4247,11 +5483,14 @@ "runway/2a0f030d0db2d3b07589b56a68def82715a67472.jpg", "Look 32 — Detail 1", "58", - "1", "32", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3419", @@ -4259,11 +5498,14 @@ "runway/ee9372fdc7b99265d2dcb53eafe14190c8cbf657.jpg", "Look 33", "59", - "0", "33", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3420", @@ -4271,11 +5513,14 @@ "runway/513944928d113e57fbc0b9a1fb4544a15ee8637f.jpg", "Look 33 — Detail 1", "60", - "1", "33", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3421", @@ -4283,11 +5528,14 @@ "runway/284bba8777b2b5fa7f70fea17eb44c33d4cb9a4f.jpg", "Look 33 — Detail 2", "61", - "1", "33", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3422", @@ -4295,11 +5543,14 @@ "runway/fe1f2d73e54983f0d21906eca5cdbc745f4c34bd.jpg", "Look 34", "62", - "0", "34", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3423", @@ -4307,11 +5558,14 @@ "runway/42a90bad6ee9c9fdcd1e505d3d42a29c508372fb.jpg", "Look 35", "63", - "0", "35", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3424", @@ -4319,11 +5573,14 @@ "runway/fe020bd891caf8a225c554ea2c8b054767846948.jpg", "Look 35 — Detail 1", "64", - "1", "35", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3425", @@ -4331,11 +5588,14 @@ "runway/592fd9d61b3face8e906fd8e2728b31d0828572b.jpg", "Look 36", "65", - "0", "36", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3426", @@ -4343,11 +5603,14 @@ "runway/15cdd7d4802a4489be73b3d6f9d669ba00015ce9.jpg", "Look 36 — Detail 1", "66", - "1", "36", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3427", @@ -4355,11 +5618,14 @@ "runway/cc7722af494c069bb406a6cf97ec3c6081dc8c6d.jpg", "Look 37", "67", - "0", "37", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3428", @@ -4367,11 +5633,14 @@ "runway/9bc4aaeb31c58b9c29f29248ab34afd3c754805c.jpg", "Look 37 — Detail 1", "68", - "1", "37", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3429", @@ -4379,11 +5648,14 @@ "runway/ec2d604745f9a523ef727761ddf44a076e918d20.jpg", "Look 37 — Detail 2", "69", - "1", "37", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3430", @@ -4391,11 +5663,14 @@ "runway/bf46672f65a75b260996f2fa06ca0e73af3b01a5.jpg", "Look 38", "70", - "0", "38", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3431", @@ -4403,11 +5678,14 @@ "runway/3c7e5f0f082cbc6d1fd33457356a9fe8f254e9e0.jpg", "Look 38 — Detail 1", "71", - "1", "38", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3432", @@ -4415,11 +5693,14 @@ "runway/df590fbcd432a093e54d87c666866bd036f19b3d.jpg", "Look 39", "72", - "0", "39", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3433", @@ -4427,11 +5708,14 @@ "runway/dde772f42b8f41f4714ff82843a01944a0611d4d.jpg", "Look 40", "73", - "0", "40", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3434", @@ -4439,11 +5723,14 @@ "runway/7f0aa0d335e5a84a1455f7b88df2276f60709953.jpg", "Look 40 — Detail 1", "74", - "1", "40", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3435", @@ -4451,11 +5738,14 @@ "runway/ae2f898eb544415db4994cad1dd25f0655aba0f7.jpg", "Look 41", "75", - "0", "41", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3436", @@ -4463,11 +5753,14 @@ "runway/c55aee9947a2bb0af8987965d6c11a71ff5c5475.jpg", "Look 42", "76", - "0", "42", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3437", @@ -4475,11 +5768,14 @@ "runway/ad153cfac4de9000c0022bd178608de75e5822dd.jpg", "Look 42 — Detail 1", "77", - "1", "42", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3438", @@ -4487,11 +5783,14 @@ "runway/341b931c7c7784d23ffe7840a0e6488cfe6ebfd9.jpg", "Look 42 — Detail 2", "78", - "1", "42", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3439", @@ -4499,11 +5798,14 @@ "runway/6be4c19c11c669c1d6d0514a7fcab8aadd165245.jpg", "Look 43", "79", - "0", "43", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3440", @@ -4511,11 +5813,14 @@ "runway/fa5129d86a1d2285134de7aad1d29e89a13dee45.jpg", "Look 43 — Detail 1", "80", - "1", "43", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3441", @@ -4523,11 +5828,14 @@ "runway/b3972a96b07ce7afd3b964b1a98ee6ac10d1d4e3.jpg", "Look 44", "81", - "0", "44", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3442", @@ -4535,11 +5843,14 @@ "runway/cf95562e2cbd7187071776379fece9ebef5761fe.jpg", "Look 44 — Detail 1", "82", - "1", "44", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3443", @@ -4547,11 +5858,14 @@ "runway/24675e62d189ca301f448634cdfce833fcd795f3.jpg", "Look 45", "83", - "0", "45", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3444", @@ -4559,11 +5873,14 @@ "runway/7fec6843988239e87952a23bdeefc07aefdf5d35.jpg", "Look 45 — Detail 1", "84", - "1", "45", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3445", @@ -4571,11 +5888,14 @@ "runway/43c7238d13567723ff3a97569b3ea6e6e5f62b7c.jpg", "Look 46", "85", - "0", "46", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3446", @@ -4583,11 +5903,14 @@ "runway/57f74a321c5aaffdfe194f221cb720e3882395af.jpg", "Look 46 — Detail 1", "86", - "1", "46", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3447", @@ -4595,11 +5918,14 @@ "runway/d3bd8b8f6bea4abf8132f5074285b9a7b150d111.jpg", "Look 47", "87", - "0", "47", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3448", @@ -4607,11 +5933,14 @@ "runway/9afb081ced6483f8971a6182ee03ead577957b15.jpg", "Look 48", "88", - "0", "48", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3449", @@ -4619,11 +5948,14 @@ "runway/eb44afb919123050d07f95635013c978ef2df52e.jpg", "Look 49", "89", - "0", "49", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3450", @@ -4631,11 +5963,14 @@ "runway/583a5f320a323c4fecd957e46f62cc53a79d591b.jpg", "Look 49 — Detail 1", "90", - "1", "49", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3451", @@ -4643,11 +5978,14 @@ "runway/75fc9a4e40dbb3a0f197ede4fb4c91c198f1de55.jpg", "Look 50", "91", - "0", "50", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3452", @@ -4655,11 +5993,14 @@ "runway/5e4095f816e70e794814006e06b31f02871cc5be.jpg", "Look 51", "92", - "0", "51", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3453", @@ -4667,11 +6008,14 @@ "runway/a86bb81cc9a151f05b3ada0a7c424c0111a66314.jpg", "Look 52", "93", - "0", "52", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3454", @@ -4679,11 +6023,14 @@ "runway/366e5c84cb7626f7bcdae6e9a3fe38a1aa323953.jpg", "Look 53", "94", - "0", "53", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3455", @@ -4691,11 +6038,14 @@ "runway/8e167ccfbe368c5ef551d05ca3f138b0de82f5ed.jpg", "Look 54", "95", - "0", "54", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3456", @@ -4703,11 +6053,14 @@ "runway/8eca1cf7cd8fb642cd990274c830b3d90b387778.jpg", "Look 55", "96", - "0", "55", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3457", @@ -4715,11 +6068,14 @@ "runway/519dcb90b10091dd02a9f5457e49569af62594ea.jpg", "Look 56", "97", - "0", "56", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3458", @@ -4727,11 +6083,14 @@ "runway/21990e3bf3510fa2ed79d507e879fc748f0ce76b.jpg", "Look 56 — Detail 1", "98", - "1", "56", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3459", @@ -4739,11 +6098,14 @@ "runway/4acee083565b55d6e9ab0f43df76413062b4e411.jpg", "Look 57", "99", - "0", "57", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3460", @@ -4751,11 +6113,14 @@ "runway/b8b4fc26bf45e1a2722af2fc0f9c701cf2d851d9.jpg", "Look 57 — Detail 1", "100", - "1", "57", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3461", @@ -4763,11 +6128,14 @@ "runway/ed3b2d2ac19ce16d4451644befb797a992bfb9fc.jpg", "Look 58", "101", - "0", "58", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3462", @@ -4775,11 +6143,14 @@ "runway/eae4f5fd9e78f0371ef8208a9098772eae366dec.jpg", "Look 58 — Detail 1", "102", - "1", "58", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3463", @@ -4787,11 +6158,14 @@ "runway/0a5e9a0fe292f5b4eec87b20250c162491c4904b.jpg", "Look 59", "103", - "0", "59", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3464", @@ -4799,11 +6173,14 @@ "runway/2cae225fbd0bf0d319b6fe49125fa75bab70d785.jpg", "Look 60", "104", - "0", "60", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3465", @@ -4811,11 +6188,14 @@ "runway/e02d21091014f79f1593b563fc213db3a1bc57f3.jpg", "Look 60 — Detail 1", "105", - "1", "60", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3466", @@ -4823,11 +6203,14 @@ "runway/34f8414949bb50622e3c78b8a2191467cd039296.jpg", "Look 60 — Detail 2", "106", - "1", "60", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3467", @@ -4835,11 +6218,14 @@ "runway/8973a6d202c87202ae1d9e3d60db11961fc52d04.jpg", "Look 61", "107", - "0", "61", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3468", @@ -4847,11 +6233,14 @@ "runway/647c71ee1176fbe7db6b8788cf9e5c4042b5b60d.jpg", "Look 62", "108", - "0", "62", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3469", @@ -4859,11 +6248,14 @@ "runway/b4a654900f8dc52aee1d74039d9fa0743ad5da14.jpg", "Look 63", "109", - "0", "63", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3470", @@ -4871,11 +6263,14 @@ "runway/b304024dd856db22f3e35c52a6a3afbf43ed6056.jpg", "Look 64", "110", - "0", "64", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3471", @@ -4883,11 +6278,14 @@ "runway/d82cf450455a686d1d1538980b64cd6e7653a9b6.jpg", "Look 64 — Detail 1", "111", - "1", "64", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3472", @@ -4895,11 +6293,14 @@ "runway/4420a40d09ae2fb2f9a03240053577b8bb218979.jpg", "Look 65", "112", - "0", "65", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3473", @@ -4907,11 +6308,14 @@ "runway/1d6e47daf0f7500db2d7f5bbdc0d264f7463668f.jpg", "Look 65 — Detail 1", "113", - "1", "65", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3474", @@ -4919,11 +6323,14 @@ "runway/4a3e58e4e6f0ff0d2f1235bdb3914e4732689f1c.jpg", "Look 65 — Detail 2", "114", - "1", "65", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3475", @@ -4931,11 +6338,14 @@ "runway/db948479946a033148b99e8cce7c328da6abe9f7.jpg", "Look 66", "115", - "0", "66", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3476", @@ -4943,11 +6353,14 @@ "runway/1b409e0ad05bf1cf4e42cc0e8d1b51aaed33ada4.jpg", "Look 67", "116", - "0", "67", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3477", @@ -4955,11 +6368,14 @@ "runway/9b211ba750f7874d95cf3e0c662ac4811a18ee72.jpg", "Look 67 — Detail 1", "117", - "1", "67", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3478", @@ -4967,11 +6383,14 @@ "runway/0d37aed2d9db36d2ce2a5bf2a3db060039cfcfba.jpg", "Look 68", "118", - "0", "68", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3479", @@ -4979,11 +6398,14 @@ "runway/037e7215c857171fa0bdd665ee0c108a0b9ae4fb.jpg", "Look 69", "119", - "0", "69", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3480", @@ -4991,11 +6413,14 @@ "runway/d56b67a0e6a13e36230e0b5db5d05dc6ac69ab22.jpg", "Look 69 — Detail 1", "120", - "1", "69", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3481", @@ -5003,11 +6428,14 @@ "runway/4de85d674d993073fda3c2de5a6d826ec8f361a4.jpg", "Look 70", "121", - "0", "70", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3482", @@ -5015,11 +6443,14 @@ "runway/23327dff6fa08c33c23ddf2b4f8a016df4d952ea.jpg", "Look 71", "122", - "0", "71", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3483", @@ -5027,11 +6458,14 @@ "runway/4588635534747bf73d940593f70dc7cdc25a78d0.jpg", "Look 71 — Detail 1", "123", - "1", "71", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3484", @@ -5039,11 +6473,14 @@ "runway/2fa23b4d2a724ccef39aced62826b037b6d536d7.jpg", "Look 71 — Detail 2", "124", - "1", "71", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3485", @@ -5051,11 +6488,14 @@ "runway/edc9322c5563bdf41ebf016ead0b7da4f5470a32.jpg", "Look 72", "125", - "0", "72", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3486", @@ -5063,11 +6503,14 @@ "runway/91ec7bcd74710fd8937d4ccb0e5f22caa42d1b3c.jpg", "Look 73", "126", - "0", "73", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3487", @@ -5075,11 +6518,14 @@ "runway/affb3a4094a7375ac54e232929950045523c0ac8.jpg", "Look 74", "127", - "0", "74", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3488", @@ -5087,11 +6533,14 @@ "runway/dae22c7d8a7e5299b4e9dd2989457ad3088a5519.jpg", "Look 75", "128", - "0", "75", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3489", @@ -5099,11 +6548,14 @@ "runway/92dbf7d866bdc102df3b05c63662e6f39246fa75.jpg", "Look 75 — Detail 1", "129", - "1", "75", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3490", @@ -5111,11 +6563,14 @@ "runway/269e8e88f696f6544719c4892e2253c6833ae408.jpg", "Look 76", "130", - "0", "76", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3491", @@ -5123,11 +6578,14 @@ "runway/907234f8c62097248fc2803a829a4e3609209fde.jpg", "Look 77", "131", - "0", "77", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3492", @@ -5135,11 +6593,14 @@ "runway/d66ac419c322e73cea9ed128764d284ec9b003c5.jpg", "Look 77 — Detail 1", "132", - "1", "77", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3493", @@ -5147,11 +6608,14 @@ "runway/187e6cdf1b9d89586721dbcf1d2689aed62765ef.jpg", "Look 78", "133", - "0", "78", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3494", @@ -5159,11 +6623,14 @@ "runway/1bba9717e6050f8b692a5586abc5ef84aff06b7e.jpg", "Look 79", "134", - "0", "79", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3495", @@ -5171,11 +6638,14 @@ "runway/fdd641605d1a5ec3f2455bc3c20ac759f6d97aa3.jpg", "Look 79 — Detail 1", "135", - "1", "79", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3496", @@ -5183,11 +6653,14 @@ "runway/2a8e005c98c85dc34b292c7c804ecd8ba5e5def8.jpg", "Look 80", "136", - "0", "80", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3497", @@ -5195,11 +6668,14 @@ "runway/517f86b868edb0c4baf7823a083b00f2c2f484b1.jpg", "Look 81", "137", - "0", "81", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3498", @@ -5207,11 +6683,14 @@ "runway/22ea382fd35c44ea1047a60843b2e7654bad6b50.jpg", "Look 81 — Detail 1", "138", - "1", "81", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3499", @@ -5219,11 +6698,14 @@ "runway/0052e8407022d800dfa4d823048b152b641f17f2.jpg", "Look 82", "139", - "0", "82", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3500", @@ -5231,11 +6713,14 @@ "runway/3b9cd4b69988cf2bdcd72edf5b5a32237279ad50.jpg", "Look 83", "140", - "0", "83", "0", + "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3501", @@ -5243,11 +6728,14 @@ "runway/21e5767b89a249ddb7847d4074cb5d522c0ea13e.jpg", "Look 83 — Detail 1", "141", - "1", "83", + "1", "0", "1789137357", - "1789137357" + "1789137357", + null, + null, + null ], [ "3502", @@ -5255,11 +6743,14 @@ "runway/a92e0d1d9dcac9c11c0c4159776895eece8baf95.jpg", "Look 1", "1", - "0", "1", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3503", @@ -5267,11 +6758,14 @@ "runway/d15f5106274a3dd195e0f8a05be6de0eb2ddb0b6.jpg", "Look 2", "2", - "0", "2", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3504", @@ -5279,11 +6773,14 @@ "runway/e67ee23bd6f427953143dbf7d3ec3280f22a0b7e.jpg", "Look 3", "3", - "0", "3", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3505", @@ -5291,11 +6788,14 @@ "runway/2252041dfb2aeff50d84c215d0bf92a620939bad.jpg", "Look 4", "4", - "0", "4", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3506", @@ -5303,11 +6803,14 @@ "runway/8b0b1ad42a092b8ba107052759f72dd5eef7992e.jpg", "Look 5", "5", - "0", "5", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3507", @@ -5315,11 +6818,14 @@ "runway/391a957ccf6f82d1681c7d7f5dd94269e5ed0e9d.jpg", "Look 6", "6", - "0", "6", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3508", @@ -5327,11 +6833,14 @@ "runway/a47f8ec4bc50496e91d331470438e5407e31918d.jpg", "Look 7", "7", - "0", "7", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3509", @@ -5339,11 +6848,14 @@ "runway/7d7061624c87ce00e38d25b9983d78b547a25ff5.jpg", "Look 8", "8", - "0", "8", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3510", @@ -5351,11 +6863,14 @@ "runway/d0b154606bf9111d3a84351522f78be0b335c408.jpg", "Look 9", "9", - "0", "9", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3511", @@ -5363,11 +6878,14 @@ "runway/be96d6a41c4b1b9323c366e16de249666a8a2acf.jpg", "Look 10", "10", - "0", "10", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3512", @@ -5375,11 +6893,14 @@ "runway/98aba15213b7f9297c5d2a3f39b4e6e4e7548886.jpg", "Look 11", "11", - "0", "11", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3513", @@ -5387,11 +6908,14 @@ "runway/a0ac5aac71d09ae1b88fb376a27950de6e33179b.jpg", "Look 12", "12", - "0", "12", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3514", @@ -5399,11 +6923,14 @@ "runway/621196b1040005a40b6a5781b6f6cb4c049fe714.jpg", "Look 13", "13", - "0", "13", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3515", @@ -5411,11 +6938,14 @@ "runway/c5da1b74fc4592eec3226ce335191538144f9808.jpg", "Look 14", "14", - "0", "14", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3516", @@ -5423,11 +6953,14 @@ "runway/d87f71e3d0f5c0cb4681a925395a444f0e8cac2d.jpg", "Look 15", "15", - "0", "15", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3517", @@ -5435,11 +6968,14 @@ "runway/2506b4883aa9a4e4061a38b5baef4ac862313a5e.jpg", "Look 16", "16", - "0", "16", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3518", @@ -5447,11 +6983,14 @@ "runway/773d16823b1ef6bcc7c47b13ef0e4719a45019ec.jpg", "Look 17", "17", - "0", "17", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3519", @@ -5459,11 +6998,14 @@ "runway/cbe882bf8bf3489def85b538d01bdda8a311f3d9.jpg", "Look 18", "18", - "0", "18", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3520", @@ -5471,11 +7013,14 @@ "runway/3b84351a00f34c071e39e3e5f24e6aad58c4eedd.jpg", "Look 19", "19", - "0", "19", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3521", @@ -5483,11 +7028,14 @@ "runway/d6715a30518f668837b514d02afcb46fcf3bde7f.jpg", "Look 20", "20", - "0", "20", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3522", @@ -5495,11 +7043,14 @@ "runway/d99e5112f446e460b3b2a7777b465368b1fe3ad3.jpg", "Look 21", "21", - "0", "21", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3523", @@ -5507,11 +7058,14 @@ "runway/4b63e5c0e050748a5304abce3bc187a06a32aa89.jpg", "Look 22", "22", - "0", "22", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3524", @@ -5519,11 +7073,14 @@ "runway/e45824d25bb40f5a9dce5edce7831bd3b21a72be.jpg", "Look 23", "23", - "0", "23", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3525", @@ -5531,11 +7088,14 @@ "runway/76e21e92af364f904a91d84da9438dfc5cc54e93.jpg", "Look 24", "24", - "0", "24", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3526", @@ -5543,11 +7103,14 @@ "runway/0cd5edf3b1c087af25ebcb5cb33199b45b2a1e29.jpg", "Look 25", "25", - "0", "25", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3527", @@ -5555,11 +7118,14 @@ "runway/a43fa8640cb9ee46db3e384f267172ed58b1485e.jpg", "Look 26", "26", - "0", "26", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3528", @@ -5567,11 +7133,14 @@ "runway/7fdb09eb1615a7f4a2d6f36be66dca04bf259fa0.jpg", "Look 27", "27", - "0", "27", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3529", @@ -5579,11 +7148,14 @@ "runway/ece3f0e9a49368125e9e8e1cb9f0208fd7abb718.jpg", "Look 28", "28", - "0", "28", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3530", @@ -5591,11 +7163,14 @@ "runway/c23d6e4835b18391f757661cb8389f797a013ca1.jpg", "Look 29", "29", - "0", "29", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3531", @@ -5603,11 +7178,14 @@ "runway/37f580aa9facc1e003f9096ef8030ab8575a1738.jpg", "Look 30", "30", - "0", "30", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3532", @@ -5615,11 +7193,14 @@ "runway/72f4fb8193982b21f960554942fd3319602a132f.jpg", "Look 31", "31", - "0", "31", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3533", @@ -5627,11 +7208,14 @@ "runway/f82afea230ad67d9e92a085351522d0f5bbb6954.jpg", "Look 32", "32", - "0", "32", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3534", @@ -5639,11 +7223,14 @@ "runway/41ac054677127943262670e8f5a469f6fead5198.jpg", "Look 33", "33", - "0", "33", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3535", @@ -5651,11 +7238,14 @@ "runway/fafa7a638c6890ba67479418818e31c2b6fcfd58.jpg", "Look 34", "34", - "0", "34", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3536", @@ -5663,11 +7253,14 @@ "runway/4e5a33c1f0583fa5fc77938c5b374fb346d4805c.jpg", "Look 35", "35", - "0", "35", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3537", @@ -5675,11 +7268,14 @@ "runway/f9288d72faf55ddedd6b79a8a7a0982bc47630e2.jpg", "Look 36", "36", - "0", "36", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3538", @@ -5687,11 +7283,14 @@ "runway/4ebfdc1635199c5c658e63095915ff4c29f9c9a0.jpg", "Look 37", "37", - "0", "37", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3539", @@ -5699,11 +7298,14 @@ "runway/abae51ebdf6ffb2d670e43af8ff1d95a344edda2.jpg", "Look 38", "38", - "0", "38", "0", + "0", "1789137373", - "1789137373" + "1789137373", + null, + null, + null ], [ "3540", @@ -5711,11 +7313,14 @@ "runway/2841c0fd79ae00e9e8b2c8fb2006ebecc088ab8a.jpg", "Look 1", "1", - "0", "1", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3541", @@ -5727,7 +7332,10 @@ "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3542", @@ -5735,11 +7343,14 @@ "runway/0ebcfe7ad4b2b0b669be1f91b155501219184f9e.jpg", "Look 2", "3", - "0", "2", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3543", @@ -5747,11 +7358,14 @@ "runway/9b3b154e32b0403fd81a8bc2ed40fe479a969aee.jpg", "Look 2 — Detail 1", "4", - "1", "2", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3544", @@ -5759,11 +7373,14 @@ "runway/9788772a24e8e595e3761d241364b90f096e370d.jpg", "Look 3", "5", - "0", "3", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3545", @@ -5771,11 +7388,14 @@ "runway/68c94eef5637a8b7a72419a20320ab91336de7ff.jpg", "Look 3 — Detail 1", "6", - "1", "3", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3546", @@ -5783,11 +7403,14 @@ "runway/4ae7f543613d54c2aedcda66f5a1780cef30e3ce.jpg", "Look 4", "7", - "0", "4", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3547", @@ -5795,11 +7418,14 @@ "runway/28c69aaa09d7154ec1685cab6221fa9cda52540f.jpg", "Look 4 — Detail 1", "8", - "1", "4", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3548", @@ -5807,11 +7433,14 @@ "runway/bb8bfab16f231eed9fadb2de6945e6215b09eeee.jpg", "Look 5", "9", - "0", "5", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3549", @@ -5819,11 +7448,14 @@ "runway/2c45940fd0995a39adb9fc72137f58fc3bf7b98c.jpg", "Look 5 — Detail 1", "10", - "1", "5", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3550", @@ -5831,11 +7463,14 @@ "runway/90d1aa40241d2c57b59d66f82232f9d51ac1a380.jpg", "Look 6", "11", - "0", "6", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3551", @@ -5843,11 +7478,14 @@ "runway/b4ce256181dd80539008dbe4a16d137637647bbb.jpg", "Look 6 — Detail 1", "12", - "1", "6", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3552", @@ -5855,11 +7493,14 @@ "runway/1372648951a2bed73f10835ba851367496e05284.jpg", "Look 7", "13", - "0", "7", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3553", @@ -5867,11 +7508,14 @@ "runway/b05e694902ee214bb8d87b53b00f5e866bc0b59d.jpg", "Look 7 — Detail 1", "14", - "1", "7", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3554", @@ -5879,11 +7523,14 @@ "runway/e0118a4fa2d523f8463a338bf79e3f6e29b9f196.jpg", "Look 8", "15", - "0", "8", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3555", @@ -5891,11 +7538,14 @@ "runway/b66c9251b7fb9d5fc407308c9e6184a719d6398f.jpg", "Look 8 — Detail 1", "16", - "1", "8", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3556", @@ -5903,11 +7553,14 @@ "runway/817feefc4568abdebd53dbaf69a9c54d90dc1c69.jpg", "Look 9", "17", - "0", "9", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3557", @@ -5915,11 +7568,14 @@ "runway/b9632d77b8426ac82342111f007f5db8263ca1a2.jpg", "Look 9 — Detail 1", "18", - "1", "9", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3558", @@ -5927,11 +7583,14 @@ "runway/2bfcd2f264190b3cf2733076dd753e61a4fdc587.jpg", "Look 10", "19", - "0", "10", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3559", @@ -5939,11 +7598,14 @@ "runway/342c98c85e219fcfdc2831b56c0ddc1fa6dfd89a.jpg", "Look 10 — Detail 1", "20", - "1", "10", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3560", @@ -5951,11 +7613,14 @@ "runway/23b38db7a43e5db5ad8575016ed41c65bda166ab.jpg", "Look 11", "21", - "0", "11", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3561", @@ -5963,11 +7628,14 @@ "runway/cce8ee7df2a568d85c67a533b226d9fa57f75485.jpg", "Look 11 — Detail 1", "22", - "1", "11", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3562", @@ -5975,11 +7643,14 @@ "runway/0f68419400ecef3656b8f7716c537742e61f79a1.jpg", "Look 12", "23", - "0", "12", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3563", @@ -5987,11 +7658,14 @@ "runway/23d4864700c43599f0b21cb534b84942d3ca5e20.jpg", "Look 12 — Detail 1", "24", - "1", "12", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3564", @@ -5999,11 +7673,14 @@ "runway/57efa5c57e6a694ba60e72527cac46486ec756aa.jpg", "Look 13", "25", - "0", "13", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3565", @@ -6011,11 +7688,14 @@ "runway/17380ce7c119d9771ffbd5812d6fe20c94d42730.jpg", "Look 13 — Detail 1", "26", - "1", "13", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3566", @@ -6023,11 +7703,14 @@ "runway/56afb88d21f859001469357fa182514659a772f8.jpg", "Look 14", "27", - "0", "14", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3567", @@ -6035,11 +7718,14 @@ "runway/8b1721ff9e55c9bb232fca10ae90127d12fa9671.jpg", "Look 14 — Detail 1", "28", - "1", "14", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3568", @@ -6047,11 +7733,14 @@ "runway/9768a28541e5d10ff1aa6bd21e2635f4898a3528.jpg", "Look 15", "29", - "0", "15", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3569", @@ -6059,11 +7748,14 @@ "runway/ab846e360d2b1e82e0da9225e3381576325e8d58.jpg", "Look 15 — Detail 1", "30", - "1", "15", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3570", @@ -6071,11 +7763,14 @@ "runway/a649fb8800bc68903bbd29aae918c06311244c74.jpg", "Look 16", "31", - "0", "16", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3571", @@ -6083,11 +7778,14 @@ "runway/7630a74dbf3daca275aae2554aa277264f08f59c.jpg", "Look 16 — Detail 1", "32", - "1", "16", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3572", @@ -6095,11 +7793,14 @@ "runway/2a3663e59a37b14d793a2b5d397dcc09635091ca.jpg", "Look 17", "33", - "0", "17", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3573", @@ -6107,11 +7808,14 @@ "runway/3af9f2c0f95f24307696cd36970d8a48e1cabf3f.jpg", "Look 17 — Detail 1", "34", - "1", "17", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3574", @@ -6119,11 +7823,14 @@ "runway/78b4627b78cafc2296c80d135b77bfc8eb4c9a8c.jpg", "Look 18", "35", - "0", "18", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3575", @@ -6131,11 +7838,14 @@ "runway/9a1e694e9e82c9e09b627a0e5e0e702e91a6bc2c.jpg", "Look 18 — Detail 1", "36", - "1", "18", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3576", @@ -6143,11 +7853,14 @@ "runway/c7b5ddd8332a433838eb904b067006dbc7b5d79f.jpg", "Look 19", "37", - "0", "19", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3577", @@ -6155,11 +7868,14 @@ "runway/0e12ad58df49cc6332ab10ca99242d434435af3c.jpg", "Look 19 — Detail 1", "38", - "1", "19", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3578", @@ -6167,11 +7883,14 @@ "runway/88817ec49c9a73ddb27724bcc7d992d2d29bcfb4.jpg", "Look 20", "39", - "0", "20", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3579", @@ -6179,11 +7898,14 @@ "runway/53bb91d8ef89268a739d57dbf3f81611c3d65b8f.jpg", "Look 20 — Detail 1", "40", - "1", "20", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3580", @@ -6191,11 +7913,14 @@ "runway/1bb7edb19c7fc06130dc02cb0cc5cad0ca0be3a9.jpg", "Look 21", "41", - "0", "21", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3581", @@ -6203,11 +7928,14 @@ "runway/c617998f33ffa13019eaa07cbdcfd2a766714535.jpg", "Look 21 — Detail 1", "42", - "1", "21", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3582", @@ -6215,11 +7943,14 @@ "runway/e542ec0a08aaafef3944176cbcac5dfb26264e3b.jpg", "Look 22", "43", - "0", "22", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3583", @@ -6227,11 +7958,14 @@ "runway/4438dfa482da539ddf49b3576a17d26ce1f99e0c.jpg", "Look 22 — Detail 1", "44", - "1", "22", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3584", @@ -6239,11 +7973,14 @@ "runway/93b4e27f8630fba077992f87b165ea249aac9195.jpg", "Look 23", "45", - "0", "23", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3585", @@ -6251,11 +7988,14 @@ "runway/c281f3be3fe3159345e370e9fc7f2f4f1c9ddafa.jpg", "Look 23 — Detail 1", "46", - "1", "23", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3586", @@ -6263,11 +8003,14 @@ "runway/2cea874b857c3faf344fb94d229ea5d04ba4a322.jpg", "Look 24", "47", - "0", "24", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3587", @@ -6275,11 +8018,14 @@ "runway/5a2f0406632339db74d38ef08bdbca684c4edf27.jpg", "Look 24 — Detail 1", "48", - "1", "24", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3588", @@ -6287,11 +8033,14 @@ "runway/cd6900a9e2b3f974c5d29dc580e8270d0fb879c6.jpg", "Look 25", "49", - "0", "25", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3589", @@ -6299,11 +8048,14 @@ "runway/6cf6263cb1e67fcc984f43bc6c703d47fd88ff5e.jpg", "Look 25 — Detail 1", "50", - "1", "25", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3590", @@ -6311,11 +8063,14 @@ "runway/6ac315e8194ed674174eca981a9bf07a00647464.jpg", "Look 26", "51", - "0", "26", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3591", @@ -6323,11 +8078,14 @@ "runway/da5584dcc511535f12f578b3d6a83d756e995d3b.jpg", "Look 26 — Detail 1", "52", - "1", "26", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3592", @@ -6335,11 +8093,14 @@ "runway/635833dc3d857a85e1b958e316bec80e676fde2c.jpg", "Look 27", "53", - "0", "27", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3593", @@ -6347,11 +8108,14 @@ "runway/d1a7a7b0130b78945b6f854f93ea970859d1de78.jpg", "Look 27 — Detail 1", "54", - "1", "27", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3594", @@ -6359,11 +8123,14 @@ "runway/2afd51fe7b7d05ed24a0d035b4e71d45c8fe8292.jpg", "Look 28", "55", - "0", "28", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3595", @@ -6371,11 +8138,14 @@ "runway/b0acffabfc7d5b885e1572175d8e0a6cb9aa70f1.jpg", "Look 28 — Detail 1", "56", - "1", "28", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3596", @@ -6383,11 +8153,14 @@ "runway/6e2ef9a2fb85c7de6d918aeb9e6617a08f39b3ea.jpg", "Look 29", "57", - "0", "29", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3597", @@ -6395,11 +8168,14 @@ "runway/1ed296eca7c31d91462b56cf72b85b2416ee4a94.jpg", "Look 29 — Detail 1", "58", - "1", "29", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3598", @@ -6407,11 +8183,14 @@ "runway/0f0f9cf998cc3cd6393e967723d336294bf6af7b.jpg", "Look 30", "59", - "0", "30", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3599", @@ -6419,11 +8198,14 @@ "runway/4fb6719a81733e2aaf2f35cc84cb41c83e6ce0fa.jpg", "Look 30 — Detail 1", "60", - "1", "30", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3600", @@ -6431,11 +8213,14 @@ "runway/5ac14a224263319ca0c0aab0453bdd6308049aa5.jpg", "Look 31", "61", - "0", "31", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3601", @@ -6443,11 +8228,14 @@ "runway/31424ef86dd96b6bb4a950f3bd359d0aec5c1231.jpg", "Look 31 — Detail 1", "62", - "1", "31", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3602", @@ -6455,11 +8243,14 @@ "runway/096429d6c3f3474fac50db493779a16ab2e1b50f.jpg", "Look 32", "63", - "0", "32", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3603", @@ -6467,11 +8258,14 @@ "runway/dc1c9c92557ed20e9a1cc157bbd98a8b27009655.jpg", "Look 32 — Detail 1", "64", - "1", "32", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3604", @@ -6479,11 +8273,14 @@ "runway/dd3f2ea7311eb18753991e9dafc04f83b914257a.jpg", "Look 33", "65", - "0", "33", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3605", @@ -6491,11 +8288,14 @@ "runway/bf3692b34e129f329f5b8bd8af29e2dbb7b57a68.jpg", "Look 33 — Detail 1", "66", - "1", "33", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3606", @@ -6503,11 +8303,14 @@ "runway/6ba5b767b749424c9c438a8285f15a4a2df08c16.jpg", "Look 34", "67", - "0", "34", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3607", @@ -6515,11 +8318,14 @@ "runway/7e32c2e037596c35f76ec5481b67274a6ddfcb68.jpg", "Look 34 — Detail 1", "68", - "1", "34", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3608", @@ -6527,11 +8333,14 @@ "runway/209bc40a8f35b411e0ac6fa86f8772640d126d68.jpg", "Look 35", "69", - "0", "35", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3609", @@ -6539,11 +8348,14 @@ "runway/ab3ab0690bc30b638ac9b02cae20b24b6fff09d3.jpg", "Look 35 — Detail 1", "70", - "1", "35", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3610", @@ -6551,11 +8363,14 @@ "runway/cec4eecc30d166ea71215881a2f0f44f95832bc1.jpg", "Look 36", "71", - "0", "36", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3611", @@ -6563,11 +8378,14 @@ "runway/4ef85641bc85d3c0b67b357be157d588827500f0.jpg", "Look 36 — Detail 1", "72", - "1", "36", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3612", @@ -6575,11 +8393,14 @@ "runway/9a0cc0c89ab0df9fdbca04237a4b67c72dc5cf31.jpg", "Look 37", "73", - "0", "37", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3613", @@ -6587,11 +8408,14 @@ "runway/b058954af3937cdd20f28e8dfcec485d4f0dad25.jpg", "Look 37 — Detail 1", "74", - "1", "37", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3614", @@ -6599,11 +8423,14 @@ "runway/4272858d72b5542e599f1932585802d4417eb181.jpg", "Look 38", "75", - "0", "38", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3615", @@ -6611,11 +8438,14 @@ "runway/919e357af4a1e9480ad17d46f37d5977ee49edd3.jpg", "Look 38 — Detail 1", "76", - "1", "38", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3616", @@ -6623,11 +8453,14 @@ "runway/d624d46222d190e0127082c1ea4aa59f1ccb5ff5.jpg", "Look 39", "77", - "0", "39", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3617", @@ -6635,11 +8468,14 @@ "runway/ebcfe9dba5ce73701583f1c4883bb8dd385ab862.jpg", "Look 39 — Detail 1", "78", - "1", "39", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3618", @@ -6647,11 +8483,14 @@ "runway/c0e918555eb9211f8a9dcf870cb9e1b542027673.jpg", "Look 40", "79", - "0", "40", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3619", @@ -6659,11 +8498,14 @@ "runway/3b80500c2b14511bfad7db7c25e241d1b03b8d07.jpg", "Look 40 — Detail 1", "80", - "1", "40", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3620", @@ -6671,11 +8513,14 @@ "runway/eaf29599a9f5c8db7ef9177111c0ac2f9402e3c7.jpg", "Look 41", "81", - "0", "41", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3621", @@ -6683,11 +8528,14 @@ "runway/87f2b1ff878beb9053a14e171e04a4bf71fb40c0.jpg", "Look 41 — Detail 1", "82", - "1", "41", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3622", @@ -6695,11 +8543,14 @@ "runway/83b5f49f8df720c9dc36789527d9f7fd70fc2116.jpg", "Look 42", "83", - "0", "42", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3623", @@ -6707,11 +8558,14 @@ "runway/96505658ec03c3be22f778c23c0db4c0d4c890aa.jpg", "Look 42 — Detail 1", "84", - "1", "42", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3624", @@ -6719,11 +8573,14 @@ "runway/76d536e2a7e9b765a0c492f86d142dfe4f9beeba.jpg", "Look 43", "85", - "0", "43", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3625", @@ -6731,11 +8588,14 @@ "runway/7dd060d8bb307f3bbd8fcda5790a80d76fd68cda.jpg", "Look 43 — Detail 1", "86", - "1", "43", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3626", @@ -6743,11 +8603,14 @@ "runway/5f310a6bec71af8e8c3fd1312553af6b9a5e356b.jpg", "Look 44", "87", - "0", "44", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3627", @@ -6755,11 +8618,14 @@ "runway/0f6d6a90cafc614d3b7a1846e67d89bc1339f9d8.jpg", "Look 44 — Detail 1", "88", - "1", "44", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3628", @@ -6767,11 +8633,14 @@ "runway/268545ebc6ae325073a176b7d71cfbdd9c3a4707.jpg", "Look 45", "89", - "0", "45", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3629", @@ -6779,11 +8648,14 @@ "runway/9987ed9be94fe3593566f8f6097be5cc66911276.jpg", "Look 45 — Detail 1", "90", - "1", "45", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3630", @@ -6791,11 +8663,14 @@ "runway/23b6b52685b5315351eb252477eca626474fd959.jpg", "Look 46", "91", - "0", "46", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3631", @@ -6803,11 +8678,14 @@ "runway/c5e1b7897acf00bfa06b9df592aa52f9f48fc885.jpg", "Look 46 — Detail 1", "92", - "1", "46", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3632", @@ -6815,11 +8693,14 @@ "runway/2acd9f6dddeae3c789f5500c96e6c2e682ce7bf6.jpg", "Look 47", "93", - "0", "47", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3633", @@ -6827,11 +8708,14 @@ "runway/344ffd9161f179346cc8d0f165d6518743af990c.jpg", "Look 47 — Detail 1", "94", - "1", "47", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3634", @@ -6839,11 +8723,14 @@ "runway/15cefd3035fa2a326dc25ed1a7bf0158b08bc1f8.jpg", "Look 48", "95", - "0", "48", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3635", @@ -6851,11 +8738,14 @@ "runway/c2579f4ddb40afcf6c503ec6e5469464da102396.jpg", "Look 48 — Detail 1", "96", - "1", "48", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3636", @@ -6863,11 +8753,14 @@ "runway/c4ba8c343baa650c4637bab3b28a9f947af73ad4.jpg", "Look 49", "97", - "0", "49", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3637", @@ -6875,11 +8768,14 @@ "runway/18ba9b696cb67eed7388cfd6b95f2aeea783d721.jpg", "Look 49 — Detail 1", "98", - "1", "49", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3638", @@ -6887,11 +8783,14 @@ "runway/f0ceab1a6bc9ec57284d32eb60532cd58d4f53a5.jpg", "Look 50", "99", - "0", "50", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3639", @@ -6899,11 +8798,14 @@ "runway/02bd5f45837e6a9ea1b62747d9d7923d0ac85391.jpg", "Look 50 — Detail 1", "100", - "1", "50", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3640", @@ -6911,11 +8813,14 @@ "runway/318f65e750af097c2af843f67df3c45b23f68dc4.jpg", "Look 51", "101", - "0", "51", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3641", @@ -6923,11 +8828,14 @@ "runway/99f30065422650536387434a72246e020fd81c78.jpg", "Look 51 — Detail 1", "102", - "1", "51", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3642", @@ -6935,11 +8843,14 @@ "runway/d66cfbd0040dc52bd95b36dec0a912d5c6df4f02.jpg", "Look 52", "103", - "0", "52", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3643", @@ -6947,11 +8858,14 @@ "runway/aa39e69cef2902bb534de395b55c03797c2ead40.jpg", "Look 52 — Detail 1", "104", - "1", "52", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3644", @@ -6959,11 +8873,14 @@ "runway/678bd8ffd50c2fc756fc1fa52fe0f6e204ad1112.jpg", "Look 53", "105", - "0", "53", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3645", @@ -6971,11 +8888,14 @@ "runway/2f9fae6b071b7f69b3492c8ec4c6356d317a795d.jpg", "Look 53 — Detail 1", "106", - "1", "53", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3646", @@ -6983,11 +8903,14 @@ "runway/c1b130fedda42ecbafb577a8621da0ea55a168f8.jpg", "Look 54", "107", - "0", "54", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3647", @@ -6995,11 +8918,14 @@ "runway/51a2b2a5ad61201bc8a8fb1dc376f0fbd5d87687.jpg", "Look 54 — Detail 1", "108", - "1", "54", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3648", @@ -7007,11 +8933,14 @@ "runway/0452e939265376f12dd213d1c311b49523f9024e.jpg", "Look 55", "109", - "0", "55", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3649", @@ -7019,11 +8948,14 @@ "runway/2301d24be3f75459dfe9f88853e34338c9d8f84e.jpg", "Look 55 — Detail 1", "110", - "1", "55", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3650", @@ -7031,11 +8963,14 @@ "runway/e9ac0589fb0ae534a66c3b5d6a72d47da8b1ad0e.jpg", "Look 56", "111", - "0", "56", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3651", @@ -7043,11 +8978,14 @@ "runway/8d188ea9b32d00a3b0b496ec2b082e4c30faa5cf.jpg", "Look 56 — Detail 1", "112", - "1", "56", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3652", @@ -7055,11 +8993,14 @@ "runway/d19383d7af885b18f016e1b092a6dd3eb0a6dd3a.jpg", "Look 57", "113", - "0", "57", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3653", @@ -7067,11 +9008,14 @@ "runway/f9aee3169a1f44450c452990ec587b5d8c64fc9a.jpg", "Look 57 — Detail 1", "114", - "1", "57", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3654", @@ -7079,11 +9023,14 @@ "runway/72e3e88aca9b6c5496158499c344dd4056b7c30c.jpg", "Look 58", "115", - "0", "58", "0", + "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ], [ "3655", @@ -7091,29 +9038,108 @@ "runway/93bfca169da9cd70fd2ad01393f37f43c90b38cd.jpg", "Look 58 — Detail 1", "116", - "1", "58", + "1", "0", "1789137445", - "1789137445" + "1789137445", + null, + null, + null ] ] }, { "name": "brand_runway_images", - "create": "CREATE TABLE `brand_runway_images` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `created_at` int unsigned DEFAULT '0',\n `updated_at` int unsigned DEFAULT '0',\n `is_deleted` tinyint unsigned DEFAULT '0',\n `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',\n `runway_id` int unsigned NOT NULL DEFAULT '0',\n `brand_id` int unsigned NOT NULL DEFAULT '0',\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',\n `sort_order` int unsigned NOT NULL DEFAULT '0',\n `is_detail` tinyint unsigned NOT NULL DEFAULT '0',\n `look_index` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`) USING BTREE,\n KEY `idx_runway_id` (`runway_id`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1661 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "created_at", - "updated_at", - "is_deleted", - "image", - "runway_id", - "brand_id", - "name", - "sort_order", - "is_detail", - "look_index" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('brand_runway_images_id_seq'::regclass)" + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "runway_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "brand_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "name", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "sort_order", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "look_index", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_detail", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "phash", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_duplicate", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "dup_of", + "type": "text", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -7126,8 +9152,11 @@ "7", "Look 1", "1", + "1", "0", - "1" + null, + null, + null ], [ "990", @@ -7140,7 +9169,10 @@ "Look 1 — Detail 1", "2", "1", - "1" + "1", + null, + null, + null ], [ "991", @@ -7152,8 +9184,11 @@ "7", "Look 2", "3", + "2", "0", - "2" + null, + null, + null ], [ "992", @@ -7165,8 +9200,11 @@ "7", "Look 2 — Detail 1", "4", + "2", "1", - "2" + null, + null, + null ], [ "993", @@ -7178,8 +9216,11 @@ "7", "Look 2 — Detail 2", "5", + "2", "1", - "2" + null, + null, + null ], [ "994", @@ -7191,8 +9232,11 @@ "7", "Look 3", "6", + "3", "0", - "3" + null, + null, + null ], [ "995", @@ -7204,8 +9248,11 @@ "7", "Look 3 — Detail 1", "7", + "3", "1", - "3" + null, + null, + null ], [ "996", @@ -7217,8 +9264,11 @@ "7", "Look 4", "8", + "4", "0", - "4" + null, + null, + null ], [ "997", @@ -7230,8 +9280,11 @@ "7", "Look 4 — Detail 1", "9", + "4", "1", - "4" + null, + null, + null ], [ "998", @@ -7243,8 +9296,11 @@ "7", "Look 4 — Detail 2", "10", + "4", "1", - "4" + null, + null, + null ], [ "999", @@ -7256,8 +9312,11 @@ "7", "Look 5", "11", + "5", "0", - "5" + null, + null, + null ], [ "1000", @@ -7269,8 +9328,11 @@ "7", "Look 6", "12", + "6", "0", - "6" + null, + null, + null ], [ "1001", @@ -7282,8 +9344,11 @@ "7", "Look 6 — Detail 1", "13", + "6", "1", - "6" + null, + null, + null ], [ "1002", @@ -7295,8 +9360,11 @@ "7", "Look 7", "14", + "7", "0", - "7" + null, + null, + null ], [ "1003", @@ -7308,8 +9376,11 @@ "7", "Look 7 — Detail 1", "15", + "7", "1", - "7" + null, + null, + null ], [ "1004", @@ -7321,8 +9392,11 @@ "7", "Look 8", "16", + "8", "0", - "8" + null, + null, + null ], [ "1005", @@ -7334,8 +9408,11 @@ "7", "Look 8 — Detail 1", "17", + "8", "1", - "8" + null, + null, + null ], [ "1006", @@ -7347,8 +9424,11 @@ "7", "Look 9", "18", + "9", "0", - "9" + null, + null, + null ], [ "1007", @@ -7360,8 +9440,11 @@ "7", "Look 9 — Detail 1", "19", + "9", "1", - "9" + null, + null, + null ], [ "1008", @@ -7373,8 +9456,11 @@ "7", "Look 10", "20", + "10", "0", - "10" + null, + null, + null ], [ "1009", @@ -7386,8 +9472,11 @@ "7", "Look 11", "21", + "11", "0", - "11" + null, + null, + null ], [ "1010", @@ -7399,8 +9488,11 @@ "7", "Look 11 — Detail 1", "22", + "11", "1", - "11" + null, + null, + null ], [ "1011", @@ -7412,8 +9504,11 @@ "7", "Look 11 — Detail 2", "23", + "11", "1", - "11" + null, + null, + null ], [ "1012", @@ -7425,8 +9520,11 @@ "7", "Look 12", "24", + "12", "0", - "12" + null, + null, + null ], [ "1013", @@ -7438,8 +9536,11 @@ "7", "Look 12 — Detail 1", "25", + "12", "1", - "12" + null, + null, + null ], [ "1014", @@ -7451,8 +9552,11 @@ "7", "Look 13", "26", + "13", "0", - "13" + null, + null, + null ], [ "1015", @@ -7464,8 +9568,11 @@ "7", "Look 13 — Detail 1", "27", + "13", "1", - "13" + null, + null, + null ], [ "1016", @@ -7477,8 +9584,11 @@ "7", "Look 13 — Detail 2", "28", + "13", "1", - "13" + null, + null, + null ], [ "1017", @@ -7490,8 +9600,11 @@ "7", "Look 14", "29", + "14", "0", - "14" + null, + null, + null ], [ "1018", @@ -7503,8 +9616,11 @@ "7", "Look 14 — Detail 1", "30", + "14", "1", - "14" + null, + null, + null ], [ "1019", @@ -7516,8 +9632,11 @@ "7", "Look 15", "31", + "15", "0", - "15" + null, + null, + null ], [ "1020", @@ -7529,8 +9648,11 @@ "7", "Look 15 — Detail 1", "32", + "15", "1", - "15" + null, + null, + null ], [ "1021", @@ -7542,8 +9664,11 @@ "7", "Look 16", "33", + "16", "0", - "16" + null, + null, + null ], [ "1022", @@ -7555,8 +9680,11 @@ "7", "Look 16 — Detail 1", "34", + "16", "1", - "16" + null, + null, + null ], [ "1023", @@ -7568,8 +9696,11 @@ "7", "Look 17", "35", + "17", "0", - "17" + null, + null, + null ], [ "1024", @@ -7581,8 +9712,11 @@ "7", "Look 17 — Detail 1", "36", + "17", "1", - "17" + null, + null, + null ], [ "1025", @@ -7594,8 +9728,11 @@ "7", "Look 18", "37", + "18", "0", - "18" + null, + null, + null ], [ "1026", @@ -7607,8 +9744,11 @@ "7", "Look 19", "38", + "19", "0", - "19" + null, + null, + null ], [ "1027", @@ -7620,8 +9760,11 @@ "7", "Look 19 — Detail 1", "39", + "19", "1", - "19" + null, + null, + null ], [ "1028", @@ -7633,8 +9776,11 @@ "7", "Look 20", "40", + "20", "0", - "20" + null, + null, + null ], [ "1029", @@ -7646,8 +9792,11 @@ "7", "Look 20 — Detail 1", "41", + "20", "1", - "20" + null, + null, + null ], [ "1030", @@ -7659,8 +9808,11 @@ "7", "Look 20 — Detail 2", "42", + "20", "1", - "20" + null, + null, + null ], [ "1031", @@ -7672,8 +9824,11 @@ "7", "Look 21", "43", + "21", "0", - "21" + null, + null, + null ], [ "1032", @@ -7685,8 +9840,11 @@ "7", "Look 21 — Detail 1", "44", + "21", "1", - "21" + null, + null, + null ], [ "1033", @@ -7698,8 +9856,11 @@ "7", "Look 22", "45", + "22", "0", - "22" + null, + null, + null ], [ "1034", @@ -7711,8 +9872,11 @@ "7", "Look 22 — Detail 1", "46", + "22", "1", - "22" + null, + null, + null ], [ "1035", @@ -7724,8 +9888,11 @@ "7", "Look 23", "47", + "23", "0", - "23" + null, + null, + null ], [ "1036", @@ -7737,8 +9904,11 @@ "7", "Look 23 — Detail 1", "48", + "23", "1", - "23" + null, + null, + null ], [ "1037", @@ -7750,8 +9920,11 @@ "7", "Look 24", "49", + "24", "0", - "24" + null, + null, + null ], [ "1038", @@ -7763,8 +9936,11 @@ "7", "Look 25", "50", + "25", "0", - "25" + null, + null, + null ], [ "1039", @@ -7776,8 +9952,11 @@ "7", "Look 25 — Detail 1", "51", + "25", "1", - "25" + null, + null, + null ], [ "1040", @@ -7789,8 +9968,11 @@ "7", "Look 26", "52", + "26", "0", - "26" + null, + null, + null ], [ "1041", @@ -7802,8 +9984,11 @@ "7", "Look 27", "53", + "27", "0", - "27" + null, + null, + null ], [ "1042", @@ -7815,8 +10000,11 @@ "7", "Look 28", "54", + "28", "0", - "28" + null, + null, + null ], [ "1043", @@ -7828,8 +10016,11 @@ "7", "Look 28 — Detail 1", "55", + "28", "1", - "28" + null, + null, + null ], [ "1044", @@ -7841,8 +10032,11 @@ "7", "Look 28 — Detail 2", "56", + "28", "1", - "28" + null, + null, + null ], [ "1045", @@ -7854,8 +10048,11 @@ "7", "Look 29", "57", + "29", "0", - "29" + null, + null, + null ], [ "1046", @@ -7867,8 +10064,11 @@ "7", "Look 29 — Detail 1", "58", + "29", "1", - "29" + null, + null, + null ], [ "1047", @@ -7880,8 +10080,11 @@ "7", "Look 30", "59", + "30", "0", - "30" + null, + null, + null ], [ "1048", @@ -7893,8 +10096,11 @@ "7", "Look 30 — Detail 1", "60", + "30", "1", - "30" + null, + null, + null ], [ "1049", @@ -7906,8 +10112,11 @@ "7", "Look 31", "61", + "31", "0", - "31" + null, + null, + null ], [ "1050", @@ -7919,8 +10128,11 @@ "7", "Look 31 — Detail 1", "62", + "31", "1", - "31" + null, + null, + null ], [ "1051", @@ -7932,8 +10144,11 @@ "7", "Look 32", "63", + "32", "0", - "32" + null, + null, + null ], [ "1052", @@ -7945,8 +10160,11 @@ "7", "Look 32 — Detail 1", "64", + "32", "1", - "32" + null, + null, + null ], [ "1053", @@ -7958,8 +10176,11 @@ "7", "Look 33", "65", + "33", "0", - "33" + null, + null, + null ], [ "1054", @@ -7971,8 +10192,11 @@ "7", "Look 33 — Detail 1", "66", + "33", "1", - "33" + null, + null, + null ], [ "1055", @@ -7984,8 +10208,11 @@ "7", "Look 34", "67", + "34", "0", - "34" + null, + null, + null ], [ "1056", @@ -7997,8 +10224,11 @@ "7", "Look 35", "68", + "35", "0", - "35" + null, + null, + null ], [ "1057", @@ -8010,8 +10240,11 @@ "7", "Look 35 — Detail 1", "69", + "35", "1", - "35" + null, + null, + null ], [ "1058", @@ -8023,8 +10256,11 @@ "7", "Look 35 — Detail 2", "70", + "35", "1", - "35" + null, + null, + null ], [ "1059", @@ -8036,8 +10272,11 @@ "7", "Look 36", "71", + "36", "0", - "36" + null, + null, + null ], [ "1060", @@ -8049,8 +10288,11 @@ "7", "Look 36 — Detail 1", "72", + "36", "1", - "36" + null, + null, + null ], [ "1061", @@ -8062,8 +10304,11 @@ "7", "Look 37", "73", + "37", "0", - "37" + null, + null, + null ], [ "1062", @@ -8075,8 +10320,11 @@ "7", "Look 37 — Detail 1", "74", + "37", "1", - "37" + null, + null, + null ], [ "1063", @@ -8088,8 +10336,11 @@ "7", "Look 38", "75", + "38", "0", - "38" + null, + null, + null ], [ "1064", @@ -8101,8 +10352,11 @@ "7", "Look 38 — Detail 1", "76", + "38", "1", - "38" + null, + null, + null ], [ "1065", @@ -8114,8 +10368,11 @@ "7", "Look 38 — Detail 2", "77", + "38", "1", - "38" + null, + null, + null ], [ "1066", @@ -8127,8 +10384,11 @@ "7", "Look 39", "78", + "39", "0", - "39" + null, + null, + null ], [ "1067", @@ -8140,8 +10400,11 @@ "7", "Look 39 — Detail 1", "79", + "39", "1", - "39" + null, + null, + null ], [ "1068", @@ -8153,8 +10416,11 @@ "7", "Look 39 — Detail 2", "80", + "39", "1", - "39" + null, + null, + null ], [ "1069", @@ -8166,8 +10432,11 @@ "7", "Look 40", "81", + "40", "0", - "40" + null, + null, + null ], [ "1070", @@ -8179,8 +10448,11 @@ "7", "Look 40 — Detail 1", "82", + "40", "1", - "40" + null, + null, + null ], [ "1071", @@ -8192,8 +10464,11 @@ "7", "Look 41", "83", + "41", "0", - "41" + null, + null, + null ], [ "1072", @@ -8205,8 +10480,11 @@ "7", "Look 41 — Detail 1", "84", + "41", "1", - "41" + null, + null, + null ], [ "1073", @@ -8218,8 +10496,11 @@ "7", "Look 41 — Detail 2", "85", + "41", "1", - "41" + null, + null, + null ], [ "1074", @@ -8231,8 +10512,11 @@ "7", "Look 42", "86", + "42", "0", - "42" + null, + null, + null ], [ "1075", @@ -8244,8 +10528,11 @@ "7", "Look 43", "87", + "43", "0", - "43" + null, + null, + null ], [ "1076", @@ -8257,8 +10544,11 @@ "7", "Look 43 — Detail 1", "88", + "43", "1", - "43" + null, + null, + null ], [ "1077", @@ -8270,8 +10560,11 @@ "7", "Look 43 — Detail 2", "89", + "43", "1", - "43" + null, + null, + null ], [ "1078", @@ -8283,8 +10576,11 @@ "7", "Look 44", "90", + "44", "0", - "44" + null, + null, + null ], [ "1079", @@ -8296,8 +10592,11 @@ "7", "Look 44 — Detail 1", "91", + "44", "1", - "44" + null, + null, + null ], [ "1080", @@ -8309,8 +10608,11 @@ "7", "Look 45", "92", + "45", "0", - "45" + null, + null, + null ], [ "1081", @@ -8322,8 +10624,11 @@ "7", "Look 45 — Detail 1", "93", + "45", "1", - "45" + null, + null, + null ], [ "1082", @@ -8335,8 +10640,11 @@ "7", "Look 46", "94", + "46", "0", - "46" + null, + null, + null ], [ "1083", @@ -8348,8 +10656,11 @@ "7", "Look 46 — Detail 1", "95", + "46", "1", - "46" + null, + null, + null ], [ "1084", @@ -8361,8 +10672,11 @@ "7", "Look 46 — Detail 2", "96", + "46", "1", - "46" + null, + null, + null ], [ "1085", @@ -8374,8 +10688,11 @@ "7", "Look 47", "97", + "47", "0", - "47" + null, + null, + null ], [ "1086", @@ -8387,8 +10704,11 @@ "7", "Look 47 — Detail 1", "98", + "47", "1", - "47" + null, + null, + null ], [ "1087", @@ -8400,8 +10720,11 @@ "7", "Look 47 — Detail 2", "99", + "47", "1", - "47" + null, + null, + null ], [ "1088", @@ -8413,8 +10736,11 @@ "7", "Look 48", "100", + "48", "0", - "48" + null, + null, + null ], [ "1089", @@ -8426,8 +10752,11 @@ "7", "Look 48 — Detail 1", "101", + "48", "1", - "48" + null, + null, + null ], [ "1090", @@ -8439,8 +10768,11 @@ "7", "Look 49", "102", + "49", "0", - "49" + null, + null, + null ], [ "1091", @@ -8452,8 +10784,11 @@ "7", "Look 49 — Detail 1", "103", + "49", "1", - "49" + null, + null, + null ], [ "1092", @@ -8465,8 +10800,11 @@ "7", "Look 50", "104", + "50", "0", - "50" + null, + null, + null ], [ "1093", @@ -8478,8 +10816,11 @@ "7", "Look 50 — Detail 1", "105", + "50", "1", - "50" + null, + null, + null ], [ "1094", @@ -8491,8 +10832,11 @@ "7", "Look 51", "106", + "51", "0", - "51" + null, + null, + null ], [ "1095", @@ -8504,8 +10848,11 @@ "7", "Look 51 — Detail 1", "107", + "51", "1", - "51" + null, + null, + null ], [ "1096", @@ -8517,8 +10864,11 @@ "7", "Look 52", "108", + "52", "0", - "52" + null, + null, + null ], [ "1097", @@ -8530,8 +10880,11 @@ "7", "Look 52 — Detail 1", "109", + "52", "1", - "52" + null, + null, + null ], [ "1098", @@ -8543,8 +10896,11 @@ "7", "Look 52 — Detail 2", "110", + "52", "1", - "52" + null, + null, + null ], [ "1099", @@ -8556,8 +10912,11 @@ "7", "Look 53", "111", + "53", "0", - "53" + null, + null, + null ], [ "1100", @@ -8569,8 +10928,11 @@ "7", "Look 53 — Detail 1", "112", + "53", "1", - "53" + null, + null, + null ], [ "1101", @@ -8582,8 +10944,11 @@ "7", "Look 54", "113", + "54", "0", - "54" + null, + null, + null ], [ "1102", @@ -8595,8 +10960,11 @@ "7", "Look 54 — Detail 1", "114", + "54", "1", - "54" + null, + null, + null ], [ "1103", @@ -8608,8 +10976,11 @@ "7", "Look 55", "115", + "55", "0", - "55" + null, + null, + null ], [ "1104", @@ -8621,8 +10992,11 @@ "7", "Look 55 — Detail 1", "116", + "55", "1", - "55" + null, + null, + null ], [ "1105", @@ -8634,8 +11008,11 @@ "7", "Look 56", "117", + "56", "0", - "56" + null, + null, + null ], [ "1106", @@ -8647,8 +11024,11 @@ "7", "Look 56 — Detail 1", "118", + "56", "1", - "56" + null, + null, + null ], [ "1107", @@ -8660,8 +11040,11 @@ "7", "Look 57", "119", + "57", "0", - "57" + null, + null, + null ], [ "1108", @@ -8673,8 +11056,11 @@ "7", "Look 57 — Detail 1", "120", + "57", "1", - "57" + null, + null, + null ], [ "1109", @@ -8686,8 +11072,11 @@ "7", "Look 57 — Detail 2", "121", + "57", "1", - "57" + null, + null, + null ], [ "1110", @@ -8699,8 +11088,11 @@ "7", "Look 58", "122", + "58", "0", - "58" + null, + null, + null ], [ "1111", @@ -8712,8 +11104,11 @@ "7", "Look 58 — Detail 1", "123", + "58", "1", - "58" + null, + null, + null ], [ "1112", @@ -8725,8 +11120,11 @@ "7", "Look 58 — Detail 2", "124", + "58", "1", - "58" + null, + null, + null ], [ "1113", @@ -8738,8 +11136,11 @@ "7", "Look 59", "125", + "59", "0", - "59" + null, + null, + null ], [ "1114", @@ -8751,8 +11152,11 @@ "7", "Look 59 — Detail 1", "126", + "59", "1", - "59" + null, + null, + null ], [ "1115", @@ -8764,8 +11168,11 @@ "7", "Look 60", "127", + "60", "0", - "60" + null, + null, + null ], [ "1116", @@ -8777,8 +11184,11 @@ "7", "Look 60 — Detail 1", "128", + "60", "1", - "60" + null, + null, + null ], [ "1117", @@ -8790,8 +11200,11 @@ "7", "Look 61", "129", + "61", "0", - "61" + null, + null, + null ], [ "1118", @@ -8803,8 +11216,11 @@ "7", "Look 61 — Detail 1", "130", + "61", "1", - "61" + null, + null, + null ], [ "1119", @@ -8816,8 +11232,11 @@ "7", "Look 62", "131", + "62", "0", - "62" + null, + null, + null ], [ "1120", @@ -8829,8 +11248,11 @@ "7", "Look 62 — Detail 1", "132", + "62", "1", - "62" + null, + null, + null ], [ "1121", @@ -8842,8 +11264,11 @@ "7", "Look 63", "133", + "63", "0", - "63" + null, + null, + null ], [ "1122", @@ -8855,8 +11280,11 @@ "7", "Look 63 — Detail 1", "134", + "63", "1", - "63" + null, + null, + null ], [ "1123", @@ -8868,8 +11296,11 @@ "7", "Look 1", "1", + "1", "0", - "1" + null, + null, + null ], [ "1124", @@ -8882,7 +11313,10 @@ "Look 1 — Detail 1", "2", "1", - "1" + "1", + null, + null, + null ], [ "1125", @@ -8895,7 +11329,10 @@ "Look 1 — Detail 2", "3", "1", - "1" + "1", + null, + null, + null ], [ "1126", @@ -8907,8 +11344,11 @@ "7", "Look 2", "4", + "2", "0", - "2" + null, + null, + null ], [ "1127", @@ -8920,8 +11360,11 @@ "7", "Look 2 — Detail 1", "5", + "2", "1", - "2" + null, + null, + null ], [ "1128", @@ -8933,8 +11376,11 @@ "7", "Look 2 — Detail 2", "6", + "2", "1", - "2" + null, + null, + null ], [ "1129", @@ -8946,8 +11392,11 @@ "7", "Look 2 — Detail 3", "7", + "2", "1", - "2" + null, + null, + null ], [ "1130", @@ -8959,8 +11408,11 @@ "7", "Look 3", "8", + "3", "0", - "3" + null, + null, + null ], [ "1131", @@ -8972,8 +11424,11 @@ "7", "Look 3 — Detail 1", "9", + "3", "1", - "3" + null, + null, + null ], [ "1132", @@ -8985,8 +11440,11 @@ "7", "Look 3 — Detail 2", "10", + "3", "1", - "3" + null, + null, + null ], [ "1133", @@ -8998,8 +11456,11 @@ "7", "Look 4", "11", + "4", "0", - "4" + null, + null, + null ], [ "1134", @@ -9011,8 +11472,11 @@ "7", "Look 4 — Detail 1", "12", + "4", "1", - "4" + null, + null, + null ], [ "1135", @@ -9024,8 +11488,11 @@ "7", "Look 4 — Detail 2", "13", + "4", "1", - "4" + null, + null, + null ], [ "1136", @@ -9037,8 +11504,11 @@ "7", "Look 4 — Detail 3", "14", + "4", "1", - "4" + null, + null, + null ], [ "1137", @@ -9050,8 +11520,11 @@ "7", "Look 5", "15", + "5", "0", - "5" + null, + null, + null ], [ "1138", @@ -9063,8 +11536,11 @@ "7", "Look 5 — Detail 1", "16", + "5", "1", - "5" + null, + null, + null ], [ "1139", @@ -9076,8 +11552,11 @@ "7", "Look 5 — Detail 2", "17", + "5", "1", - "5" + null, + null, + null ], [ "1140", @@ -9089,8 +11568,11 @@ "7", "Look 5 — Detail 3", "18", + "5", "1", - "5" + null, + null, + null ], [ "1141", @@ -9102,8 +11584,11 @@ "7", "Look 6", "19", + "6", "0", - "6" + null, + null, + null ], [ "1142", @@ -9115,8 +11600,11 @@ "7", "Look 6 — Detail 1", "20", + "6", "1", - "6" + null, + null, + null ], [ "1143", @@ -9128,8 +11616,11 @@ "7", "Look 6 — Detail 2", "21", + "6", "1", - "6" + null, + null, + null ], [ "1144", @@ -9141,8 +11632,11 @@ "7", "Look 7", "22", + "7", "0", - "7" + null, + null, + null ], [ "1145", @@ -9154,8 +11648,11 @@ "7", "Look 7 — Detail 1", "23", + "7", "1", - "7" + null, + null, + null ], [ "1146", @@ -9167,8 +11664,11 @@ "7", "Look 8", "24", + "8", "0", - "8" + null, + null, + null ], [ "1147", @@ -9180,8 +11680,11 @@ "7", "Look 8 — Detail 1", "25", + "8", "1", - "8" + null, + null, + null ], [ "1148", @@ -9193,8 +11696,11 @@ "7", "Look 9", "26", + "9", "0", - "9" + null, + null, + null ], [ "1149", @@ -9206,8 +11712,11 @@ "7", "Look 9 — Detail 1", "27", + "9", "1", - "9" + null, + null, + null ], [ "1150", @@ -9219,8 +11728,11 @@ "7", "Look 10", "28", + "10", "0", - "10" + null, + null, + null ], [ "1151", @@ -9232,8 +11744,11 @@ "7", "Look 10 — Detail 1", "29", + "10", "1", - "10" + null, + null, + null ], [ "1152", @@ -9245,8 +11760,11 @@ "7", "Look 10 — Detail 2", "30", + "10", "1", - "10" + null, + null, + null ], [ "1153", @@ -9258,8 +11776,11 @@ "7", "Look 11", "31", + "11", "0", - "11" + null, + null, + null ], [ "1154", @@ -9271,8 +11792,11 @@ "7", "Look 11 — Detail 1", "32", + "11", "1", - "11" + null, + null, + null ], [ "1155", @@ -9284,8 +11808,11 @@ "7", "Look 11 — Detail 2", "33", + "11", "1", - "11" + null, + null, + null ], [ "1156", @@ -9297,8 +11824,11 @@ "7", "Look 12", "34", + "12", "0", - "12" + null, + null, + null ], [ "1157", @@ -9310,8 +11840,11 @@ "7", "Look 12 — Detail 1", "35", + "12", "1", - "12" + null, + null, + null ], [ "1158", @@ -9323,8 +11856,11 @@ "7", "Look 12 — Detail 2", "36", + "12", "1", - "12" + null, + null, + null ], [ "1159", @@ -9336,8 +11872,11 @@ "7", "Look 12 — Detail 3", "37", + "12", "1", - "12" + null, + null, + null ], [ "1160", @@ -9349,8 +11888,11 @@ "7", "Look 13", "38", + "13", "0", - "13" + null, + null, + null ], [ "1161", @@ -9362,8 +11904,11 @@ "7", "Look 13 — Detail 1", "39", + "13", "1", - "13" + null, + null, + null ], [ "1162", @@ -9375,8 +11920,11 @@ "7", "Look 13 — Detail 2", "40", + "13", "1", - "13" + null, + null, + null ], [ "1163", @@ -9388,8 +11936,11 @@ "7", "Look 13 — Detail 3", "41", + "13", "1", - "13" + null, + null, + null ], [ "1164", @@ -9401,8 +11952,11 @@ "7", "Look 14", "42", + "14", "0", - "14" + null, + null, + null ], [ "1165", @@ -9414,8 +11968,11 @@ "7", "Look 15", "43", + "15", "0", - "15" + null, + null, + null ], [ "1166", @@ -9427,8 +11984,11 @@ "7", "Look 15 — Detail 1", "44", + "15", "1", - "15" + null, + null, + null ], [ "1167", @@ -9440,8 +12000,11 @@ "7", "Look 15 — Detail 2", "45", + "15", "1", - "15" + null, + null, + null ], [ "1168", @@ -9453,8 +12016,11 @@ "7", "Look 16", "46", + "16", "0", - "16" + null, + null, + null ], [ "1169", @@ -9466,8 +12032,11 @@ "7", "Look 16 — Detail 1", "47", + "16", "1", - "16" + null, + null, + null ], [ "1170", @@ -9479,8 +12048,11 @@ "7", "Look 16 — Detail 2", "48", + "16", "1", - "16" + null, + null, + null ], [ "1171", @@ -9492,8 +12064,11 @@ "7", "Look 17", "49", + "17", "0", - "17" + null, + null, + null ], [ "1172", @@ -9505,8 +12080,11 @@ "7", "Look 17 — Detail 1", "50", + "17", "1", - "17" + null, + null, + null ], [ "1173", @@ -9518,8 +12096,11 @@ "7", "Look 17 — Detail 2", "51", + "17", "1", - "17" + null, + null, + null ], [ "1174", @@ -9531,8 +12112,11 @@ "7", "Look 18", "52", + "18", "0", - "18" + null, + null, + null ], [ "1175", @@ -9544,8 +12128,11 @@ "7", "Look 18 — Detail 1", "53", + "18", "1", - "18" + null, + null, + null ], [ "1176", @@ -9557,8 +12144,11 @@ "7", "Look 18 — Detail 2", "54", + "18", "1", - "18" + null, + null, + null ], [ "1177", @@ -9570,8 +12160,11 @@ "7", "Look 19", "55", + "19", "0", - "19" + null, + null, + null ], [ "1178", @@ -9583,8 +12176,11 @@ "7", "Look 19 — Detail 1", "56", + "19", "1", - "19" + null, + null, + null ], [ "1179", @@ -9596,8 +12192,11 @@ "7", "Look 19 — Detail 2", "57", + "19", "1", - "19" + null, + null, + null ], [ "1180", @@ -9609,8 +12208,11 @@ "7", "Look 19 — Detail 3", "58", + "19", "1", - "19" + null, + null, + null ], [ "1181", @@ -9622,8 +12224,11 @@ "7", "Look 20", "59", + "20", "0", - "20" + null, + null, + null ], [ "1182", @@ -9635,8 +12240,11 @@ "7", "Look 20 — Detail 1", "60", + "20", "1", - "20" + null, + null, + null ], [ "1183", @@ -9648,8 +12256,11 @@ "7", "Look 20 — Detail 2", "61", + "20", "1", - "20" + null, + null, + null ], [ "1184", @@ -9661,8 +12272,11 @@ "7", "Look 20 — Detail 3", "62", + "20", "1", - "20" + null, + null, + null ], [ "1185", @@ -9674,8 +12288,11 @@ "7", "Look 21", "63", + "21", "0", - "21" + null, + null, + null ], [ "1186", @@ -9687,8 +12304,11 @@ "7", "Look 21 — Detail 1", "64", + "21", "1", - "21" + null, + null, + null ], [ "1187", @@ -9700,8 +12320,11 @@ "7", "Look 21 — Detail 2", "65", + "21", "1", - "21" + null, + null, + null ], [ "1188", @@ -9713,8 +12336,11 @@ "7", "Look 21 — Detail 3", "66", + "21", "1", - "21" + null, + null, + null ], [ "1189", @@ -9726,8 +12352,11 @@ "7", "Look 22", "67", + "22", "0", - "22" + null, + null, + null ], [ "1190", @@ -9739,8 +12368,11 @@ "7", "Look 22 — Detail 1", "68", + "22", "1", - "22" + null, + null, + null ], [ "1191", @@ -9752,8 +12384,11 @@ "7", "Look 22 — Detail 2", "69", + "22", "1", - "22" + null, + null, + null ], [ "1192", @@ -9765,8 +12400,11 @@ "7", "Look 23", "70", + "23", "0", - "23" + null, + null, + null ], [ "1193", @@ -9778,8 +12416,11 @@ "7", "Look 23 — Detail 1", "71", + "23", "1", - "23" + null, + null, + null ], [ "1194", @@ -9791,8 +12432,11 @@ "7", "Look 23 — Detail 2", "72", + "23", "1", - "23" + null, + null, + null ], [ "1195", @@ -9804,8 +12448,11 @@ "7", "Look 24", "73", + "24", "0", - "24" + null, + null, + null ], [ "1196", @@ -9817,8 +12464,11 @@ "7", "Look 24 — Detail 1", "74", + "24", "1", - "24" + null, + null, + null ], [ "1197", @@ -9830,8 +12480,11 @@ "7", "Look 25", "75", + "25", "0", - "25" + null, + null, + null ], [ "1198", @@ -9843,8 +12496,11 @@ "7", "Look 25 — Detail 1", "76", + "25", "1", - "25" + null, + null, + null ], [ "1199", @@ -9856,8 +12512,11 @@ "7", "Look 25 — Detail 2", "77", + "25", "1", - "25" + null, + null, + null ], [ "1200", @@ -9869,8 +12528,11 @@ "7", "Look 25 — Detail 3", "78", + "25", "1", - "25" + null, + null, + null ], [ "1201", @@ -9882,8 +12544,11 @@ "7", "Look 26", "79", + "26", "0", - "26" + null, + null, + null ], [ "1202", @@ -9895,8 +12560,11 @@ "7", "Look 26 — Detail 1", "80", + "26", "1", - "26" + null, + null, + null ], [ "1203", @@ -9908,8 +12576,11 @@ "7", "Look 26 — Detail 2", "81", + "26", "1", - "26" + null, + null, + null ], [ "1204", @@ -9921,8 +12592,11 @@ "7", "Look 26 — Detail 3", "82", + "26", "1", - "26" + null, + null, + null ], [ "1205", @@ -9934,8 +12608,11 @@ "7", "Look 27", "83", + "27", "0", - "27" + null, + null, + null ], [ "1206", @@ -9947,8 +12624,11 @@ "7", "Look 27 — Detail 1", "84", + "27", "1", - "27" + null, + null, + null ], [ "1207", @@ -9960,8 +12640,11 @@ "7", "Look 27 — Detail 2", "85", + "27", "1", - "27" + null, + null, + null ], [ "1208", @@ -9973,8 +12656,11 @@ "7", "Look 28", "86", + "28", "0", - "28" + null, + null, + null ], [ "1209", @@ -9986,8 +12672,11 @@ "7", "Look 28 — Detail 1", "87", + "28", "1", - "28" + null, + null, + null ], [ "1210", @@ -9999,8 +12688,11 @@ "7", "Look 28 — Detail 2", "88", + "28", "1", - "28" + null, + null, + null ], [ "1211", @@ -10012,8 +12704,11 @@ "7", "Look 29", "89", + "29", "0", - "29" + null, + null, + null ], [ "1212", @@ -10025,8 +12720,11 @@ "7", "Look 29 — Detail 1", "90", + "29", "1", - "29" + null, + null, + null ], [ "1213", @@ -10038,8 +12736,11 @@ "7", "Look 29 — Detail 2", "91", + "29", "1", - "29" + null, + null, + null ], [ "1214", @@ -10051,8 +12752,11 @@ "7", "Look 29 — Detail 3", "92", + "29", "1", - "29" + null, + null, + null ], [ "1215", @@ -10064,8 +12768,11 @@ "7", "Look 29 — Detail 4", "93", + "29", "1", - "29" + null, + null, + null ], [ "1216", @@ -10077,8 +12784,11 @@ "7", "Look 30", "94", + "30", "0", - "30" + null, + null, + null ], [ "1217", @@ -10090,8 +12800,11 @@ "7", "Look 31", "95", + "31", "0", - "31" + null, + null, + null ], [ "1218", @@ -10103,8 +12816,11 @@ "7", "Look 31 — Detail 1", "96", + "31", "1", - "31" + null, + null, + null ], [ "1219", @@ -10116,8 +12832,11 @@ "7", "Look 32", "97", + "32", "0", - "32" + null, + null, + null ], [ "1220", @@ -10129,8 +12848,11 @@ "7", "Look 32 — Detail 1", "98", + "32", "1", - "32" + null, + null, + null ], [ "1221", @@ -10142,8 +12864,11 @@ "7", "Look 32 — Detail 2", "99", + "32", "1", - "32" + null, + null, + null ], [ "1222", @@ -10155,8 +12880,11 @@ "7", "Look 33", "100", + "33", "0", - "33" + null, + null, + null ], [ "1223", @@ -10168,8 +12896,11 @@ "7", "Look 33 — Detail 1", "101", + "33", "1", - "33" + null, + null, + null ], [ "1224", @@ -10181,8 +12912,11 @@ "7", "Look 34", "102", + "34", "0", - "34" + null, + null, + null ], [ "1225", @@ -10194,8 +12928,11 @@ "7", "Look 34 — Detail 1", "103", + "34", "1", - "34" + null, + null, + null ], [ "1226", @@ -10207,8 +12944,11 @@ "7", "Look 34 — Detail 2", "104", + "34", "1", - "34" + null, + null, + null ], [ "1227", @@ -10220,8 +12960,11 @@ "7", "Look 34 — Detail 3", "105", + "34", "1", - "34" + null, + null, + null ], [ "1228", @@ -10233,8 +12976,11 @@ "7", "Look 35", "106", + "35", "0", - "35" + null, + null, + null ], [ "1229", @@ -10246,8 +12992,11 @@ "7", "Look 35 — Detail 1", "107", + "35", "1", - "35" + null, + null, + null ], [ "1230", @@ -10259,8 +13008,11 @@ "7", "Look 35 — Detail 2", "108", + "35", "1", - "35" + null, + null, + null ], [ "1231", @@ -10272,8 +13024,11 @@ "7", "Look 36", "109", + "36", "0", - "36" + null, + null, + null ], [ "1232", @@ -10285,8 +13040,11 @@ "7", "Look 36 — Detail 1", "110", + "36", "1", - "36" + null, + null, + null ], [ "1233", @@ -10298,8 +13056,11 @@ "7", "Look 36 — Detail 2", "111", + "36", "1", - "36" + null, + null, + null ], [ "1234", @@ -10311,8 +13072,11 @@ "7", "Look 37", "112", + "37", "0", - "37" + null, + null, + null ], [ "1235", @@ -10324,8 +13088,11 @@ "7", "Look 37 — Detail 1", "113", + "37", "1", - "37" + null, + null, + null ], [ "1236", @@ -10337,8 +13104,11 @@ "7", "Look 37 — Detail 2", "114", + "37", "1", - "37" + null, + null, + null ], [ "1237", @@ -10350,8 +13120,11 @@ "7", "Look 38", "115", + "38", "0", - "38" + null, + null, + null ], [ "1238", @@ -10363,8 +13136,11 @@ "7", "Look 38 — Detail 1", "116", + "38", "1", - "38" + null, + null, + null ], [ "1239", @@ -10376,8 +13152,11 @@ "7", "Look 38 — Detail 2", "117", + "38", "1", - "38" + null, + null, + null ], [ "1240", @@ -10389,8 +13168,11 @@ "7", "Look 39", "118", + "39", "0", - "39" + null, + null, + null ], [ "1241", @@ -10402,8 +13184,11 @@ "7", "Look 40", "119", + "40", "0", - "40" + null, + null, + null ], [ "1242", @@ -10415,8 +13200,11 @@ "7", "Look 40 — Detail 1", "120", + "40", "1", - "40" + null, + null, + null ], [ "1243", @@ -10428,8 +13216,11 @@ "7", "Look 40 — Detail 2", "121", + "40", "1", - "40" + null, + null, + null ], [ "1244", @@ -10441,8 +13232,11 @@ "7", "Look 40 — Detail 3", "122", + "40", "1", - "40" + null, + null, + null ], [ "1245", @@ -10454,8 +13248,11 @@ "7", "Look 41", "123", + "41", "0", - "41" + null, + null, + null ], [ "1246", @@ -10467,8 +13264,11 @@ "7", "Look 41 — Detail 1", "124", + "41", "1", - "41" + null, + null, + null ], [ "1247", @@ -10480,8 +13280,11 @@ "7", "Look 41 — Detail 2", "125", + "41", "1", - "41" + null, + null, + null ], [ "1248", @@ -10493,8 +13296,11 @@ "7", "Look 42", "126", + "42", "0", - "42" + null, + null, + null ], [ "1249", @@ -10506,8 +13312,11 @@ "7", "Look 42 — Detail 1", "127", + "42", "1", - "42" + null, + null, + null ], [ "1250", @@ -10519,8 +13328,11 @@ "7", "Look 1", "1", + "1", "0", - "1" + null, + null, + null ], [ "1251", @@ -10533,7 +13345,10 @@ "Look 1 — Detail 1", "2", "1", - "1" + "1", + null, + null, + null ], [ "1252", @@ -10546,7 +13361,10 @@ "Look 1 — Detail 2", "3", "1", - "1" + "1", + null, + null, + null ], [ "1253", @@ -10558,8 +13376,11 @@ "7", "Look 2", "4", + "2", "0", - "2" + null, + null, + null ], [ "1254", @@ -10571,8 +13392,11 @@ "7", "Look 2 — Detail 1", "5", + "2", "1", - "2" + null, + null, + null ], [ "1255", @@ -10584,8 +13408,11 @@ "7", "Look 3", "6", + "3", "0", - "3" + null, + null, + null ], [ "1256", @@ -10597,8 +13424,11 @@ "7", "Look 4", "7", + "4", "0", - "4" + null, + null, + null ], [ "1257", @@ -10610,8 +13440,11 @@ "7", "Look 5", "8", + "5", "0", - "5" + null, + null, + null ], [ "1258", @@ -10623,8 +13456,11 @@ "7", "Look 5 — Detail 1", "9", + "5", "1", - "5" + null, + null, + null ], [ "1259", @@ -10636,8 +13472,11 @@ "7", "Look 6", "10", + "6", "0", - "6" + null, + null, + null ], [ "1260", @@ -10649,8 +13488,11 @@ "7", "Look 6 — Detail 1", "11", + "6", "1", - "6" + null, + null, + null ], [ "1261", @@ -10662,8 +13504,11 @@ "7", "Look 7", "12", + "7", "0", - "7" + null, + null, + null ], [ "1262", @@ -10675,8 +13520,11 @@ "7", "Look 7 — Detail 1", "13", + "7", "1", - "7" + null, + null, + null ], [ "1263", @@ -10688,8 +13536,11 @@ "7", "Look 7 — Detail 2", "14", + "7", "1", - "7" + null, + null, + null ], [ "1264", @@ -10701,8 +13552,11 @@ "7", "Look 8", "15", + "8", "0", - "8" + null, + null, + null ], [ "1265", @@ -10714,8 +13568,11 @@ "7", "Look 9", "16", + "9", "0", - "9" + null, + null, + null ], [ "1266", @@ -10727,8 +13584,11 @@ "7", "Look 9 — Detail 1", "17", + "9", "1", - "9" + null, + null, + null ], [ "1267", @@ -10740,8 +13600,11 @@ "7", "Look 9 — Detail 2", "18", + "9", "1", - "9" + null, + null, + null ], [ "1268", @@ -10753,8 +13616,11 @@ "7", "Look 10", "19", + "10", "0", - "10" + null, + null, + null ], [ "1269", @@ -10766,8 +13632,11 @@ "7", "Look 11", "20", + "11", "0", - "11" + null, + null, + null ], [ "1270", @@ -10779,8 +13648,11 @@ "7", "Look 11 — Detail 1", "21", + "11", "1", - "11" + null, + null, + null ], [ "1271", @@ -10792,8 +13664,11 @@ "7", "Look 12", "22", + "12", "0", - "12" + null, + null, + null ], [ "1272", @@ -10805,8 +13680,11 @@ "7", "Look 12 — Detail 1", "23", + "12", "1", - "12" + null, + null, + null ], [ "1273", @@ -10818,8 +13696,11 @@ "7", "Look 13", "24", + "13", "0", - "13" + null, + null, + null ], [ "1274", @@ -10831,8 +13712,11 @@ "7", "Look 13 — Detail 1", "25", + "13", "1", - "13" + null, + null, + null ], [ "1275", @@ -10844,8 +13728,11 @@ "7", "Look 14", "26", + "14", "0", - "14" + null, + null, + null ], [ "1276", @@ -10857,8 +13744,11 @@ "7", "Look 15", "27", + "15", "0", - "15" + null, + null, + null ], [ "1277", @@ -10870,8 +13760,11 @@ "7", "Look 15 — Detail 1", "28", + "15", "1", - "15" + null, + null, + null ], [ "1278", @@ -10883,8 +13776,11 @@ "7", "Look 16", "29", + "16", "0", - "16" + null, + null, + null ], [ "1279", @@ -10896,8 +13792,11 @@ "7", "Look 17", "30", + "17", "0", - "17" + null, + null, + null ], [ "1280", @@ -10909,8 +13808,11 @@ "7", "Look 17 — Detail 1", "31", + "17", "1", - "17" + null, + null, + null ], [ "1281", @@ -10922,8 +13824,11 @@ "7", "Look 18", "32", + "18", "0", - "18" + null, + null, + null ], [ "1282", @@ -10935,8 +13840,11 @@ "7", "Look 18 — Detail 1", "33", + "18", "1", - "18" + null, + null, + null ], [ "1283", @@ -10948,8 +13856,11 @@ "7", "Look 19", "34", + "19", "0", - "19" + null, + null, + null ], [ "1284", @@ -10961,8 +13872,11 @@ "7", "Look 19 — Detail 1", "35", + "19", "1", - "19" + null, + null, + null ], [ "1285", @@ -10974,8 +13888,11 @@ "7", "Look 20", "36", + "20", "0", - "20" + null, + null, + null ], [ "1286", @@ -10987,8 +13904,11 @@ "7", "Look 21", "37", + "21", "0", - "21" + null, + null, + null ], [ "1287", @@ -11000,8 +13920,11 @@ "7", "Look 21 — Detail 1", "38", + "21", "1", - "21" + null, + null, + null ], [ "1288", @@ -11013,8 +13936,11 @@ "7", "Look 21 — Detail 2", "39", + "21", "1", - "21" + null, + null, + null ], [ "1289", @@ -11026,8 +13952,11 @@ "7", "Look 22", "40", + "22", "0", - "22" + null, + null, + null ], [ "1290", @@ -11039,8 +13968,11 @@ "7", "Look 23", "41", + "23", "0", - "23" + null, + null, + null ], [ "1291", @@ -11052,8 +13984,11 @@ "7", "Look 23 — Detail 1", "42", + "23", "1", - "23" + null, + null, + null ], [ "1292", @@ -11065,8 +14000,11 @@ "7", "Look 24", "43", + "24", "0", - "24" + null, + null, + null ], [ "1293", @@ -11078,8 +14016,11 @@ "7", "Look 24 — Detail 1", "44", + "24", "1", - "24" + null, + null, + null ], [ "1294", @@ -11091,8 +14032,11 @@ "7", "Look 25", "45", + "25", "0", - "25" + null, + null, + null ], [ "1295", @@ -11104,8 +14048,11 @@ "7", "Look 26", "46", + "26", "0", - "26" + null, + null, + null ], [ "1296", @@ -11117,8 +14064,11 @@ "7", "Look 27", "47", + "27", "0", - "27" + null, + null, + null ], [ "1297", @@ -11130,8 +14080,11 @@ "7", "Look 27 — Detail 1", "48", + "27", "1", - "27" + null, + null, + null ], [ "1298", @@ -11143,8 +14096,11 @@ "7", "Look 28", "49", + "28", "0", - "28" + null, + null, + null ], [ "1299", @@ -11156,8 +14112,11 @@ "7", "Look 28 — Detail 1", "50", + "28", "1", - "28" + null, + null, + null ], [ "1300", @@ -11169,8 +14128,11 @@ "7", "Look 29", "51", + "29", "0", - "29" + null, + null, + null ], [ "1301", @@ -11182,8 +14144,11 @@ "7", "Look 29 — Detail 1", "52", + "29", "1", - "29" + null, + null, + null ], [ "1302", @@ -11195,8 +14160,11 @@ "7", "Look 30", "53", + "30", "0", - "30" + null, + null, + null ], [ "1303", @@ -11208,8 +14176,11 @@ "7", "Look 31", "54", + "31", "0", - "31" + null, + null, + null ], [ "1304", @@ -11221,8 +14192,11 @@ "7", "Look 31 — Detail 1", "55", + "31", "1", - "31" + null, + null, + null ], [ "1305", @@ -11234,8 +14208,11 @@ "7", "Look 31 — Detail 2", "56", + "31", "1", - "31" + null, + null, + null ], [ "1306", @@ -11247,8 +14224,11 @@ "7", "Look 32", "57", + "32", "0", - "32" + null, + null, + null ], [ "1307", @@ -11260,8 +14240,11 @@ "7", "Look 32 — Detail 1", "58", + "32", "1", - "32" + null, + null, + null ], [ "1308", @@ -11273,8 +14256,11 @@ "7", "Look 33", "59", + "33", "0", - "33" + null, + null, + null ], [ "1309", @@ -11286,8 +14272,11 @@ "7", "Look 33 — Detail 1", "60", + "33", "1", - "33" + null, + null, + null ], [ "1310", @@ -11299,8 +14288,11 @@ "7", "Look 33 — Detail 2", "61", + "33", "1", - "33" + null, + null, + null ], [ "1311", @@ -11312,8 +14304,11 @@ "7", "Look 34", "62", + "34", "0", - "34" + null, + null, + null ], [ "1312", @@ -11325,8 +14320,11 @@ "7", "Look 35", "63", + "35", "0", - "35" + null, + null, + null ], [ "1313", @@ -11338,8 +14336,11 @@ "7", "Look 35 — Detail 1", "64", + "35", "1", - "35" + null, + null, + null ], [ "1314", @@ -11351,8 +14352,11 @@ "7", "Look 36", "65", + "36", "0", - "36" + null, + null, + null ], [ "1315", @@ -11364,8 +14368,11 @@ "7", "Look 36 — Detail 1", "66", + "36", "1", - "36" + null, + null, + null ], [ "1316", @@ -11377,8 +14384,11 @@ "7", "Look 37", "67", + "37", "0", - "37" + null, + null, + null ], [ "1317", @@ -11390,8 +14400,11 @@ "7", "Look 37 — Detail 1", "68", + "37", "1", - "37" + null, + null, + null ], [ "1318", @@ -11403,8 +14416,11 @@ "7", "Look 37 — Detail 2", "69", + "37", "1", - "37" + null, + null, + null ], [ "1319", @@ -11416,8 +14432,11 @@ "7", "Look 38", "70", + "38", "0", - "38" + null, + null, + null ], [ "1320", @@ -11429,8 +14448,11 @@ "7", "Look 38 — Detail 1", "71", + "38", "1", - "38" + null, + null, + null ], [ "1321", @@ -11442,8 +14464,11 @@ "7", "Look 39", "72", + "39", "0", - "39" + null, + null, + null ], [ "1322", @@ -11455,8 +14480,11 @@ "7", "Look 40", "73", + "40", "0", - "40" + null, + null, + null ], [ "1323", @@ -11468,8 +14496,11 @@ "7", "Look 40 — Detail 1", "74", + "40", "1", - "40" + null, + null, + null ], [ "1324", @@ -11481,8 +14512,11 @@ "7", "Look 41", "75", + "41", "0", - "41" + null, + null, + null ], [ "1325", @@ -11494,8 +14528,11 @@ "7", "Look 42", "76", + "42", "0", - "42" + null, + null, + null ], [ "1326", @@ -11507,8 +14544,11 @@ "7", "Look 42 — Detail 1", "77", + "42", "1", - "42" + null, + null, + null ], [ "1327", @@ -11520,8 +14560,11 @@ "7", "Look 42 — Detail 2", "78", + "42", "1", - "42" + null, + null, + null ], [ "1328", @@ -11533,8 +14576,11 @@ "7", "Look 43", "79", + "43", "0", - "43" + null, + null, + null ], [ "1329", @@ -11546,8 +14592,11 @@ "7", "Look 43 — Detail 1", "80", + "43", "1", - "43" + null, + null, + null ], [ "1330", @@ -11559,8 +14608,11 @@ "7", "Look 44", "81", + "44", "0", - "44" + null, + null, + null ], [ "1331", @@ -11572,8 +14624,11 @@ "7", "Look 44 — Detail 1", "82", + "44", "1", - "44" + null, + null, + null ], [ "1332", @@ -11585,8 +14640,11 @@ "7", "Look 45", "83", + "45", "0", - "45" + null, + null, + null ], [ "1333", @@ -11598,8 +14656,11 @@ "7", "Look 45 — Detail 1", "84", + "45", "1", - "45" + null, + null, + null ], [ "1334", @@ -11611,8 +14672,11 @@ "7", "Look 46", "85", + "46", "0", - "46" + null, + null, + null ], [ "1335", @@ -11624,8 +14688,11 @@ "7", "Look 46 — Detail 1", "86", + "46", "1", - "46" + null, + null, + null ], [ "1336", @@ -11637,8 +14704,11 @@ "7", "Look 47", "87", + "47", "0", - "47" + null, + null, + null ], [ "1337", @@ -11650,8 +14720,11 @@ "7", "Look 48", "88", + "48", "0", - "48" + null, + null, + null ], [ "1338", @@ -11663,8 +14736,11 @@ "7", "Look 49", "89", + "49", "0", - "49" + null, + null, + null ], [ "1339", @@ -11676,8 +14752,11 @@ "7", "Look 49 — Detail 1", "90", + "49", "1", - "49" + null, + null, + null ], [ "1340", @@ -11689,8 +14768,11 @@ "7", "Look 50", "91", + "50", "0", - "50" + null, + null, + null ], [ "1341", @@ -11702,8 +14784,11 @@ "7", "Look 51", "92", + "51", "0", - "51" + null, + null, + null ], [ "1342", @@ -11715,8 +14800,11 @@ "7", "Look 52", "93", + "52", "0", - "52" + null, + null, + null ], [ "1343", @@ -11728,8 +14816,11 @@ "7", "Look 53", "94", + "53", "0", - "53" + null, + null, + null ], [ "1344", @@ -11741,8 +14832,11 @@ "7", "Look 54", "95", + "54", "0", - "54" + null, + null, + null ], [ "1345", @@ -11754,8 +14848,11 @@ "7", "Look 55", "96", + "55", "0", - "55" + null, + null, + null ], [ "1346", @@ -11767,8 +14864,11 @@ "7", "Look 56", "97", + "56", "0", - "56" + null, + null, + null ], [ "1347", @@ -11780,8 +14880,11 @@ "7", "Look 56 — Detail 1", "98", + "56", "1", - "56" + null, + null, + null ], [ "1348", @@ -11793,8 +14896,11 @@ "7", "Look 57", "99", + "57", "0", - "57" + null, + null, + null ], [ "1349", @@ -11806,8 +14912,11 @@ "7", "Look 57 — Detail 1", "100", + "57", "1", - "57" + null, + null, + null ], [ "1350", @@ -11819,8 +14928,11 @@ "7", "Look 58", "101", + "58", "0", - "58" + null, + null, + null ], [ "1351", @@ -11832,8 +14944,11 @@ "7", "Look 58 — Detail 1", "102", + "58", "1", - "58" + null, + null, + null ], [ "1352", @@ -11845,8 +14960,11 @@ "7", "Look 59", "103", + "59", "0", - "59" + null, + null, + null ], [ "1353", @@ -11858,8 +14976,11 @@ "7", "Look 60", "104", + "60", "0", - "60" + null, + null, + null ], [ "1354", @@ -11871,8 +14992,11 @@ "7", "Look 60 — Detail 1", "105", + "60", "1", - "60" + null, + null, + null ], [ "1355", @@ -11884,8 +15008,11 @@ "7", "Look 60 — Detail 2", "106", + "60", "1", - "60" + null, + null, + null ], [ "1356", @@ -11897,8 +15024,11 @@ "7", "Look 61", "107", + "61", "0", - "61" + null, + null, + null ], [ "1357", @@ -11910,8 +15040,11 @@ "7", "Look 62", "108", + "62", "0", - "62" + null, + null, + null ], [ "1358", @@ -11923,8 +15056,11 @@ "7", "Look 63", "109", + "63", "0", - "63" + null, + null, + null ], [ "1359", @@ -11936,8 +15072,11 @@ "7", "Look 64", "110", + "64", "0", - "64" + null, + null, + null ], [ "1360", @@ -11949,8 +15088,11 @@ "7", "Look 64 — Detail 1", "111", + "64", "1", - "64" + null, + null, + null ], [ "1361", @@ -11962,8 +15104,11 @@ "7", "Look 65", "112", + "65", "0", - "65" + null, + null, + null ], [ "1362", @@ -11975,632 +15120,11 @@ "7", "Look 65 — Detail 1", "113", + "65", "1", - "65" - ], - [ - "1363", - "1789137486", - "1789137486", - "0", - "runway/4a3e58e4e6f0ff0d2f1235bdb3914e4732689f1c.jpg", - "11", - "7", - "Look 65 — Detail 2", - "114", - "1", - "65" - ], - [ - "1364", - "1789137486", - "1789137486", - "0", - "runway/db948479946a033148b99e8cce7c328da6abe9f7.jpg", - "11", - "7", - "Look 66", - "115", - "0", - "66" - ], - [ - "1365", - "1789137486", - "1789137486", - "0", - "runway/1b409e0ad05bf1cf4e42cc0e8d1b51aaed33ada4.jpg", - "11", - "7", - "Look 67", - "116", - "0", - "67" - ], - [ - "1366", - "1789137486", - "1789137486", - "0", - "runway/9b211ba750f7874d95cf3e0c662ac4811a18ee72.jpg", - "11", - "7", - "Look 67 — Detail 1", - "117", - "1", - "67" - ], - [ - "1367", - "1789137486", - "1789137486", - "0", - "runway/0d37aed2d9db36d2ce2a5bf2a3db060039cfcfba.jpg", - "11", - "7", - "Look 68", - "118", - "0", - "68" - ], - [ - "1368", - "1789137486", - "1789137486", - "0", - "runway/037e7215c857171fa0bdd665ee0c108a0b9ae4fb.jpg", - "11", - "7", - "Look 69", - "119", - "0", - "69" - ], - [ - "1369", - "1789137486", - "1789137486", - "0", - "runway/d56b67a0e6a13e36230e0b5db5d05dc6ac69ab22.jpg", - "11", - "7", - "Look 69 — Detail 1", - "120", - "1", - "69" - ], - [ - "1370", - "1789137486", - "1789137486", - "0", - "runway/4de85d674d993073fda3c2de5a6d826ec8f361a4.jpg", - "11", - "7", - "Look 70", - "121", - "0", - "70" - ], - [ - "1371", - "1789137486", - "1789137486", - "0", - "runway/23327dff6fa08c33c23ddf2b4f8a016df4d952ea.jpg", - "11", - "7", - "Look 71", - "122", - "0", - "71" - ], - [ - "1372", - "1789137486", - "1789137486", - "0", - "runway/4588635534747bf73d940593f70dc7cdc25a78d0.jpg", - "11", - "7", - "Look 71 — Detail 1", - "123", - "1", - "71" - ], - [ - "1373", - "1789137486", - "1789137486", - "0", - "runway/2fa23b4d2a724ccef39aced62826b037b6d536d7.jpg", - "11", - "7", - "Look 71 — Detail 2", - "124", - "1", - "71" - ], - [ - "1374", - "1789137486", - "1789137486", - "0", - "runway/edc9322c5563bdf41ebf016ead0b7da4f5470a32.jpg", - "11", - "7", - "Look 72", - "125", - "0", - "72" - ], - [ - "1375", - "1789137486", - "1789137486", - "0", - "runway/91ec7bcd74710fd8937d4ccb0e5f22caa42d1b3c.jpg", - "11", - "7", - "Look 73", - "126", - "0", - "73" - ], - [ - "1376", - "1789137486", - "1789137486", - "0", - "runway/affb3a4094a7375ac54e232929950045523c0ac8.jpg", - "11", - "7", - "Look 74", - "127", - "0", - "74" - ], - [ - "1377", - "1789137486", - "1789137486", - "0", - "runway/dae22c7d8a7e5299b4e9dd2989457ad3088a5519.jpg", - "11", - "7", - "Look 75", - "128", - "0", - "75" - ], - [ - "1378", - "1789137486", - "1789137486", - "0", - "runway/92dbf7d866bdc102df3b05c63662e6f39246fa75.jpg", - "11", - "7", - "Look 75 — Detail 1", - "129", - "1", - "75" - ], - [ - "1379", - "1789137486", - "1789137486", - "0", - "runway/269e8e88f696f6544719c4892e2253c6833ae408.jpg", - "11", - "7", - "Look 76", - "130", - "0", - "76" - ], - [ - "1380", - "1789137486", - "1789137486", - "0", - "runway/907234f8c62097248fc2803a829a4e3609209fde.jpg", - "11", - "7", - "Look 77", - "131", - "0", - "77" - ], - [ - "1381", - "1789137486", - "1789137486", - "0", - "runway/d66ac419c322e73cea9ed128764d284ec9b003c5.jpg", - "11", - "7", - "Look 77 — Detail 1", - "132", - "1", - "77" - ], - [ - "1382", - "1789137486", - "1789137486", - "0", - "runway/187e6cdf1b9d89586721dbcf1d2689aed62765ef.jpg", - "11", - "7", - "Look 78", - "133", - "0", - "78" - ], - [ - "1383", - "1789137486", - "1789137486", - "0", - "runway/1bba9717e6050f8b692a5586abc5ef84aff06b7e.jpg", - "11", - "7", - "Look 79", - "134", - "0", - "79" - ], - [ - "1384", - "1789137486", - "1789137486", - "0", - "runway/fdd641605d1a5ec3f2455bc3c20ac759f6d97aa3.jpg", - "11", - "7", - "Look 79 — Detail 1", - "135", - "1", - "79" - ], - [ - "1385", - "1789137486", - "1789137486", - "0", - "runway/2a8e005c98c85dc34b292c7c804ecd8ba5e5def8.jpg", - "11", - "7", - "Look 80", - "136", - "0", - "80" - ], - [ - "1386", - "1789137486", - "1789137486", - "0", - "runway/517f86b868edb0c4baf7823a083b00f2c2f484b1.jpg", - "11", - "7", - "Look 81", - "137", - "0", - "81" - ], - [ - "1387", - "1789137486", - "1789137486", - "0", - "runway/22ea382fd35c44ea1047a60843b2e7654bad6b50.jpg", - "11", - "7", - "Look 81 — Detail 1", - "138", - "1", - "81" - ], - [ - "1388", - "1789137486", - "1789137486", - "0", - "runway/0052e8407022d800dfa4d823048b152b641f17f2.jpg", - "11", - "7", - "Look 82", - "139", - "0", - "82" - ], - [ - "1389", - "1789137486", - "1789137486", - "0", - "runway/3b9cd4b69988cf2bdcd72edf5b5a32237279ad50.jpg", - "11", - "7", - "Look 83", - "140", - "0", - "83" - ], - [ - "1390", - "1789137486", - "1789137486", - "0", - "runway/21e5767b89a249ddb7847d4074cb5d522c0ea13e.jpg", - "11", - "7", - "Look 83 — Detail 1", - "141", - "1", - "83" - ], - [ - "1391", - "1789137486", - "1789137486", - "0", - "runway/a92e0d1d9dcac9c11c0c4159776895eece8baf95.jpg", - "12", - "7", - "Look 1", - "1", - "0", - "1" - ], - [ - "1392", - "1789137486", - "1789137486", - "0", - "runway/d15f5106274a3dd195e0f8a05be6de0eb2ddb0b6.jpg", - "12", - "7", - "Look 2", - "2", - "0", - "2" - ], - [ - "1393", - "1789137486", - "1789137486", - "0", - "runway/e67ee23bd6f427953143dbf7d3ec3280f22a0b7e.jpg", - "12", - "7", - "Look 3", - "3", - "0", - "3" - ], - [ - "1394", - "1789137486", - "1789137486", - "0", - "runway/2252041dfb2aeff50d84c215d0bf92a620939bad.jpg", - "12", - "7", - "Look 4", - "4", - "0", - "4" - ], - [ - "1395", - "1789137486", - "1789137486", - "0", - "runway/8b0b1ad42a092b8ba107052759f72dd5eef7992e.jpg", - "12", - "7", - "Look 5", - "5", - "0", - "5" - ], - [ - "1396", - "1789137486", - "1789137486", - "0", - "runway/391a957ccf6f82d1681c7d7f5dd94269e5ed0e9d.jpg", - "12", - "7", - "Look 6", - "6", - "0", - "6" - ], - [ - "1397", - "1789137486", - "1789137486", - "0", - "runway/a47f8ec4bc50496e91d331470438e5407e31918d.jpg", - "12", - "7", - "Look 7", - "7", - "0", - "7" - ], - [ - "1398", - "1789137486", - "1789137486", - "0", - "runway/7d7061624c87ce00e38d25b9983d78b547a25ff5.jpg", - "12", - "7", - "Look 8", - "8", - "0", - "8" - ], - [ - "1399", - "1789137486", - "1789137486", - "0", - "runway/d0b154606bf9111d3a84351522f78be0b335c408.jpg", - "12", - "7", - "Look 9", - "9", - "0", - "9" - ], - [ - "1400", - "1789137486", - "1789137486", - "0", - "runway/be96d6a41c4b1b9323c366e16de249666a8a2acf.jpg", - "12", - "7", - "Look 10", - "10", - "0", - "10" - ], - [ - "1401", - "1789137486", - "1789137486", - "0", - "runway/98aba15213b7f9297c5d2a3f39b4e6e4e7548886.jpg", - "12", - "7", - "Look 11", - "11", - "0", - "11" - ], - [ - "1402", - "1789137486", - "1789137486", - "0", - "runway/a0ac5aac71d09ae1b88fb376a27950de6e33179b.jpg", - "12", - "7", - "Look 12", - "12", - "0", - "12" - ], - [ - "1403", - "1789137486", - "1789137486", - "0", - "runway/621196b1040005a40b6a5781b6f6cb4c049fe714.jpg", - "12", - "7", - "Look 13", - "13", - "0", - "13" - ], - [ - "1404", - "1789137486", - "1789137486", - "0", - "runway/c5da1b74fc4592eec3226ce335191538144f9808.jpg", - "12", - "7", - "Look 14", - "14", - "0", - "14" - ], - [ - "1405", - "1789137486", - "1789137486", - "0", - "runway/d87f71e3d0f5c0cb4681a925395a444f0e8cac2d.jpg", - "12", - "7", - "Look 15", - "15", - "0", - "15" - ], - [ - "1406", - "1789137486", - "1789137486", - "0", - "runway/2506b4883aa9a4e4061a38b5baef4ac862313a5e.jpg", - "12", - "7", - "Look 16", - "16", - "0", - "16" - ], - [ - "1407", - "1789137486", - "1789137486", - "0", - "runway/773d16823b1ef6bcc7c47b13ef0e4719a45019ec.jpg", - "12", - "7", - "Look 17", - "17", - "0", - "17" - ], - [ - "1408", - "1789137486", - "1789137486", - "0", - "runway/cbe882bf8bf3489def85b538d01bdda8a311f3d9.jpg", - "12", - "7", - "Look 18", - "18", - "0", - "18" - ], - [ - "1409", - "1789137486", - "1789137486", - "0", - "runway/3b84351a00f34c071e39e3e5f24e6aad58c4eedd.jpg", - "12", - "7", - "Look 19", - "19", - "0", - "19" - ], - [ - "1410", - "1789137486", - "1789137486", - "0", - "runway/d6715a30518f668837b514d02afcb46fcf3bde7f.jpg", - "12", - "7", - "Look 20", - "20", - "0", - "20" + null, + null, + null ], [ "1411", @@ -12612,8 +15136,779 @@ "7", "Look 21", "21", + "21", "0", - "21" + null, + null, + null + ], + [ + "1363", + "1789137486", + "1789137486", + "0", + "runway/4a3e58e4e6f0ff0d2f1235bdb3914e4732689f1c.jpg", + "11", + "7", + "Look 65 — Detail 2", + "114", + "65", + "1", + null, + null, + null + ], + [ + "1364", + "1789137486", + "1789137486", + "0", + "runway/db948479946a033148b99e8cce7c328da6abe9f7.jpg", + "11", + "7", + "Look 66", + "115", + "66", + "0", + null, + null, + null + ], + [ + "1365", + "1789137486", + "1789137486", + "0", + "runway/1b409e0ad05bf1cf4e42cc0e8d1b51aaed33ada4.jpg", + "11", + "7", + "Look 67", + "116", + "67", + "0", + null, + null, + null + ], + [ + "1366", + "1789137486", + "1789137486", + "0", + "runway/9b211ba750f7874d95cf3e0c662ac4811a18ee72.jpg", + "11", + "7", + "Look 67 — Detail 1", + "117", + "67", + "1", + null, + null, + null + ], + [ + "1367", + "1789137486", + "1789137486", + "0", + "runway/0d37aed2d9db36d2ce2a5bf2a3db060039cfcfba.jpg", + "11", + "7", + "Look 68", + "118", + "68", + "0", + null, + null, + null + ], + [ + "1368", + "1789137486", + "1789137486", + "0", + "runway/037e7215c857171fa0bdd665ee0c108a0b9ae4fb.jpg", + "11", + "7", + "Look 69", + "119", + "69", + "0", + null, + null, + null + ], + [ + "1369", + "1789137486", + "1789137486", + "0", + "runway/d56b67a0e6a13e36230e0b5db5d05dc6ac69ab22.jpg", + "11", + "7", + "Look 69 — Detail 1", + "120", + "69", + "1", + null, + null, + null + ], + [ + "1370", + "1789137486", + "1789137486", + "0", + "runway/4de85d674d993073fda3c2de5a6d826ec8f361a4.jpg", + "11", + "7", + "Look 70", + "121", + "70", + "0", + null, + null, + null + ], + [ + "1371", + "1789137486", + "1789137486", + "0", + "runway/23327dff6fa08c33c23ddf2b4f8a016df4d952ea.jpg", + "11", + "7", + "Look 71", + "122", + "71", + "0", + null, + null, + null + ], + [ + "1372", + "1789137486", + "1789137486", + "0", + "runway/4588635534747bf73d940593f70dc7cdc25a78d0.jpg", + "11", + "7", + "Look 71 — Detail 1", + "123", + "71", + "1", + null, + null, + null + ], + [ + "1373", + "1789137486", + "1789137486", + "0", + "runway/2fa23b4d2a724ccef39aced62826b037b6d536d7.jpg", + "11", + "7", + "Look 71 — Detail 2", + "124", + "71", + "1", + null, + null, + null + ], + [ + "1374", + "1789137486", + "1789137486", + "0", + "runway/edc9322c5563bdf41ebf016ead0b7da4f5470a32.jpg", + "11", + "7", + "Look 72", + "125", + "72", + "0", + null, + null, + null + ], + [ + "1375", + "1789137486", + "1789137486", + "0", + "runway/91ec7bcd74710fd8937d4ccb0e5f22caa42d1b3c.jpg", + "11", + "7", + "Look 73", + "126", + "73", + "0", + null, + null, + null + ], + [ + "1376", + "1789137486", + "1789137486", + "0", + "runway/affb3a4094a7375ac54e232929950045523c0ac8.jpg", + "11", + "7", + "Look 74", + "127", + "74", + "0", + null, + null, + null + ], + [ + "1377", + "1789137486", + "1789137486", + "0", + "runway/dae22c7d8a7e5299b4e9dd2989457ad3088a5519.jpg", + "11", + "7", + "Look 75", + "128", + "75", + "0", + null, + null, + null + ], + [ + "1378", + "1789137486", + "1789137486", + "0", + "runway/92dbf7d866bdc102df3b05c63662e6f39246fa75.jpg", + "11", + "7", + "Look 75 — Detail 1", + "129", + "75", + "1", + null, + null, + null + ], + [ + "1379", + "1789137486", + "1789137486", + "0", + "runway/269e8e88f696f6544719c4892e2253c6833ae408.jpg", + "11", + "7", + "Look 76", + "130", + "76", + "0", + null, + null, + null + ], + [ + "1380", + "1789137486", + "1789137486", + "0", + "runway/907234f8c62097248fc2803a829a4e3609209fde.jpg", + "11", + "7", + "Look 77", + "131", + "77", + "0", + null, + null, + null + ], + [ + "1381", + "1789137486", + "1789137486", + "0", + "runway/d66ac419c322e73cea9ed128764d284ec9b003c5.jpg", + "11", + "7", + "Look 77 — Detail 1", + "132", + "77", + "1", + null, + null, + null + ], + [ + "1382", + "1789137486", + "1789137486", + "0", + "runway/187e6cdf1b9d89586721dbcf1d2689aed62765ef.jpg", + "11", + "7", + "Look 78", + "133", + "78", + "0", + null, + null, + null + ], + [ + "1383", + "1789137486", + "1789137486", + "0", + "runway/1bba9717e6050f8b692a5586abc5ef84aff06b7e.jpg", + "11", + "7", + "Look 79", + "134", + "79", + "0", + null, + null, + null + ], + [ + "1384", + "1789137486", + "1789137486", + "0", + "runway/fdd641605d1a5ec3f2455bc3c20ac759f6d97aa3.jpg", + "11", + "7", + "Look 79 — Detail 1", + "135", + "79", + "1", + null, + null, + null + ], + [ + "1385", + "1789137486", + "1789137486", + "0", + "runway/2a8e005c98c85dc34b292c7c804ecd8ba5e5def8.jpg", + "11", + "7", + "Look 80", + "136", + "80", + "0", + null, + null, + null + ], + [ + "1386", + "1789137486", + "1789137486", + "0", + "runway/517f86b868edb0c4baf7823a083b00f2c2f484b1.jpg", + "11", + "7", + "Look 81", + "137", + "81", + "0", + null, + null, + null + ], + [ + "1387", + "1789137486", + "1789137486", + "0", + "runway/22ea382fd35c44ea1047a60843b2e7654bad6b50.jpg", + "11", + "7", + "Look 81 — Detail 1", + "138", + "81", + "1", + null, + null, + null + ], + [ + "1388", + "1789137486", + "1789137486", + "0", + "runway/0052e8407022d800dfa4d823048b152b641f17f2.jpg", + "11", + "7", + "Look 82", + "139", + "82", + "0", + null, + null, + null + ], + [ + "1389", + "1789137486", + "1789137486", + "0", + "runway/3b9cd4b69988cf2bdcd72edf5b5a32237279ad50.jpg", + "11", + "7", + "Look 83", + "140", + "83", + "0", + null, + null, + null + ], + [ + "1390", + "1789137486", + "1789137486", + "0", + "runway/21e5767b89a249ddb7847d4074cb5d522c0ea13e.jpg", + "11", + "7", + "Look 83 — Detail 1", + "141", + "83", + "1", + null, + null, + null + ], + [ + "1391", + "1789137486", + "1789137486", + "0", + "runway/a92e0d1d9dcac9c11c0c4159776895eece8baf95.jpg", + "12", + "7", + "Look 1", + "1", + "1", + "0", + null, + null, + null + ], + [ + "1392", + "1789137486", + "1789137486", + "0", + "runway/d15f5106274a3dd195e0f8a05be6de0eb2ddb0b6.jpg", + "12", + "7", + "Look 2", + "2", + "2", + "0", + null, + null, + null + ], + [ + "1393", + "1789137486", + "1789137486", + "0", + "runway/e67ee23bd6f427953143dbf7d3ec3280f22a0b7e.jpg", + "12", + "7", + "Look 3", + "3", + "3", + "0", + null, + null, + null + ], + [ + "1394", + "1789137486", + "1789137486", + "0", + "runway/2252041dfb2aeff50d84c215d0bf92a620939bad.jpg", + "12", + "7", + "Look 4", + "4", + "4", + "0", + null, + null, + null + ], + [ + "1395", + "1789137486", + "1789137486", + "0", + "runway/8b0b1ad42a092b8ba107052759f72dd5eef7992e.jpg", + "12", + "7", + "Look 5", + "5", + "5", + "0", + null, + null, + null + ], + [ + "1396", + "1789137486", + "1789137486", + "0", + "runway/391a957ccf6f82d1681c7d7f5dd94269e5ed0e9d.jpg", + "12", + "7", + "Look 6", + "6", + "6", + "0", + null, + null, + null + ], + [ + "1397", + "1789137486", + "1789137486", + "0", + "runway/a47f8ec4bc50496e91d331470438e5407e31918d.jpg", + "12", + "7", + "Look 7", + "7", + "7", + "0", + null, + null, + null + ], + [ + "1398", + "1789137486", + "1789137486", + "0", + "runway/7d7061624c87ce00e38d25b9983d78b547a25ff5.jpg", + "12", + "7", + "Look 8", + "8", + "8", + "0", + null, + null, + null + ], + [ + "1399", + "1789137486", + "1789137486", + "0", + "runway/d0b154606bf9111d3a84351522f78be0b335c408.jpg", + "12", + "7", + "Look 9", + "9", + "9", + "0", + null, + null, + null + ], + [ + "1400", + "1789137486", + "1789137486", + "0", + "runway/be96d6a41c4b1b9323c366e16de249666a8a2acf.jpg", + "12", + "7", + "Look 10", + "10", + "10", + "0", + null, + null, + null + ], + [ + "1401", + "1789137486", + "1789137486", + "0", + "runway/98aba15213b7f9297c5d2a3f39b4e6e4e7548886.jpg", + "12", + "7", + "Look 11", + "11", + "11", + "0", + null, + null, + null + ], + [ + "1402", + "1789137486", + "1789137486", + "0", + "runway/a0ac5aac71d09ae1b88fb376a27950de6e33179b.jpg", + "12", + "7", + "Look 12", + "12", + "12", + "0", + null, + null, + null + ], + [ + "1403", + "1789137486", + "1789137486", + "0", + "runway/621196b1040005a40b6a5781b6f6cb4c049fe714.jpg", + "12", + "7", + "Look 13", + "13", + "13", + "0", + null, + null, + null + ], + [ + "1404", + "1789137486", + "1789137486", + "0", + "runway/c5da1b74fc4592eec3226ce335191538144f9808.jpg", + "12", + "7", + "Look 14", + "14", + "14", + "0", + null, + null, + null + ], + [ + "1405", + "1789137486", + "1789137486", + "0", + "runway/d87f71e3d0f5c0cb4681a925395a444f0e8cac2d.jpg", + "12", + "7", + "Look 15", + "15", + "15", + "0", + null, + null, + null + ], + [ + "1406", + "1789137486", + "1789137486", + "0", + "runway/2506b4883aa9a4e4061a38b5baef4ac862313a5e.jpg", + "12", + "7", + "Look 16", + "16", + "16", + "0", + null, + null, + null + ], + [ + "1407", + "1789137486", + "1789137486", + "0", + "runway/773d16823b1ef6bcc7c47b13ef0e4719a45019ec.jpg", + "12", + "7", + "Look 17", + "17", + "17", + "0", + null, + null, + null + ], + [ + "1408", + "1789137486", + "1789137486", + "0", + "runway/cbe882bf8bf3489def85b538d01bdda8a311f3d9.jpg", + "12", + "7", + "Look 18", + "18", + "18", + "0", + null, + null, + null + ], + [ + "1409", + "1789137486", + "1789137486", + "0", + "runway/3b84351a00f34c071e39e3e5f24e6aad58c4eedd.jpg", + "12", + "7", + "Look 19", + "19", + "19", + "0", + null, + null, + null + ], + [ + "1410", + "1789137486", + "1789137486", + "0", + "runway/d6715a30518f668837b514d02afcb46fcf3bde7f.jpg", + "12", + "7", + "Look 20", + "20", + "20", + "0", + null, + null, + null ], [ "1412", @@ -12625,8 +15920,11 @@ "7", "Look 22", "22", + "22", "0", - "22" + null, + null, + null ], [ "1413", @@ -12638,8 +15936,11 @@ "7", "Look 23", "23", + "23", "0", - "23" + null, + null, + null ], [ "1414", @@ -12651,8 +15952,11 @@ "7", "Look 24", "24", + "24", "0", - "24" + null, + null, + null ], [ "1415", @@ -12664,8 +15968,11 @@ "7", "Look 25", "25", + "25", "0", - "25" + null, + null, + null ], [ "1416", @@ -12677,8 +15984,11 @@ "7", "Look 26", "26", + "26", "0", - "26" + null, + null, + null ], [ "1417", @@ -12690,8 +16000,11 @@ "7", "Look 27", "27", + "27", "0", - "27" + null, + null, + null ], [ "1418", @@ -12703,8 +16016,11 @@ "7", "Look 28", "28", + "28", "0", - "28" + null, + null, + null ], [ "1419", @@ -12716,8 +16032,11 @@ "7", "Look 29", "29", + "29", "0", - "29" + null, + null, + null ], [ "1420", @@ -12729,8 +16048,11 @@ "7", "Look 30", "30", + "30", "0", - "30" + null, + null, + null ], [ "1421", @@ -12742,8 +16064,11 @@ "7", "Look 31", "31", + "31", "0", - "31" + null, + null, + null ], [ "1422", @@ -12755,8 +16080,11 @@ "7", "Look 32", "32", + "32", "0", - "32" + null, + null, + null ], [ "1423", @@ -12768,8 +16096,11 @@ "7", "Look 33", "33", + "33", "0", - "33" + null, + null, + null ], [ "1424", @@ -12781,8 +16112,11 @@ "7", "Look 34", "34", + "34", "0", - "34" + null, + null, + null ], [ "1425", @@ -12794,8 +16128,11 @@ "7", "Look 35", "35", + "35", "0", - "35" + null, + null, + null ], [ "1426", @@ -12807,8 +16144,11 @@ "7", "Look 36", "36", + "36", "0", - "36" + null, + null, + null ], [ "1427", @@ -12820,8 +16160,11 @@ "7", "Look 37", "37", + "37", "0", - "37" + null, + null, + null ], [ "1428", @@ -12833,8 +16176,11 @@ "7", "Look 38", "38", + "38", "0", - "38" + null, + null, + null ], [ "1429", @@ -12846,8 +16192,11 @@ "7", "Look 1", "1", + "1", "0", - "1" + null, + null, + null ], [ "1430", @@ -12860,7 +16209,10 @@ "Look 1 — Detail 1", "2", "1", - "1" + "1", + null, + null, + null ], [ "1431", @@ -12872,8 +16224,11 @@ "7", "Look 2", "3", + "2", "0", - "2" + null, + null, + null ], [ "1432", @@ -12885,8 +16240,11 @@ "7", "Look 2 — Detail 1", "4", + "2", "1", - "2" + null, + null, + null ], [ "1433", @@ -12898,8 +16256,11 @@ "7", "Look 3", "5", + "3", "0", - "3" + null, + null, + null ], [ "1434", @@ -12911,8 +16272,11 @@ "7", "Look 3 — Detail 1", "6", + "3", "1", - "3" + null, + null, + null ], [ "1435", @@ -12924,8 +16288,11 @@ "7", "Look 4", "7", + "4", "0", - "4" + null, + null, + null ], [ "1436", @@ -12937,8 +16304,11 @@ "7", "Look 4 — Detail 1", "8", + "4", "1", - "4" + null, + null, + null ], [ "1437", @@ -12950,8 +16320,11 @@ "7", "Look 5", "9", + "5", "0", - "5" + null, + null, + null ], [ "1438", @@ -12963,8 +16336,11 @@ "7", "Look 5 — Detail 1", "10", + "5", "1", - "5" + null, + null, + null ], [ "1439", @@ -12976,8 +16352,11 @@ "7", "Look 6", "11", + "6", "0", - "6" + null, + null, + null ], [ "1440", @@ -12989,8 +16368,11 @@ "7", "Look 6 — Detail 1", "12", + "6", "1", - "6" + null, + null, + null ], [ "1441", @@ -13002,8 +16384,11 @@ "7", "Look 7", "13", + "7", "0", - "7" + null, + null, + null ], [ "1442", @@ -13015,8 +16400,11 @@ "7", "Look 7 — Detail 1", "14", + "7", "1", - "7" + null, + null, + null ], [ "1443", @@ -13028,8 +16416,11 @@ "7", "Look 8", "15", + "8", "0", - "8" + null, + null, + null ], [ "1444", @@ -13041,8 +16432,11 @@ "7", "Look 8 — Detail 1", "16", + "8", "1", - "8" + null, + null, + null ], [ "1445", @@ -13054,8 +16448,11 @@ "7", "Look 9", "17", + "9", "0", - "9" + null, + null, + null ], [ "1446", @@ -13067,8 +16464,11 @@ "7", "Look 9 — Detail 1", "18", + "9", "1", - "9" + null, + null, + null ], [ "1447", @@ -13080,8 +16480,11 @@ "7", "Look 10", "19", + "10", "0", - "10" + null, + null, + null ], [ "1448", @@ -13093,8 +16496,11 @@ "7", "Look 10 — Detail 1", "20", + "10", "1", - "10" + null, + null, + null ], [ "1449", @@ -13106,8 +16512,11 @@ "7", "Look 11", "21", + "11", "0", - "11" + null, + null, + null ], [ "1450", @@ -13119,8 +16528,11 @@ "7", "Look 11 — Detail 1", "22", + "11", "1", - "11" + null, + null, + null ], [ "1451", @@ -13132,8 +16544,11 @@ "7", "Look 12", "23", + "12", "0", - "12" + null, + null, + null ], [ "1452", @@ -13145,8 +16560,11 @@ "7", "Look 12 — Detail 1", "24", + "12", "1", - "12" + null, + null, + null ], [ "1453", @@ -13158,8 +16576,11 @@ "7", "Look 13", "25", + "13", "0", - "13" + null, + null, + null ], [ "1454", @@ -13171,8 +16592,11 @@ "7", "Look 13 — Detail 1", "26", + "13", "1", - "13" + null, + null, + null ], [ "1455", @@ -13184,8 +16608,11 @@ "7", "Look 14", "27", + "14", "0", - "14" + null, + null, + null ], [ "1456", @@ -13197,8 +16624,11 @@ "7", "Look 14 — Detail 1", "28", + "14", "1", - "14" + null, + null, + null ], [ "1457", @@ -13210,8 +16640,11 @@ "7", "Look 15", "29", + "15", "0", - "15" + null, + null, + null ], [ "1458", @@ -13223,8 +16656,11 @@ "7", "Look 15 — Detail 1", "30", + "15", "1", - "15" + null, + null, + null ], [ "1459", @@ -13236,8 +16672,11 @@ "7", "Look 16", "31", + "16", "0", - "16" + null, + null, + null ], [ "1460", @@ -13249,8 +16688,11 @@ "7", "Look 16 — Detail 1", "32", + "16", "1", - "16" + null, + null, + null ], [ "1461", @@ -13262,8 +16704,11 @@ "7", "Look 17", "33", + "17", "0", - "17" + null, + null, + null ], [ "1462", @@ -13275,8 +16720,11 @@ "7", "Look 17 — Detail 1", "34", + "17", "1", - "17" + null, + null, + null ], [ "1463", @@ -13288,8 +16736,11 @@ "7", "Look 18", "35", + "18", "0", - "18" + null, + null, + null ], [ "1464", @@ -13301,8 +16752,11 @@ "7", "Look 18 — Detail 1", "36", + "18", "1", - "18" + null, + null, + null ], [ "1465", @@ -13314,8 +16768,11 @@ "7", "Look 19", "37", + "19", "0", - "19" + null, + null, + null ], [ "1466", @@ -13327,8 +16784,11 @@ "7", "Look 19 — Detail 1", "38", + "19", "1", - "19" + null, + null, + null ], [ "1467", @@ -13340,8 +16800,11 @@ "7", "Look 20", "39", + "20", "0", - "20" + null, + null, + null ], [ "1468", @@ -13353,8 +16816,11 @@ "7", "Look 20 — Detail 1", "40", + "20", "1", - "20" + null, + null, + null ], [ "1469", @@ -13366,8 +16832,11 @@ "7", "Look 21", "41", + "21", "0", - "21" + null, + null, + null ], [ "1470", @@ -13379,8 +16848,11 @@ "7", "Look 21 — Detail 1", "42", + "21", "1", - "21" + null, + null, + null ], [ "1471", @@ -13392,8 +16864,11 @@ "7", "Look 22", "43", + "22", "0", - "22" + null, + null, + null ], [ "1472", @@ -13405,8 +16880,11 @@ "7", "Look 22 — Detail 1", "44", + "22", "1", - "22" + null, + null, + null ], [ "1473", @@ -13418,8 +16896,11 @@ "7", "Look 23", "45", + "23", "0", - "23" + null, + null, + null ], [ "1474", @@ -13431,8 +16912,11 @@ "7", "Look 23 — Detail 1", "46", + "23", "1", - "23" + null, + null, + null ], [ "1475", @@ -13444,8 +16928,11 @@ "7", "Look 24", "47", + "24", "0", - "24" + null, + null, + null ], [ "1476", @@ -13457,8 +16944,11 @@ "7", "Look 24 — Detail 1", "48", + "24", "1", - "24" + null, + null, + null ], [ "1477", @@ -13470,8 +16960,11 @@ "7", "Look 25", "49", + "25", "0", - "25" + null, + null, + null ], [ "1478", @@ -13483,8 +16976,11 @@ "7", "Look 25 — Detail 1", "50", + "25", "1", - "25" + null, + null, + null ], [ "1479", @@ -13496,8 +16992,11 @@ "7", "Look 26", "51", + "26", "0", - "26" + null, + null, + null ], [ "1480", @@ -13509,8 +17008,11 @@ "7", "Look 26 — Detail 1", "52", + "26", "1", - "26" + null, + null, + null ], [ "1481", @@ -13522,8 +17024,11 @@ "7", "Look 27", "53", + "27", "0", - "27" + null, + null, + null ], [ "1482", @@ -13535,8 +17040,11 @@ "7", "Look 27 — Detail 1", "54", + "27", "1", - "27" + null, + null, + null ], [ "1483", @@ -13548,8 +17056,11 @@ "7", "Look 28", "55", + "28", "0", - "28" + null, + null, + null ], [ "1484", @@ -13561,8 +17072,11 @@ "7", "Look 28 — Detail 1", "56", + "28", "1", - "28" + null, + null, + null ], [ "1485", @@ -13574,8 +17088,11 @@ "7", "Look 29", "57", + "29", "0", - "29" + null, + null, + null ], [ "1486", @@ -13587,8 +17104,11 @@ "7", "Look 29 — Detail 1", "58", + "29", "1", - "29" + null, + null, + null ], [ "1487", @@ -13600,8 +17120,11 @@ "7", "Look 30", "59", + "30", "0", - "30" + null, + null, + null ], [ "1488", @@ -13613,8 +17136,11 @@ "7", "Look 30 — Detail 1", "60", + "30", "1", - "30" + null, + null, + null ], [ "1489", @@ -13626,8 +17152,11 @@ "7", "Look 31", "61", + "31", "0", - "31" + null, + null, + null ], [ "1490", @@ -13639,8 +17168,11 @@ "7", "Look 31 — Detail 1", "62", + "31", "1", - "31" + null, + null, + null ], [ "1491", @@ -13652,8 +17184,11 @@ "7", "Look 32", "63", + "32", "0", - "32" + null, + null, + null ], [ "1492", @@ -13665,8 +17200,11 @@ "7", "Look 32 — Detail 1", "64", + "32", "1", - "32" + null, + null, + null ], [ "1493", @@ -13678,8 +17216,11 @@ "7", "Look 33", "65", + "33", "0", - "33" + null, + null, + null ], [ "1494", @@ -13691,8 +17232,11 @@ "7", "Look 33 — Detail 1", "66", + "33", "1", - "33" + null, + null, + null ], [ "1495", @@ -13704,8 +17248,11 @@ "7", "Look 34", "67", + "34", "0", - "34" + null, + null, + null ], [ "1496", @@ -13717,8 +17264,11 @@ "7", "Look 34 — Detail 1", "68", + "34", "1", - "34" + null, + null, + null ], [ "1497", @@ -13730,8 +17280,11 @@ "7", "Look 35", "69", + "35", "0", - "35" + null, + null, + null ], [ "1498", @@ -13743,8 +17296,11 @@ "7", "Look 35 — Detail 1", "70", + "35", "1", - "35" + null, + null, + null ], [ "1499", @@ -13756,8 +17312,11 @@ "7", "Look 36", "71", + "36", "0", - "36" + null, + null, + null ], [ "1500", @@ -13769,8 +17328,11 @@ "7", "Look 36 — Detail 1", "72", + "36", "1", - "36" + null, + null, + null ], [ "1501", @@ -13782,8 +17344,11 @@ "7", "Look 37", "73", + "37", "0", - "37" + null, + null, + null ], [ "1502", @@ -13795,8 +17360,11 @@ "7", "Look 37 — Detail 1", "74", + "37", "1", - "37" + null, + null, + null ], [ "1503", @@ -13808,8 +17376,11 @@ "7", "Look 38", "75", + "38", "0", - "38" + null, + null, + null ], [ "1504", @@ -13821,8 +17392,11 @@ "7", "Look 38 — Detail 1", "76", + "38", "1", - "38" + null, + null, + null ], [ "1505", @@ -13834,8 +17408,11 @@ "7", "Look 39", "77", + "39", "0", - "39" + null, + null, + null ], [ "1506", @@ -13847,8 +17424,11 @@ "7", "Look 39 — Detail 1", "78", + "39", "1", - "39" + null, + null, + null ], [ "1507", @@ -13860,8 +17440,11 @@ "7", "Look 40", "79", + "40", "0", - "40" + null, + null, + null ], [ "1508", @@ -13873,8 +17456,11 @@ "7", "Look 40 — Detail 1", "80", + "40", "1", - "40" + null, + null, + null ], [ "1509", @@ -13886,8 +17472,11 @@ "7", "Look 41", "81", + "41", "0", - "41" + null, + null, + null ], [ "1510", @@ -13899,8 +17488,11 @@ "7", "Look 41 — Detail 1", "82", + "41", "1", - "41" + null, + null, + null ], [ "1511", @@ -13912,8 +17504,11 @@ "7", "Look 42", "83", + "42", "0", - "42" + null, + null, + null ], [ "1512", @@ -13925,8 +17520,11 @@ "7", "Look 42 — Detail 1", "84", + "42", "1", - "42" + null, + null, + null ], [ "1513", @@ -13938,8 +17536,11 @@ "7", "Look 43", "85", + "43", "0", - "43" + null, + null, + null ], [ "1514", @@ -13951,8 +17552,11 @@ "7", "Look 43 — Detail 1", "86", + "43", "1", - "43" + null, + null, + null ], [ "1515", @@ -13964,8 +17568,11 @@ "7", "Look 44", "87", + "44", "0", - "44" + null, + null, + null ], [ "1516", @@ -13977,8 +17584,11 @@ "7", "Look 44 — Detail 1", "88", + "44", "1", - "44" + null, + null, + null ], [ "1517", @@ -13990,8 +17600,11 @@ "7", "Look 45", "89", + "45", "0", - "45" + null, + null, + null ], [ "1518", @@ -14003,8 +17616,11 @@ "7", "Look 45 — Detail 1", "90", + "45", "1", - "45" + null, + null, + null ], [ "1519", @@ -14016,8 +17632,11 @@ "7", "Look 46", "91", + "46", "0", - "46" + null, + null, + null ], [ "1520", @@ -14029,8 +17648,11 @@ "7", "Look 46 — Detail 1", "92", + "46", "1", - "46" + null, + null, + null ], [ "1521", @@ -14042,8 +17664,11 @@ "7", "Look 47", "93", + "47", "0", - "47" + null, + null, + null ], [ "1522", @@ -14055,8 +17680,11 @@ "7", "Look 47 — Detail 1", "94", + "47", "1", - "47" + null, + null, + null ], [ "1523", @@ -14068,8 +17696,11 @@ "7", "Look 48", "95", + "48", "0", - "48" + null, + null, + null ], [ "1524", @@ -14081,8 +17712,11 @@ "7", "Look 48 — Detail 1", "96", + "48", "1", - "48" + null, + null, + null ], [ "1525", @@ -14094,8 +17728,11 @@ "7", "Look 49", "97", + "49", "0", - "49" + null, + null, + null ], [ "1526", @@ -14107,8 +17744,11 @@ "7", "Look 49 — Detail 1", "98", + "49", "1", - "49" + null, + null, + null ], [ "1527", @@ -14120,8 +17760,11 @@ "7", "Look 50", "99", + "50", "0", - "50" + null, + null, + null ], [ "1528", @@ -14133,8 +17776,11 @@ "7", "Look 50 — Detail 1", "100", + "50", "1", - "50" + null, + null, + null ], [ "1529", @@ -14146,8 +17792,11 @@ "7", "Look 51", "101", + "51", "0", - "51" + null, + null, + null ], [ "1530", @@ -14159,8 +17808,11 @@ "7", "Look 51 — Detail 1", "102", + "51", "1", - "51" + null, + null, + null ], [ "1531", @@ -14172,8 +17824,11 @@ "7", "Look 52", "103", + "52", "0", - "52" + null, + null, + null ], [ "1532", @@ -14185,8 +17840,11 @@ "7", "Look 52 — Detail 1", "104", + "52", "1", - "52" + null, + null, + null ], [ "1533", @@ -14198,8 +17856,11 @@ "7", "Look 53", "105", + "53", "0", - "53" + null, + null, + null ], [ "1534", @@ -14211,8 +17872,11 @@ "7", "Look 53 — Detail 1", "106", + "53", "1", - "53" + null, + null, + null ], [ "1535", @@ -14224,8 +17888,11 @@ "7", "Look 54", "107", + "54", "0", - "54" + null, + null, + null ], [ "1536", @@ -14237,8 +17904,11 @@ "7", "Look 54 — Detail 1", "108", + "54", "1", - "54" + null, + null, + null ], [ "1537", @@ -14250,8 +17920,11 @@ "7", "Look 55", "109", + "55", "0", - "55" + null, + null, + null ], [ "1538", @@ -14263,8 +17936,11 @@ "7", "Look 55 — Detail 1", "110", + "55", "1", - "55" + null, + null, + null ], [ "1539", @@ -14276,8 +17952,11 @@ "7", "Look 56", "111", + "56", "0", - "56" + null, + null, + null ], [ "1540", @@ -14289,8 +17968,11 @@ "7", "Look 56 — Detail 1", "112", + "56", "1", - "56" + null, + null, + null ], [ "1541", @@ -14302,8 +17984,11 @@ "7", "Look 57", "113", + "57", "0", - "57" + null, + null, + null ], [ "1542", @@ -14315,8 +18000,11 @@ "7", "Look 57 — Detail 1", "114", + "57", "1", - "57" + null, + null, + null ], [ "1543", @@ -14328,8 +18016,11 @@ "7", "Look 58", "115", + "58", "0", - "58" + null, + null, + null ], [ "1544", @@ -14341,8 +18032,11 @@ "7", "Look 58 — Detail 1", "116", + "58", "1", - "58" + null, + null, + null ], [ "1545", @@ -14354,8 +18048,11 @@ "7", "Look 1", "1", + "1", "0", - "1" + null, + null, + null ], [ "1546", @@ -14368,7 +18065,10 @@ "Look 1 — Detail 1", "2", "1", - "1" + "1", + null, + null, + null ], [ "1547", @@ -14380,8 +18080,11 @@ "7", "Look 2", "3", + "2", "0", - "2" + null, + null, + null ], [ "1548", @@ -14393,8 +18096,11 @@ "7", "Look 2 — Detail 1", "4", + "2", "1", - "2" + null, + null, + null ], [ "1549", @@ -14406,8 +18112,11 @@ "7", "Look 3", "5", + "3", "0", - "3" + null, + null, + null ], [ "1550", @@ -14419,8 +18128,11 @@ "7", "Look 3 — Detail 1", "6", + "3", "1", - "3" + null, + null, + null ], [ "1551", @@ -14432,8 +18144,11 @@ "7", "Look 4", "7", + "4", "0", - "4" + null, + null, + null ], [ "1552", @@ -14445,8 +18160,11 @@ "7", "Look 4 — Detail 1", "8", + "4", "1", - "4" + null, + null, + null ], [ "1553", @@ -14458,8 +18176,11 @@ "7", "Look 5", "9", + "5", "0", - "5" + null, + null, + null ], [ "1554", @@ -14471,8 +18192,11 @@ "7", "Look 5 — Detail 1", "10", + "5", "1", - "5" + null, + null, + null ], [ "1555", @@ -14484,8 +18208,11 @@ "7", "Look 6", "11", + "6", "0", - "6" + null, + null, + null ], [ "1556", @@ -14497,8 +18224,11 @@ "7", "Look 6 — Detail 1", "12", + "6", "1", - "6" + null, + null, + null ], [ "1557", @@ -14510,8 +18240,11 @@ "7", "Look 7", "13", + "7", "0", - "7" + null, + null, + null ], [ "1558", @@ -14523,8 +18256,11 @@ "7", "Look 7 — Detail 1", "14", + "7", "1", - "7" + null, + null, + null ], [ "1559", @@ -14536,8 +18272,11 @@ "7", "Look 8", "15", + "8", "0", - "8" + null, + null, + null ], [ "1560", @@ -14549,8 +18288,11 @@ "7", "Look 8 — Detail 1", "16", + "8", "1", - "8" + null, + null, + null ], [ "1561", @@ -14562,8 +18304,11 @@ "7", "Look 9", "17", + "9", "0", - "9" + null, + null, + null ], [ "1562", @@ -14575,8 +18320,11 @@ "7", "Look 9 — Detail 1", "18", + "9", "1", - "9" + null, + null, + null ], [ "1563", @@ -14588,8 +18336,11 @@ "7", "Look 10", "19", + "10", "0", - "10" + null, + null, + null ], [ "1564", @@ -14601,8 +18352,11 @@ "7", "Look 10 — Detail 1", "20", + "10", "1", - "10" + null, + null, + null ], [ "1565", @@ -14614,8 +18368,11 @@ "7", "Look 11", "21", + "11", "0", - "11" + null, + null, + null ], [ "1566", @@ -14627,8 +18384,11 @@ "7", "Look 11 — Detail 1", "22", + "11", "1", - "11" + null, + null, + null ], [ "1567", @@ -14640,8 +18400,11 @@ "7", "Look 12", "23", + "12", "0", - "12" + null, + null, + null ], [ "1568", @@ -14653,8 +18416,11 @@ "7", "Look 12 — Detail 1", "24", + "12", "1", - "12" + null, + null, + null ], [ "1569", @@ -14666,8 +18432,11 @@ "7", "Look 13", "25", + "13", "0", - "13" + null, + null, + null ], [ "1570", @@ -14679,8 +18448,11 @@ "7", "Look 13 — Detail 1", "26", + "13", "1", - "13" + null, + null, + null ], [ "1571", @@ -14692,8 +18464,11 @@ "7", "Look 14", "27", + "14", "0", - "14" + null, + null, + null ], [ "1572", @@ -14705,8 +18480,11 @@ "7", "Look 14 — Detail 1", "28", + "14", "1", - "14" + null, + null, + null ], [ "1573", @@ -14718,8 +18496,11 @@ "7", "Look 15", "29", + "15", "0", - "15" + null, + null, + null ], [ "1574", @@ -14731,8 +18512,11 @@ "7", "Look 15 — Detail 1", "30", + "15", "1", - "15" + null, + null, + null ], [ "1575", @@ -14744,8 +18528,11 @@ "7", "Look 16", "31", + "16", "0", - "16" + null, + null, + null ], [ "1576", @@ -14757,8 +18544,11 @@ "7", "Look 16 — Detail 1", "32", + "16", "1", - "16" + null, + null, + null ], [ "1577", @@ -14770,8 +18560,11 @@ "7", "Look 17", "33", + "17", "0", - "17" + null, + null, + null ], [ "1578", @@ -14783,8 +18576,11 @@ "7", "Look 17 — Detail 1", "34", + "17", "1", - "17" + null, + null, + null ], [ "1579", @@ -14796,8 +18592,11 @@ "7", "Look 18", "35", + "18", "0", - "18" + null, + null, + null ], [ "1580", @@ -14809,8 +18608,11 @@ "7", "Look 18 — Detail 1", "36", + "18", "1", - "18" + null, + null, + null ], [ "1581", @@ -14822,8 +18624,11 @@ "7", "Look 19", "37", + "19", "0", - "19" + null, + null, + null ], [ "1582", @@ -14835,8 +18640,11 @@ "7", "Look 19 — Detail 1", "38", + "19", "1", - "19" + null, + null, + null ], [ "1583", @@ -14848,8 +18656,11 @@ "7", "Look 20", "39", + "20", "0", - "20" + null, + null, + null ], [ "1584", @@ -14861,8 +18672,11 @@ "7", "Look 20 — Detail 1", "40", + "20", "1", - "20" + null, + null, + null ], [ "1585", @@ -14874,8 +18688,11 @@ "7", "Look 21", "41", + "21", "0", - "21" + null, + null, + null ], [ "1586", @@ -14887,8 +18704,11 @@ "7", "Look 21 — Detail 1", "42", + "21", "1", - "21" + null, + null, + null ], [ "1587", @@ -14900,8 +18720,11 @@ "7", "Look 22", "43", + "22", "0", - "22" + null, + null, + null ], [ "1588", @@ -14913,8 +18736,11 @@ "7", "Look 22 — Detail 1", "44", + "22", "1", - "22" + null, + null, + null ], [ "1589", @@ -14926,8 +18752,11 @@ "7", "Look 23", "45", + "23", "0", - "23" + null, + null, + null ], [ "1590", @@ -14939,8 +18768,11 @@ "7", "Look 23 — Detail 1", "46", + "23", "1", - "23" + null, + null, + null ], [ "1591", @@ -14952,8 +18784,11 @@ "7", "Look 24", "47", + "24", "0", - "24" + null, + null, + null ], [ "1592", @@ -14965,8 +18800,11 @@ "7", "Look 24 — Detail 1", "48", + "24", "1", - "24" + null, + null, + null ], [ "1593", @@ -14978,8 +18816,11 @@ "7", "Look 25", "49", + "25", "0", - "25" + null, + null, + null ], [ "1594", @@ -14991,8 +18832,11 @@ "7", "Look 25 — Detail 1", "50", + "25", "1", - "25" + null, + null, + null ], [ "1595", @@ -15004,8 +18848,11 @@ "7", "Look 26", "51", + "26", "0", - "26" + null, + null, + null ], [ "1596", @@ -15017,8 +18864,11 @@ "7", "Look 26 — Detail 1", "52", + "26", "1", - "26" + null, + null, + null ], [ "1597", @@ -15030,8 +18880,11 @@ "7", "Look 27", "53", + "27", "0", - "27" + null, + null, + null ], [ "1598", @@ -15043,8 +18896,11 @@ "7", "Look 27 — Detail 1", "54", + "27", "1", - "27" + null, + null, + null ], [ "1599", @@ -15056,8 +18912,11 @@ "7", "Look 28", "55", + "28", "0", - "28" + null, + null, + null ], [ "1600", @@ -15069,8 +18928,11 @@ "7", "Look 28 — Detail 1", "56", + "28", "1", - "28" + null, + null, + null ], [ "1601", @@ -15082,8 +18944,11 @@ "7", "Look 29", "57", + "29", "0", - "29" + null, + null, + null ], [ "1602", @@ -15095,8 +18960,11 @@ "7", "Look 29 — Detail 1", "58", + "29", "1", - "29" + null, + null, + null ], [ "1603", @@ -15108,8 +18976,11 @@ "7", "Look 30", "59", + "30", "0", - "30" + null, + null, + null ], [ "1604", @@ -15121,8 +18992,11 @@ "7", "Look 30 — Detail 1", "60", + "30", "1", - "30" + null, + null, + null ], [ "1605", @@ -15134,8 +19008,11 @@ "7", "Look 31", "61", + "31", "0", - "31" + null, + null, + null ], [ "1606", @@ -15147,8 +19024,11 @@ "7", "Look 31 — Detail 1", "62", + "31", "1", - "31" + null, + null, + null ], [ "1607", @@ -15160,8 +19040,11 @@ "7", "Look 32", "63", + "32", "0", - "32" + null, + null, + null ], [ "1608", @@ -15173,8 +19056,11 @@ "7", "Look 32 — Detail 1", "64", + "32", "1", - "32" + null, + null, + null ], [ "1609", @@ -15186,8 +19072,11 @@ "7", "Look 33", "65", + "33", "0", - "33" + null, + null, + null ], [ "1610", @@ -15199,8 +19088,11 @@ "7", "Look 33 — Detail 1", "66", + "33", "1", - "33" + null, + null, + null ], [ "1611", @@ -15212,8 +19104,11 @@ "7", "Look 34", "67", + "34", "0", - "34" + null, + null, + null ], [ "1612", @@ -15225,8 +19120,11 @@ "7", "Look 34 — Detail 1", "68", + "34", "1", - "34" + null, + null, + null ], [ "1613", @@ -15238,8 +19136,11 @@ "7", "Look 35", "69", + "35", "0", - "35" + null, + null, + null ], [ "1614", @@ -15251,8 +19152,11 @@ "7", "Look 35 — Detail 1", "70", + "35", "1", - "35" + null, + null, + null ], [ "1615", @@ -15264,8 +19168,11 @@ "7", "Look 36", "71", + "36", "0", - "36" + null, + null, + null ], [ "1616", @@ -15277,8 +19184,11 @@ "7", "Look 36 — Detail 1", "72", + "36", "1", - "36" + null, + null, + null ], [ "1617", @@ -15290,8 +19200,11 @@ "7", "Look 37", "73", + "37", "0", - "37" + null, + null, + null ], [ "1618", @@ -15303,8 +19216,11 @@ "7", "Look 37 — Detail 1", "74", + "37", "1", - "37" + null, + null, + null ], [ "1619", @@ -15316,8 +19232,11 @@ "7", "Look 38", "75", + "38", "0", - "38" + null, + null, + null ], [ "1620", @@ -15329,8 +19248,11 @@ "7", "Look 38 — Detail 1", "76", + "38", "1", - "38" + null, + null, + null ], [ "1621", @@ -15342,8 +19264,11 @@ "7", "Look 39", "77", + "39", "0", - "39" + null, + null, + null ], [ "1622", @@ -15355,8 +19280,11 @@ "7", "Look 39 — Detail 1", "78", + "39", "1", - "39" + null, + null, + null ], [ "1623", @@ -15368,8 +19296,11 @@ "7", "Look 40", "79", + "40", "0", - "40" + null, + null, + null ], [ "1624", @@ -15381,8 +19312,11 @@ "7", "Look 40 — Detail 1", "80", + "40", "1", - "40" + null, + null, + null ], [ "1625", @@ -15394,8 +19328,11 @@ "7", "Look 41", "81", + "41", "0", - "41" + null, + null, + null ], [ "1626", @@ -15407,8 +19344,11 @@ "7", "Look 41 — Detail 1", "82", + "41", "1", - "41" + null, + null, + null ], [ "1627", @@ -15420,8 +19360,11 @@ "7", "Look 42", "83", + "42", "0", - "42" + null, + null, + null ], [ "1628", @@ -15433,8 +19376,11 @@ "7", "Look 42 — Detail 1", "84", + "42", "1", - "42" + null, + null, + null ], [ "1629", @@ -15446,8 +19392,11 @@ "7", "Look 43", "85", + "43", "0", - "43" + null, + null, + null ], [ "1630", @@ -15459,8 +19408,11 @@ "7", "Look 43 — Detail 1", "86", + "43", "1", - "43" + null, + null, + null ], [ "1631", @@ -15472,8 +19424,11 @@ "7", "Look 44", "87", + "44", "0", - "44" + null, + null, + null ], [ "1632", @@ -15485,8 +19440,11 @@ "7", "Look 44 — Detail 1", "88", + "44", "1", - "44" + null, + null, + null ], [ "1633", @@ -15498,8 +19456,11 @@ "7", "Look 45", "89", + "45", "0", - "45" + null, + null, + null ], [ "1634", @@ -15511,8 +19472,11 @@ "7", "Look 45 — Detail 1", "90", + "45", "1", - "45" + null, + null, + null ], [ "1635", @@ -15524,8 +19488,11 @@ "7", "Look 46", "91", + "46", "0", - "46" + null, + null, + null ], [ "1636", @@ -15537,8 +19504,11 @@ "7", "Look 46 — Detail 1", "92", + "46", "1", - "46" + null, + null, + null ], [ "1637", @@ -15550,8 +19520,11 @@ "7", "Look 47", "93", + "47", "0", - "47" + null, + null, + null ], [ "1638", @@ -15563,8 +19536,11 @@ "7", "Look 47 — Detail 1", "94", + "47", "1", - "47" + null, + null, + null ], [ "1639", @@ -15576,8 +19552,11 @@ "7", "Look 48", "95", + "48", "0", - "48" + null, + null, + null ], [ "1640", @@ -15589,8 +19568,11 @@ "7", "Look 48 — Detail 1", "96", + "48", "1", - "48" + null, + null, + null ], [ "1641", @@ -15602,8 +19584,11 @@ "7", "Look 49", "97", + "49", "0", - "49" + null, + null, + null ], [ "1642", @@ -15615,8 +19600,11 @@ "7", "Look 49 — Detail 1", "98", + "49", "1", - "49" + null, + null, + null ], [ "1643", @@ -15628,8 +19616,11 @@ "7", "Look 50", "99", + "50", "0", - "50" + null, + null, + null ], [ "1644", @@ -15641,8 +19632,11 @@ "7", "Look 50 — Detail 1", "100", + "50", "1", - "50" + null, + null, + null ], [ "1645", @@ -15654,8 +19648,11 @@ "7", "Look 51", "101", + "51", "0", - "51" + null, + null, + null ], [ "1646", @@ -15667,8 +19664,11 @@ "7", "Look 51 — Detail 1", "102", + "51", "1", - "51" + null, + null, + null ], [ "1647", @@ -15680,8 +19680,11 @@ "7", "Look 52", "103", + "52", "0", - "52" + null, + null, + null ], [ "1648", @@ -15693,8 +19696,11 @@ "7", "Look 52 — Detail 1", "104", + "52", "1", - "52" + null, + null, + null ], [ "1649", @@ -15706,8 +19712,11 @@ "7", "Look 53", "105", + "53", "0", - "53" + null, + null, + null ], [ "1650", @@ -15719,8 +19728,11 @@ "7", "Look 53 — Detail 1", "106", + "53", "1", - "53" + null, + null, + null ], [ "1651", @@ -15732,8 +19744,11 @@ "7", "Look 54", "107", + "54", "0", - "54" + null, + null, + null ], [ "1652", @@ -15745,8 +19760,11 @@ "7", "Look 54 — Detail 1", "108", + "54", "1", - "54" + null, + null, + null ], [ "1653", @@ -15758,8 +19776,11 @@ "7", "Look 55", "109", + "55", "0", - "55" + null, + null, + null ], [ "1654", @@ -15771,8 +19792,11 @@ "7", "Look 55 — Detail 1", "110", + "55", "1", - "55" + null, + null, + null ], [ "1655", @@ -15784,8 +19808,11 @@ "7", "Look 56", "111", + "56", "0", - "56" + null, + null, + null ], [ "1656", @@ -15797,8 +19824,11 @@ "7", "Look 56 — Detail 1", "112", + "56", "1", - "56" + null, + null, + null ], [ "1657", @@ -15810,8 +19840,11 @@ "7", "Look 57", "113", + "57", "0", - "57" + null, + null, + null ], [ "1658", @@ -15823,8 +19856,11 @@ "7", "Look 57 — Detail 1", "114", + "57", "1", - "57" + null, + null, + null ], [ "1659", @@ -15836,8 +19872,11 @@ "7", "Look 58", "115", + "58", "0", - "58" + null, + null, + null ], [ "1660", @@ -15849,26 +19888,88 @@ "7", "Look 58 — Detail 1", "116", + "58", "1", - "58" + null, + null, + null ] ] }, { "name": "favorites", - "create": "CREATE TABLE `favorites` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `user_id` int unsigned NOT NULL,\n `target_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `target_uid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `cover` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `brand` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `kind` varchar(16) NOT NULL DEFAULT 'gallery' COMMENT 'gallery=整篇图集 / image=单张图片',\n `image_url` varchar(512) NOT NULL DEFAULT '' COMMENT 'kind=image 时这一张图的地址',\n `parent_uid` varchar(64) NOT NULL DEFAULT '' COMMENT 'kind=image 时所属图集的 uid',\n PRIMARY KEY (`id`) USING BTREE,\n UNIQUE KEY `uniq_user_target` (`user_id`,`target_uid`) USING BTREE,\n KEY `idx_user` (`user_id`) USING BTREE,\n KEY `idx_user_created` (`user_id`,`created_at`) USING BTREE,\n KEY `idx_user_kind` (`user_id`,`kind`,`created_at`)\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "created_at", - "user_id", - "target_type", - "target_uid", - "title", - "cover", - "brand", - "kind", - "image_url", - "parent_uid" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('favorites_id_seq'::regclass)" + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "user_id", + "type": "int8", + "is_nullable": false, + "is_identity": false + }, + { + "name": "target_type", + "type": "varchar", + "is_nullable": false, + "is_identity": false + }, + { + "name": "target_uid", + "type": "varchar", + "is_nullable": false, + "is_identity": false + }, + { + "name": "title", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "cover", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "brand", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "kind", + "type": "varchar", + "is_nullable": false, + "is_identity": false, + "default": "'gallery'::character varying" + }, + { + "name": "image_url", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "parent_uid", + "type": "varchar", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -15909,17 +20010,105 @@ "image", "https://toomstudio.s3.bitiful.net/runway/ff447bf8a206cab6cb458513e474874fc1cc0c16.jpg!style:high", "r002L7Kcq" + ], + [ + "4", + "1789298755", + "8", + "runway", + "r001TI3O5", + "Pre-Fall 2026", + "https://toomstudio.s3.bitiful.net/runway/2841c0fd79ae00e9e8b2c8fb2006ebecc088ab8a.jpg!style:thumb", + "Gucci", + "gallery", + "", + "" + ], + [ + "5", + "1789298799", + "8", + "runway", + "r000zAwwQ", + "Spring 2026 Ready-to-Wear", + "https://toomstudio.s3.bitiful.net/runway/a92e0d1d9dcac9c11c0c4159776895eece8baf95.jpg!style:thumb", + "Gucci", + "gallery", + "", + "" + ], + [ + "6", + "1789298800", + "8", + "runway", + "r0008CZYI", + "Resort 2027", + "https://toomstudio.s3.bitiful.net/runway/3b9b7e07916b454ba93c56b4d2edc81614101e3c.jpg!style:thumb", + "Gucci", + "gallery", + "", + "" + ], + [ + "7", + "1789298800", + "8", + "runway", + "r002L7Kcq", + "Fall 2026 Ready-to-Wear", + "https://toomstudio.s3.bitiful.net/runway/cc1924c01b84613de52e4a1409f777ad04a880b5.jpg!style:thumb", + "Gucci", + "gallery", + "", + "" + ], + [ + "8", + "1789298801", + "8", + "runway", + "r004sYho3", + "Resort 2026", + "https://toomstudio.s3.bitiful.net/runway/7a79af2f7d456b427cdb68d5330ba1b9decf5dce.jpg!style:thumb", + "Gucci", + "gallery", + "", + "" ] ] }, { "name": "histories", - "create": "CREATE TABLE `histories` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `viewed_at` int unsigned NOT NULL DEFAULT '0',\n `user_id` int unsigned NOT NULL,\n `target_uid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n PRIMARY KEY (`id`) USING BTREE,\n UNIQUE KEY `uniq_user_target` (`user_id`,`target_uid`) USING BTREE,\n KEY `idx_user` (`user_id`) USING BTREE,\n KEY `idx_user_viewed` (`user_id`,`viewed_at`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "viewed_at", - "user_id", - "target_uid" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('histories_id_seq'::regclass)" + }, + { + "name": "viewed_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "user_id", + "type": "int8", + "is_nullable": false, + "is_identity": false + }, + { + "name": "target_uid", + "type": "varchar", + "is_nullable": false, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -15930,7 +20119,7 @@ ], [ "6", - "1789193091", + "1789473110", "8", "r0008CZYI" ], @@ -15951,23 +20140,86 @@ "1789150463", "8", "r004sYho3" + ], + [ + "79", + "1789528788", + "8", + "001FkcmD" ] ] }, { "name": "ingest_jobs", - "create": "CREATE TABLE `ingest_jobs` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n `locked_at` int unsigned NOT NULL DEFAULT '0',\n `status` varchar(16) NOT NULL DEFAULT 'pending',\n `attempts` tinyint unsigned NOT NULL DEFAULT '0',\n `payload` mediumtext NOT NULL,\n `last_error` mediumtext NOT NULL,\n `kind` varchar(16) NOT NULL DEFAULT 'crawl',\n `next_attempt_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`),\n KEY `idx_status` (`status`),\n KEY `idx_status_next` (`status`,`next_attempt_at`)\n) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", "columns": [ - "id", - "created_at", - "updated_at", - "locked_at", - "status", - "attempts", - "payload", - "last_error", - "kind", - "next_attempt_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('ingest_jobs_id_seq'::regclass)" + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "locked_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "status", + "type": "varchar", + "is_nullable": false, + "is_identity": false, + "default": "'pending'::character varying" + }, + { + "name": "attempts", + "type": "int2", + "is_nullable": false, + "is_identity": false, + "default": "0" + }, + { + "name": "payload", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "last_error", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "kind", + "type": "varchar", + "is_nullable": false, + "is_identity": false, + "default": "'crawl'::character varying" + }, + { + "name": "next_attempt_at", + "type": "int8", + "is_nullable": false, + "is_identity": false, + "default": "0" + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -16570,6 +20822,18 @@ "crawl", "0" ], + [ + "56", + "1788620324", + "1788621956", + "1788621908", + "done", + "0", + "{\"kind\":\"runway\",\"brand_uid\":\"004xh65e\",\"title_en\":\"Fall 2014 Ready-to-Wear\",\"title_cn\":\"\",\"description_en\":\"\",\"description_cn\":\"\",\"year\":2014,\"season\":\"fall\",\"collection_type\":\"rtw\",\"city\":\"\",\"source_url\":\"https://www.vogue.com/fashion-shows/fall-2014-ready-to-wear/acne-studios/slideshow/collection\",\"images\":[\"https://assets.vogue.com/photos/55c6513d08298d8be21ded45/master/w_2560,c_limit/_KIM0017.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded46/master/w_2560,c_limit/_KIM0024.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded47/master/w_2560,c_limit/_KIM0032.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded48/master/w_2560,c_limit/_KIM0041.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded49/master/w_2560,c_limit/_KIM0058.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4a/master/w_2560,c_limit/_KIM0067.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4b/master/w_2560,c_limit/_KIM0075.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4c/master/w_2560,c_limit/_KIM0099.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4d/master/w_2560,c_limit/_KIM0114.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4e/master/w_2560,c_limit/_KIM0139.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4f/master/w_2560,c_limit/_KIM0152.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded50/master/w_2560,c_limit/_KIM0170.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded51/master/w_2560,c_limit/_KIM0179.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded52/master/w_2560,c_limit/_KIM0195.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded53/master/w_2560,c_limit/_KIM0205.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded54/master/w_2560,c_limit/_KIM0225.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded55/master/w_2560,c_limit/_KIM0235.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded56/master/w_2560,c_limit/_KIM0248.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded57/master/w_2560,c_limit/_KIM0258.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded58/master/w_2560,c_limit/_KIM0276.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded59/master/w_2560,c_limit/_KIM0286.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5a/master/w_2560,c_limit/_KIM0304.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5b/master/w_2560,c_limit/_KIM0320.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5c/master/w_2560,c_limit/_KIM0329.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5d/master/w_2560,c_limit/_KIM0340.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5e/master/w_2560,c_limit/_KIM0355.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5f/master/w_2560,c_limit/_KIM0371.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded60/master/w_2560,c_limit/_KIM0387.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded61/master/w_2560,c_limit/_KIM0399.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded62/master/w_2560,c_limit/_KIM0412.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded63/master/w_2560,c_limit/_KIM0424.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded64/master/w_2560,c_limit/_KIM0438.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded65/master/w_2560,c_limit/_KIM0450.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded66/master/w_2560,c_limit/_KIM0466.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded67/master/w_2560,c_limit/_KIM0483.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded68/master/w_2560,c_limit/_KIM0492.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded69/master/w_2560,c_limit/_KIM0507.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6a/master/w_2560,c_limit/_KIM0530.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6b/master/w_2560,c_limit/_KIM0543.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6c/master/w_2560,c_limit/_KIM0554.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6d/master/w_2560,c_limit/_KIM0573.1366x2048.JPG\"]}", + "", + "crawl", + "0" + ], [ "51", "1788620324", @@ -16630,18 +20894,6 @@ "crawl", "0" ], - [ - "56", - "1788620324", - "1788621956", - "1788621908", - "done", - "0", - "{\"kind\":\"runway\",\"brand_uid\":\"004xh65e\",\"title_en\":\"Fall 2014 Ready-to-Wear\",\"title_cn\":\"\",\"description_en\":\"\",\"description_cn\":\"\",\"year\":2014,\"season\":\"fall\",\"collection_type\":\"rtw\",\"city\":\"\",\"source_url\":\"https://www.vogue.com/fashion-shows/fall-2014-ready-to-wear/acne-studios/slideshow/collection\",\"images\":[\"https://assets.vogue.com/photos/55c6513d08298d8be21ded45/master/w_2560,c_limit/_KIM0017.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded46/master/w_2560,c_limit/_KIM0024.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded47/master/w_2560,c_limit/_KIM0032.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded48/master/w_2560,c_limit/_KIM0041.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded49/master/w_2560,c_limit/_KIM0058.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4a/master/w_2560,c_limit/_KIM0067.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4b/master/w_2560,c_limit/_KIM0075.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4c/master/w_2560,c_limit/_KIM0099.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4d/master/w_2560,c_limit/_KIM0114.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4e/master/w_2560,c_limit/_KIM0139.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded4f/master/w_2560,c_limit/_KIM0152.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded50/master/w_2560,c_limit/_KIM0170.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded51/master/w_2560,c_limit/_KIM0179.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded52/master/w_2560,c_limit/_KIM0195.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded53/master/w_2560,c_limit/_KIM0205.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded54/master/w_2560,c_limit/_KIM0225.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded55/master/w_2560,c_limit/_KIM0235.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded56/master/w_2560,c_limit/_KIM0248.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded57/master/w_2560,c_limit/_KIM0258.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded58/master/w_2560,c_limit/_KIM0276.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded59/master/w_2560,c_limit/_KIM0286.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5a/master/w_2560,c_limit/_KIM0304.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5b/master/w_2560,c_limit/_KIM0320.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5c/master/w_2560,c_limit/_KIM0329.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5d/master/w_2560,c_limit/_KIM0340.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5e/master/w_2560,c_limit/_KIM0355.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded5f/master/w_2560,c_limit/_KIM0371.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded60/master/w_2560,c_limit/_KIM0387.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded61/master/w_2560,c_limit/_KIM0399.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded62/master/w_2560,c_limit/_KIM0412.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded63/master/w_2560,c_limit/_KIM0424.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded64/master/w_2560,c_limit/_KIM0438.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded65/master/w_2560,c_limit/_KIM0450.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded66/master/w_2560,c_limit/_KIM0466.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded67/master/w_2560,c_limit/_KIM0483.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded68/master/w_2560,c_limit/_KIM0492.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded69/master/w_2560,c_limit/_KIM0507.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6a/master/w_2560,c_limit/_KIM0530.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6b/master/w_2560,c_limit/_KIM0543.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6c/master/w_2560,c_limit/_KIM0554.1366x2048.JPG\",\"https://assets.vogue.com/photos/55c6513d08298d8be21ded6d/master/w_2560,c_limit/_KIM0573.1366x2048.JPG\"]}", - "", - "crawl", - "0" - ], [ "57", "1788620325", @@ -17078,10 +21330,22 @@ }, { "name": "ingest_nonces", - "create": "CREATE TABLE `ingest_nonces` (\n `nonce` varchar(64) NOT NULL,\n `created_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`nonce`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", "columns": [ - "nonce", - "created_at" + { + "name": "nonce", + "type": "varchar", + "is_nullable": false, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "nonce" ], "rows": [ [ @@ -17520,14 +21784,47 @@ }, { "name": "refresh_tokens", - "create": "CREATE TABLE `refresh_tokens` (\n `id` bigint unsigned NOT NULL AUTO_INCREMENT,\n `user_id` int unsigned NOT NULL,\n `token_hash` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n `expires_at` int unsigned NOT NULL DEFAULT '0',\n `revoked` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`) USING BTREE,\n UNIQUE KEY `uk_token_hash` (`token_hash`) USING BTREE,\n KEY `idx_user_id` (`user_id`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=107 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "user_id", - "token_hash", - "expires_at", - "revoked", - "created_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('refresh_tokens_id_seq'::regclass)" + }, + { + "name": "user_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "token_hash", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "expires_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "revoked", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ @@ -18375,89 +22672,426 @@ "8", "e31ee908c298498aec6fef629418be71131ae444780257b9800a5815ba69eccd", "1791792802", - "0", + "1", "1789200802" + ], + [ + "107", + "8", + "409f92c490e950f4f5cd5651eb810f3b5d4313547a8d87699fef77941c58492a", + "1791875855", + "1", + "1789283855" + ], + [ + "108", + "8", + "70193ca537cf5bd2f35b925ae4ad9232f319f56376db712b60f09af01d0b3714", + "1791883446", + "1", + "1789291446" + ], + [ + "109", + "8", + "657e2fbc46a6e907b3f032e810616482e9c3fb7ffde7970ec7fdd2727d9a9e9d", + "1791890744", + "1", + "1789298744" + ], + [ + "110", + "8", + "ee359442e4c5d117e02afe91bb122b48d887e4fca5d1e6a8e5a179bd3434a249", + "1791891010", + "1", + "1789299010" + ], + [ + "111", + "8", + "ce67009fb0eac30226a49f5800e4935f7433024e231971e18832ac997151544a", + "1792061397", + "1", + "1789469397" + ], + [ + "112", + "8", + "816b96381d886887a05c12ec5883371671a95a9fa3bf27a308097c6565a23473", + "1792062995", + "1", + "1789470995" + ], + [ + "113", + "8", + "6b6a514221de8aa4c0fda45fa6c9d6eab318aeb3ae8f72c37eec1100e11ffb73", + "1792114905", + "0", + "1789522905" ] ] }, { "name": "street_snap", - "create": "CREATE TABLE `street_snap` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `year` smallint unsigned NOT NULL DEFAULT '0',\n `city` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `cover` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `image_count` smallint unsigned NOT NULL DEFAULT '0',\n `is_deleted` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`) USING BTREE,\n UNIQUE KEY `uk_city_year` (`city`,`year`),\n KEY `idx_year_imgcount` (`year`,`image_count`) USING BTREE,\n KEY `idx_imagecount` (`image_count`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "title", - "year", - "city", - "cover", - "image_count", - "is_deleted", - "created_at", - "updated_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('street_snap_id_seq'::regclass)" + }, + { + "name": "title", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "year", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "city", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "cover", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image_count", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [] }, { "name": "street_snap_draft", - "create": "CREATE TABLE `street_snap_draft` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `job_id` int unsigned NOT NULL DEFAULT '0',\n `title` varchar(512) NOT NULL DEFAULT '',\n `year` smallint unsigned NOT NULL DEFAULT '0',\n `city` varchar(128) NOT NULL DEFAULT '',\n `cover` varchar(1024) NOT NULL DEFAULT '',\n `image_count` smallint unsigned NOT NULL DEFAULT '0',\n `status` varchar(16) NOT NULL DEFAULT 'pending',\n `reviewer` varchar(64) NOT NULL DEFAULT '',\n `reject_reason` varchar(512) NOT NULL DEFAULT '',\n `is_deleted` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`),\n KEY `idx_status` (`status`),\n KEY `idx_job` (`job_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", "columns": [ - "id", - "job_id", - "title", - "year", - "city", - "cover", - "image_count", - "status", - "reviewer", - "reject_reason", - "is_deleted", - "created_at", - "updated_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('street_snap_draft_id_seq'::regclass)" + }, + { + "name": "job_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "title", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "year", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "city", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "cover", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image_count", + "type": "int4", + "is_nullable": true, + "is_identity": false + }, + { + "name": "status", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "reviewer", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "reject_reason", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [] }, { "name": "street_snap_draft_images", - "create": "CREATE TABLE `street_snap_draft_images` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `draft_id` int unsigned NOT NULL DEFAULT '0',\n `image` varchar(1024) NOT NULL DEFAULT '',\n `name` varchar(255) NOT NULL DEFAULT '',\n `sort_order` int unsigned NOT NULL DEFAULT '0',\n `is_deleted` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`),\n KEY `idx_draft` (`draft_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", "columns": [ - "id", - "draft_id", - "image", - "name", - "sort_order", - "is_deleted", - "created_at", - "updated_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('street_snap_draft_images_id_seq'::regclass)" + }, + { + "name": "draft_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "name", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "sort_order", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "phash", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_duplicate", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "dup_of", + "type": "text", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [] }, { "name": "street_snap_images", - "create": "CREATE TABLE `street_snap_images` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `snap_id` int unsigned NOT NULL DEFAULT '0',\n `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',\n `sort_order` int unsigned NOT NULL DEFAULT '0',\n `is_deleted` tinyint unsigned NOT NULL DEFAULT '0',\n `created_at` int unsigned NOT NULL DEFAULT '0',\n `updated_at` int unsigned NOT NULL DEFAULT '0',\n PRIMARY KEY (`id`) USING BTREE,\n KEY `idx_snap` (`snap_id`,`sort_order`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "snap_id", - "image", - "name", - "sort_order", - "is_deleted", - "created_at", - "updated_at" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('street_snap_images_id_seq'::regclass)" + }, + { + "name": "snap_id", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "image", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "name", + "type": "text", + "is_nullable": true, + "is_identity": false + }, + { + "name": "sort_order", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "phash", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_duplicate", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "dup_of", + "type": "text", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [] }, { "name": "users", - "create": "CREATE TABLE `users` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `created_at` int unsigned DEFAULT NULL,\n `updated_at` int unsigned DEFAULT NULL,\n `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,\n `email` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,\n `password_hash` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,\n `is_deleted` tinyint unsigned DEFAULT NULL,\n `tier` varchar(16) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'free' COMMENT '用户等级 free/vip;详情页据其决定返回普通还是高清图',\n PRIMARY KEY (`id`) USING BTREE,\n UNIQUE KEY `idx_users_username` (`username`) USING BTREE,\n UNIQUE KEY `idx_users_email` (`email`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC", "columns": [ - "id", - "created_at", - "updated_at", - "username", - "email", - "password_hash", - "is_deleted", - "tier" + { + "name": "id", + "type": "int8", + "is_nullable": false, + "is_identity": true, + "default": "nextval('users_id_seq'::regclass)" + }, + { + "name": "created_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "updated_at", + "type": "int8", + "is_nullable": true, + "is_identity": false + }, + { + "name": "username", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "email", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "password_hash", + "type": "varchar", + "is_nullable": true, + "is_identity": false + }, + { + "name": "is_deleted", + "type": "int2", + "is_nullable": true, + "is_identity": false + }, + { + "name": "tier", + "type": "varchar", + "is_nullable": true, + "is_identity": false + } + ], + "pk": [ + "id" ], "rows": [ [ diff --git a/cmd/dbtool/dbtool_bin.exe b/cmd/dbtool/dbtool_bin.exe new file mode 100644 index 0000000..13635dc Binary files /dev/null and b/cmd/dbtool/dbtool_bin.exe differ diff --git a/cmd/dbtool/main.go b/cmd/dbtool/main.go index dd387c2..90464ea 100644 --- a/cmd/dbtool/main.go +++ b/cmd/dbtool/main.go @@ -1,14 +1,14 @@ // Command dbtool 是后台管理用的数据库一键迁移脚本。 // -// 用途:在不同开发电脑之间搬运 MySQL 库(db_dev)的「结构 + 数据」, -// 省去手动 mysqldump / 重新 seed 的麻烦。完全复用后端既有的 mysql 驱动与 -// configs/config.yml,不依赖任何外部二进制(mysqldump 等)。 +// 用途:在不同开发电脑 / 环境之间搬运 PostgreSQL 库(fashion)的「结构 + 数据」, +// 省去手动 pg_dump / 重新 seed 的麻烦。完全复用后端既有的 pgx 驱动与 +// configs/config.yml,不依赖任何外部二进制(pg_dump 等)。 // // 子命令: // // dbtool dump -out db_dump.json 导出当前库全部表(schema+data)为单个 JSON 文件 // dbtool import -in db_dump.json 读取 JSON 文件,DROP+CREATE+INSERT 回灌到目标库 -// (可用 -data-only 只导数据,表结构需已存在) +// (可用 -data-only 只导数据,表结构须已由 AutoMigrate 创建) // // 连接信息来自 configs/config.yml 的 database 段(同后端服务),可用 -config 指定其它配置。 package main @@ -16,6 +16,7 @@ package main import ( "database/sql" "encoding/json" + "errors" "flag" "fmt" "log" @@ -23,17 +24,27 @@ import ( "strings" "time" - _ "github.com/go-sql-driver/mysql" + "github.com/jackc/pgx/v5/pgconn" + _ "github.com/jackc/pgx/v5/stdlib" "fashionapi/internal/config" ) +// columnMeta 是单列的元信息,用于重建 DDL 与导入时类型转换。 +type columnMeta struct { + Name string `json:"name"` + Type string `json:"type"` // udt_name,如 int8 / varchar / timestamptz / bool / jsonb + IsNullable bool `json:"is_nullable"` + IsIdentity bool `json:"is_identity"` + Default string `json:"default,omitempty"` +} + // tableDump 是单张表的导出结构。 type tableDump struct { - Name string `json:"name"` - Create string `json:"create"` // SHOW CREATE TABLE 得到的完整 DDL - Columns []string `json:"columns"` // SELECT * 得到的列顺序,导入时按此生成 INSERT - Rows [][]any `json:"rows"` // 每行为一组值;nil 表示 NULL,string 表示值 + Name string `json:"name"` + Columns []columnMeta `json:"columns"` + Pk []string `json:"pk"` + Rows [][]any `json:"rows"` // 每行为一组值;nil 表示 NULL,string 表示值 } // dumpFile 是 dump 输出的顶层结构。 @@ -44,6 +55,30 @@ type dumpFile struct { Tables []tableDump `json:"tables"` } +// verbose 控制是否打印每条执行的 SQL(用于排查)。由 dump/import 子命令的 -v 开关设置。 +var verbose bool + +// vlog 在开启 verbose 时打印调试信息。 +func vlog(format string, args ...any) { + if verbose { + log.Printf("[sql] "+format, args...) + } +} + +// pgDetail 提取 PostgreSQL 报错的位置/消息,便于定位语法错误。 +func pgDetail(err error) string { + var pgErr *pgconn.PgError + if errors.As(err, &pgErr) { + return fmt.Sprintf(" [position=%d message=%q where=%q]", pgErr.Position, pgErr.Message, pgErr.Where) + } + return "" +} + +// quoteLit 安全包裹 SQL 字符串字面量(转义单引号),用于内联可信的内部标识符/表名。 +func quoteLit(s string) string { + return "'" + strings.ReplaceAll(s, "'", "''") + "'" +} + func main() { if len(os.Args) < 2 { usage() @@ -61,15 +96,15 @@ func main() { } func usage() { - fmt.Println(`dbtool - 后台数据库一键迁移脚本 + fmt.Println(`dbtool - 后台数据库一键迁移脚本(PostgreSQL) 用法: dbtool dump [-config ] [-out ] 导出全库 schema+data 到 JSON - dbtool import [-config ] [-in ] [-data-only] 从 JSON 回灌(DROP+CREATE+INSERT) + dbtool import [-config ] [-in ] [-data-only] 从 JSON 回灌(默认 DROP+CREATE+INSERT) 说明: 连接信息读取 configs/config.yml 的 database 段(可用 -config 覆盖)。 - import 默认连结构带数据全部重建;-data-only 仅导数据(目标库表结构须已存在)。`) + import 默认连结构带数据全部重建;-data-only 仅导数据(表结构须已由后端 AutoMigrate 创建)。`) } // openDB 按 config 加载 DSN 并探活。 @@ -78,7 +113,7 @@ func openDB(cfgPath string) (*sql.DB, *config.DatabaseConfig, error) { if err != nil { return nil, nil, fmt.Errorf("加载配置失败: %w", err) } - db, err := sql.Open("mysql", cfg.Database.DSN()) + db, err := sql.Open("pgx", cfg.Database.DSN()) if err != nil { return nil, nil, fmt.Errorf("打开数据库连接失败: %w", err) } @@ -94,7 +129,9 @@ func runDump(args []string) { fs := flag.NewFlagSet("dump", flag.ExitOnError) out := fs.String("out", "db_dump.json", "导出文件路径") cfgPath := fs.String("config", "", "配置文件路径(默认 configs/config.yml)") + v := fs.Bool("v", false, "打印每条执行的 SQL,便于排查") _ = fs.Parse(args) + verbose = *v db, dcfg, err := openDB(*cfgPath) if err != nil { @@ -138,7 +175,7 @@ func runImport(args []string) { fs := flag.NewFlagSet("import", flag.ExitOnError) in := fs.String("in", "db_dump.json", "导入文件路径") cfgPath := fs.String("config", "", "配置文件路径(默认 configs/config.yml)") - dataOnly := fs.Bool("data-only", false, "仅导数据(表结构须已存在)") + dataOnly := fs.Bool("data-only", false, "仅导数据(表结构须已由 AutoMigrate 创建)") _ = fs.Parse(args) raw, err := os.ReadFile(*in) @@ -156,21 +193,30 @@ func runImport(args []string) { } defer db.Close() - // 关掉外键检查,避免建表/插数据顺序受 FK 约束(全量重建无需保序)。 - if _, err := db.Exec("SET FOREIGN_KEY_CHECKS=0"); err != nil { - log.Fatalf("✗ 关闭外键检查失败: %v", err) + // 关闭外键 / 触发器,避免插入顺序受约束(整库重建无需保序)。 + if _, err := db.Exec("SET session_replication_role = 'replica'"); err != nil { + log.Fatalf("✗ 关闭约束检查失败: %v", err) } - defer db.Exec("SET FOREIGN_KEY_CHECKS=1") + defer db.Exec("SET session_replication_role = 'origin'") for _, t := range df.Tables { if !*dataOnly { log.Printf("→ 重建表 %s ...", t.Name) - if _, err := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS `%s`", t.Name)); err != nil { + if _, err := db.Exec(fmt.Sprintf(`DROP TABLE IF EXISTS "%s" CASCADE`, t.Name)); err != nil { log.Fatalf("✗ 删表 %s 失败: %v", t.Name, err) } - if _, err := db.Exec(t.Create); err != nil { + ddl, err := buildCreate(t) + if err != nil { + log.Fatalf("✗ 生成建表语句失败(%s): %v", t.Name, err) + } + if _, err := db.Exec(ddl); err != nil { log.Fatalf("✗ 建表 %s 失败: %v", t.Name, err) } + } else { + // 仅导数据:先清空目标表(约束已由 replica 角色关闭),再插入。 + if _, err := db.Exec(fmt.Sprintf(`DELETE FROM "%s"`, t.Name)); err != nil { + log.Fatalf("✗ 清空表 %s 失败: %v", t.Name, err) + } } if err := importRows(db, t); err != nil { log.Fatalf("✗ 导数据到 %s 失败: %v", t.Name, err) @@ -180,9 +226,12 @@ func runImport(args []string) { log.Printf("✓ 导入完成(%d 张表)", len(df.Tables)) } -// listTables 返回当前库所有表名。 +// listTables 返回 public 模式下所有基表名。 func listTables(db *sql.DB) ([]string, error) { - rows, err := db.Query("SHOW TABLES") + rows, err := db.Query(` + SELECT table_name FROM information_schema.tables + WHERE table_schema = 'public' AND table_type = 'BASE TABLE' + ORDER BY table_name`) if err != nil { return nil, err } @@ -198,27 +247,27 @@ func listTables(db *sql.DB) ([]string, error) { return out, rows.Err() } -// dumpTable 导出单张表的 DDL + 数据。 +// dumpTable 导出单张表的列元信息 + 数据。 func dumpTable(db *sql.DB, name string) (tableDump, error) { - // 1) DDL - var dummy, ddl string - if err := db.QueryRow(fmt.Sprintf("SHOW CREATE TABLE `%s`", name)).Scan(&dummy, &ddl); err != nil { + cols, pk, err := dumpColumns(db, name) + if err != nil { return tableDump{}, err } - // 2) 数据 - rows, err := db.Query(fmt.Sprintf("SELECT * FROM `%s`", name)) + dataQuery := fmt.Sprintf(`SELECT * FROM "%s"`, name) + vlog("dump data: %s", dataQuery) + rows, err := db.Query(dataQuery) if err != nil { - return tableDump{}, err + return tableDump{}, fmt.Errorf("读取数据失败(表 %s): %w\nSQL: %s", name, err, dataQuery) } defer rows.Close() - cols, err := rows.Columns() + colNames, err := rows.Columns() if err != nil { return tableDump{}, err } - n := len(cols) - td := tableDump{Name: name, Create: ddl, Columns: cols, Rows: make([][]any, 0)} + n := len(colNames) + td := tableDump{Name: name, Columns: cols, Pk: pk, Rows: make([][]any, 0)} scanPtrs := make([]any, n) raw := make([]sql.RawBytes, n) @@ -234,7 +283,7 @@ func dumpTable(db *sql.DB, name string) (tableDump, error) { if raw[i] == nil { row[i] = nil // NULL } else { - row[i] = string(raw[i]) // 全部按字符串搬运,导入时由驱动按列类型适配 + row[i] = string(raw[i]) // 全部按字符串搬运,导入时按列类型转换 } } td.Rows = append(td.Rows, row) @@ -242,17 +291,192 @@ func dumpTable(db *sql.DB, name string) (tableDump, error) { return td, rows.Err() } -// importRows 把一张表的数据批量 INSERT 进目标库(单表一个事务,每批多行,减少网络往返)。 +// dumpColumns 读取列元信息与主键。 +func dumpColumns(db *sql.DB, table string) ([]columnMeta, []string, error) { + colQuery := strings.Replace(` + SELECT c.column_name, + c.udt_name, + (c.is_nullable = 'YES'), + COALESCE(c.column_default, ''), + COALESCE(c.column_default LIKE 'nextval(%', false) + FROM information_schema.columns c + WHERE c.table_schema = 'public' AND c.table_name = $1 + ORDER BY c.ordinal_position`, "$1", quoteLit(table), 1) + vlog("dump columns: table=%q query=%s", table, colQuery) + rows, err := db.Query(colQuery) + if err != nil { + return nil, nil, fmt.Errorf("读取列元信息失败(表 %s): %w%s\nSQL: %s", table, err, pgDetail(err), strings.TrimSpace(colQuery)) + } + defer rows.Close() + + var cols []columnMeta + for rows.Next() { + var name, udt, def string + var nullable, isIdent bool + if err := rows.Scan(&name, &udt, &nullable, &def, &isIdent); err != nil { + return nil, nil, err + } + cols = append(cols, columnMeta{ + Name: name, Type: udt, IsNullable: nullable, IsIdentity: isIdent, Default: def, + }) + } + if err := rows.Err(); err != nil { + return nil, nil, err + } + + pkQuery := strings.Replace(` + SELECT kcu.column_name + FROM information_schema.table_constraints tc + JOIN information_schema.key_column_usage kcu + ON kcu.constraint_name = tc.constraint_name AND kcu.table_schema = tc.table_schema + WHERE tc.table_schema = 'public' AND tc.table_name = $1 AND tc.constraint_type = 'PRIMARY KEY' + ORDER BY kcu.ordinal_position`, "$1", quoteLit(table), 1) + vlog("dump pk: %s", strings.TrimSpace(pkQuery)) + pkRows, err := db.Query(pkQuery) + if err != nil { + return nil, nil, fmt.Errorf("读取主键失败(表 %s): %w\nSQL: %s", table, err, strings.TrimSpace(pkQuery)) + } + defer pkRows.Close() + var pk []string + for pkRows.Next() { + var c string + if err := pkRows.Scan(&c); err != nil { + return nil, nil, err + } + pk = append(pk, c) + } + return cols, pk, pkRows.Err() +} + +// pgType 将 udt_name 映射为建表用的列类型。 +func pgType(udt string) string { + switch udt { + case "int2": + return "smallint" + case "int4": + return "integer" + case "int8": + return "bigint" + case "numeric": + return "numeric" + case "float4": + return "real" + case "float8": + return "double precision" + case "bool": + return "boolean" + case "timestamp": + return "timestamp" + case "timestamptz": + return "timestamptz" + case "date": + return "date" + case "time": + return "time" + case "text": + return "text" + case "json": + return "json" + case "jsonb": + return "jsonb" + case "uuid": + return "uuid" + case "bytea": + return "bytea" + default: + return udt // varchar / char / 未知类型原样返回 + } +} + +// buildCreate 由列元信息重建 CREATE TABLE 语句。 +func buildCreate(t tableDump) (string, error) { + var b strings.Builder + b.WriteString(fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "%s" (`, t.Name)) + first := true + for _, c := range t.Columns { + if !first { + b.WriteString(",") + } + first = false + b.WriteString(fmt.Sprintf("\n \"%s\" %s", c.Name, pgType(c.Type))) + if c.IsIdentity { + b.WriteString(" GENERATED BY DEFAULT AS IDENTITY") + } else if c.Default != "" { + b.WriteString(" DEFAULT " + c.Default) + } + if !c.IsNullable && !c.IsIdentity { + b.WriteString(" NOT NULL") + } + } + if len(t.Pk) > 0 { + b.WriteString(",\n PRIMARY KEY (" + strings.Join(quoteAll(t.Pk), ",") + ")") + } + b.WriteString("\n);") + return b.String(), nil +} + +func quoteAll(cols []string) []string { + out := make([]string, len(cols)) + for i, c := range cols { + out[i] = `"` + c + `"` + } + return out +} + +// castFor 返回列类型对应的 pg 类型转换后缀(用于导入时把字符串值转为正确类型)。 +func castFor(udt string) string { + switch udt { + case "int2", "int4", "int8": + return "bigint" + case "numeric": + return "numeric" + case "float4", "float8": + return "double precision" + case "bool": + return "boolean" + case "timestamp": + return "timestamp" + case "timestamptz": + return "timestamptz" + case "date": + return "date" + case "time": + return "time" + case "json", "jsonb": + return "jsonb" + case "uuid": + return "uuid" + default: + return "" // text / varchar / char 等字符串类型无需转换 + } +} + +// importRows 把一张表的数据批量 INSERT 进目标库(单表一个事务,每批多行)。 func importRows(db *sql.DB, t tableDump) error { if len(t.Rows) == 0 { return nil } + hasIdentity := false + for _, c := range t.Columns { + if c.IsIdentity { + hasIdentity = true + break + } + } + tx, err := db.Begin() if err != nil { return err } - colList := "`" + strings.Join(t.Columns, "`,`") + "`" - ph := "(" + strings.TrimSuffix(strings.Repeat("?,", len(t.Columns)), ",") + ")" + defer func() { _ = tx.Rollback() }() + + colList := make([]string, len(t.Columns)) + casts := make([]string, len(t.Columns)) + for i, c := range t.Columns { + colList[i] = `"` + c.Name + `"` + casts[i] = castFor(c.Type) + } + const batchSize = 200 for start := 0; start < len(t.Rows); start += batchSize { end := start + batchSize @@ -260,20 +484,52 @@ func importRows(db *sql.DB, t tableDump) error { end = len(t.Rows) } chunk := t.Rows[start:end] + var sb strings.Builder - sb.WriteString(fmt.Sprintf("INSERT INTO `%s` (%s) VALUES ", t.Name, colList)) + ov := "" + if hasIdentity { + ov = " OVERRIDING SYSTEM VALUE" + } + sb.WriteString(fmt.Sprintf(`INSERT INTO "%s" (%s)%s VALUES `, t.Name, strings.Join(colList, ","), ov)) args := make([]any, 0, len(chunk)*len(t.Columns)) - for i, r := range chunk { - if i > 0 { + param := 1 + for ri, row := range chunk { + if ri > 0 { sb.WriteString(",") } - sb.WriteString(ph) - args = append(args, r...) + sb.WriteString("(") + for ci, val := range row { + if ci > 0 { + sb.WriteString(",") + } + if val == nil { + sb.WriteString("NULL") + } else { + if casts[ci] != "" { + sb.WriteString(fmt.Sprintf("$%d::%s", param, casts[ci])) + } else { + sb.WriteString(fmt.Sprintf("$%d", param)) + } + args = append(args, val) + param++ + } + } + sb.WriteString(")") } if _, err := tx.Exec(sb.String(), args...); err != nil { - _ = tx.Rollback() return err } } + + // 重置 identity 序列,避免后续自增插入与已导入的最大 ID 冲突。 + for _, c := range t.Columns { + if c.IsIdentity { + seq := fmt.Sprintf("pg_get_serial_sequence('%s','%s')", t.Name, c.Name) + if _, err := tx.Exec(fmt.Sprintf( + `SELECT setval(%s, COALESCE((SELECT MAX("%s") FROM "%s"), 1))`, seq, c.Name, t.Name)); err != nil { + log.Printf("! 重置序列 %s.%s 失败: %v", t.Name, c.Name, err) + } + } + } return tx.Commit() } diff --git a/cmd/server/main.go b/cmd/server/main.go index 1a08c41..60c99cc 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -67,7 +67,11 @@ func main() { log.Printf("! 关闭数据库连接失败: %v", err) } }() - log.Println("✓ MySQL 已连接:", cfg.Database.Addr()) + // 2.5 幂等自动迁移表结构(替代原手写 MySQL 迁移脚本) + if err := database.AutoMigrate(db); err != nil { + log.Fatalf("✗ 自动迁移失败: %v", err) + } + log.Println("✓ PostgreSQL 已连接:", cfg.Database.Addr()) // 3. 确保上传目录存在(静态文件服务的根目录) uploadDir, _ := filepath.Abs(cfg.Upload.Dir) diff --git a/configs/config.yml b/configs/config.yml index d01e107..e5d729f 100644 --- a/configs/config.yml +++ b/configs/config.yml @@ -20,19 +20,18 @@ server: database: host: 127.0.0.1 # env: DB_HOST - port: 3306 # env: DB_PORT - user: root # env: DB_USER - password: root # env: DB_PASSWORD(兼容 DB_PASS) - # 本地开发库名为 db_dev;docker-compose 部署时用环境变量覆盖为 fashionadmin - name: db_dev # env: DB_NAME - charset: utf8mb4 + port: 5432 # env: DB_PORT + user: fashion # env: DB_USER + password: fashion_dev_2026 # env: DB_PASSWORD(兼容 DB_PASS) + # 本地开发库名 fashion;对应 scripts/pgvector 的 Docker PostgreSQL 容器 + name: fashion # env: DB_NAME # GORM 日志级别:silent | error | warn | info log_level: warn # 连接池 max_idle_conns: 10 max_open_conns: 100 conn_max_lifetime: 3600 # 秒 - conn_max_idle_time: 60 # 秒,空闲连接回收时间;须 < MySQL wait_timeout,防止池子持有被回收的死连接导致 invalid connection + conn_max_idle_time: 60 # 秒,空闲连接回收时间,防止池子持有被服务端回收的死连接导致 invalid connection jwt: # 生产环境务必用环境变量覆盖为随机长字符串 @@ -80,7 +79,7 @@ client_sign: # 爬虫入库管线:暴露 :8092 /admin/internal/ingest 接收爬虫 HMAC 签名上报。 # 设计:服务端到服务端(非前端 JS),密钥绝不下发前端、只存爬虫配置与 INGEST_SECRET,安全高。 # - secret 必须与爬虫端 config.yml 的 ingest.secret 完全一致;env INGEST_SECRET 注入随机长串(生产)。 -# - 依赖迁移 db/migrations/002_ingest.sql(建 ingest_jobs / ingest_nonces)。 +# - 建表由 GORM AutoMigrate 自动完成(ingest_jobs / ingest_nonces 等),无需手工 SQL 迁移。 # - 启用后 worker 随主进程拉起(cmd/server 内 goroutine),异步下载图、补 season_code、写正式表。 ingest: secret: "dev-ingest-secret-2026" # env: INGEST_SECRET(须与爬虫 config.yml 的 ingest.secret 一致) diff --git a/go.mod b/go.mod index 940fcb1..3b26bf0 100644 --- a/go.mod +++ b/go.mod @@ -3,20 +3,21 @@ module fashionapi go 1.26.5 require ( + github.com/aws/aws-sdk-go-v2 v1.47.0 + github.com/aws/aws-sdk-go-v2/config v1.33.4 + github.com/aws/aws-sdk-go-v2/credentials v1.20.4 + github.com/aws/aws-sdk-go-v2/service/s3 v1.113.0 github.com/gin-gonic/gin v1.12.0 github.com/goccy/go-yaml v1.19.2 github.com/golang-jwt/jwt/v5 v5.3.1 + github.com/jackc/pgx/v5 v5.11.0 golang.org/x/crypto v0.54.0 - gorm.io/driver/mysql v1.6.0 + gorm.io/driver/postgres v1.6.3 gorm.io/gorm v1.31.2 ) require ( - filippo.io/edwards25519 v1.1.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.47.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 // indirect - github.com/aws/aws-sdk-go-v2/config v1.33.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.20.4 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.20.0 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.3 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.3 // indirect @@ -25,7 +26,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.11.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.20.3 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.113.0 // indirect github.com/aws/aws-sdk-go-v2/service/signin v1.10.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.38.0 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.43.0 // indirect @@ -40,8 +40,10 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.30.1 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/goccy/go-json v0.10.5 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -58,6 +60,7 @@ require ( go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect golang.org/x/arch v0.22.0 // indirect golang.org/x/net v0.56.0 // indirect + golang.org/x/sync v0.22.0 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/text v0.40.0 // indirect google.golang.org/protobuf v1.36.10 // indirect diff --git a/go.sum b/go.sum index e51d97f..5d34374 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/aws/aws-sdk-go-v2 v1.47.0 h1:0jsHallhJCeaU0Ko48c/3FK1ctOQ7NpzggxriJOQ8MQ= github.com/aws/aws-sdk-go-v2 v1.47.0/go.mod h1:bttEH6JqnUL8LepvDVfdrds/fZ5bCIxzpe3abyUrhDU= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 h1:GPRlPwz40I2B2VrBEASOA3Bi77NyeqejNLkifosX0rs= @@ -45,6 +43,7 @@ github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCc github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw= github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= @@ -52,21 +51,31 @@ github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.11.0 h1:IzBBtyK9AHqf98cctWFifYSci2hgQR/cd56wB4p+ogg= +github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= @@ -79,6 +88,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -86,6 +97,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= @@ -96,41 +108,43 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE= go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI= golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= -gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= +gorm.io/driver/postgres v1.6.3 h1:bAn6O2pUa8LtpWEvL5NFU4+52Tfx8Ut7IVaIacCLcI0= +gorm.io/driver/postgres v1.6.3/go.mod h1:0c4fQA44XhOklXDkgtuKqysHCycTa5i9e3EIpDGCwXk= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo= gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/internal/config/config.go b/internal/config/config.go index 87a0f66..37cdc73 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -59,32 +59,27 @@ type ServerConfig struct { HashIDSecret string `yaml:"hashid_secret"` } -// DatabaseConfig MySQL 连接与连接池配置。 +// DatabaseConfig PostgreSQL 连接与连接池配置。 type DatabaseConfig struct { Host string `yaml:"host"` Port string `yaml:"port"` User string `yaml:"user"` Password string `yaml:"password"` Name string `yaml:"name"` - Charset string `yaml:"charset"` LogLevel string `yaml:"log_level"` MaxIdleConns int `yaml:"max_idle_conns"` MaxOpenConns int `yaml:"max_open_conns"` ConnMaxLifetime int `yaml:"conn_max_lifetime"` - // ConnMaxIdleTime 空闲连接回收时间(秒)。必须 < MySQL wait_timeout,否则 MySQL 回收空闲 - // 连接后,连接池仍持有死连接,下一次查询会报 "invalid connection" / "bad connection"。 + // ConnMaxIdleTime 空闲连接回收时间(秒)。避免长时间持有被服务端回收的死连接, + // 下一次查询报 "invalid connection" / "bad connection"。 ConnMaxIdleTime int `yaml:"conn_max_idle_time"` } -// DSN 组装 MySQL 连接串。 +// DSN 组装 PostgreSQL 连接串(pgx 驱动,本地开发禁用 SSL)。 func (d DatabaseConfig) DSN() string { - charset := d.Charset - if charset == "" { - charset = "utf8mb4" - } return fmt.Sprintf( - "%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local&timeout=10s", - d.User, d.Password, d.Host, d.Port, d.Name, charset, + "postgres://%s:%s@%s:%s/%s?sslmode=disable", + d.User, d.Password, d.Host, d.Port, d.Name, ) } @@ -186,11 +181,10 @@ func defaultConfig() *Config { }, Database: DatabaseConfig{ Host: "127.0.0.1", - Port: "3306", - User: "root", - Password: "root", - Name: "db_dev", - Charset: "utf8mb4", + Port: "5432", + User: "fashion", + Password: "fashion_dev_2026", + Name: "fashion", LogLevel: "warn", MaxIdleConns: 10, MaxOpenConns: 100, diff --git a/internal/database/mysql.go b/internal/database/mysql.go deleted file mode 100644 index 01e4e22..0000000 --- a/internal/database/mysql.go +++ /dev/null @@ -1,72 +0,0 @@ -// Package database 负责数据库连接的建立与生命周期管理。 -// -// 这里刻意不提供包级全局 DB 变量:*gorm.DB 由 main 装配后显式注入各 repository, -// 依赖关系清晰可见,也让 repository 可以在测试中替换为独立的数据库实例。 -package database - -import ( - "fmt" - "time" - - "fashionapi/internal/config" - - "gorm.io/driver/mysql" - "gorm.io/gorm" - "gorm.io/gorm/logger" -) - -// New 建立 MySQL 连接并完成连接池设置。 -func New(cfg config.DatabaseConfig) (*gorm.DB, error) { - db, err := gorm.Open(mysql.Open(cfg.DSN()), &gorm.Config{ - Logger: logger.Default.LogMode(parseLogLevel(cfg.LogLevel)), - // 关闭默认事务可显著提升只读接口的吞吐;写操作按需显式开启事务 - SkipDefaultTransaction: true, - }) - if err != nil { - return nil, fmt.Errorf("连接数据库失败: %w", err) - } - - sqlDB, err := db.DB() - if err != nil { - return nil, fmt.Errorf("获取底层连接池失败: %w", err) - } - sqlDB.SetMaxIdleConns(cfg.MaxIdleConns) - sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) - sqlDB.SetConnMaxLifetime(time.Duration(cfg.ConnMaxLifetime) * time.Second) - // 空闲回收:定期关闭空闲连接,避免持有被 MySQL wait_timeout 回收的死连接。 - // 仅当配置 > 0 时启用(0 = 沿用旧行为,不回收)。 - if cfg.ConnMaxIdleTime > 0 { - sqlDB.SetConnMaxIdleTime(time.Duration(cfg.ConnMaxIdleTime) * time.Second) - } - - // 立刻探活,避免"启动成功但首个请求才报错" - if err := sqlDB.Ping(); err != nil { - return nil, fmt.Errorf("数据库 Ping 失败: %w", err) - } - return db, nil -} - -// Close 关闭数据库连接池。 -func Close(db *gorm.DB) error { - if db == nil { - return nil - } - sqlDB, err := db.DB() - if err != nil { - return err - } - return sqlDB.Close() -} - -func parseLogLevel(s string) logger.LogLevel { - switch s { - case "silent": - return logger.Silent - case "error": - return logger.Error - case "info": - return logger.Info - default: - return logger.Warn - } -} diff --git a/internal/database/postgres.go b/internal/database/postgres.go new file mode 100644 index 0000000..1d0ba43 --- /dev/null +++ b/internal/database/postgres.go @@ -0,0 +1,157 @@ +// Package database 负责数据库连接的建立与生命周期管理。 +// +// 这里刻意不提供包级全局 DB 变量:*gorm.DB 由 main 装配后显式注入各 repository, +// 依赖关系清晰可见,也让 repository 可以在测试中替换为独立的数据库实例。 +// +// 数据库已迁移至 PostgreSQL(见 scripts/pgvector 的本地 Docker 环境)。 +// 表结构由 GORM AutoMigrate 在启动时幂等创建,不再依赖手写的 MySQL 迁移脚本。 +package database + +import ( + "fmt" + "time" + + "fashionapi/internal/config" + "fashionapi/internal/model" + + "gorm.io/driver/postgres" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +// New 建立 PostgreSQL 连接并完成连接池设置。 +func New(cfg config.DatabaseConfig) (*gorm.DB, error) { + db, err := gorm.Open(postgres.Open(cfg.DSN()), &gorm.Config{ + Logger: logger.Default.LogMode(parseLogLevel(cfg.LogLevel)), + // 关闭默认事务可显著提升只读接口的吞吐;写操作按需显式开启事务 + SkipDefaultTransaction: true, + }) + if err != nil { + return nil, fmt.Errorf("连接数据库失败: %w", err) + } + + sqlDB, err := db.DB() + if err != nil { + return nil, fmt.Errorf("获取底层连接池失败: %w", err) + } + sqlDB.SetMaxIdleConns(cfg.MaxIdleConns) + sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) + sqlDB.SetConnMaxLifetime(time.Duration(cfg.ConnMaxLifetime) * time.Second) + // 空闲回收:定期关闭空闲连接,避免持有被服务端回收的死连接。 + // 仅当配置 > 0 时启用(0 = 沿用旧行为,不回收)。 + if cfg.ConnMaxIdleTime > 0 { + sqlDB.SetConnMaxIdleTime(time.Duration(cfg.ConnMaxIdleTime) * time.Second) + } + + // 立刻探活,避免"启动成功但首个请求才报错" + if err := sqlDB.Ping(); err != nil { + return nil, fmt.Errorf("数据库 Ping 失败: %w", err) + } + return db, nil +} + +// AutoMigrate 幂等创建 / 更新全部表结构。 +// +// 表结构由 GORM 模型定义托管(替代原 scripts/sql、db/migrations 下的手写 MySQL 脚本)。 +// 仅在缺少列/索引时增量变更,已存在的表不会被重建;对存量大表(如 brand_runway_images) +// 的加列操作可能短暂加锁,属一次性开销。 +func AutoMigrate(db *gorm.DB) error { + // 确保 pgvector 扩展存在(dHash 近重复 HNSW 索引与语义 embedding 向量列均依赖它)。 + if err := db.Exec("CREATE EXTENSION IF NOT EXISTS vector").Error; err != nil { + return fmt.Errorf("create extension vector: %w", err) + } + return db.AutoMigrate( + &model.Brand{}, + &model.User{}, + &model.RefreshToken{}, + &model.IngestNonce{}, + &model.IngestJob{}, + &model.StreetSnap{}, + &model.StreetSnapImage{}, + &model.StreetSnapDraft{}, + &model.StreetSnapDraftImage{}, + &model.Favorite{}, + &model.History{}, + &model.BrandRunway{}, + &model.BrandRunwayImage{}, + &model.BrandRunwayDraft{}, + &model.BrandRunwayDraftImage{}, + ) +} + +// ensureDedupSchema 在 GORM AutoMigrate 之外,补充去重所需的索引与语义 embedding 表。 +// 全部幂等(IF NOT EXISTS),可随服务启动重复执行。 +// +// - 各 image 表的 content_sha1 部分唯一索引(排除迁移前遗留的空串行,避免唯一约束冲突); +// - phash 的 HNSW 索引(bit_hamming_ops,汉明距离近邻检索,替代原先的全表扫描); +// - image_embeddings 表 + cosine HNSW 索引:语义 embedding(CLIP/DINOv2)落库位, +// 待后续接入推理填充,当前不写入。 +func ensureDedupSchema(db *gorm.DB) error { + tables := []struct { + name string + idx string + }{ + {"brand_runway_images", "uq_br_imgs_sha1"}, + {"brand_runway_draft_images", "uq_br_draft_imgs_sha1"}, + {"street_snap_images", "uq_ss_imgs_sha1"}, + {"street_snap_draft_images", "uq_ss_draft_imgs_sha1"}, + } + for _, t := range tables { + // 精确去重:content_sha1 唯一(排除空串遗留行)。 + if err := db.Exec(fmt.Sprintf( + "CREATE UNIQUE INDEX IF NOT EXISTS %s ON %s (content_sha1) WHERE content_sha1 <> ''", + t.idx, t.name, + )).Error; err != nil { + return fmt.Errorf("create unique index %s: %w", t.idx, err) + } + // 近重复检索:dHash 向量(vector(64) 二进制)汉明 HNSW 索引。 + if err := db.Exec(fmt.Sprintf( + "CREATE INDEX IF NOT EXISTS %s_phash_hnsw ON %s USING hnsw (phash bit_hamming_ops)", + t.idx, t.name, + )).Error; err != nil { + return fmt.Errorf("create hnsw index %s: %w", t.idx, err) + } + } + // 语义 embedding 表(CLIP/DINOv2 等 512 维向量):待后续推理接入填充;当前不写入。 + if err := db.Exec(` + CREATE TABLE IF NOT EXISTS image_embeddings ( + id BIGSERIAL PRIMARY KEY, + image_id INTEGER NOT NULL, + kind SMALLINT NOT NULL, + embedding vector(512), + created_at INTEGER NOT NULL DEFAULT 0 + )`).Error; err != nil { + return fmt.Errorf("create image_embeddings: %w", err) + } + if err := db.Exec( + "CREATE INDEX IF NOT EXISTS image_embeddings_vec_idx ON image_embeddings USING hnsw (embedding vector_cosine_ops)", + ).Error; err != nil { + return fmt.Errorf("create embeddings hnsw: %w", err) + } + return nil +} + +// Close 关闭数据库连接池。 +func Close(db *gorm.DB) error { + if db == nil { + return nil + } + sqlDB, err := db.DB() + if err != nil { + return err + } + return sqlDB.Close() +} + +func parseLogLevel(s string) logger.LogLevel { + switch s { + case "silent": + return logger.Silent + case "error": + return logger.Error + case "info": + return logger.Info + default: + return logger.Warn + } +} diff --git a/internal/model/runway_draft.go b/internal/model/runway_draft.go index f956899..76f9088 100644 --- a/internal/model/runway_draft.go +++ b/internal/model/runway_draft.go @@ -1,5 +1,7 @@ package model +import "database/sql" + // BrandRunwayDraft 走秀草稿(爬虫入库待审核)。 // // 爬虫 worker 处理完 ingest_jobs 后不直写正式表,而是写入本表并置为 pending; @@ -42,9 +44,12 @@ type BrandRunwayDraftImage struct { IsDeleted uint8 `gorm:"column:is_deleted" json:"is_deleted"` CreatedAt uint32 `gorm:"column:created_at" json:"created_at"` UpdatedAt uint32 `gorm:"column:updated_at" json:"updated_at"` - Phash uint64 `gorm:"column:phash" json:"phash"` // 感知哈希 64-bit;0=未计算 - IsDuplicate uint8 `gorm:"column:is_duplicate" json:"is_duplicate"` // 近似重复标记:0=否 1=是(命中留痕不删) - DupOf string `gorm:"column:dup_of" json:"dup_of"` // 近似重复指向的图 uid(hashid),''=非重复 + + // 去重字段:见 BrandRunwayImage 注释。phash 为 vector(64) 二进制向量(NULL=无法解码)。 + ContentSha1 string `gorm:"column:content_sha1;type:varchar(64);not null;default:''" json:"content_sha1"` + Phash sql.NullString `gorm:"column:phash;type:vector(64)" json:"phash"` + IsDuplicate uint8 `gorm:"column:is_duplicate;not null;default:0" json:"is_duplicate"` + DupOf string `gorm:"column:dup_of;type:varchar(32);not null;default:''" json:"dup_of"` } // TableName 指定草稿图片表名。 diff --git a/internal/model/runway_image.go b/internal/model/runway_image.go index 5a09e64..17ff2ee 100644 --- a/internal/model/runway_image.go +++ b/internal/model/runway_image.go @@ -1,5 +1,7 @@ package model +import "database/sql" + // BrandRunwayImage 走秀图片。 type BrandRunwayImage struct { ID uint32 `gorm:"primaryKey;column:id" json:"id"` @@ -13,9 +15,15 @@ type BrandRunwayImage struct { SortOrder uint32 `gorm:"column:sort_order" json:"sort_order"` // 拖拽排序用,由迁移脚本新增 LookIndex uint32 `gorm:"column:look_index" json:"look_index"` // 细节图归属的主图序号(主图=该 look;细节图=所属主图的 look) IsDetail uint8 `gorm:"column:is_detail" json:"is_detail"` // 0=主图/look 图(默认展示) 1=细节图 - Phash uint64 `gorm:"column:phash" json:"phash"` // 感知哈希 64-bit;0=未计算(存量) - IsDuplicate uint8 `gorm:"column:is_duplicate" json:"is_duplicate"` // 近似重复标记:0=否 1=是(命中留痕不删) - DupOf string `gorm:"column:dup_of" json:"dup_of"` // 近似重复指向的图 uid(hashid),''=非重复 + + // 去重字段(精确 + 近重复 + 语义 embedding 留痕): + // content_sha1 图片内容 sha1,与存储 key 同源,空串为迁移前遗留行; + // phash 为 dHash 的 pgvector 二进制向量(vector(64)),NULL 表示无法解码(如 webp),不参与检索; + // is_duplicate / dup_of 仅在命中近重复时标记,供人工审核留痕,不阻断入库。 + ContentSha1 string `gorm:"column:content_sha1;type:varchar(64);not null;default:''" json:"content_sha1"` + Phash sql.NullString `gorm:"column:phash;type:vector(64)" json:"phash"` + IsDuplicate uint8 `gorm:"column:is_duplicate;not null;default:0" json:"is_duplicate"` + DupOf string `gorm:"column:dup_of;type:varchar(32);not null;default:''" json:"dup_of"` } // TableName 指定表名。 diff --git a/internal/model/street_snap.go b/internal/model/street_snap.go index 4210b5b..bd3f9b3 100644 --- a/internal/model/street_snap.go +++ b/internal/model/street_snap.go @@ -1,5 +1,7 @@ package model +import "database/sql" + // StreetSnap 街拍主表(对应 db_dev.street_snap)。 // // 字段对齐 db_dev 约定:INT UNSIGNED 主键、int unsigned 时间戳、is_deleted 软删、varchar(255)。 @@ -31,9 +33,12 @@ type StreetSnapImage struct { IsDeleted uint8 `gorm:"column:is_deleted" json:"is_deleted"` CreatedAt uint32 `gorm:"column:created_at" json:"created_at"` UpdatedAt uint32 `gorm:"column:updated_at" json:"updated_at"` - Phash uint64 `gorm:"column:phash" json:"phash"` // 感知哈希 64-bit;0=未计算(存量) - IsDuplicate uint8 `gorm:"column:is_duplicate" json:"is_duplicate"` // 近似重复标记:0=否 1=是(命中留痕不删) - DupOf string `gorm:"column:dup_of" json:"dup_of"` // 近似重复指向的图 uid(hashid),''=非重复 + + // 去重字段:见 BrandRunwayImage 注释。phash 为 vector(64) 二进制向量(NULL=无法解码)。 + ContentSha1 string `gorm:"column:content_sha1;type:varchar(64);not null;default:''" json:"content_sha1"` + Phash sql.NullString `gorm:"column:phash;type:vector(64)" json:"phash"` + IsDuplicate uint8 `gorm:"column:is_duplicate;not null;default:0" json:"is_duplicate"` + DupOf string `gorm:"column:dup_of;type:varchar(32);not null;default:''" json:"dup_of"` } // TableName 指定图片明细表名。 diff --git a/internal/model/street_snap_draft.go b/internal/model/street_snap_draft.go index 30f0155..4a06517 100644 --- a/internal/model/street_snap_draft.go +++ b/internal/model/street_snap_draft.go @@ -1,5 +1,7 @@ package model +import "database/sql" + // StreetSnapDraft 街拍草稿(爬虫入库待审核)。 // // 与 brand_runway_draft 同构的审核流程:爬虫 worker 处理完 ingest_jobs 后写入本表并置 @@ -36,9 +38,12 @@ type StreetSnapDraftImage struct { IsDeleted uint8 `gorm:"column:is_deleted" json:"is_deleted"` CreatedAt uint32 `gorm:"column:created_at" json:"created_at"` UpdatedAt uint32 `gorm:"column:updated_at" json:"updated_at"` - Phash uint64 `gorm:"column:phash" json:"phash"` // 感知哈希 64-bit;0=未计算 - IsDuplicate uint8 `gorm:"column:is_duplicate" json:"is_duplicate"` // 近似重复标记:0=否 1=是(命中留痕不删) - DupOf string `gorm:"column:dup_of" json:"dup_of"` // 近似重复指向的图 uid(hashid),''=非重复 + + // 去重字段:见 BrandRunwayImage 注释。phash 为 vector(64) 二进制向量(NULL=无法解码)。 + ContentSha1 string `gorm:"column:content_sha1;type:varchar(64);not null;default:''" json:"content_sha1"` + Phash sql.NullString `gorm:"column:phash;type:vector(64)" json:"phash"` + IsDuplicate uint8 `gorm:"column:is_duplicate;not null;default:0" json:"is_duplicate"` + DupOf string `gorm:"column:dup_of;type:varchar(32);not null;default:''" json:"dup_of"` } // TableName 指定草稿图片表名。 diff --git a/internal/pkg/phash/phash.go b/internal/pkg/phash/phash.go new file mode 100644 index 0000000..878402c --- /dev/null +++ b/internal/pkg/phash/phash.go @@ -0,0 +1,126 @@ +// Package phash 计算图片的感知哈希(dHash,Difference Hash)。 +// +// dHash 是 64-bit 轻量指纹,用于判断「同一张图被转码 / 加水印 / 改尺寸」这类近重复。 +// 去重检索不在这里做——交给 PostgreSQL + pgvector 的 HNSW 索引(见 database 包的 +// ensureDedupSchema),本包只负责产出指纹,复杂度极低、零 CGO、零 ML 依赖。 +// +// 与之前被移除的全表扫描实现不同:现在指纹只写库、检索交给索引,O(1) 桶内比对即可, +// 图片量级再大也扛得住。 +package phash + +import ( + "bytes" + "image" + _ "image/gif" + _ "image/jpeg" + _ "image/png" + "math" + "strings" +) + +// Size 是哈希位数(9x8 灰度 → 8 行 × 8 差 = 64 bit)。 +const Size = 64 + +// DefaultThreshold 汉明距离阈值:≤ 该值判为近重复。可按真实样本微调。 +const DefaultThreshold = 10 + +// Of 计算 data(jpeg/png/gif 字节流)的 dHash 指纹。 +// 解码失败返回 0,调用方据此把 phash 置空(NULL,不参与近邻检索),不阻断入库。 +func Of(data []byte) uint64 { + img, _, err := image.Decode(bytes.NewReader(data)) + if err != nil { + return 0 + } + return dhash(img) +} + +const ( + dw = 9 // 灰度矩阵宽度(列数) + dh = 8 // 灰度矩阵高度(行数) +) + +// dhash 把图像缩到 9x8 灰度,逐行比较相邻像素亮度,得到 64-bit 指纹。 +func dhash(img image.Image) uint64 { + b := img.Bounds() + scaleX := float64(b.Dx()) / float64(dw) + scaleY := float64(b.Dy()) / float64(dh) + + gray := make([][]float64, dh) + for y := 0; y < dh; y++ { + gray[y] = make([]float64, dw) + y0 := int(float64(y) * scaleY) + y1 := int(math.Ceil(float64(y+1) * scaleY)) + if y1 <= y0 { + y1 = y0 + 1 + } + for x := 0; x < dw; x++ { + x0 := int(float64(x) * scaleX) + x1 := int(math.Ceil(float64(x+1) * scaleX)) + if x1 <= x0 { + x1 = x0 + 1 + } + var sum float64 + var n int + for sy := y0; sy < y1 && sy < b.Dy(); sy++ { + for sx := x0; sx < x1 && sx < b.Dx(); sx++ { + r, g, bl, _ := img.At(b.Min.X+sx, b.Min.Y+sy).RGBA() + // 感知亮度(ITU-R BT.601) + lum := 0.299*float64(r>>8) + 0.587*float64(g>>8) + 0.114*float64(bl>>8) + sum += lum + n++ + } + } + if n > 0 { + gray[y][x] = sum / float64(n) + } + } + } + + var hash uint64 + i := 0 + for y := 0; y < dh; y++ { + for x := 0; x < dw-1; x++ { + if gray[y][x] > gray[y][x+1] { + hash |= 1 << uint(i) + } + i++ + } + } + return hash +} + +// ToVectorBits 把 64-bit 指纹转成 pgvector 的二进制向量字符串 "[0,1,...,1]"(长度 64), +// 用于写入 vector(64) 列,并以 bit_hamming_ops 建 HNSW 索引做汉明近邻检索。 +// h 为 0(解码失败)时返回空串,调用方据此存 NULL、不参与检索。 +func ToVectorBits(h uint64) string { + if h == 0 { + return "" + } + var sb strings.Builder + sb.Grow(Size + 1) + sb.WriteByte('[') + for i := 0; i < Size; i++ { + if i > 0 { + sb.WriteByte(',') + } + if (h>>uint(i))&1 == 1 { + sb.WriteByte('1') + } else { + sb.WriteByte('0') + } + } + sb.WriteByte(']') + return sb.String() +} + +// Hamming 返回两个指纹的汉明距离(不同 bit 数)。仅在 Go 侧需要手工比对时使用; +// 检索场景直接交给 pgvector 的 <~> 算子。 +func Hamming(a, b uint64) int { + c := 0 + x := a ^ b + for x != 0 { + x &= x - 1 + c++ + } + return c +} diff --git a/internal/repository/brand_repository.go b/internal/repository/brand_repository.go index b04f3b5..a34340e 100644 --- a/internal/repository/brand_repository.go +++ b/internal/repository/brand_repository.go @@ -92,7 +92,7 @@ func (r *brandRepository) brandFilterScope(q dto.BrandQuery, restrictIDs []uint3 case q.Letter >= "A" && q.Letter <= "Z" && len(q.Letter) == 1: db = db.Where("UPPER(LEFT(name_en,1)) = ?", q.Letter) default: - db = db.Where("name_en REGEXP ?", latinPrefixRegexp) + db = db.Where("name_en ~ ?", latinPrefixRegexp) } // 字母索引始终只返回"拥有走秀档案"的品牌(库中有 2 万+ 无档案品牌, diff --git a/internal/repository/ingest_repository.go b/internal/repository/ingest_repository.go index 29a6f9e..ee49da1 100644 --- a/internal/repository/ingest_repository.go +++ b/internal/repository/ingest_repository.go @@ -44,6 +44,10 @@ type IngestRepository interface { CreateStreetSnapDraft(ctx context.Context, d *model.StreetSnapDraft) (uint32, error) // CreateStreetSnapDraftImages 批量插入街拍草稿图片行。 CreateStreetSnapDraftImages(ctx context.Context, imgs []model.StreetSnapDraftImage) error + // ImageExistsBySha1 在给定图片表中是否已存在相同内容哈希(精确重复);用于入库前跳过该行。 + ImageExistsBySha1(ctx context.Context, tables []string, sha1 string) (bool, error) + // FindNearDuplicateImage 在给定图片表中按 dHash 汉明距离检索近重复,返回命中行 id(仅取最近一条)。 + FindNearDuplicateImage(ctx context.Context, tables []string, phashBits string, threshold int) (dupID uint32, found bool, err error) // ListJobs 按 id 倒序分页列出入库任务(用于后台监控页)。offset/limit 控制分页。 ListJobs(ctx context.Context, offset, limit int) ([]model.IngestJob, error) // CountJobs 返回 ingest_jobs 总条数(用于分页计算总页数)。 @@ -56,16 +60,6 @@ type IngestRepository interface { // ScheduleRetry 失败时调用:attempts+1,未达上限则退避后重置 pending,达上限则置 failed。 // 用于临时失败(网络抖动 / 单图下载失败)的自动重试,区别于永久失败(payload 解析错等)直接 MarkFailed。 ScheduleRetry(ctx context.Context, id uint32, errMsg string) error - // ListImagePHashes 返回全部已晋升图片(runway + street)的 (id, phash, kind), - // 跳过 is_deleted 与 phash=0/NULL(存量未计算)。供入库时与新增图做全局汉明比对(近似去重)。 - ListImagePHashes(ctx context.Context) ([]ImagePHash, error) -} - -// ImagePHash 已晋升图片的感知哈希摘要,供入库时全局近似去重比对。 -type ImagePHash struct { - ID uint32 // 图片数字主键 - Phash uint64 // 感知哈希(SQL 已过滤 0/NULL) - Kind string // "runway" | "street"(决定 dup_of 的 hashid 类型) } type ingestRepository struct { @@ -376,38 +370,45 @@ func (r *ingestRepository) RetryJob(ctx context.Context, id uint32) error { }).Error } -// ListImagePHashes 返回全部已晋升图片(runway + street)的感知哈希摘要,供入库时全局近似去重。 -// 跳过 is_deleted 与 phash=0/NULL(存量未计算)。结果合并 runway + street 两类, -// 用 Kind 标注类型,调用方据此把 dup_of 编码成对应 hashid 类型。 -// -// 注:每次入库任务都会全量拉取一次(图片量当前为千级,可接受);若后续图片量到十万级, -// 可改为按 runway_id/snap_id 分批或加内存缓存 + 定时刷新,避免每 job 一次全表扫描。 -func (r *ingestRepository) ListImagePHashes(ctx context.Context) ([]ImagePHash, error) { - type phRow struct { - ID uint32 `gorm:"column:id"` - Phash uint64 `gorm:"column:phash"` - } - out := make([]ImagePHash, 0, 64) - const whereActive = "is_deleted = 0 AND phash IS NOT NULL AND phash <> 0" - var rw []phRow - if err := r.db.WithContext(ctx).Model(&model.BrandRunwayImage{}). - Select("id, phash").Where(whereActive).Scan(&rw).Error; err != nil { - return nil, err - } - for _, x := range rw { - out = append(out, ImagePHash{ID: x.ID, Phash: x.Phash, Kind: "runway"}) - } - var sn []phRow - if err := r.db.WithContext(ctx).Model(&model.StreetSnapImage{}). - Select("id, phash").Where(whereActive).Scan(&sn).Error; err != nil { - return nil, err +// ImageExistsBySha1 在给定图片表中是否已存在相同 content_sha1(精确重复)。 +func (r *ingestRepository) ImageExistsBySha1(ctx context.Context, tables []string, sha1 string) (bool, error) { + for _, t := range tables { + var c int64 + if err := r.db.WithContext(ctx).Table(t). + Where("content_sha1 = ? AND is_deleted = 0", sha1).Count(&c).Error; err != nil { + return false, err + } + if c > 0 { + return true, nil + } } - for _, x := range sn { - out = append(out, ImagePHash{ID: x.ID, Phash: x.Phash, Kind: "street"}) + return false, nil +} + +// FindNearDuplicateImage 在给定图片表中按 dHash 汉明距离(pgvector <~> 算子)检索近重复, +// 取距离 ≤ threshold 的最近一条。phashBits 为 vector(64) 二进制向量串;NULL 的 phash 不参与比较。 +func (r *ingestRepository) FindNearDuplicateImage(ctx context.Context, tables []string, phashBits string, threshold int) (uint32, bool, error) { + for _, t := range tables { + var row struct { + ID uint32 `gorm:"column:id"` + Dist int `gorm:"column:dist"` + } + err := r.db.WithContext(ctx).Table(t). + Select("id, (phash <~> ?::vector) AS dist", phashBits). + Where("(phash <~> ?::vector) <= ?", phashBits, threshold). + Order("dist ASC"). + Limit(1). + Scan(&row).Error + if err != nil { + return 0, false, err + } + if row.ID != 0 { + return row.ID, true, nil + } } - return out, nil + return 0, false, nil } // isDuplicateKey 兜底:gorm 的 ErrDuplicatedKey 在不同驱动下的封装不一定一致, diff --git a/internal/repository/review_repository.go b/internal/repository/review_repository.go index 9835419..a86ab83 100644 --- a/internal/repository/review_repository.go +++ b/internal/repository/review_repository.go @@ -244,20 +244,21 @@ func (r *reviewRepository) SaveRunwayFromDraft(ctx context.Context, draftID uint if len(imgs) > 0 { rows := make([]model.BrandRunwayImage, 0, len(imgs)) for i, im := range imgs { - rows = append(rows, model.BrandRunwayImage{ - RunwayID: runwayID, - BrandID: draft.BrandID, - Image: im.Image, - Name: im.Name, - SortOrder: uint32(i + 1), - LookIndex: im.LookIndex, - IsDetail: im.IsDetail, - Phash: im.Phash, - IsDuplicate: im.IsDuplicate, - DupOf: im.DupOf, - CreatedAt: now, - UpdatedAt: now, - }) + rows = append(rows, model.BrandRunwayImage{ + RunwayID: runwayID, + BrandID: draft.BrandID, + Image: im.Image, + Name: im.Name, + SortOrder: uint32(i + 1), + LookIndex: im.LookIndex, + IsDetail: im.IsDetail, + ContentSha1: im.ContentSha1, + Phash: im.Phash, + IsDuplicate: im.IsDuplicate, + DupOf: im.DupOf, + CreatedAt: now, + UpdatedAt: now, + }) } if cErr := tx.Create(&rows).Error; cErr != nil { return cErr @@ -439,17 +440,18 @@ func (r *reviewRepository) SaveStreetSnapFromDraft(ctx context.Context, draftID if len(imgs) > 0 { rows := make([]model.StreetSnapImage, 0, len(imgs)) for i, im := range imgs { - rows = append(rows, model.StreetSnapImage{ - SnapID: snapID, - Image: im.Image, - Name: im.Name, - SortOrder: uint32(i + 1), - Phash: im.Phash, - IsDuplicate: im.IsDuplicate, - DupOf: im.DupOf, - CreatedAt: now, - UpdatedAt: now, - }) + rows = append(rows, model.StreetSnapImage{ + SnapID: snapID, + Image: im.Image, + Name: im.Name, + SortOrder: uint32(i + 1), + ContentSha1: im.ContentSha1, + Phash: im.Phash, + IsDuplicate: im.IsDuplicate, + DupOf: im.DupOf, + CreatedAt: now, + UpdatedAt: now, + }) } if cErr := tx.Create(&rows).Error; cErr != nil { return cErr diff --git a/internal/service/ingest_cleanup_test.go b/internal/service/ingest_cleanup_test.go index bae1e24..43a84df 100644 --- a/internal/service/ingest_cleanup_test.go +++ b/internal/service/ingest_cleanup_test.go @@ -9,6 +9,7 @@ import ( "strings" "testing" + "fashionapi/internal/dto" "fashionapi/internal/pkg/storage" ) @@ -25,12 +26,12 @@ func TestFetchImagesCleansUpOnFailure(t *testing.T) { return } w.Header().Set("Content-Type", "image/jpeg") - _, _ = w.Write([]byte("fakeimagebytes")) + _, _ = w.Write([]byte("fakeimagebytes" + r.URL.Path)) })) defer srv.Close() urls := []string{srv.URL + "/ok1.jpg", srv.URL + "/ok2.jpg", srv.URL + "/bad.jpg"} - _, out, _, keys, failed := s.fetchImages(context.Background(), urls, "runway") + _, out, keys, failed := s.fetchImages(context.Background(), urls, "runway", dto.IngestKindRunway) if !failed { t.Fatalf("expected failed=true when one image errors") } diff --git a/internal/service/ingest_service.go b/internal/service/ingest_service.go index 025f1e9..0e0299e 100644 --- a/internal/service/ingest_service.go +++ b/internal/service/ingest_service.go @@ -3,6 +3,7 @@ package service import ( "context" "crypto/sha1" + "database/sql" "encoding/hex" "encoding/json" "fmt" @@ -10,6 +11,7 @@ import ( "log" "net/http" "path" + "strconv" "time" "fashionapi/internal/dto" @@ -235,36 +237,31 @@ func (s *IngestService) processRunway(ctx context.Context, job model.IngestJob, // 4) 下载图片并上传到存储(结构化 Looks 优先:主图+细节图分组;否则回退 Images 全部视为主图)。 // 内容哈希(sha1)key 保证重爬不产生孤儿文件:失败回滚删本批 key 即可。 - // 同时算出每张图的 pHash(downloadOne 内基于原始字节),供后续全局近似去重标记。 - var cover string + var cover string var draftImages []model.BrandRunwayDraftImage var keys []string var imgFailed bool var imageCount uint16 - var phashList []uint64 if len(p.Looks) > 0 { cover, draftImages, keys, imgFailed = s.fetchLookImages(ctx, p.Looks, "runway") imageCount = uint16(len(p.Looks)) - phashList = make([]uint64, len(draftImages)) - for i, d := range draftImages { - phashList[i] = d.Phash - } } else { - var imgs []string - var phs []uint64 - cover, imgs, phs, keys, imgFailed = s.fetchImages(ctx, p.Images, "runway") - imageCount = uint16(len(imgs)) - for i, img := range imgs { + var fimgs []fetchedImage + cover, fimgs, keys, imgFailed = s.fetchImages(ctx, p.Images, "runway", dto.IngestKindRunway) + imageCount = uint16(len(fimgs)) + for i, fi := range fimgs { draftImages = append(draftImages, model.BrandRunwayDraftImage{ - Image: img, - Name: fmt.Sprintf("Look %d", i+1), - SortOrder: uint32(i + 1), - LookIndex: uint32(i + 1), - IsDetail: 0, - Phash: phs[i], + Image: fi.url, + Name: fmt.Sprintf("Look %d", i+1), + SortOrder: uint32(i + 1), + LookIndex: uint32(i + 1), + IsDetail: 0, + ContentSha1: fi.sha1, + Phash: sqlNull(fi.phash), + IsDuplicate: fi.isDup, + DupOf: strconv.FormatUint(uint64(fi.dupID), 10), }) } - phashList = phs } if imgFailed { // 单图失败=整任务失败:先回滚本批已上传的图(S4 + 本地兜底),避免孤儿文件永远堆在存储里, @@ -274,12 +271,6 @@ func (s *IngestService) processRunway(ctx context.Context, job model.IngestJob, return } - // 4.5) 全局近似去重标记:与「已晋升图片」比对汉明距离,命中则留痕(is_duplicate=1 + dup_of), - // 不丢弃、交后台人工裁决(只拦新增,不碰存量)。比对失败仅告警,不阻断入库。 - s.tagDuplicates(ctx, phashList, func(i int, dupOf string) { - draftImages[i].IsDuplicate = 1 - draftImages[i].DupOf = dupOf - }) // 5) 写草稿表(status=pending),等待后台审核通过后再晋升正式表 draft := &model.BrandRunwayDraft{ @@ -316,31 +307,44 @@ func (s *IngestService) processRunway(ctx context.Context, job model.IngestJob, // BrandRunwayDraftImage 行(带 look_index / is_detail 分组)。任意一张下载/上传失败即把 // failed 置 true,调用方据此把整条任务判失败并回滚本批已上传的 key,符合「单图失败=整任务失败」策略。 // cover 取首个成功下载的主图;image_count(主图数)由调用方按 len(Looks) 计,不在此返回。 +// 每张图入库前做去重:content_sha1 已存在则整行跳过(精确重复);命中 dHash 近重复则仍入库但标记留痕。 func (s *IngestService) fetchLookImages(ctx context.Context, looks []dto.RunwayLook, prefix string) (string, []model.BrandRunwayDraftImage, []string, bool) { cover := "" rows := make([]model.BrandRunwayDraftImage, 0) keys := make([]string, 0) + seen := make(map[string]bool) failed := false order := 0 for li, look := range looks { lookIdx := li + 1 if look.Main != "" { - order++ - url, key, ph, err := s.downloadOne(ctx, look.Main, order, prefix) + url, key, sha1h, ph, err := s.downloadOne(ctx, look.Main, order, prefix) if err != nil { failed = true } else { + keys = append(keys, key) + if seen[sha1h] { + continue + } + seen[sha1h] = true + skip, dupID, isDup := s.dedupImage(ctx, dto.IngestKindRunway, sha1h, ph) + if skip { + continue + } + order++ if cover == "" { cover = url } - keys = append(keys, key) rows = append(rows, model.BrandRunwayDraftImage{ - Image: url, - Name: fmt.Sprintf("Look %d", lookIdx), - SortOrder: uint32(order), - LookIndex: uint32(lookIdx), - IsDetail: 0, - Phash: ph, + Image: url, + Name: fmt.Sprintf("Look %d", lookIdx), + SortOrder: uint32(order), + LookIndex: uint32(lookIdx), + IsDetail: 0, + ContentSha1: sha1h, + Phash: sqlNull(ph), + IsDuplicate: isDup, + DupOf: strconv.FormatUint(uint64(dupID), 10), }) } } @@ -348,20 +352,31 @@ func (s *IngestService) fetchLookImages(ctx context.Context, looks []dto.RunwayL if d == "" { continue } - order++ - url, key, ph, err := s.downloadOne(ctx, d, order, prefix) + url, key, sha1h, ph, err := s.downloadOne(ctx, d, order, prefix) if err != nil { failed = true continue } keys = append(keys, key) + if seen[sha1h] { + continue + } + seen[sha1h] = true + skip, dupID, isDup := s.dedupImage(ctx, dto.IngestKindRunway, sha1h, ph) + if skip { + continue + } + order++ rows = append(rows, model.BrandRunwayDraftImage{ - Image: url, - Name: fmt.Sprintf("Look %d — Detail %d", lookIdx, di+1), - SortOrder: uint32(order), - LookIndex: uint32(lookIdx), - IsDetail: 1, - Phash: ph, + Image: url, + Name: fmt.Sprintf("Look %d — Detail %d", lookIdx, di+1), + SortOrder: uint32(order), + LookIndex: uint32(lookIdx), + IsDetail: 1, + ContentSha1: sha1h, + Phash: sqlNull(ph), + IsDuplicate: isDup, + DupOf: strconv.FormatUint(uint64(dupID), 10), }) } } @@ -377,8 +392,8 @@ func (s *IngestService) processStreet(ctx context.Context, job model.IngestJob, return } - // 2) 下载图片并上传到存储(七牛优先,失败兜底本地);同时算 pHash 供近似去重。 - cover, imgs, phs, keys, imgFailed := s.fetchImages(ctx, p.Images, "street") + // 2) 下载图片并上传到存储(七牛优先,失败兜底本地)。 + cover, fimgs, keys, imgFailed := s.fetchImages(ctx, p.Images, "street", dto.IngestKindStreet) if len(p.Images) > 0 && imgFailed { // 单图失败=整任务失败:先回滚本批已上传的图(七牛 + 本地兜底),避免孤儿文件永远堆在存储里, // 然后按指数退避自动重试,达上限才置 failed 等后台手动重试。 @@ -394,7 +409,7 @@ func (s *IngestService) processStreet(ctx context.Context, job model.IngestJob, Year: p.Year, City: p.City, Cover: cover, - ImageCount: uint16(len(imgs)), + ImageCount: uint16(len(fimgs)), Status: model.DraftStatusPending, } id, err := s.repo.CreateStreetSnapDraft(ctx, draft) @@ -402,22 +417,20 @@ func (s *IngestService) processStreet(ctx context.Context, job model.IngestJob, s.failOrRetry(ctx, job.ID, "create street draft: "+err.Error()) return } - rows := make([]model.StreetSnapDraftImage, 0, len(imgs)) - for i, img := range imgs { + rows := make([]model.StreetSnapDraftImage, 0, len(fimgs)) + for i, fi := range fimgs { rows = append(rows, model.StreetSnapDraftImage{ - DraftID: id, - Image: img, - Name: fmt.Sprintf("Look %d", i+1), - SortOrder: uint32(i + 1), - Phash: phs[i], + DraftID: id, + Image: fi.url, + Name: fmt.Sprintf("Look %d", i+1), + SortOrder: uint32(i + 1), + ContentSha1: fi.sha1, + Phash: sqlNull(fi.phash), + IsDuplicate: fi.isDup, + DupOf: strconv.FormatUint(uint64(fi.dupID), 10), }) } - // 3.5) 全局近似去重标记(与走秀同逻辑,只拦新增、留痕不删)。 - s.tagDuplicates(ctx, phs, func(i int, dupOf string) { - rows[i].IsDuplicate = 1 - rows[i].DupOf = dupOf - }) if err := s.repo.CreateStreetSnapDraftImages(ctx, rows); err != nil { s.failOrRetry(ctx, job.ID, "create street draft images: "+err.Error()) @@ -426,30 +439,48 @@ func (s *IngestService) processStreet(ctx context.Context, job model.IngestJob, _ = s.repo.MarkDone(ctx, job.ID) } -// fetchImages 下载图片并上传到存储,返回 (cover 地址, 全部图片地址, 各图 pHash, 已成功上传对象的 key 列表, 是否有任意一张失败)。 +// fetchImages 下载图片并上传到存储,返回 (cover 地址, 全部图片地址, 已成功上传对象的 key 列表, 是否有任意一张失败)。 // prefix 为七牛 key 前缀(runway/ 或 street/)。只要任意一张下载/上传失败,failed 即置 true, // 调用方据此把整条任务判为失败(不再写草稿),并拿 keys 回滚本批已上传的对象,符合「单图失败=整任务失败」策略。 -// 返回的 pHash 与图片地址按索引对齐(phash=0 表示解码失败未计算,比对时跳过)。 -func (s *IngestService) fetchImages(ctx context.Context, urls []string, prefix string) (string, []string, []uint64, []string, bool) { + +// fetchImages 下载图片并上传到存储,返回 (cover 地址, 已下载图结构, 已成功上传对象的 key 列表, 是否有任意一张失败)。 +// prefix 为七牛 key 前缀(runway/ 或 street/)。kind 用于选择去重比对表。 +// 只要任意一张下载/上传失败,failed 即置 true,调用方据此把整条任务判为失败并回滚本批已上传的对象, +// 符合「单图失败=整任务失败」策略。每张图入库前做去重(精确跳过 + 近重复标记)。 +func (s *IngestService) fetchImages(ctx context.Context, urls []string, prefix, kind string) (string, []fetchedImage, []string, bool) { cover := "" - out := make([]string, 0, len(urls)) - phashes := make([]uint64, 0, len(urls)) + out := make([]fetchedImage, 0, len(urls)) keys := make([]string, 0, len(urls)) + seen := make(map[string]bool) failed := false - for i, u := range urls { - url, key, ph, err := s.downloadOne(ctx, u, i, prefix) + for _, u := range urls { + url, key, sha1h, ph, err := s.downloadOne(ctx, u, 0, prefix) if err != nil { failed = true continue } - if i == 0 { + keys = append(keys, key) + if seen[sha1h] { + continue + } + seen[sha1h] = true + skip, dupID, isDup := s.dedupImage(ctx, kind, sha1h, ph) + if skip { + continue + } + if cover == "" { cover = url } - out = append(out, url) - phashes = append(phashes, ph) - keys = append(keys, key) + out = append(out, fetchedImage{ + url: url, + key: key, + sha1: sha1h, + phash: ph, + dupID: dupID, + isDup: isDup, + }) } - return cover, out, phashes, keys, failed + return cover, out, keys, failed } // cleanupUploads 删除一批本批次成功上传的对象(七牛 + 本地兜底),用于任务失败回滚: @@ -471,21 +502,65 @@ func (s *IngestService) cleanupUploads(ctx context.Context, keys []string) { } } +// fetchedImage 是单张已下载图片的暂存结构,携带去重所需的指纹信息。 +type fetchedImage struct { + url string + key string + sha1 string // 内容 sha1(与存储 key 同源) + phash string // dHash 的 pgvector 二进制向量串,空串表示无法解码 + dupID uint32 // 命中近重复时的参考图 id + isDup uint8 // 是否标记为近重复(供审核留痕) +} + +// sqlNull 把 phash 字符串转成可空向量字段:空串 → NULL(不参与近邻检索)。 +func sqlNull(ph string) sql.NullString { + return sql.NullString{String: ph, Valid: ph != ""} +} + +// dedupImage 判断单张图是否重复: +// - 精确重复(content_sha1 已在库)→ 返回 skip=true(不入库该行); +// - 近重复(dHash 汉明距离 ≤ 阈值)→ 仍入库,但标记 is_duplicate + dup_of; +// - 否则正常入库。 +func (s *IngestService) dedupImage(ctx context.Context, kind, sha1hash, phashBits string) (skip bool, dupID uint32, isDup uint8) { + // repo 未注入(如离线单测)时跳过去重,不阻断主流程。生产环境 repo 必不为空。 + if s.repo == nil { + return false, 0, 0 + } + var tables []string + switch kind { + case dto.IngestKindRunway: + tables = []string{"brand_runway_draft_images", "brand_runway_images"} + case dto.IngestKindStreet: + tables = []string{"street_snap_draft_images", "street_snap_images"} + default: + return false, 0, 0 + } + if exists, err := s.repo.ImageExistsBySha1(ctx, tables, sha1hash); err == nil && exists { + return true, 0, 0 + } + if phashBits != "" { + if id, found, err := s.repo.FindNearDuplicateImage(ctx, tables, phashBits, phash.DefaultThreshold); err == nil && found { + return false, id, 1 + } + } + return false, 0, 0 +} + // downloadOne 把单张远程图下载后上传到存储(七牛优先,失败兜底本地), -// 返回 (访问地址, 对象 key, 感知哈希, error)。访问地址可直接写入数据库 -// (七牛为完整 https URL,本地为相对 /uploads 路径);感知哈希基于原始字节算一次,供入库时近似去重。 -func (s *IngestService) downloadOne(ctx context.Context, u string, idx int, prefix string) (string, string, uint64, error) { +// 返回 (访问地址, 对象 key, 内容 sha1, dHash 向量串, error)。访问地址可直接写入数据库 +// (七牛为完整 https URL,本地为相对 /uploads 路径)。 +func (s *IngestService) downloadOne(ctx context.Context, u string, idx int, prefix string) (string, string, string, string, error) { resp, err := s.httpClient.Get(u) if err != nil { - return "", "", 0, err + return "", "", "", "", err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return "", "", 0, fmt.Errorf("status %d", resp.StatusCode) + return "", "", "", "", fmt.Errorf("status %d", resp.StatusCode) } data, err := io.ReadAll(resp.Body) if err != nil { - return "", "", 0, err + return "", "", "", "", err } ext := path.Ext(u) if ext == "" || len(ext) > 5 { @@ -498,74 +573,21 @@ func (s *IngestService) downloadOne(ctx context.Context, u string, idx int, pref key := fmt.Sprintf("%s/%s%s", prefix, hash, ext) ct := resp.Header.Get("Content-Type") - // 感知哈希:同一份字节在此算一次(decode 失败时 ph=0,比对时跳过,不阻断入库)。 + // 计算 dHash 指纹(仅用于近重复检索;解码失败返回空串 → NULL,不参与检索)。 ph := phash.Of(data) - if ph == 0 { - log.Printf("[warn] ingest pHash 未计算(解码失败或非 jpeg/png/gif 格式) url=%s", u) - } + phashBits := phash.ToVectorBits(ph) // 主上传器(七牛) if url, err := s.uploader.Upload(ctx, key, data, ct); err == nil { - return url, key, ph, nil + return url, key, hash, phashBits, nil } else if s.local != nil { // 兜底本地,避免图片完全丢失 if lurl, lerr := s.local.Upload(ctx, key, data, ct); lerr == nil { - return lurl, key, ph, nil + return lurl, key, hash, phashBits, nil } else { - return "", "", 0, err + return "", "", "", "", err } } - return "", "", 0, err + return "", "", "", "", err } -// tagDuplicates 对一批图片(phashList 与 apply 下标对齐)做全局近似去重标记: -// 与「已晋升图片」的 phash 库比汉明距离(≤ phash.DefaultThreshold 即近似重复), -// 命中则调用 apply(i, dupOf) 由调用方把第 i 张图标 IsDuplicate=1、DupOf=命中图 uid。 -// 不丢弃任何图、仅留痕(交后台人工裁决),契合「只拦新增、全局跨所有图、标记不删」。 -// 比对库拉取失败仅告警并跳过(不阻断入库);phash=0 的图不比对、不误杀。 -func (s *IngestService) tagDuplicates(ctx context.Context, phashList []uint64, apply func(i int, dupOf string)) { - uids, err := s.matchDuplicates(ctx, phashList) - if err != nil { - log.Printf("[warn] ingest 近似去重比对失败 err=%v(跳过标记,不阻断入库)", err) - return - } - for i, u := range uids { - if u != "" { - apply(i, u) - } - } -} - -// matchDuplicates 返回与 phashList 等长的 dup_of uid 切片(""=未命中近似重复)。 -// 对每张新图,在已晋升图片库里找汉明距离 ≤ 阈值的命中,取距离最近者, -// 按其 kind(runway/street)编码成对应 hashid 类型作为 dup_of。 -func (s *IngestService) matchDuplicates(ctx context.Context, phashList []uint64) ([]string, error) { - refs, err := s.repo.ListImagePHashes(ctx) - if err != nil { - return nil, err - } - out := make([]string, len(phashList)) - for i, ph := range phashList { - if ph == 0 { - continue // 未计算 phash 的图不比对(避免误杀) - } - bestUID := "" - bestDist := phash.DefaultThreshold + 1 - for _, ref := range refs { - if ref.Phash == 0 { - continue - } - d := phash.Hamming(ph, ref.Phash) - if d <= phash.DefaultThreshold && d < bestDist { - var typ byte = hashid.TypeRunwayImage - if ref.Kind == "street" { - typ = hashid.TypeSnapImage - } - bestUID = hashid.EncodeWithType(ref.ID, typ) - bestDist = d - } - } - out[i] = bestUID - } - return out, nil -} diff --git a/scripts/diag_brand/main.go b/scripts/diag_brand/main.go index 970726f..14a94b8 100644 --- a/scripts/diag_brand/main.go +++ b/scripts/diag_brand/main.go @@ -3,14 +3,14 @@ package main import ( "fmt" - "gorm.io/driver/mysql" + "gorm.io/driver/postgres" "gorm.io/gorm" ) -const dsn = "root:root@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local" +const dsn = "postgres://fashion:fashion_dev_2026@127.0.0.1:5432/fashion?sslmode=disable" func main() { - db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } diff --git a/scripts/diag_hot/main.go b/scripts/diag_hot/main.go index d92f46f..0dbb0d8 100644 --- a/scripts/diag_hot/main.go +++ b/scripts/diag_hot/main.go @@ -5,14 +5,14 @@ package main import ( "fmt" - "gorm.io/driver/mysql" + "gorm.io/driver/postgres" "gorm.io/gorm" ) -const dsn = "root:root@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local" +const dsn = "postgres://fashion:fashion_dev_2026@127.0.0.1:5432/fashion?sslmode=disable" func main() { - db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } diff --git a/scripts/seed_users/main.go b/scripts/seed_users/main.go index 5b46c07..b36b63b 100644 --- a/scripts/seed_users/main.go +++ b/scripts/seed_users/main.go @@ -1,7 +1,7 @@ // Command seed_users 预置内部账号(运营/编辑用,不开放公开注册)。 // -// 项目已移除 AutoMigrate,表结构由 scripts/sql/005_create_users.sql 托管; -// 本脚本用 CREATE TABLE IF NOT EXISTS 兜底建表,再 upsert 一个内部账号。 +// 项目表结构由 GORM AutoMigrate 托管(服务启动时创建); +// 本脚本仅在独立运行、尚未跑过服务时兜底建表,再 upsert 一个内部账号。 // // 用法: // go run ./scripts/seed_users @@ -43,19 +43,19 @@ func main() { } }() - // 1. 兜底建表(与 scripts/sql/005_create_users.sql 完全一致) + // 1. 兜底建表(与 User 模型保持一致;正式结构由服务启动时 AutoMigrate 创建,此处仅作独立运行兜底) createSQL := `CREATE TABLE IF NOT EXISTS users ( - id int unsigned NOT NULL AUTO_INCREMENT, - created_at int unsigned NOT NULL DEFAULT 0, - updated_at int unsigned NOT NULL DEFAULT 0, + id bigserial PRIMARY KEY, + created_at bigint NOT NULL DEFAULT 0, + updated_at bigint NOT NULL DEFAULT 0, username varchar(64) NOT NULL, email varchar(191) NOT NULL, password_hash varchar(255) NOT NULL DEFAULT '', - is_deleted tinyint unsigned NOT NULL DEFAULT 0, - PRIMARY KEY (id), - UNIQUE KEY uk_username (username), - UNIQUE KEY uk_email (email) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;` + is_deleted smallint NOT NULL DEFAULT 0, + tier varchar(16) NOT NULL DEFAULT 'free', + UNIQUE (username), + UNIQUE (email) + );` if e := db.Exec(createSQL).Error; e != nil { log.Fatalf("✗ 建表失败: %v", e) } diff --git a/scripts/sql/002_i18n_columns.sql b/scripts/sql/002_i18n_columns.sql deleted file mode 100644 index 38d963e..0000000 --- a/scripts/sql/002_i18n_columns.sql +++ /dev/null @@ -1,79 +0,0 @@ --- ============================================================================ --- 002_i18n_columns.sql --- 方案 A(独立列):把品牌名 / 走秀标题 / 描述 拆分为 en / cn 两列。 --- --- 设计前提(已用探查脚本核对线上数据): --- * brand.name 多为拉丁名,但 266 个含中文;show_name 形如 "拉丁/中文"(2025 个含中文)。 --- * brand_runway.title / description 校验过 han=0,当前全为英文。 --- * 排序 / A-Z 索引 / 关键词搜索 统一基于 name_en(拉丁),中文品牌(name_en 为空)归入 OTHER 桶。 --- --- 回填策略: --- name_en = name 去掉中文后的部分;若 name 全中文则取 show_name 斜杠前部分。 --- name_cn = show_name 斜杠后含中文的部分;否则 show_name 本身(含中文);否则 name(含中文)。 --- title_en / description_en = 原 title / description;title_cn / description_cn = ''(当前无中文)。 --- --- 旧列 name / show_name / title / description 保留不删,作为回退与对比; --- 代码全部改用 *_en / *_cn 后,可择机在后续迁移中 DROP。 --- ============================================================================ - -ALTER TABLE brand - ADD COLUMN name_en VARCHAR(255) NOT NULL DEFAULT '' AFTER name, - ADD COLUMN name_cn VARCHAR(255) NOT NULL DEFAULT '' AFTER name_en; - -ALTER TABLE brand_runway - ADD COLUMN title_en VARCHAR(255) NOT NULL DEFAULT '' AFTER title, - ADD COLUMN title_cn VARCHAR(255) NOT NULL DEFAULT '' AFTER title_en, - ADD COLUMN description_en VARCHAR(1024) NOT NULL DEFAULT '' AFTER description, - ADD COLUMN description_cn VARCHAR(1024) NOT NULL DEFAULT '' AFTER description_en; - --- 回填品牌名:拆拉丁 / 中文 -UPDATE brand SET - name_en = CASE - WHEN TRIM(REGEXP_REPLACE(name, '[一-鿿]', '')) <> '' THEN TRIM(REGEXP_REPLACE(name, '[一-鿿]', '')) - WHEN show_name LIKE '%/%' THEN TRIM(SUBSTRING_INDEX(show_name, '/', 1)) - ELSE '' - END, - name_cn = CASE - WHEN show_name LIKE '%/%' AND SUBSTRING_INDEX(show_name, '/', -1) REGEXP '[一-鿿]' - THEN TRIM(SUBSTRING_INDEX(show_name, '/', -1)) - WHEN show_name REGEXP '[一-鿿]' THEN TRIM(show_name) - WHEN name REGEXP '[一-鿿]' THEN TRIM(name) - ELSE '' - END; - --- 回填走秀:当前 title / description 全为英文,直接进 *_en -UPDATE brand_runway SET - title_en = title, - description_en = description, - title_cn = '', - description_cn = ''; - --- ============================================================================ --- 第 5 步(依赖「分类字段回填迁移」之后执行):title_cn 规则生成 --- --- 前提:collection_type / season / year 已由历史迁移解析回填(rtw/menswear/ --- couture/resort/pre_fall × spring/fall/空)。title 本质是「季节/品类描述」, --- 品牌名在 JOIN 的 brand_name 里单独给,因此 title_cn 可纯规则生成, --- 完全不依赖外部翻译服务,结果稳定可重跑。 --- --- 映射:resort→「{year} 度假系列」、pre_fall→「{year} 早秋系列」、 --- rtw→「{year} {春夏|秋冬}成衣」、menswear→「{year} {春夏|秋冬}男装」、 --- couture→「{year} {春夏|秋冬}高定」。 --- --- 执行器:scripts/backfill_title_cn/main.go(幂等,整表覆盖重跑无害)。 --- 该步骤与上方 i18n 加列/回填相互独立,可单独重跑。 --- ============================================================================ -UPDATE brand_runway -SET title_cn = CASE - WHEN collection_type = 'resort' THEN CONCAT(year, ' 度假系列') - WHEN collection_type = 'pre_fall' THEN CONCAT(year, ' 早秋系列') - WHEN collection_type = 'rtw' AND season = 'spring' THEN CONCAT(year, ' 春夏成衣') - WHEN collection_type = 'rtw' AND season = 'fall' THEN CONCAT(year, ' 秋冬成衣') - WHEN collection_type = 'rtw' THEN CONCAT(year, ' 成衣') - WHEN collection_type = 'menswear' AND season = 'spring' THEN CONCAT(year, ' 春夏男装') - WHEN collection_type = 'menswear' AND season = 'fall' THEN CONCAT(year, ' 秋冬男装') - WHEN collection_type = 'couture' AND season = 'spring' THEN CONCAT(year, ' 春夏高定') - WHEN collection_type = 'couture' AND season = 'fall' THEN CONCAT(year, ' 秋冬高定') - ELSE CONCAT(year, ' 系列') -END -WHERE is_deleted = 0; diff --git a/scripts/sql/003_drop_brand_alias.sql b/scripts/sql/003_drop_brand_alias.sql deleted file mode 100644 index 19afb82..0000000 --- a/scripts/sql/003_drop_brand_alias.sql +++ /dev/null @@ -1,8 +0,0 @@ --- 003_drop_brand_alias.sql --- 删除 brand_alias 孤儿表。 --- 背景:i18n 方案 A 落地后,brand.name_cn / name_en 已成为品牌名权威来源; --- brand_alias 全代码库零引用,且 99.9% 中文记录与 brand.name_cn 完全重复, --- 保留它只会成为名字的第二来源、后期悄然分叉。故删除。 --- 注意:本文件为审阅底稿,实际执行由 scripts/i18n/drop_alias/main.go 驱动(无 mysql 客户端环境)。 - -DROP TABLE IF EXISTS brand_alias; diff --git a/scripts/sql/004_add_streetsnap_city.sql b/scripts/sql/004_add_streetsnap_city.sql deleted file mode 100644 index 5260275..0000000 --- a/scripts/sql/004_add_streetsnap_city.sql +++ /dev/null @@ -1,4 +0,0 @@ --- 街拍地区筛选:street_snap 新增 city 列(从 title 第一段 \t 解析回填) --- 对应执行器 scripts/backfill_city/main.go(幂等,可重跑) --- city 存「地点」原文(如 Paris / 巴黎 / New York),'' 表示未归类,不参与地区筛选 -ALTER TABLE street_snap ADD COLUMN city VARCHAR(128) NOT NULL DEFAULT '' AFTER year; diff --git a/scripts/sql/005_create_users.sql b/scripts/sql/005_create_users.sql deleted file mode 100644 index 2d501da..0000000 --- a/scripts/sql/005_create_users.sql +++ /dev/null @@ -1,14 +0,0 @@ --- 账号体系用户表(内部运营/编辑账号,不开放公开注册)。 --- 与 scripts/seed_users/main.go 中内置的建表语句保持一致。 -CREATE TABLE IF NOT EXISTS `users` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `created_at` int unsigned NOT NULL DEFAULT 0, - `updated_at` int unsigned NOT NULL DEFAULT 0, - `username` varchar(64) NOT NULL, - `email` varchar(191) NOT NULL, - `password_hash` varchar(255) NOT NULL DEFAULT '', - `is_deleted` tinyint unsigned NOT NULL DEFAULT 0, - PRIMARY KEY (`id`), - UNIQUE KEY `uk_username` (`username`), - UNIQUE KEY `uk_email` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/scripts/sql/006_create_refresh_tokens.sql b/scripts/sql/006_create_refresh_tokens.sql deleted file mode 100644 index 65132bc..0000000 --- a/scripts/sql/006_create_refresh_tokens.sql +++ /dev/null @@ -1,15 +0,0 @@ --- 006: refresh_tokens —— 刷新令牌表(双令牌续期 + 踢下线的服务端状态) --- 与项目约定一致:表结构由 SQL 托管,不依赖 GORM AutoMigrate。 -CREATE TABLE IF NOT EXISTS refresh_tokens ( - id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - user_id INT UNSIGNED NOT NULL, - token_hash VARCHAR(64) NOT NULL, - expires_at INT UNSIGNED NOT NULL DEFAULT 0, - revoked TINYINT UNSIGNED NOT NULL DEFAULT 0, - user_agent VARCHAR(255) NOT NULL DEFAULT '', - ip VARCHAR(64) NOT NULL DEFAULT '', - created_at INT UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY (id), - UNIQUE KEY uk_token_hash (token_hash), - KEY idx_user_id (user_id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/scripts/sql/007_create_favorites.sql b/scripts/sql/007_create_favorites.sql deleted file mode 100644 index b471ff6..0000000 --- a/scripts/sql/007_create_favorites.sql +++ /dev/null @@ -1,17 +0,0 @@ --- 007: favorites —— 用户收藏(服务端持久化,按用户隔离) --- 与项目约定一致:表结构由 SQL 托管,不依赖 GORM AutoMigrate。 --- target_uid 存前端卡片的 it.id(编码串),与前端直接对齐;title/cover/brand 为收藏时快照。 -CREATE TABLE IF NOT EXISTS `favorites` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `created_at` int unsigned NOT NULL DEFAULT 0, - `user_id` int unsigned NOT NULL, - `target_type` varchar(16) NOT NULL DEFAULT '', - `target_uid` varchar(64) NOT NULL DEFAULT '', - `title` varchar(255) NOT NULL DEFAULT '', - `cover` varchar(512) NOT NULL DEFAULT '', - `brand` varchar(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - UNIQUE KEY `uniq_user_target` (`user_id`, `target_uid`), - KEY `idx_user` (`user_id`), - KEY `idx_user_created` (`user_id`, `created_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/scripts/sql/008_create_histories.sql b/scripts/sql/008_create_histories.sql deleted file mode 100644 index 4d12d52..0000000 --- a/scripts/sql/008_create_histories.sql +++ /dev/null @@ -1,21 +0,0 @@ --- 008: histories —— 用户浏览历史(服务端持久化,按用户隔离,跨设备一致) --- 与 favorites 同理:表结构由 SQL 托管,不依赖 GORM AutoMigrate。 --- --- 2026-09-02 收敛为「文章级」浏览历史: --- 1) 触发点:点开某篇走秀/街拍详情(/item/xxx)时记一条;进入列表页不再记。 --- 2) 仅存 (user_id, target_uid, viewed_at):target_uid 为带类型前缀的对外编码串 --- (runway r=xxx / street s=xxx,见后端 hashid.EncodeTyped),前缀本身携带类型, --- 无需 kind / target_type 列。 --- 3) title/cover/brand 快照已移除:账户页展示时按 target_uid 回查公开详情接口, --- 保持表最简、展示数据新鲜。 --- 唯一键 (user_id, target_uid):同一篇文章反复打开只 upsert 刷新 viewed_at,绝不新增行。 --- 每用户上限 HISTORY_CAP(应用层维护,默认 2000),超出 FIFO 删最旧。 -CREATE TABLE IF NOT EXISTS `histories` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `viewed_at` int unsigned NOT NULL DEFAULT 0, - `user_id` int unsigned NOT NULL, - `target_uid` varchar(64) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - UNIQUE KEY `uniq_user_target` (`user_id`, `target_uid`), - KEY `idx_user_viewed` (`user_id`, `viewed_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;