patreon-dl 3.8.0 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -311,6 +311,9 @@ Note the URL shown in the output. Open this URL in a web browser to begin viewin
311
311
 
312
312
  ## Changelog
313
313
 
314
+ 3.8.1
315
+ - YT embeds: obtain images directly from YT instead of Patreon API data, since the latter could give 0-byte content ([@Fabelwesen](https://github.com/Fabelwesen) - [#120](https://github.com/patrickkfkan/patreon-dl/issues/120)).
316
+
314
317
  3.8.0
315
318
  - Add support for custom URLs (creators hosting Patreon pages on their own domains) ([@lucasoskorep](https://github.com/lucasoskorep) - [PR #129](https://github.com/patrickkfkan/patreon-dl/pull/129)).
316
319
  - Fix YT download errors ([#132](https://github.com/patrickkfkan/patreon-dl/issues/132)).
@@ -448,7 +448,7 @@ export function ContentDBMixin(Base) {
448
448
  const value = groupBy === 'year' ?
449
449
  String(date.getUTCFullYear())
450
450
  : getYearMonthString(date);
451
- whereValues.push(String(value));
451
+ whereValues.push(value);
452
452
  }
453
453
  const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;
454
454
  const strftimeFormat = groupBy === 'year' ? '%Y' : '%Y-%m';
@@ -1 +1 @@
1
- {"version":3,"file":"ContentDBMixin.js","sourceRoot":"","sources":["../../../src/browse/db/ContentDBMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Comment, type Downloadable, type Post, type Product, type Tier, type Campaign } from '../../entities';\nimport { type PostTag, type Collection } from '../../entities/Post';\nimport { getYearMonthString, type KeysOfValue } from '../../utils/Misc.js';\nimport { type GetContentContext, type GetPreviousNextContentResult, type ContentList, type ContentType, type GetContentListParams, type PostWithComments, type ContentListSortBy, type GetCollectionListParams, type CollectionList, type GetPostTagListParams, type PostTagList } from '../types/Content.js';\nimport { type CampaignDBConstructor } from './CampaignDBMixin.js';\n\nexport function ContentDBMixin<TBase extends CampaignDBConstructor>(Base: TBase) {\n return class ContentDB extends Base {\n saveContent(content: Post | Product) {\n const title = content.type === 'post' ? content.title : content.name;\n this.log('debug', `Save ${content.type} #${content.id} (${title}) to DB`);\n try {\n // Normally, campaign would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCampaign(content.campaign, new Date(), false);\n\n const contentExists = this.checkContentExists(content.id, content.type, content.campaign);\n this.exec('BEGIN TRANSACTION');\n\n if (!contentExists) {\n this.log('debug', `INSERT ${content.type} \"${title}\" (${content.id})`);\n this.run(\n `\n INSERT INTO content (\n content_id,\n content_type,\n campaign_id,\n title,\n content_subtype,\n is_viewable,\n published_at,\n details\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `,\n [\n content.id,\n content.type,\n content.campaign?.id || '-1',\n title,\n content.type === 'post' ? content.postType : content.productType || null,\n (content.type === 'post' ? content.isViewable : content.isAccessible) ? 1 : 0,\n this.#publishedAtToTime(content.publishedAt),\n JSON.stringify(content)\n ]\n );\n } else {\n this.log('debug', `${content.type} #${content.id} already exists in DB - update record`);\n this.run(`\n UPDATE content\n SET\n content_type = ?,\n campaign_id = ?,\n title = ?,\n content_subtype = ?,\n is_viewable = ?,\n published_at = ?,\n details = ?\n WHERE content_id = ?\n `,\n [\n content.type,\n content.campaign?.id || '-1',\n title,\n content.type === 'post' ? content.postType : content.productType || null,\n (content.type === 'post' ? content.isViewable : content.isAccessible) ? 1 : 0,\n this.#publishedAtToTime(content.publishedAt),\n JSON.stringify(content),\n content.id\n ]\n );\n }\n\n // Save content media\n this.#saveContentMedia(content);\n\n // Save tiers and collections and tags\n if (content.type === 'post') {\n this.#savePostTiers(content);\n this.#savePostCollection(content);\n this.#savePostTags(content);\n }\n\n this.exec('COMMIT');\n } catch (error) {\n this.log(\n 'error',\n `Failed to save content \"${title}\" (${content.id}) to DB:`,\n error\n );\n this.exec('ROLLBACK');\n }\n }\n\n #saveContentMedia(\n content: Post | Product\n ) {\n this.log('debug', `Save media for ${content.type} #${content.id} to DB`);\n switch (content.type) {\n case 'post':\n this.#savepostMedia(content);\n break;\n case 'product':\n this.#saveProductMedia(content);\n break;\n }\n }\n\n #savepostMedia(post: Post) {\n const mediaProps: KeysOfValue<Post, Downloadable | Downloadable[] | null>[] = [\n 'embed',\n 'attachments',\n 'audio',\n 'audioPreview',\n 'images',\n 'videoPreview',\n 'video'\n ];\n if (post.coverImage) {\n this.saveMedia(post.coverImage);\n }\n if (post.thumbnail) {\n this.saveMedia(post.thumbnail);\n }\n for (const prop of mediaProps) {\n if (post[prop]) {\n const data = post[prop];\n const downloadables = (Array.isArray(data) ? data : [data])\n .filter((data) => data !== undefined);\n downloadables.forEach((dl, index) => this.#doSaveContentMedia(\n post,\n dl,\n index,\n prop === 'audioPreview'||\n prop === 'videoPreview' ||\n (prop === 'images' && !post.isViewable)\n ));\n }\n }\n }\n\n #saveProductMedia(product: Product) {\n const mediaProps: KeysOfValue<Product, Downloadable[]>[] = [\n 'contentMedia',\n 'previewMedia'\n ];\n for (const prop of mediaProps) {\n if (product[prop]) {\n const data = product[prop];\n const downloadables = (Array.isArray(data) ? data : [data])\n .filter((data) => data !== undefined);\n downloadables.forEach((dl, index) => this.#doSaveContentMedia(\n product,\n dl,\n index,\n prop === 'previewMedia'\n ));\n }\n }\n }\n\n #doSaveContentMedia(\n content: Post | Product,\n media: Downloadable,\n mediaIndex: number,\n isPreview: boolean\n ) {\n if (!media.downloaded || !media.downloaded.path) {\n return;\n }\n this.log('debug',\n `Save ${content.type} media to DB`,\n `(${content.type} ID: ${content.id}, media ID: ${media.id})`\n );\n this.saveMedia(media);\n try {\n const contentMediaExists = this.checkContentMediaExists(content, media);\n if (!contentMediaExists) {\n this.run(\n `\n INSERT INTO content_media (\n media_id,\n content_id,\n content_type,\n media_index,\n campaign_id,\n is_preview\n )\n VALUES (?, ?, ?, ?, ?, ?)\n `,\n [\n media.id,\n content.id,\n content.type,\n mediaIndex,\n content.campaign?.id || '-1',\n isPreview ? 1 : 0\n ]\n );\n }\n else {\n this.log('debug',\n `${content.type} media already exists in DB`,\n `(${content.type} ID: ${content.id}, media ID: ${media.id})`,\n '- update record'\n );\n this.run(\n `\n UPDATE content_media\n SET\n content_id = ?,\n content_type = ?,\n media_index = ?,\n campaign_id = ?,\n is_preview = ?\n WHERE\n media_id = ?\n `,\n [\n content.id,\n content.type,\n mediaIndex,\n content.campaign?.id || '-1',\n isPreview ? 1 : 0,\n media.id,\n ]\n );\n }\n }\n catch (error) {\n this.log(\n 'error',\n `Failed to save content media (type: ${content.type}, content_id: ${content.id}, media_id: ${media.id}) to DB:`,\n error\n );\n throw error;\n }\n }\n\n #publishedAtToTime(publishedAt: string | null) {\n try {\n if (!publishedAt) {\n return null;\n }\n return new Date(publishedAt).getTime();\n }\n catch (error) {\n this.log('warn', `Failed to convert publishedAt value \"${publishedAt}\" to date integer:`, error);\n return null;\n }\n }\n\n #savePostTiers(post: Post) {\n this.log('debug', `Save tiers for post #${post.id} to DB`);\n // Clear existing tiers for post\n this.log('debug', `Clear existing tiers in DB for post #${post.id} before saving current ones`);\n this.run(`DELETE FROM post_tier WHERE post_id = ?`, [\n post.id\n ]);\n post.tiers.forEach((tier) => this.#doSaveTier(post, tier));\n }\n\n #doSaveTier(post: Post, tier: Tier) {\n this.log('debug', `Add post tier #${tier.id} (${tier.title}) to DB`);\n this.run(`\n INSERT INTO post_tier (\n post_id,\n tier_id,\n campaign_id\n )\n VALUES (?, ?, ?)\n `,\n [\n post.id,\n tier.id,\n post.campaign?.id || '-1'\n ]);\n }\n\n savePostComments(post: Post, comments: Comment[]) {\n try {\n this.log('debug', `Save comments for post #${post.id}`);\n const commentsExist = this.checkPostCommentsExist(post);\n if (!commentsExist) {\n this.run(\n `\n INSERT INTO post_comments (\n post_id,\n comment_count,\n comments\n )\n VALUES (?, ?, ?)\n `,\n [\n post.id,\n post.commentCount,\n JSON.stringify(comments)\n ]\n );\n }\n else {\n this.log('debug', `Comments for post #${post.id} already exists in DB - update record`);\n this.run(\n `\n UPDATE post_comments\n SET\n comment_count = ?,\n comments = ?\n WHERE\n post_id = ?\n `,\n [\n post.commentCount,\n JSON.stringify(comments),\n post.id\n ]\n );\n }\n }\n catch (error) {\n this.log(\n 'error',\n `Failed to save comments for post #${post.id} to DB:`,\n error\n );\n throw error;\n }\n }\n\n checkPostCommentsExist(post: Post) {\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM post_comments\n WHERE\n post_id = ?\n `,\n [ post.id ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if comments for post #${post.id} exist in DB:`,\n error\n );\n return false;\n }\n }\n\n getContent(id: string, contentType: 'post'): PostWithComments | null;\n getContent(id: string, contentType: 'product'): Product | null;\n getContent(id: string, contentType: ContentType) {\n this.log('debug', `Get ${contentType} #${id} from DB`);\n const result = this.get(\n `\n SELECT\n details,\n IFNULL(post_comments.comment_count, 0) AS comment_count,\n comments\n FROM\n content\n LEFT JOIN\n post_comments ON post_comments.post_id = content.content_id AND content.content_type = 'post'\n WHERE\n content_id = ? AND content_type = ?`,\n [id, contentType]\n );\n return result ? this.#parseContentRowJoinedComments(result) : null;\n }\n\n getPreviousNextContent<T extends ContentType>(\n content: Post | Product,\n context: GetContentContext<T>\n ): GetPreviousNextContentResult<T> {\n let previousWhere: string;\n let previousSortBy: ContentListSortBy;\n let nextWhere: string;\n let nextSortBy: ContentListSortBy;\n let whereValues: any[];\n const sortBy = context.sortBy ?? 'latest';\n const publishedAt = this.#publishedAtToTime(content.publishedAt);\n const title = content.type === 'post' ? content.title : content.name;\n switch (sortBy) {\n case 'a-z':\n case 'z-a': {\n const p = `\n (\n (title < ?)\n OR\n (title = ? AND published_at > ?)\n OR\n (title = ? AND published_at = ? AND content_id > ?)\n )\n `;\n const n = `\n (\n (title > ?)\n OR\n (title = ? AND published_at < ?)\n OR\n (title = ? AND published_at = ? AND content_id < ?)\n )\n `;\n whereValues = [title, title, publishedAt, title, publishedAt, content.id];\n if (sortBy === 'a-z') {\n previousWhere = p;\n previousSortBy = 'z-a';\n nextWhere = n;\n nextSortBy = 'a-z';\n }\n else { // z-a\n previousWhere = n;\n previousSortBy = 'a-z';\n nextWhere = p;\n nextSortBy = 'z-a';\n }\n break;\n }\n case 'latest':\n case 'oldest':\n case 'best_match': {\n const older = `\n (\n (published_at < ?)\n OR\n (published_at = ? AND content_id < ?)\n )\n `;\n const newer = `\n (\n (published_at > ?)\n OR\n (published_at = ? AND content_id > ?)\n )\n `;\n whereValues = [publishedAt, publishedAt, content.id];\n if (sortBy === 'latest') {\n previousWhere = newer;\n previousSortBy = 'oldest';\n nextWhere = older;\n nextSortBy = 'latest';\n }\n else { // oldest\n previousWhere = older;\n previousSortBy = 'latest';\n nextWhere = newer;\n nextSortBy = 'oldest';\n }\n break;\n }\n }\n const previous = (this.getContentList(\n {\n ...context,\n search: context.search,\n sortBy: previousSortBy,\n limit: 1, offset: 0\n },\n {\n whereClauses: [previousWhere],\n whereValues\n },\n false\n )).items[0] || null;\n const next = (this.getContentList(\n {\n ...context,\n search: context.search,\n sortBy: nextSortBy,\n limit: 1, offset: 0\n },\n {\n whereClauses: [nextWhere],\n whereValues\n },\n false\n )).items[0] || null;\n\n return {\n previous,\n next\n } as GetPreviousNextContentResult<T>;\n }\n\n getContentList<T extends ContentType>(\n params: GetContentListParams<T>,\n db?: { whereClauses: string[]; whereValues: any[]; },\n includeTotal = true\n ): ContentList<T> {\n const { campaign, type: contentType, isViewable, datePublished, search, sortBy, limit, offset } = params;\n const { whereClauses: extraWhereClauses = [], whereValues: extraWhereValues = [] } = db || {};\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id);\n const tiers = params.type === 'post' ? (params as GetContentListParams<'post'>).tiers : null;\n const collection = params.type === 'post' ? (params as GetContentListParams<'post'>).collection : null;\n const tag = params.type === 'post' ? (params as GetContentListParams<'post'>).tag : null;\n this.log('debug', `Get ${contentType}s from DB:`, {\n campaign: campaignId,\n isViewable,\n datePublished,\n search,\n tiers: params.type === 'post' ? JSON.stringify(tiers) : 'N/A',\n collection: params.type === 'post' ? JSON.stringify(collection) : 'N/A',\n tag: params.type === 'post' ? JSON.stringify(tag) : 'N/A',\n sortBy,\n limit,\n offset\n });\n const contentSubtypes = params.type === 'post' ? (params as GetContentListParams<'post'>).postTypes : null;\n if (tiers && tiers.length > 0 && !campaign) {\n throw Error('Invalid params: \"tiers\" must be used with \"campaign\"');\n }\n if (search && !contentType) {\n throw Error('Invalid params: \"search\" must be used with \"contentType\"');\n }\n const joinParts: string[] = [];\n if (tiers && tiers.length > 0) {\n joinParts.push('LEFT JOIN post_tier ON post_tier.post_id = content.content_id');\n }\n if (collection) {\n joinParts.push(`LEFT JOIN post_collection ON post_collection.post_id = content.content_id`);\n }\n if (tag) {\n joinParts.push(`LEFT JOIN post_tag_post ON post_tag_post.post_id = content.content_id AND post_tag_post.campaign_id = content.campaign_id`);\n }\n const join = joinParts.join(' ');\n const whereEquals: { column: string; value: string | number; }[] = [];\n if (campaignId) {\n whereEquals.push({ column: 'content.campaign_id', value: campaignId });\n }\n if (contentType) {\n whereEquals.push({ column: 'content_type', value: contentType });\n }\n if (isViewable !== undefined) {\n whereEquals.push({ column: 'is_viewable', value: isViewable ? 1 : 0});\n }\n if (datePublished) {\n const strftimeFormat =\n /^\\d{4}$/.test(datePublished) ? '%Y' :\n /^\\d{4}-\\d{2}$/.test(datePublished) ? '%Y-%m'\n : null;\n if (!strftimeFormat) {\n throw Error('Invalid params: \"datePublished\" must be in format \"YYYY\" or \"YYYY-MM\" (e.g. \"2025-06\")');\n }\n whereEquals.push({\n column: `strftime('${strftimeFormat}', datetime(published_at / 1000, 'unixepoch'))`,\n value: datePublished\n });\n }\n if (collection) {\n whereEquals.push({\n column: 'post_collection.collection_id',\n value: typeof collection === 'string' ? collection : collection.id\n });\n }\n if (tag) {\n whereEquals.push({\n column: 'post_tag_post.post_tag_id',\n value: typeof tag === 'string' ? tag : tag.id\n });\n }\n const whereIns: { column: string; values: (string | number)[] }[] = [];\n if (contentSubtypes && contentSubtypes.length > 0) {\n whereIns.push({ column: 'content_subtype', values: contentSubtypes})\n }\n if (tiers && tiers.length > 0) {\n const ids = tiers.map((tier) => typeof tier === 'string' ? tier : tier.id);\n whereIns.push({ column: 'tier_id', values: ids });\n }\n const whereClauseParts: string[] = [];\n if (whereEquals.length > 0) {\n whereClauseParts.push(...whereEquals.map(({column: field}) => `${field} = ?` ));\n }\n if (whereIns.length > 0) {\n whereClauseParts.push(...whereIns.map((wi) => `${wi.column} IN (${wi.values.map(() => '?').join(', ')})`));\n }\n if (search) {\n whereClauseParts.push(`${contentType}_fts MATCH ?`);\n }\n whereClauseParts.push(...extraWhereClauses);\n const whereClause = whereClauseParts.length > 0 ? 'WHERE ' + whereClauseParts.join(' AND ') : '';\n const whereValues = [\n ...whereEquals.map(({value}) => value),\n ...whereIns.reduce<(string | number)[]>((result, {values}) => {\n result.push(...values);\n return result;\n }, [])\n ];\n if (search) {\n whereValues.push(search); \n }\n whereValues.push(...extraWhereValues);\n let orderByClause: string;\n switch (sortBy) {\n case 'a-z':\n orderByClause = 'title ASC';\n break;\n case 'z-a':\n orderByClause = 'title DESC';\n break;\n case 'latest':\n orderByClause = 'published_at DESC';\n break;\n case 'oldest':\n orderByClause = 'published_at ASC';\n break;\n case 'best_match':\n orderByClause = `ORDER BY bm25(${contentType}_fts) DESC`;\n break;\n default:\n orderByClause = '';\n }\n if (orderByClause) {\n orderByClause = `ORDER BY ${orderByClause}`;\n }\n let limitOffsetClause = '';\n const limitOffsetValues: number[] = [];\n if (limit !== undefined && offset !== undefined) {\n limitOffsetClause = 'LIMIT ? OFFSET ?';\n limitOffsetValues.push(limit, offset);\n }\n else if (limit !== undefined) {\n limitOffsetClause = 'LIMIT ?';\n limitOffsetValues.push(limit);\n }\n\n let fromClause: string;\n if (search) {\n fromClause = `\n FROM\n ${contentType}_fts\n LEFT JOIN\n ${contentType}_fts_source ON ${contentType}_fts_source.fts_rowid = ${contentType}_fts.rowid\n LEFT JOIN\n content ON content.content_id = ${contentType}_fts_source.${contentType}_id\n `;\n } else {\n fromClause = 'FROM content';\n }\n\n const rows = this.all(\n `\n SELECT DISTINCT\n details,\n IFNULL(post_comments.comment_count, 0) AS comment_count,\n comments\n ${fromClause}\n LEFT JOIN\n post_comments ON post_comments.post_id = content.content_id AND content.content_type = 'post'\n ${join}\n ${whereClause}\n ${orderByClause}\n ${limitOffsetClause}\n `,\n [ ...whereValues, ...limitOffsetValues ]\n );\n const items = rows.map<T extends 'post' ? PostWithComments : T extends 'product' ? Product : PostWithComments | Product>((row) => this.#parseContentRowJoinedComments(row));\n const totalResult = includeTotal ? this.get(\n `SELECT COUNT(*) AS content_count ${fromClause} ${join} ${whereClause}`,\n [...whereValues]\n ) : null;\n const total = totalResult ? (totalResult.content_count as number) : 0;\n return {\n items,\n total\n };\n }\n\n /**\n * \n * @param row Must have `details`, `comment_count` and `comments`\n * @returns \n */\n #parseContentRowJoinedComments(row: any) {\n const details = JSON.parse(row.details);\n if (!Reflect.has(details, 'type')) {\n return details;\n }\n switch (details.type) {\n case 'post': {\n // `comment_count` column somehow created as string type\n // Cast it back to number as some were saved as decimals (e.g. \"2.0\")\n const commentCount = Number(row.comment_count) || 0;\n const comments = row.comments !== null ? JSON.parse(row.comments) : null;\n return {\n ...details,\n commentCount,\n comments\n } satisfies PostWithComments;\n }\n case 'product':\n default:\n return details;\n }\n }\n\n getContentCountByDate(\n contentType: ContentType,\n groupBy: 'year' | 'month',\n filter?: {\n campaign?: Campaign | string | null,\n date?: Date | null}\n ) {\n const campaign = filter?.campaign || null;\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id);\n this.log('debug', `Get ${contentType} count by date:`, {\n groupBy,\n filter: !filter ? null : {\n campaign: campaignId,\n date: filter.date\n }\n });\n const date = filter?.date || null;\n const whereClauseParts = ['content_type = ?'];\n const whereValues: string[] = [contentType];\n if (campaignId) {\n whereClauseParts.push('campaign_id = ?');\n whereValues.push(campaignId);\n }\n if (date) {\n whereClauseParts.push(`dt = ?`);\n const value = groupBy === 'year' ?\n String(date.getUTCFullYear())\n : getYearMonthString(date);\n whereValues.push(String(value));\n }\n const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;\n const strftimeFormat = groupBy === 'year' ? '%Y' : '%Y-%m'\n const rows = this.all(\n `\n SELECT\n COUNT(content_id) AS content_count,\n strftime('${strftimeFormat}',\n datetime(published_at / 1000, 'unixepoch')) AS dt\n FROM\n content\n ${whereClause}\n GROUP BY dt\n ORDER BY dt DESC\n `,\n [...whereValues]\n );\n return rows.map((row) => ({\n dt: row.dt as string,\n count: row.content_count as number\n }));\n }\n\n getPostCountByType(campaign: Campaign | string) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n this.log('debug', `Get post count by type for campaign #${campaignId}`);\n const rows = this.all(\n `\n SELECT\n COUNT(content_id) AS post_count, content_subtype AS post_type\n FROM\n content\n WHERE\n content_type = 'post' AND campaign_id = ?\n GROUP BY content_subtype \n `,\n [campaignId]\n );\n return rows.map((row) => ({\n postType: row.post_type as string,\n count: row.post_count as number\n }));\n }\n\n getPostCountByTier(campaign: Campaign | string) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n this.log('debug', `Get post count by tier for campaign #${campaignId}`);\n const rows = this.all(\n `\n SELECT\n COUNT(post_id) as post_count, tier_id, reward.title\n FROM post_tier\n RIGHT JOIN reward ON reward.reward_id = post_tier.tier_id AND reward.campaign_id = post_tier.campaign_id\n WHERE\n post_tier.campaign_id = ?\n GROUP BY\n tier_id\n `,\n [campaignId]\n );\n return rows.map((row) => ({\n tierId: row.tier_id as string,\n title: row.title as string,\n count: row.post_count as number\n }));\n }\n\n checkContentExists(id: string, contentType: ContentType, campaign?: Campaign | null) {\n this.log('debug', `Check if ${contentType} #${id} exists in DB`);\n const whereClauseParts = [\n 'content_id = ?',\n 'content_type = ?'\n ];\n const whereValues = [id, contentType];\n if (campaign !== undefined) {\n whereClauseParts.push('campaign_id = ?');\n whereValues.push(campaign?.id || '-1');\n }\n const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM content\n ${whereClause}\n `,\n whereValues\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if ${contentType} #${id} exists in DB:`,\n error\n );\n return false;\n }\n }\n\n saveCollection(collection: Collection, campaign: Campaign | null, overwriteIfExists = true) {\n this.log('debug', `Save collection #${collection.id} (${collection.title}) to DB`);\n try {\n // Normally, campaign would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCampaign(campaign, new Date(), false);\n\n const collectionExists = this.checkCollectionExists(collection.id);\n if (collectionExists && !overwriteIfExists) {\n return;\n }\n\n if (collection.thumbnail) {\n this.saveMedia(collection.thumbnail);\n }\n\n if (!collectionExists) {\n this.log('debug', `INSERT collection \"${collection.title}\" (${collection.id})`);\n this.run(\n `\n INSERT INTO collection (\n collection_id,\n campaign_id,\n title,\n created_at,\n edited_at,\n details\n )\n VALUES (?, ?, ?, ?, ?, ?)\n `,\n [\n collection.id,\n campaign?.id || '-1',\n collection.title,\n this.#publishedAtToTime(collection.createdAt),\n this.#publishedAtToTime(collection.editedAt),\n JSON.stringify(collection)\n ]\n );\n } else {\n this.log('debug', `Collection #${collection.id} already exists in DB - update record`);\n this.run(`\n UPDATE collection\n SET\n title = ?,\n created_at = ?,\n edited_at = ?,\n details = ?\n WHERE\n collection_id = ? AND\n campaign_id = ?\n `,\n [\n collection.title,\n this.#publishedAtToTime(collection.createdAt),\n this.#publishedAtToTime(collection.editedAt),\n JSON.stringify(collection),\n collection.id,\n campaign?.id || '-1'\n ]\n );\n }\n } catch (error) {\n this.log(\n 'error',\n `Failed to save collection \"${collection.title}\" (${collection.id}) to DB:`,\n error\n );\n }\n }\n\n savePostTag(tag: PostTag, campaign: Campaign | null, overwriteIfExists = true) {\n this.log('debug', `Save post_tag \"${tag.id}\" to DB`);\n try {\n // Normally, campaign would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCampaign(campaign, new Date(), false);\n\n const tagExists = this.checkPostTagExists(tag.id, campaign);\n if (tagExists && !overwriteIfExists) {\n return;\n }\n\n if (!tagExists) {\n this.log('debug', `INSERT post_tag \"${tag.id}\"`);\n this.run(\n `\n INSERT INTO post_tag (\n post_tag_id,\n campaign_id,\n value,\n details\n )\n VALUES (?, ?, ?, ?)\n `,\n [\n tag.id,\n campaign?.id || '-1',\n tag.value,\n JSON.stringify(tag)\n ]\n );\n } else {\n this.log('debug', `post_tag \"${tag.id}\" already exists in DB - update record`);\n this.run(`\n UPDATE post_tag\n SET\n value = ?,\n details = ?\n WHERE\n post_tag_id = ? AND\n campaign_id = ?\n `,\n [\n tag.value,\n JSON.stringify(tag),\n tag.id,\n campaign?.id || '-1'\n ]\n );\n }\n } catch (error) {\n this.log(\n 'error',\n `Failed to save post_tag \"${tag.id}\" to DB:`,\n error\n );\n }\n }\n\n getCollection(id: string) {\n this.log('debug', `Get collection #${id} from DB`);\n try {\n const result = this.get(\n `\n SELECT\n campaign_id,\n details,\n (SELECT COUNT(post_id) AS post_count FROM post_collection WHERE collection_id = ?) AS post_count\n FROM collection\n WHERE collection_id = ?;\n `,\n [id, id]\n );\n if (result) {\n const collection = JSON.parse(result.details) as Collection;\n collection.numPosts = result.post_count || 0;\n return {\n collection,\n campaignId: result.campaign_id as string\n };\n }\n return null;\n } catch (error) {\n this.log('error', `Failed to get collection #${id} from DB:`, error);\n return null;\n }\n }\n\n #savePostCollection(post: Post) {\n this.log('debug', `Clear post_collection for post #${post.id}`);\n this.run(`DELETE FROM post_collection WHERE post_id = ?`, [\n post.id\n ]);\n if (!post.collections || post.collections.length === 0) {\n return;\n }\n for (const collection of post.collections) {\n // Normally, collection would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCollection(collection, post.campaign, false);\n try {\n this.run(\n `\n INSERT INTO post_collection (\n collection_id,\n campaign_id,\n post_id,\n post_created_at\n )\n VALUES (?, ?, ?, ?)\n `,\n [\n collection.id,\n post.campaign?.id || '-1',\n post.id,\n this.#publishedAtToTime(collection.createdAt)\n ]\n );\n }\n catch (error) {\n this.log('error', `Failed to save post_collection for post #${post.id} -> collection #${collection.id}:`, error);\n }\n }\n }\n\n getCollectionList(params: GetCollectionListParams): CollectionList {\n const { campaign, search, sortBy, limit, offset } = params;\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n\n const whereClauseParts: string[] = [ 'campaign_id = ?' ];\n const whereValues: (string | number)[] = [ campaignId ];\n if (search) {\n whereClauseParts.push('collection_fts MATCH ?');\n whereValues.push(search);\n }\n const whereClause = whereClauseParts.length > 0 ? 'WHERE ' + whereClauseParts.join(' AND ') : '';\n\n let orderByClause: string;\n switch (sortBy) {\n case 'a-z':\n orderByClause = 'collection.title ASC';\n break;\n case 'z-a':\n orderByClause = 'collection.title DESC';\n break;\n case 'last_created':\n orderByClause = 'created_at DESC';\n break;\n case 'last_updated':\n orderByClause = 'edited_at DESC';\n break;\n default:\n orderByClause = '';\n }\n if (orderByClause) {\n orderByClause = `ORDER BY ${orderByClause}`;\n }\n\n let limitOffsetClause = '';\n const limitOffsetValues: number[] = [];\n if (limit !== undefined && offset !== undefined) {\n limitOffsetClause = 'LIMIT ? OFFSET ?';\n limitOffsetValues.push(limit, offset);\n }\n else if (limit !== undefined) {\n limitOffsetClause = 'LIMIT ?';\n limitOffsetValues.push(limit);\n }\n\n let fromClause: string;\n if (search) {\n fromClause = `\n FROM\n collection_fts\n LEFT JOIN\n collection_fts_source ON collection_fts_source.fts_rowid = collection_fts.rowid\n LEFT JOIN\n collection ON collection.collection_id = collection_fts_source.collection_id\n `;\n } else {\n fromClause = 'FROM collection';\n }\n\n const rows = this.all(\n `\n SELECT\n details, post_count\n ${fromClause}\n LEFT JOIN\n (SELECT COUNT(post_id) AS post_count, collection_id FROM post_collection GROUP BY collection_id) pcc ON pcc.collection_id = collection.collection_id\n ${whereClause}\n ${orderByClause}\n ${limitOffsetClause}\n `,\n [...whereValues, ...limitOffsetValues]\n );\n const totalResult = this.get(\n `SELECT COUNT(*) AS collection_count ${fromClause} ${whereClause}`,\n [...whereValues]\n );\n const total = totalResult ? (totalResult.collection_count as number) : 0;\n const collections = rows.map((row) => {\n const collection = JSON.parse(row.details) as Collection;\n collection.numPosts = row.post_count || 0;\n return collection;\n });\n return {\n collections,\n total\n };\n }\n\n checkCollectionExists(id: string) {\n this.log('debug', `Check if collection #${id} exists in DB`);\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM collection\n WHERE\n collection_id = ?\n `,\n [ id ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if collection #${id} exists in DB:`,\n error\n );\n return false;\n }\n }\n\n checkPostTagExists(id: string, campaign: Campaign | null) {\n this.log('debug', `Check if tag \"${id}\" exists in DB`);\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM post_tag\n WHERE\n post_tag_id = ? AND\n campaign_id = ?\n `,\n [ id, campaign?.id || '-1']\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if post_tag \"${id}\" exists in DB:`,\n error\n );\n return false;\n }\n }\n\n getPostComments(post: Post | string): Comment[] | null {\n const postId = typeof post === 'string' ? post : post.id;\n this.log('debug', `Get comments for post #${postId}`);\n const result = this.get(\n `SELECT comments FROM post_comments WHERE post_id = ?`,\n [postId]\n );\n return result ? JSON.parse(result.comments) : null; \n }\n\n #savePostTags(post: Post) {\n this.log('debug', `Clear post_tag_post for post #${post.id}`);\n this.run(`DELETE FROM post_tag_post WHERE post_id = ?`, [\n post.id\n ]);\n if (!post.tags || post.tags.length === 0) {\n return;\n }\n for (const tag of post.tags) {\n this.savePostTag(tag, post.campaign, false);\n try {\n this.run(\n `\n INSERT INTO post_tag_post (\n post_tag_id,\n campaign_id,\n post_id\n )\n VALUES (?, ?, ?)\n `,\n [\n tag.id,\n post.campaign?.id || '-1',\n post.id\n ]\n );\n }\n catch (error) {\n this.log('error', `Failed to save post_tag_post for post #${post.id} -> post_tag \"${tag.id}\":`, error);\n }\n }\n }\n\n getPostTagList(params: GetPostTagListParams): PostTagList {\n const { campaign } = params;\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n\n const whereClauseParts: string[] = [ 'campaign_id = ?' ];\n const whereValues: (string | number)[] = [ campaignId ]; \n const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;\n const orderByClause = 'ORDER BY post_tag.value ASC';\n const fromClause = 'FROM post_tag';\n\n const rows = this.all(\n `\n SELECT\n details\n ${fromClause}\n ${whereClause}\n ${orderByClause}\n `,\n [...whereValues]\n );\n const totalResult = this.get(\n `SELECT COUNT(*) AS tag_count ${fromClause} ${whereClause}`,\n [...whereValues]\n );\n const total = totalResult ? (totalResult.tag_count as number) : 0;\n const tags = rows.map((row) => {\n return JSON.parse(row.details) as PostTag;\n });\n return {\n tags,\n total\n };\n }\n };\n}\n"]}
1
+ {"version":3,"file":"ContentDBMixin.js","sourceRoot":"","sources":["../../../src/browse/db/ContentDBMixin.ts"],"names":[],"mappings":";;;;;AAEA,OAAO,EAAE,kBAAkB,EAAoB,MAAM,qBAAqB,CAAC;AAI3E,MAAM,UAAU,cAAc,CAAsC,IAAW;;IAC7E,YAAO,MAAM,SAAU,SAAQ,IAAI;YAA5B;;;YAgtCP,CAAC;YA/sCC,WAAW,CAAC,OAAuB;gBACjC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;gBAC1E,IAAI,CAAC;oBACH,6DAA6D;oBAC7D,yDAAyD;oBACzD,yDAAyD;oBACzD,iCAAiC;oBACjC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;oBAEvD,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC1F,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;oBAE/B,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,OAAO,CAAC,IAAI,KAAK,KAAK,MAAM,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;wBACvE,IAAI,CAAC,GAAG,CACN;;;;;;;;;;;;aAYC,EACD;4BACE,OAAO,CAAC,EAAE;4BACV,OAAO,CAAC,IAAI;4BACZ,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;4BAC5B,KAAK;4BACL,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI;4BACxE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC7E,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,OAAO,CAAC,WAAW,CAAC;4BAC5C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;yBACxB,CACF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,uCAAuC,CAAC,CAAC;wBACzF,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;;aAWN,EACD;4BACE,OAAO,CAAC,IAAI;4BACZ,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;4BAC5B,KAAK;4BACL,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI;4BACxE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC7E,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,OAAO,CAAC,WAAW,CAAC;4BAC5C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;4BACvB,OAAO,CAAC,EAAE;yBACX,CACF,CAAC;oBACJ,CAAC;oBAED,qBAAqB;oBACrB,uBAAA,IAAI,yDAAkB,MAAtB,IAAI,EAAmB,OAAO,CAAC,CAAC;oBAEhC,sCAAsC;oBACtC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBAC5B,uBAAA,IAAI,sDAAe,MAAnB,IAAI,EAAgB,OAAO,CAAC,CAAC;wBAC7B,uBAAA,IAAI,2DAAoB,MAAxB,IAAI,EAAqB,OAAO,CAAC,CAAC;wBAClC,uBAAA,IAAI,qDAAc,MAAlB,IAAI,EAAe,OAAO,CAAC,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACtB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,2BAA2B,KAAK,MAAM,OAAO,CAAC,EAAE,UAAU,EAC1D,KAAK,CACN,CAAC;oBACF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YA2LD,gBAAgB,CAAC,IAAU,EAAE,QAAmB;gBAC9C,IAAI,CAAC;oBACH,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,2BAA2B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;oBACxD,MAAM,aAAa,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;oBACxD,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,IAAI,CAAC,GAAG,CACN;;;;;;;aAOC,EACD;4BACE,IAAI,CAAC,EAAE;4BACP,IAAI,CAAC,YAAY;4BACjB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;yBACzB,CACF,CAAC;oBACJ,CAAC;yBACI,CAAC;wBACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAsB,IAAI,CAAC,EAAE,uCAAuC,CAAC,CAAC;wBACxF,IAAI,CAAC,GAAG,CACN;;;;;;;aAOC,EACD;4BACE,IAAI,CAAC,YAAY;4BACjB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;4BACxB,IAAI,CAAC,EAAE;yBACR,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,GAAG,CACN,OAAO,EACP,qCAAqC,IAAI,CAAC,EAAE,SAAS,EACrD,KAAK,CACN,CAAC;oBACF,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YAED,sBAAsB,CAAC,IAAU;gBAC/B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB;;;;;WAKC,EACD,CAAE,IAAI,CAAC,EAAE,CAAE,CACZ,CAAC;oBACF,OAAO,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,yCAAyC,IAAI,CAAC,EAAE,eAAe,EAC/D,KAAK,CACN,CAAC;oBACF,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAID,UAAU,CAAC,EAAU,EAAE,WAAwB;gBAC7C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,WAAW,KAAK,EAAE,UAAU,CAAC,CAAC;gBACvD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB;;;;;;;;;;8CAUsC,EACtC,CAAC,EAAE,EAAE,WAAW,CAAC,CAClB,CAAC;gBACF,OAAO,MAAM,CAAC,CAAC,CAAC,uBAAA,IAAI,sEAA+B,MAAnC,IAAI,EAAgC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACrE,CAAC;YAED,sBAAsB,CACpB,OAAuB,EACvB,OAA6B;gBAE7B,IAAI,aAAqB,CAAC;gBAC1B,IAAI,cAAiC,CAAC;gBACtC,IAAI,SAAiB,CAAC;gBACtB,IAAI,UAA6B,CAAC;gBAClC,IAAI,WAAkB,CAAC;gBACvB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC;gBAC1C,MAAM,WAAW,GAAG,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,OAAO,CAAC,WAAW,CAAC,CAAC;gBACjE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrE,QAAQ,MAAM,EAAE,CAAC;oBACf,KAAK,KAAK,CAAC;oBACX,KAAK,KAAK,CAAC,CAAC,CAAC;wBACX,MAAM,CAAC,GAAG;;;;;;;;WAQT,CAAC;wBACF,MAAM,CAAC,GAAG;;;;;;;;WAQT,CAAC;wBACF,WAAW,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;wBAC1E,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;4BACrB,aAAa,GAAG,CAAC,CAAC;4BAClB,cAAc,GAAG,KAAK,CAAC;4BACvB,SAAS,GAAG,CAAC,CAAC;4BACd,UAAU,GAAG,KAAK,CAAC;wBACrB,CAAC;6BACI,CAAC,CAAC,MAAM;4BACX,aAAa,GAAG,CAAC,CAAC;4BAClB,cAAc,GAAG,KAAK,CAAC;4BACvB,SAAS,GAAG,CAAC,CAAC;4BACd,UAAU,GAAG,KAAK,CAAC;wBACrB,CAAC;wBACD,MAAM;oBACR,CAAC;oBACD,KAAK,QAAQ,CAAC;oBACd,KAAK,QAAQ,CAAC;oBACd,KAAK,YAAY,CAAC,CAAC,CAAC;wBAClB,MAAM,KAAK,GAAG;;;;;;WAMb,CAAC;wBACF,MAAM,KAAK,GAAG;;;;;;WAMb,CAAC;wBACF,WAAW,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;wBACrD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;4BACxB,aAAa,GAAG,KAAK,CAAC;4BACtB,cAAc,GAAG,QAAQ,CAAC;4BAC1B,SAAS,GAAG,KAAK,CAAC;4BAClB,UAAU,GAAG,QAAQ,CAAC;wBACxB,CAAC;6BACI,CAAC,CAAC,SAAS;4BACd,aAAa,GAAG,KAAK,CAAC;4BACtB,cAAc,GAAG,QAAQ,CAAC;4BAC1B,SAAS,GAAG,KAAK,CAAC;4BAClB,UAAU,GAAG,QAAQ,CAAC;wBACxB,CAAC;wBACD,MAAM;oBACR,CAAC;gBACH,CAAC;gBACD,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,cAAc,CACnC;oBACE,GAAG,OAAO;oBACV,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,MAAM,EAAE,cAAc;oBACtB,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;iBACpB,EACD;oBACE,YAAY,EAAE,CAAC,aAAa,CAAC;oBAC7B,WAAW;iBACZ,EACD,KAAK,CACN,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;gBACpB,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAC/B;oBACE,GAAG,OAAO;oBACV,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,MAAM,EAAE,UAAU;oBAClB,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;iBACpB,EACD;oBACE,YAAY,EAAE,CAAC,SAAS,CAAC;oBACzB,WAAW;iBACZ,EACD,KAAK,CACN,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;gBAEpB,OAAO;oBACL,QAAQ;oBACR,IAAI;iBAC8B,CAAC;YACvC,CAAC;YAED,cAAc,CACZ,MAA+B,EAC/B,EAAoD,EACpD,YAAY,GAAG,IAAI;gBAEnB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;gBACzG,MAAM,EAAE,YAAY,EAAE,iBAAiB,GAAG,EAAE,EAAE,WAAW,EAAE,gBAAgB,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;gBAC9F,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAC9F,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAE,MAAuC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC7F,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAE,MAAuC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;gBACvG,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAE,MAAuC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,WAAW,YAAY,EAAE;oBAChD,QAAQ,EAAE,UAAU;oBACpB,UAAU;oBACV,aAAa;oBACb,MAAM;oBACN,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;oBAC7D,UAAU,EAAE,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK;oBACvE,GAAG,EAAE,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK;oBACzD,MAAM;oBACN,KAAK;oBACL,MAAM;iBACP,CAAC,CAAC;gBACH,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAE,MAAuC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC3G,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC3C,MAAM,KAAK,CAAC,sDAAsD,CAAC,CAAC;gBACtE,CAAC;gBACD,IAAI,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC3B,MAAM,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAC1E,CAAC;gBACD,MAAM,SAAS,GAAa,EAAE,CAAC;gBAC/B,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9B,SAAS,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;gBAClF,CAAC;gBACD,IAAI,UAAU,EAAE,CAAC;oBACf,SAAS,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;gBAC9F,CAAC;gBACD,IAAI,GAAG,EAAE,CAAC;oBACR,SAAS,CAAC,IAAI,CAAC,2HAA2H,CAAC,CAAC;gBAC9I,CAAC;gBACD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjC,MAAM,WAAW,GAAkD,EAAE,CAAC;gBACtE,IAAI,UAAU,EAAE,CAAC;oBACf,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;gBACzE,CAAC;gBACD,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;gBACnE,CAAC;gBACD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;oBAC7B,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC;gBACxE,CAAC;gBACD,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,cAAc,GAClB,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBACtC,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO;4BAC7C,CAAC,CAAC,IAAI,CAAC;oBACT,IAAI,CAAC,cAAc,EAAE,CAAC;wBACpB,MAAM,KAAK,CAAC,wFAAwF,CAAC,CAAC;oBACxG,CAAC;oBACD,WAAW,CAAC,IAAI,CAAC;wBACf,MAAM,EAAE,aAAa,cAAc,gDAAgD;wBACnF,KAAK,EAAE,aAAa;qBACrB,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,UAAU,EAAE,CAAC;oBACf,WAAW,CAAC,IAAI,CAAC;wBACf,MAAM,EAAE,+BAA+B;wBACvC,KAAK,EAAE,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;qBACnE,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,GAAG,EAAE,CAAC;oBACR,WAAW,CAAC,IAAI,CAAC;wBACf,MAAM,EAAE,2BAA2B;wBACnC,KAAK,EAAE,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;qBAC9C,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,QAAQ,GAAsD,EAAE,CAAC;gBACvE,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,eAAe,EAAC,CAAC,CAAA;gBACtE,CAAC;gBACD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpD,CAAC;gBACD,MAAM,gBAAgB,GAAa,EAAE,CAAC;gBACtC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,gBAAgB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAE,CAAC,CAAC;gBAClF,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,gBAAgB,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,QAAQ,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC7G,CAAC;gBACD,IAAI,MAAM,EAAE,CAAC;oBACX,gBAAgB,CAAC,IAAI,CAAC,GAAG,WAAW,cAAc,CAAC,CAAC;gBACtD,CAAC;gBACD,gBAAgB,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC;gBAC5C,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjG,MAAM,WAAW,GAAG;oBAClB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,KAAK,CAAC;oBACtC,GAAG,QAAQ,CAAC,MAAM,CAAsB,CAAC,MAAM,EAAE,EAAC,MAAM,EAAC,EAAE,EAAE;wBAC3D,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;wBACvB,OAAO,MAAM,CAAC;oBAChB,CAAC,EAAE,EAAE,CAAC;iBACP,CAAC;gBACF,IAAI,MAAM,EAAE,CAAC;oBACX,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC3B,CAAC;gBACD,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;gBACtC,IAAI,aAAqB,CAAC;gBAC1B,QAAQ,MAAM,EAAE,CAAC;oBACf,KAAK,KAAK;wBACR,aAAa,GAAG,WAAW,CAAC;wBAC5B,MAAM;oBACR,KAAK,KAAK;wBACR,aAAa,GAAG,YAAY,CAAC;wBAC7B,MAAM;oBACR,KAAK,QAAQ;wBACX,aAAa,GAAG,mBAAmB,CAAC;wBACpC,MAAM;oBACR,KAAK,QAAQ;wBACX,aAAa,GAAG,kBAAkB,CAAC;wBACnC,MAAM;oBACR,KAAK,YAAY;wBACf,aAAa,GAAG,iBAAiB,WAAW,YAAY,CAAC;wBACzD,MAAM;oBACR;wBACE,aAAa,GAAG,EAAE,CAAC;gBACvB,CAAC;gBACD,IAAI,aAAa,EAAE,CAAC;oBAClB,aAAa,GAAG,YAAY,aAAa,EAAE,CAAC;gBAC9C,CAAC;gBACD,IAAI,iBAAiB,GAAG,EAAE,CAAC;gBAC3B,MAAM,iBAAiB,GAAa,EAAE,CAAC;gBACvC,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAChD,iBAAiB,GAAG,kBAAkB,CAAC;oBACvC,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACxC,CAAC;qBACI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC7B,iBAAiB,GAAG,SAAS,CAAC;oBAC9B,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;gBAED,IAAI,UAAkB,CAAC;gBACvB,IAAI,MAAM,EAAE,CAAC;oBACX,UAAU,GAAG;;cAEP,WAAW;;cAEX,WAAW,kBAAkB,WAAW,2BAA2B,WAAW;;8CAE9C,WAAW,eAAe,WAAW;SAC1E,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,UAAU,GAAG,cAAc,CAAC;gBAC9B,CAAC;gBAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB;;;;;UAKE,UAAU;;;UAGV,IAAI;UACJ,WAAW;UACX,aAAa;UACb,iBAAiB;SAClB,EACD,CAAE,GAAG,WAAW,EAAE,GAAG,iBAAiB,CAAE,CACzC,CAAC;gBACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAmG,CAAC,GAAG,EAAE,EAAE,CAAC,uBAAA,IAAI,sEAA+B,MAAnC,IAAI,EAAgC,GAAG,CAAC,CAAC,CAAC;gBAC5K,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CACvC,oCAAoC,UAAU,IAAI,IAAI,IAAI,WAAW,EAAE,EACvE,CAAC,GAAG,WAAW,CAAC,CACnB,CAAC,CAAC,CAAC,IAAI,CAAC;gBACT,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAE,WAAW,CAAC,aAAwB,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtE,OAAO;oBACL,KAAK;oBACL,KAAK;iBACN,CAAC;YACJ,CAAC;YA8BD,qBAAqB,CACnB,WAAwB,EACxB,OAAyB,EACzB,MAEqB;gBAErB,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;gBAC1C,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAC9F,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,WAAW,iBAAiB,EAAE;oBACrD,OAAO;oBACP,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;wBACvB,QAAQ,EAAE,UAAU;wBACpB,IAAI,EAAE,MAAM,CAAC,IAAI;qBAClB;iBACF,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;gBAClC,MAAM,gBAAgB,GAAG,CAAC,kBAAkB,CAAC,CAAC;gBAC9C,MAAM,WAAW,GAAa,CAAC,WAAW,CAAC,CAAC;gBAC5C,IAAI,UAAU,EAAE,CAAC;oBACf,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACzC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/B,CAAC;gBACD,IAAI,IAAI,EAAE,CAAC;oBACT,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAChC,MAAM,KAAK,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC;wBAChC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;wBAC7B,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;oBAC7B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1B,CAAC;gBACD,MAAM,WAAW,GAAG,SAAS,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9D,MAAM,cAAc,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAA;gBAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB;;;sBAGc,cAAc;;;;UAI1B,WAAW;;;SAGZ,EACD,CAAC,GAAG,WAAW,CAAC,CACjB,CAAC;gBACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACxB,EAAE,EAAE,GAAG,CAAC,EAAY;oBACpB,KAAK,EAAE,GAAG,CAAC,aAAuB;iBACnC,CAAC,CAAC,CAAC;YACN,CAAC;YAED,kBAAkB,CAAC,QAA2B;gBAC5C,MAAM,UAAU,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wCAAwC,UAAU,EAAE,CAAC,CAAC;gBACxE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB;;;;;;;;SAQC,EACD,CAAC,UAAU,CAAC,CACb,CAAC;gBACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACxB,QAAQ,EAAE,GAAG,CAAC,SAAmB;oBACjC,KAAK,EAAE,GAAG,CAAC,UAAoB;iBAChC,CAAC,CAAC,CAAC;YACN,CAAC;YAED,kBAAkB,CAAC,QAA2B;gBAC5C,MAAM,UAAU,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wCAAwC,UAAU,EAAE,CAAC,CAAC;gBACxE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB;;;;;;;;;SASC,EACD,CAAC,UAAU,CAAC,CACb,CAAC;gBACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACxB,MAAM,EAAE,GAAG,CAAC,OAAiB;oBAC7B,KAAK,EAAE,GAAG,CAAC,KAAe;oBAC1B,KAAK,EAAE,GAAG,CAAC,UAAoB;iBAChC,CAAC,CAAC,CAAC;YACN,CAAC;YAED,kBAAkB,CAAC,EAAU,EAAE,WAAwB,EAAE,QAA0B;gBACjF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,WAAW,KAAK,EAAE,eAAe,CAAC,CAAC;gBACjE,MAAM,gBAAgB,GAAG;oBACvB,gBAAgB;oBAChB,kBAAkB;iBACnB,CAAC;gBACF,MAAM,WAAW,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;gBACtC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACzC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;gBACzC,CAAC;gBACD,MAAM,WAAW,GAAG,SAAS,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9D,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB;;;YAGE,WAAW;WACZ,EACD,WAAW,CACZ,CAAC;oBACF,OAAO,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,sBAAsB,WAAW,KAAK,EAAE,gBAAgB,EACxD,KAAK,CACN,CAAC;oBACF,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAED,cAAc,CAAC,UAAsB,EAAE,QAAyB,EAAE,iBAAiB,GAAG,IAAI;gBACxF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,KAAK,SAAS,CAAC,CAAC;gBACnF,IAAI,CAAC;oBACH,6DAA6D;oBAC7D,yDAAyD;oBACzD,yDAAyD;oBACzD,iCAAiC;oBACjC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;oBAE/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACnE,IAAI,gBAAgB,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBAC3C,OAAO;oBACT,CAAC;oBAED,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;wBACzB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;oBACvC,CAAC;oBAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;wBACtB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAsB,UAAU,CAAC,KAAK,MAAM,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC;wBAChF,IAAI,CAAC,GAAG,CACN;;;;;;;;;;aAUC,EACD;4BACE,UAAU,CAAC,EAAE;4BACb,QAAQ,EAAE,EAAE,IAAI,IAAI;4BACpB,UAAU,CAAC,KAAK;4BAChB,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,UAAU,CAAC,SAAS,CAAC;4BAC7C,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,UAAU,CAAC,QAAQ,CAAC;4BAC5C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;yBAC3B,CACF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,UAAU,CAAC,EAAE,uCAAuC,CAAC,CAAC;wBACvF,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;aAUN,EACD;4BACE,UAAU,CAAC,KAAK;4BAChB,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,UAAU,CAAC,SAAS,CAAC;4BAC7C,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,UAAU,CAAC,QAAQ,CAAC;4BAC5C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;4BAC1B,UAAU,CAAC,EAAE;4BACb,QAAQ,EAAE,EAAE,IAAI,IAAI;yBACrB,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,8BAA8B,UAAU,CAAC,KAAK,MAAM,UAAU,CAAC,EAAE,UAAU,EAC3E,KAAK,CACN,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,WAAW,CAAC,GAAY,EAAE,QAAyB,EAAE,iBAAiB,GAAG,IAAI;gBAC3E,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,kBAAkB,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;gBACrD,IAAI,CAAC;oBACH,6DAA6D;oBAC7D,yDAAyD;oBACzD,yDAAyD;oBACzD,iCAAiC;oBACjC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;oBAE/C,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;oBAC5D,IAAI,SAAS,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBACpC,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;wBACjD,IAAI,CAAC,GAAG,CACN;;;;;;;;aAQC,EACD;4BACE,GAAG,CAAC,EAAE;4BACN,QAAQ,EAAE,EAAE,IAAI,IAAI;4BACpB,GAAG,CAAC,KAAK;4BACT,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;yBACpB,CACF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,CAAC,EAAE,wCAAwC,CAAC,CAAC;wBAC/E,IAAI,CAAC,GAAG,CAAC;;;;;;;;aAQN,EACD;4BACE,GAAG,CAAC,KAAK;4BACT,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;4BACnB,GAAG,CAAC,EAAE;4BACN,QAAQ,EAAE,EAAE,IAAI,IAAI;yBACrB,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,4BAA4B,GAAG,CAAC,EAAE,UAAU,EAC5C,KAAK,CACN,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,aAAa,CAAC,EAAU;gBACtB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;gBACnD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB;;;;;;;WAOC,EACD,CAAC,EAAE,EAAE,EAAE,CAAC,CACT,CAAC;oBACF,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAe,CAAC;wBAC5D,UAAU,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;wBAC7C,OAAO;4BACL,UAAU;4BACV,UAAU,EAAE,MAAM,CAAC,WAAqB;yBACzC,CAAC;oBACJ,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,6BAA6B,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;oBACrE,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAyCD,iBAAiB,CAAC,MAA+B;gBAC/C,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;gBAC3D,MAAM,UAAU,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAEzE,MAAM,gBAAgB,GAAa,CAAE,iBAAiB,CAAE,CAAC;gBACzD,MAAM,WAAW,GAAwB,CAAE,UAAU,CAAE,CAAC;gBACxD,IAAI,MAAM,EAAE,CAAC;oBACX,gBAAgB,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;oBAChD,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC3B,CAAC;gBACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEjG,IAAI,aAAqB,CAAC;gBAC1B,QAAQ,MAAM,EAAE,CAAC;oBACf,KAAK,KAAK;wBACR,aAAa,GAAG,sBAAsB,CAAC;wBACvC,MAAM;oBACR,KAAK,KAAK;wBACR,aAAa,GAAG,uBAAuB,CAAC;wBACxC,MAAM;oBACR,KAAK,cAAc;wBACjB,aAAa,GAAG,iBAAiB,CAAC;wBAClC,MAAM;oBACR,KAAK,cAAc;wBACjB,aAAa,GAAG,gBAAgB,CAAC;wBACjC,MAAM;oBACR;wBACE,aAAa,GAAG,EAAE,CAAC;gBACvB,CAAC;gBACD,IAAI,aAAa,EAAE,CAAC;oBAClB,aAAa,GAAG,YAAY,aAAa,EAAE,CAAC;gBAC9C,CAAC;gBAED,IAAI,iBAAiB,GAAG,EAAE,CAAC;gBAC3B,MAAM,iBAAiB,GAAa,EAAE,CAAC;gBACvC,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAChD,iBAAiB,GAAG,kBAAkB,CAAC;oBACvC,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACxC,CAAC;qBACI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC7B,iBAAiB,GAAG,SAAS,CAAC;oBAC9B,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,CAAC;gBAED,IAAI,UAAkB,CAAC;gBACvB,IAAI,MAAM,EAAE,CAAC;oBACX,UAAU,GAAG;;;;;;;SAOZ,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,UAAU,GAAG,iBAAiB,CAAC;gBACjC,CAAC;gBAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB;;;UAGE,UAAU;;;UAGV,WAAW;UACX,aAAa;UACb,iBAAiB;SAClB,EACD,CAAC,GAAG,WAAW,EAAE,GAAG,iBAAiB,CAAC,CACvC,CAAC;gBACF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAC1B,uCAAuC,UAAU,IAAI,WAAW,EAAE,EAClE,CAAC,GAAG,WAAW,CAAC,CACjB,CAAC;gBACF,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAE,WAAW,CAAC,gBAA2B,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzE,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;oBACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAe,CAAC;oBACzD,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC;oBAC1C,OAAO,UAAU,CAAC;gBACpB,CAAC,CAAC,CAAC;gBACH,OAAO;oBACL,WAAW;oBACX,KAAK;iBACN,CAAC;YACJ,CAAC;YAED,qBAAqB,CAAC,EAAU;gBAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAwB,EAAE,eAAe,CAAC,CAAC;gBAC7D,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB;;;;;WAKC,EACD,CAAE,EAAE,CAAE,CACP,CAAC;oBACF,OAAO,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,kCAAkC,EAAE,gBAAgB,EACpD,KAAK,CACN,CAAC;oBACF,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAED,kBAAkB,CAAC,EAAU,EAAE,QAAyB;gBACtD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;gBACvD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB;;;;;;WAMC,EACD,CAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,IAAI,CAAC,CAC5B,CAAC;oBACF,OAAO,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CACN,OAAO,EACP,gCAAgC,EAAE,iBAAiB,EACnD,KAAK,CACN,CAAC;oBACF,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAED,eAAe,CAAC,IAAmB;gBACjC,MAAM,MAAM,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,0BAA0B,MAAM,EAAE,CAAC,CAAC;gBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB,sDAAsD,EACtD,CAAC,MAAM,CAAC,CACT,CAAC;gBACF,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACrD,CAAC;YAmCD,cAAc,CAAC,MAA4B;gBACzC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;gBAC5B,MAAM,UAAU,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAEzE,MAAM,gBAAgB,GAAa,CAAE,iBAAiB,CAAE,CAAC;gBACzD,MAAM,WAAW,GAAwB,CAAE,UAAU,CAAE,CAAC;gBACxD,MAAM,WAAW,GAAG,SAAS,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9D,MAAM,aAAa,GAAG,6BAA6B,CAAC;gBACpD,MAAM,UAAU,GAAG,eAAe,CAAC;gBAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB;;;UAGE,UAAU;UACV,WAAW;UACX,aAAa;SACd,EACD,CAAC,GAAG,WAAW,CAAC,CACjB,CAAC;gBACF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAC1B,gCAAgC,UAAU,IAAI,WAAW,EAAE,EAC3D,CAAC,GAAG,WAAW,CAAC,CACjB,CAAC;gBACF,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAE,WAAW,CAAC,SAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAY,CAAC;gBAC5C,CAAC,CAAC,CAAC;gBACH,OAAO;oBACL,IAAI;oBACJ,KAAK;iBACN,CAAC;YACJ,CAAC;SACF;;2EAtnCG,OAAuB;YAEvB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,kBAAkB,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;YACzE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;gBACrB,KAAK,MAAM;oBACT,uBAAA,IAAI,sDAAe,MAAnB,IAAI,EAAgB,OAAO,CAAC,CAAC;oBAC7B,MAAM;gBACR,KAAK,SAAS;oBACZ,uBAAA,IAAI,yDAAkB,MAAtB,IAAI,EAAmB,OAAO,CAAC,CAAC;oBAChC,MAAM;YACV,CAAC;QACH,CAAC;qEAEc,IAAU;YACvB,MAAM,UAAU,GAA8D;gBAC5E,OAAO;gBACP,aAAa;gBACb,OAAO;gBACP,cAAc;gBACd,QAAQ;gBACR,cAAc;gBACd,OAAO;aACR,CAAC;YACF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACjC,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;oBACxB,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBACxD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;oBACxC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,uBAAA,IAAI,2DAAoB,MAAxB,IAAI,EACvC,IAAI,EACJ,EAAE,EACF,KAAK,EACL,IAAI,KAAK,cAAc;wBACvB,IAAI,KAAK,cAAc;wBACvB,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CACxC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;2EAEiB,OAAgB;YAChC,MAAM,UAAU,GAA2C;gBACzD,cAAc;gBACd,cAAc;aACf,CAAC;YACF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;oBAC3B,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBACxD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;oBACxC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,uBAAA,IAAI,2DAAoB,MAAxB,IAAI,EACvC,OAAO,EACP,EAAE,EACF,KAAK,EACL,IAAI,KAAK,cAAc,CACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;+EAGC,OAAuB,EACvB,KAAmB,EACnB,UAAkB,EAClB,SAAkB;YAElB,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;gBAChD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,OAAO,EACd,QAAQ,OAAO,CAAC,IAAI,cAAc,EAClC,IAAI,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,eAAe,KAAK,CAAC,EAAE,GAAG,CAC7D,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,kBAAkB,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBACxE,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACxB,IAAI,CAAC,GAAG,CACN;;;;;;;;;;aAUC,EACD;wBACE,KAAK,CAAC,EAAE;wBACR,OAAO,CAAC,EAAE;wBACV,OAAO,CAAC,IAAI;wBACZ,UAAU;wBACV,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;wBAC5B,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBAClB,CACF,CAAC;gBACJ,CAAC;qBACI,CAAC;oBACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EACd,GAAG,OAAO,CAAC,IAAI,6BAA6B,EAC5C,IAAI,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,eAAe,KAAK,CAAC,EAAE,GAAG,EAC5D,iBAAiB,CAClB,CAAC;oBACF,IAAI,CAAC,GAAG,CACN;;;;;;;;;;aAUC,EACD;wBACE,OAAO,CAAC,EAAE;wBACV,OAAO,CAAC,IAAI;wBACZ,UAAU;wBACV,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;wBAC5B,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACjB,KAAK,CAAC,EAAE;qBACT,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CACN,OAAO,EACP,uCAAuC,OAAO,CAAC,IAAI,iBAAiB,OAAO,CAAC,EAAE,eAAe,KAAK,CAAC,EAAE,UAAU,EAC/G,KAAK,CACN,CAAC;gBACF,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;6EAEkB,WAA0B;YAC3C,IAAI,CAAC;gBACH,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACzC,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,wCAAwC,WAAW,oBAAoB,EAAE,KAAK,CAAC,CAAC;gBACjG,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;qEAEc,IAAU;YACvB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAwB,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC3D,gCAAgC;YAChC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wCAAwC,IAAI,CAAC,EAAE,6BAA6B,CAAC,CAAC;YAChG,IAAI,CAAC,GAAG,CAAC,yCAAyC,EAAE;gBAClD,IAAI,CAAC,EAAE;aACR,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAA,IAAI,mDAAY,MAAhB,IAAI,EAAa,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC7D,CAAC;+DAEW,IAAU,EAAE,IAAU;YAChC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,kBAAkB,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;YACrE,IAAI,CAAC,GAAG,CAAC;;;;;;;OAOR,EACD;gBACE,IAAI,CAAC,EAAE;gBACP,IAAI,CAAC,EAAE;gBACP,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;aAC1B,CAAC,CAAC;QACL,CAAC;qGA6Y8B,GAAQ;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;gBAClC,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;gBACrB,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,wDAAwD;oBACxD,qEAAqE;oBACrE,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;oBACpD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACzE,OAAO;wBACL,GAAG,OAAO;wBACV,YAAY;wBACZ,QAAQ;qBACkB,CAAC;gBAC/B,CAAC;gBACD,KAAK,SAAS,CAAC;gBACf;oBACE,OAAO,OAAO,CAAC;YACnB,CAAC;QACH,CAAC;+EAqSmB,IAAU;YAC5B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mCAAmC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC,GAAG,CAAC,+CAA+C,EAAE;gBACxD,IAAI,CAAC,EAAE;aACR,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvD,OAAO;YACT,CAAC;YACD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC1C,+DAA+D;gBAC/D,yDAAyD;gBACzD,yDAAyD;gBACzD,iCAAiC;gBACjC,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBACtD,IAAI,CAAC;oBACH,IAAI,CAAC,GAAG,CACN;;;;;;;;aAQC,EACD;wBACE,UAAU,CAAC,EAAE;wBACb,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;wBACzB,IAAI,CAAC,EAAE;wBACP,uBAAA,IAAI,0DAAmB,MAAvB,IAAI,EAAoB,UAAU,CAAC,SAAS,CAAC;qBAC9C,CACF,CAAC;gBACJ,CAAC;gBACD,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,4CAA4C,IAAI,CAAC,EAAE,mBAAmB,UAAU,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACnH,CAAC;YACH,CAAC;QACH,CAAC;mEAkJa,IAAU;YACtB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,iCAAiC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,GAAG,CAAC,6CAA6C,EAAE;gBACtD,IAAI,CAAC,EAAE;aACR,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzC,OAAO;YACT,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC5C,IAAI,CAAC;oBACH,IAAI,CAAC,GAAG,CACN;;;;;;;aAOC,EACD;wBACE,GAAG,CAAC,EAAE;wBACN,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI;wBACzB,IAAI,CAAC,EAAE;qBACR,CACF,CAAC;gBACJ,CAAC;gBACD,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,0CAA0C,IAAI,CAAC,EAAE,iBAAiB,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBACzG,CAAC;YACH,CAAC;QACH,CAAC;WAmCD;AACJ,CAAC","sourcesContent":["import { type Comment, type Downloadable, type Post, type Product, type Tier, type Campaign } from '../../entities';\nimport { type PostTag, type Collection } from '../../entities/Post';\nimport { getYearMonthString, type KeysOfValue } from '../../utils/Misc.js';\nimport { type GetContentContext, type GetPreviousNextContentResult, type ContentList, type ContentType, type GetContentListParams, type PostWithComments, type ContentListSortBy, type GetCollectionListParams, type CollectionList, type GetPostTagListParams, type PostTagList } from '../types/Content.js';\nimport { type CampaignDBConstructor } from './CampaignDBMixin.js';\n\nexport function ContentDBMixin<TBase extends CampaignDBConstructor>(Base: TBase) {\n return class ContentDB extends Base {\n saveContent(content: Post | Product) {\n const title = content.type === 'post' ? content.title : content.name;\n this.log('debug', `Save ${content.type} #${content.id} (${title}) to DB`);\n try {\n // Normally, campaign would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCampaign(content.campaign, new Date(), false);\n\n const contentExists = this.checkContentExists(content.id, content.type, content.campaign);\n this.exec('BEGIN TRANSACTION');\n\n if (!contentExists) {\n this.log('debug', `INSERT ${content.type} \"${title}\" (${content.id})`);\n this.run(\n `\n INSERT INTO content (\n content_id,\n content_type,\n campaign_id,\n title,\n content_subtype,\n is_viewable,\n published_at,\n details\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `,\n [\n content.id,\n content.type,\n content.campaign?.id || '-1',\n title,\n content.type === 'post' ? content.postType : content.productType || null,\n (content.type === 'post' ? content.isViewable : content.isAccessible) ? 1 : 0,\n this.#publishedAtToTime(content.publishedAt),\n JSON.stringify(content)\n ]\n );\n } else {\n this.log('debug', `${content.type} #${content.id} already exists in DB - update record`);\n this.run(`\n UPDATE content\n SET\n content_type = ?,\n campaign_id = ?,\n title = ?,\n content_subtype = ?,\n is_viewable = ?,\n published_at = ?,\n details = ?\n WHERE content_id = ?\n `,\n [\n content.type,\n content.campaign?.id || '-1',\n title,\n content.type === 'post' ? content.postType : content.productType || null,\n (content.type === 'post' ? content.isViewable : content.isAccessible) ? 1 : 0,\n this.#publishedAtToTime(content.publishedAt),\n JSON.stringify(content),\n content.id\n ]\n );\n }\n\n // Save content media\n this.#saveContentMedia(content);\n\n // Save tiers and collections and tags\n if (content.type === 'post') {\n this.#savePostTiers(content);\n this.#savePostCollection(content);\n this.#savePostTags(content);\n }\n\n this.exec('COMMIT');\n } catch (error) {\n this.log(\n 'error',\n `Failed to save content \"${title}\" (${content.id}) to DB:`,\n error\n );\n this.exec('ROLLBACK');\n }\n }\n\n #saveContentMedia(\n content: Post | Product\n ) {\n this.log('debug', `Save media for ${content.type} #${content.id} to DB`);\n switch (content.type) {\n case 'post':\n this.#savepostMedia(content);\n break;\n case 'product':\n this.#saveProductMedia(content);\n break;\n }\n }\n\n #savepostMedia(post: Post) {\n const mediaProps: KeysOfValue<Post, Downloadable | Downloadable[] | null>[] = [\n 'embed',\n 'attachments',\n 'audio',\n 'audioPreview',\n 'images',\n 'videoPreview',\n 'video'\n ];\n if (post.coverImage) {\n this.saveMedia(post.coverImage);\n }\n if (post.thumbnail) {\n this.saveMedia(post.thumbnail);\n }\n for (const prop of mediaProps) {\n if (post[prop]) {\n const data = post[prop];\n const downloadables = (Array.isArray(data) ? data : [data])\n .filter((data) => data !== undefined);\n downloadables.forEach((dl, index) => this.#doSaveContentMedia(\n post,\n dl,\n index,\n prop === 'audioPreview'||\n prop === 'videoPreview' ||\n (prop === 'images' && !post.isViewable)\n ));\n }\n }\n }\n\n #saveProductMedia(product: Product) {\n const mediaProps: KeysOfValue<Product, Downloadable[]>[] = [\n 'contentMedia',\n 'previewMedia'\n ];\n for (const prop of mediaProps) {\n if (product[prop]) {\n const data = product[prop];\n const downloadables = (Array.isArray(data) ? data : [data])\n .filter((data) => data !== undefined);\n downloadables.forEach((dl, index) => this.#doSaveContentMedia(\n product,\n dl,\n index,\n prop === 'previewMedia'\n ));\n }\n }\n }\n\n #doSaveContentMedia(\n content: Post | Product,\n media: Downloadable,\n mediaIndex: number,\n isPreview: boolean\n ) {\n if (!media.downloaded || !media.downloaded.path) {\n return;\n }\n this.log('debug',\n `Save ${content.type} media to DB`,\n `(${content.type} ID: ${content.id}, media ID: ${media.id})`\n );\n this.saveMedia(media);\n try {\n const contentMediaExists = this.checkContentMediaExists(content, media);\n if (!contentMediaExists) {\n this.run(\n `\n INSERT INTO content_media (\n media_id,\n content_id,\n content_type,\n media_index,\n campaign_id,\n is_preview\n )\n VALUES (?, ?, ?, ?, ?, ?)\n `,\n [\n media.id,\n content.id,\n content.type,\n mediaIndex,\n content.campaign?.id || '-1',\n isPreview ? 1 : 0\n ]\n );\n }\n else {\n this.log('debug',\n `${content.type} media already exists in DB`,\n `(${content.type} ID: ${content.id}, media ID: ${media.id})`,\n '- update record'\n );\n this.run(\n `\n UPDATE content_media\n SET\n content_id = ?,\n content_type = ?,\n media_index = ?,\n campaign_id = ?,\n is_preview = ?\n WHERE\n media_id = ?\n `,\n [\n content.id,\n content.type,\n mediaIndex,\n content.campaign?.id || '-1',\n isPreview ? 1 : 0,\n media.id,\n ]\n );\n }\n }\n catch (error) {\n this.log(\n 'error',\n `Failed to save content media (type: ${content.type}, content_id: ${content.id}, media_id: ${media.id}) to DB:`,\n error\n );\n throw error;\n }\n }\n\n #publishedAtToTime(publishedAt: string | null) {\n try {\n if (!publishedAt) {\n return null;\n }\n return new Date(publishedAt).getTime();\n }\n catch (error) {\n this.log('warn', `Failed to convert publishedAt value \"${publishedAt}\" to date integer:`, error);\n return null;\n }\n }\n\n #savePostTiers(post: Post) {\n this.log('debug', `Save tiers for post #${post.id} to DB`);\n // Clear existing tiers for post\n this.log('debug', `Clear existing tiers in DB for post #${post.id} before saving current ones`);\n this.run(`DELETE FROM post_tier WHERE post_id = ?`, [\n post.id\n ]);\n post.tiers.forEach((tier) => this.#doSaveTier(post, tier));\n }\n\n #doSaveTier(post: Post, tier: Tier) {\n this.log('debug', `Add post tier #${tier.id} (${tier.title}) to DB`);\n this.run(`\n INSERT INTO post_tier (\n post_id,\n tier_id,\n campaign_id\n )\n VALUES (?, ?, ?)\n `,\n [\n post.id,\n tier.id,\n post.campaign?.id || '-1'\n ]);\n }\n\n savePostComments(post: Post, comments: Comment[]) {\n try {\n this.log('debug', `Save comments for post #${post.id}`);\n const commentsExist = this.checkPostCommentsExist(post);\n if (!commentsExist) {\n this.run(\n `\n INSERT INTO post_comments (\n post_id,\n comment_count,\n comments\n )\n VALUES (?, ?, ?)\n `,\n [\n post.id,\n post.commentCount,\n JSON.stringify(comments)\n ]\n );\n }\n else {\n this.log('debug', `Comments for post #${post.id} already exists in DB - update record`);\n this.run(\n `\n UPDATE post_comments\n SET\n comment_count = ?,\n comments = ?\n WHERE\n post_id = ?\n `,\n [\n post.commentCount,\n JSON.stringify(comments),\n post.id\n ]\n );\n }\n }\n catch (error) {\n this.log(\n 'error',\n `Failed to save comments for post #${post.id} to DB:`,\n error\n );\n throw error;\n }\n }\n\n checkPostCommentsExist(post: Post) {\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM post_comments\n WHERE\n post_id = ?\n `,\n [ post.id ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if comments for post #${post.id} exist in DB:`,\n error\n );\n return false;\n }\n }\n\n getContent(id: string, contentType: 'post'): PostWithComments | null;\n getContent(id: string, contentType: 'product'): Product | null;\n getContent(id: string, contentType: ContentType) {\n this.log('debug', `Get ${contentType} #${id} from DB`);\n const result = this.get(\n `\n SELECT\n details,\n IFNULL(post_comments.comment_count, 0) AS comment_count,\n comments\n FROM\n content\n LEFT JOIN\n post_comments ON post_comments.post_id = content.content_id AND content.content_type = 'post'\n WHERE\n content_id = ? AND content_type = ?`,\n [id, contentType]\n );\n return result ? this.#parseContentRowJoinedComments(result) : null;\n }\n\n getPreviousNextContent<T extends ContentType>(\n content: Post | Product,\n context: GetContentContext<T>\n ): GetPreviousNextContentResult<T> {\n let previousWhere: string;\n let previousSortBy: ContentListSortBy;\n let nextWhere: string;\n let nextSortBy: ContentListSortBy;\n let whereValues: any[];\n const sortBy = context.sortBy ?? 'latest';\n const publishedAt = this.#publishedAtToTime(content.publishedAt);\n const title = content.type === 'post' ? content.title : content.name;\n switch (sortBy) {\n case 'a-z':\n case 'z-a': {\n const p = `\n (\n (title < ?)\n OR\n (title = ? AND published_at > ?)\n OR\n (title = ? AND published_at = ? AND content_id > ?)\n )\n `;\n const n = `\n (\n (title > ?)\n OR\n (title = ? AND published_at < ?)\n OR\n (title = ? AND published_at = ? AND content_id < ?)\n )\n `;\n whereValues = [title, title, publishedAt, title, publishedAt, content.id];\n if (sortBy === 'a-z') {\n previousWhere = p;\n previousSortBy = 'z-a';\n nextWhere = n;\n nextSortBy = 'a-z';\n }\n else { // z-a\n previousWhere = n;\n previousSortBy = 'a-z';\n nextWhere = p;\n nextSortBy = 'z-a';\n }\n break;\n }\n case 'latest':\n case 'oldest':\n case 'best_match': {\n const older = `\n (\n (published_at < ?)\n OR\n (published_at = ? AND content_id < ?)\n )\n `;\n const newer = `\n (\n (published_at > ?)\n OR\n (published_at = ? AND content_id > ?)\n )\n `;\n whereValues = [publishedAt, publishedAt, content.id];\n if (sortBy === 'latest') {\n previousWhere = newer;\n previousSortBy = 'oldest';\n nextWhere = older;\n nextSortBy = 'latest';\n }\n else { // oldest\n previousWhere = older;\n previousSortBy = 'latest';\n nextWhere = newer;\n nextSortBy = 'oldest';\n }\n break;\n }\n }\n const previous = (this.getContentList(\n {\n ...context,\n search: context.search,\n sortBy: previousSortBy,\n limit: 1, offset: 0\n },\n {\n whereClauses: [previousWhere],\n whereValues\n },\n false\n )).items[0] || null;\n const next = (this.getContentList(\n {\n ...context,\n search: context.search,\n sortBy: nextSortBy,\n limit: 1, offset: 0\n },\n {\n whereClauses: [nextWhere],\n whereValues\n },\n false\n )).items[0] || null;\n\n return {\n previous,\n next\n } as GetPreviousNextContentResult<T>;\n }\n\n getContentList<T extends ContentType>(\n params: GetContentListParams<T>,\n db?: { whereClauses: string[]; whereValues: any[]; },\n includeTotal = true\n ): ContentList<T> {\n const { campaign, type: contentType, isViewable, datePublished, search, sortBy, limit, offset } = params;\n const { whereClauses: extraWhereClauses = [], whereValues: extraWhereValues = [] } = db || {};\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id);\n const tiers = params.type === 'post' ? (params as GetContentListParams<'post'>).tiers : null;\n const collection = params.type === 'post' ? (params as GetContentListParams<'post'>).collection : null;\n const tag = params.type === 'post' ? (params as GetContentListParams<'post'>).tag : null;\n this.log('debug', `Get ${contentType}s from DB:`, {\n campaign: campaignId,\n isViewable,\n datePublished,\n search,\n tiers: params.type === 'post' ? JSON.stringify(tiers) : 'N/A',\n collection: params.type === 'post' ? JSON.stringify(collection) : 'N/A',\n tag: params.type === 'post' ? JSON.stringify(tag) : 'N/A',\n sortBy,\n limit,\n offset\n });\n const contentSubtypes = params.type === 'post' ? (params as GetContentListParams<'post'>).postTypes : null;\n if (tiers && tiers.length > 0 && !campaign) {\n throw Error('Invalid params: \"tiers\" must be used with \"campaign\"');\n }\n if (search && !contentType) {\n throw Error('Invalid params: \"search\" must be used with \"contentType\"');\n }\n const joinParts: string[] = [];\n if (tiers && tiers.length > 0) {\n joinParts.push('LEFT JOIN post_tier ON post_tier.post_id = content.content_id');\n }\n if (collection) {\n joinParts.push(`LEFT JOIN post_collection ON post_collection.post_id = content.content_id`);\n }\n if (tag) {\n joinParts.push(`LEFT JOIN post_tag_post ON post_tag_post.post_id = content.content_id AND post_tag_post.campaign_id = content.campaign_id`);\n }\n const join = joinParts.join(' ');\n const whereEquals: { column: string; value: string | number; }[] = [];\n if (campaignId) {\n whereEquals.push({ column: 'content.campaign_id', value: campaignId });\n }\n if (contentType) {\n whereEquals.push({ column: 'content_type', value: contentType });\n }\n if (isViewable !== undefined) {\n whereEquals.push({ column: 'is_viewable', value: isViewable ? 1 : 0});\n }\n if (datePublished) {\n const strftimeFormat =\n /^\\d{4}$/.test(datePublished) ? '%Y' :\n /^\\d{4}-\\d{2}$/.test(datePublished) ? '%Y-%m'\n : null;\n if (!strftimeFormat) {\n throw Error('Invalid params: \"datePublished\" must be in format \"YYYY\" or \"YYYY-MM\" (e.g. \"2025-06\")');\n }\n whereEquals.push({\n column: `strftime('${strftimeFormat}', datetime(published_at / 1000, 'unixepoch'))`,\n value: datePublished\n });\n }\n if (collection) {\n whereEquals.push({\n column: 'post_collection.collection_id',\n value: typeof collection === 'string' ? collection : collection.id\n });\n }\n if (tag) {\n whereEquals.push({\n column: 'post_tag_post.post_tag_id',\n value: typeof tag === 'string' ? tag : tag.id\n });\n }\n const whereIns: { column: string; values: (string | number)[] }[] = [];\n if (contentSubtypes && contentSubtypes.length > 0) {\n whereIns.push({ column: 'content_subtype', values: contentSubtypes})\n }\n if (tiers && tiers.length > 0) {\n const ids = tiers.map((tier) => typeof tier === 'string' ? tier : tier.id);\n whereIns.push({ column: 'tier_id', values: ids });\n }\n const whereClauseParts: string[] = [];\n if (whereEquals.length > 0) {\n whereClauseParts.push(...whereEquals.map(({column: field}) => `${field} = ?` ));\n }\n if (whereIns.length > 0) {\n whereClauseParts.push(...whereIns.map((wi) => `${wi.column} IN (${wi.values.map(() => '?').join(', ')})`));\n }\n if (search) {\n whereClauseParts.push(`${contentType}_fts MATCH ?`);\n }\n whereClauseParts.push(...extraWhereClauses);\n const whereClause = whereClauseParts.length > 0 ? 'WHERE ' + whereClauseParts.join(' AND ') : '';\n const whereValues = [\n ...whereEquals.map(({value}) => value),\n ...whereIns.reduce<(string | number)[]>((result, {values}) => {\n result.push(...values);\n return result;\n }, [])\n ];\n if (search) {\n whereValues.push(search); \n }\n whereValues.push(...extraWhereValues);\n let orderByClause: string;\n switch (sortBy) {\n case 'a-z':\n orderByClause = 'title ASC';\n break;\n case 'z-a':\n orderByClause = 'title DESC';\n break;\n case 'latest':\n orderByClause = 'published_at DESC';\n break;\n case 'oldest':\n orderByClause = 'published_at ASC';\n break;\n case 'best_match':\n orderByClause = `ORDER BY bm25(${contentType}_fts) DESC`;\n break;\n default:\n orderByClause = '';\n }\n if (orderByClause) {\n orderByClause = `ORDER BY ${orderByClause}`;\n }\n let limitOffsetClause = '';\n const limitOffsetValues: number[] = [];\n if (limit !== undefined && offset !== undefined) {\n limitOffsetClause = 'LIMIT ? OFFSET ?';\n limitOffsetValues.push(limit, offset);\n }\n else if (limit !== undefined) {\n limitOffsetClause = 'LIMIT ?';\n limitOffsetValues.push(limit);\n }\n\n let fromClause: string;\n if (search) {\n fromClause = `\n FROM\n ${contentType}_fts\n LEFT JOIN\n ${contentType}_fts_source ON ${contentType}_fts_source.fts_rowid = ${contentType}_fts.rowid\n LEFT JOIN\n content ON content.content_id = ${contentType}_fts_source.${contentType}_id\n `;\n } else {\n fromClause = 'FROM content';\n }\n\n const rows = this.all(\n `\n SELECT DISTINCT\n details,\n IFNULL(post_comments.comment_count, 0) AS comment_count,\n comments\n ${fromClause}\n LEFT JOIN\n post_comments ON post_comments.post_id = content.content_id AND content.content_type = 'post'\n ${join}\n ${whereClause}\n ${orderByClause}\n ${limitOffsetClause}\n `,\n [ ...whereValues, ...limitOffsetValues ]\n );\n const items = rows.map<T extends 'post' ? PostWithComments : T extends 'product' ? Product : PostWithComments | Product>((row) => this.#parseContentRowJoinedComments(row));\n const totalResult = includeTotal ? this.get(\n `SELECT COUNT(*) AS content_count ${fromClause} ${join} ${whereClause}`,\n [...whereValues]\n ) : null;\n const total = totalResult ? (totalResult.content_count as number) : 0;\n return {\n items,\n total\n };\n }\n\n /**\n * \n * @param row Must have `details`, `comment_count` and `comments`\n * @returns \n */\n #parseContentRowJoinedComments(row: any) {\n const details = JSON.parse(row.details);\n if (!Reflect.has(details, 'type')) {\n return details;\n }\n switch (details.type) {\n case 'post': {\n // `comment_count` column somehow created as string type\n // Cast it back to number as some were saved as decimals (e.g. \"2.0\")\n const commentCount = Number(row.comment_count) || 0;\n const comments = row.comments !== null ? JSON.parse(row.comments) : null;\n return {\n ...details,\n commentCount,\n comments\n } satisfies PostWithComments;\n }\n case 'product':\n default:\n return details;\n }\n }\n\n getContentCountByDate(\n contentType: ContentType,\n groupBy: 'year' | 'month',\n filter?: {\n campaign?: Campaign | string | null,\n date?: Date | null}\n ) {\n const campaign = filter?.campaign || null;\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id);\n this.log('debug', `Get ${contentType} count by date:`, {\n groupBy,\n filter: !filter ? null : {\n campaign: campaignId,\n date: filter.date\n }\n });\n const date = filter?.date || null;\n const whereClauseParts = ['content_type = ?'];\n const whereValues: string[] = [contentType];\n if (campaignId) {\n whereClauseParts.push('campaign_id = ?');\n whereValues.push(campaignId);\n }\n if (date) {\n whereClauseParts.push(`dt = ?`);\n const value = groupBy === 'year' ?\n String(date.getUTCFullYear())\n : getYearMonthString(date);\n whereValues.push(value);\n }\n const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;\n const strftimeFormat = groupBy === 'year' ? '%Y' : '%Y-%m'\n const rows = this.all(\n `\n SELECT\n COUNT(content_id) AS content_count,\n strftime('${strftimeFormat}',\n datetime(published_at / 1000, 'unixepoch')) AS dt\n FROM\n content\n ${whereClause}\n GROUP BY dt\n ORDER BY dt DESC\n `,\n [...whereValues]\n );\n return rows.map((row) => ({\n dt: row.dt as string,\n count: row.content_count as number\n }));\n }\n\n getPostCountByType(campaign: Campaign | string) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n this.log('debug', `Get post count by type for campaign #${campaignId}`);\n const rows = this.all(\n `\n SELECT\n COUNT(content_id) AS post_count, content_subtype AS post_type\n FROM\n content\n WHERE\n content_type = 'post' AND campaign_id = ?\n GROUP BY content_subtype \n `,\n [campaignId]\n );\n return rows.map((row) => ({\n postType: row.post_type as string,\n count: row.post_count as number\n }));\n }\n\n getPostCountByTier(campaign: Campaign | string) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n this.log('debug', `Get post count by tier for campaign #${campaignId}`);\n const rows = this.all(\n `\n SELECT\n COUNT(post_id) as post_count, tier_id, reward.title\n FROM post_tier\n RIGHT JOIN reward ON reward.reward_id = post_tier.tier_id AND reward.campaign_id = post_tier.campaign_id\n WHERE\n post_tier.campaign_id = ?\n GROUP BY\n tier_id\n `,\n [campaignId]\n );\n return rows.map((row) => ({\n tierId: row.tier_id as string,\n title: row.title as string,\n count: row.post_count as number\n }));\n }\n\n checkContentExists(id: string, contentType: ContentType, campaign?: Campaign | null) {\n this.log('debug', `Check if ${contentType} #${id} exists in DB`);\n const whereClauseParts = [\n 'content_id = ?',\n 'content_type = ?'\n ];\n const whereValues = [id, contentType];\n if (campaign !== undefined) {\n whereClauseParts.push('campaign_id = ?');\n whereValues.push(campaign?.id || '-1');\n }\n const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM content\n ${whereClause}\n `,\n whereValues\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if ${contentType} #${id} exists in DB:`,\n error\n );\n return false;\n }\n }\n\n saveCollection(collection: Collection, campaign: Campaign | null, overwriteIfExists = true) {\n this.log('debug', `Save collection #${collection.id} (${collection.title}) to DB`);\n try {\n // Normally, campaign would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCampaign(campaign, new Date(), false);\n\n const collectionExists = this.checkCollectionExists(collection.id);\n if (collectionExists && !overwriteIfExists) {\n return;\n }\n\n if (collection.thumbnail) {\n this.saveMedia(collection.thumbnail);\n }\n\n if (!collectionExists) {\n this.log('debug', `INSERT collection \"${collection.title}\" (${collection.id})`);\n this.run(\n `\n INSERT INTO collection (\n collection_id,\n campaign_id,\n title,\n created_at,\n edited_at,\n details\n )\n VALUES (?, ?, ?, ?, ?, ?)\n `,\n [\n collection.id,\n campaign?.id || '-1',\n collection.title,\n this.#publishedAtToTime(collection.createdAt),\n this.#publishedAtToTime(collection.editedAt),\n JSON.stringify(collection)\n ]\n );\n } else {\n this.log('debug', `Collection #${collection.id} already exists in DB - update record`);\n this.run(`\n UPDATE collection\n SET\n title = ?,\n created_at = ?,\n edited_at = ?,\n details = ?\n WHERE\n collection_id = ? AND\n campaign_id = ?\n `,\n [\n collection.title,\n this.#publishedAtToTime(collection.createdAt),\n this.#publishedAtToTime(collection.editedAt),\n JSON.stringify(collection),\n collection.id,\n campaign?.id || '-1'\n ]\n );\n }\n } catch (error) {\n this.log(\n 'error',\n `Failed to save collection \"${collection.title}\" (${collection.id}) to DB:`,\n error\n );\n }\n }\n\n savePostTag(tag: PostTag, campaign: Campaign | null, overwriteIfExists = true) {\n this.log('debug', `Save post_tag \"${tag.id}\" to DB`);\n try {\n // Normally, campaign would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCampaign(campaign, new Date(), false);\n\n const tagExists = this.checkPostTagExists(tag.id, campaign);\n if (tagExists && !overwriteIfExists) {\n return;\n }\n\n if (!tagExists) {\n this.log('debug', `INSERT post_tag \"${tag.id}\"`);\n this.run(\n `\n INSERT INTO post_tag (\n post_tag_id,\n campaign_id,\n value,\n details\n )\n VALUES (?, ?, ?, ?)\n `,\n [\n tag.id,\n campaign?.id || '-1',\n tag.value,\n JSON.stringify(tag)\n ]\n );\n } else {\n this.log('debug', `post_tag \"${tag.id}\" already exists in DB - update record`);\n this.run(`\n UPDATE post_tag\n SET\n value = ?,\n details = ?\n WHERE\n post_tag_id = ? AND\n campaign_id = ?\n `,\n [\n tag.value,\n JSON.stringify(tag),\n tag.id,\n campaign?.id || '-1'\n ]\n );\n }\n } catch (error) {\n this.log(\n 'error',\n `Failed to save post_tag \"${tag.id}\" to DB:`,\n error\n );\n }\n }\n\n getCollection(id: string) {\n this.log('debug', `Get collection #${id} from DB`);\n try {\n const result = this.get(\n `\n SELECT\n campaign_id,\n details,\n (SELECT COUNT(post_id) AS post_count FROM post_collection WHERE collection_id = ?) AS post_count\n FROM collection\n WHERE collection_id = ?;\n `,\n [id, id]\n );\n if (result) {\n const collection = JSON.parse(result.details) as Collection;\n collection.numPosts = result.post_count || 0;\n return {\n collection,\n campaignId: result.campaign_id as string\n };\n }\n return null;\n } catch (error) {\n this.log('error', `Failed to get collection #${id} from DB:`, error);\n return null;\n }\n }\n\n #savePostCollection(post: Post) {\n this.log('debug', `Clear post_collection for post #${post.id}`);\n this.run(`DELETE FROM post_collection WHERE post_id = ?`, [\n post.id\n ]);\n if (!post.collections || post.collections.length === 0) {\n return;\n }\n for (const collection of post.collections) {\n // Normally, collection would have already been saved to DB via\n // downloader logic, but we should still save it one more\n // time just in case. Difference is, we do not overwrite \n // DB entry if it already exists.\n this.saveCollection(collection, post.campaign, false);\n try {\n this.run(\n `\n INSERT INTO post_collection (\n collection_id,\n campaign_id,\n post_id,\n post_created_at\n )\n VALUES (?, ?, ?, ?)\n `,\n [\n collection.id,\n post.campaign?.id || '-1',\n post.id,\n this.#publishedAtToTime(collection.createdAt)\n ]\n );\n }\n catch (error) {\n this.log('error', `Failed to save post_collection for post #${post.id} -> collection #${collection.id}:`, error);\n }\n }\n }\n\n getCollectionList(params: GetCollectionListParams): CollectionList {\n const { campaign, search, sortBy, limit, offset } = params;\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n\n const whereClauseParts: string[] = [ 'campaign_id = ?' ];\n const whereValues: (string | number)[] = [ campaignId ];\n if (search) {\n whereClauseParts.push('collection_fts MATCH ?');\n whereValues.push(search);\n }\n const whereClause = whereClauseParts.length > 0 ? 'WHERE ' + whereClauseParts.join(' AND ') : '';\n\n let orderByClause: string;\n switch (sortBy) {\n case 'a-z':\n orderByClause = 'collection.title ASC';\n break;\n case 'z-a':\n orderByClause = 'collection.title DESC';\n break;\n case 'last_created':\n orderByClause = 'created_at DESC';\n break;\n case 'last_updated':\n orderByClause = 'edited_at DESC';\n break;\n default:\n orderByClause = '';\n }\n if (orderByClause) {\n orderByClause = `ORDER BY ${orderByClause}`;\n }\n\n let limitOffsetClause = '';\n const limitOffsetValues: number[] = [];\n if (limit !== undefined && offset !== undefined) {\n limitOffsetClause = 'LIMIT ? OFFSET ?';\n limitOffsetValues.push(limit, offset);\n }\n else if (limit !== undefined) {\n limitOffsetClause = 'LIMIT ?';\n limitOffsetValues.push(limit);\n }\n\n let fromClause: string;\n if (search) {\n fromClause = `\n FROM\n collection_fts\n LEFT JOIN\n collection_fts_source ON collection_fts_source.fts_rowid = collection_fts.rowid\n LEFT JOIN\n collection ON collection.collection_id = collection_fts_source.collection_id\n `;\n } else {\n fromClause = 'FROM collection';\n }\n\n const rows = this.all(\n `\n SELECT\n details, post_count\n ${fromClause}\n LEFT JOIN\n (SELECT COUNT(post_id) AS post_count, collection_id FROM post_collection GROUP BY collection_id) pcc ON pcc.collection_id = collection.collection_id\n ${whereClause}\n ${orderByClause}\n ${limitOffsetClause}\n `,\n [...whereValues, ...limitOffsetValues]\n );\n const totalResult = this.get(\n `SELECT COUNT(*) AS collection_count ${fromClause} ${whereClause}`,\n [...whereValues]\n );\n const total = totalResult ? (totalResult.collection_count as number) : 0;\n const collections = rows.map((row) => {\n const collection = JSON.parse(row.details) as Collection;\n collection.numPosts = row.post_count || 0;\n return collection;\n });\n return {\n collections,\n total\n };\n }\n\n checkCollectionExists(id: string) {\n this.log('debug', `Check if collection #${id} exists in DB`);\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM collection\n WHERE\n collection_id = ?\n `,\n [ id ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if collection #${id} exists in DB:`,\n error\n );\n return false;\n }\n }\n\n checkPostTagExists(id: string, campaign: Campaign | null) {\n this.log('debug', `Check if tag \"${id}\" exists in DB`);\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM post_tag\n WHERE\n post_tag_id = ? AND\n campaign_id = ?\n `,\n [ id, campaign?.id || '-1']\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if post_tag \"${id}\" exists in DB:`,\n error\n );\n return false;\n }\n }\n\n getPostComments(post: Post | string): Comment[] | null {\n const postId = typeof post === 'string' ? post : post.id;\n this.log('debug', `Get comments for post #${postId}`);\n const result = this.get(\n `SELECT comments FROM post_comments WHERE post_id = ?`,\n [postId]\n );\n return result ? JSON.parse(result.comments) : null; \n }\n\n #savePostTags(post: Post) {\n this.log('debug', `Clear post_tag_post for post #${post.id}`);\n this.run(`DELETE FROM post_tag_post WHERE post_id = ?`, [\n post.id\n ]);\n if (!post.tags || post.tags.length === 0) {\n return;\n }\n for (const tag of post.tags) {\n this.savePostTag(tag, post.campaign, false);\n try {\n this.run(\n `\n INSERT INTO post_tag_post (\n post_tag_id,\n campaign_id,\n post_id\n )\n VALUES (?, ?, ?)\n `,\n [\n tag.id,\n post.campaign?.id || '-1',\n post.id\n ]\n );\n }\n catch (error) {\n this.log('error', `Failed to save post_tag_post for post #${post.id} -> post_tag \"${tag.id}\":`, error);\n }\n }\n }\n\n getPostTagList(params: GetPostTagListParams): PostTagList {\n const { campaign } = params;\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n\n const whereClauseParts: string[] = [ 'campaign_id = ?' ];\n const whereValues: (string | number)[] = [ campaignId ]; \n const whereClause = `WHERE ${whereClauseParts.join(' AND ')}`;\n const orderByClause = 'ORDER BY post_tag.value ASC';\n const fromClause = 'FROM post_tag';\n\n const rows = this.all(\n `\n SELECT\n details\n ${fromClause}\n ${whereClause}\n ${orderByClause}\n `,\n [...whereValues]\n );\n const totalResult = this.get(\n `SELECT COUNT(*) AS tag_count ${fromClause} ${whereClause}`,\n [...whereValues]\n );\n const total = totalResult ? (totalResult.tag_count as number) : 0;\n const tags = rows.map((row) => {\n return JSON.parse(row.details) as PostTag;\n });\n return {\n tags,\n total\n };\n }\n };\n}\n"]}
@@ -276,7 +276,7 @@ export function MediaDBMixin(Base) {
276
276
  const value = groupBy === 'year' ?
277
277
  String(date.getUTCFullYear())
278
278
  : getYearMonthString(date);
279
- whereValues.push(String(value));
279
+ whereValues.push(value);
280
280
  }
281
281
  const whereClause = whereClauseParts.join(' AND ');
282
282
  const strftimeFormat = groupBy === 'year' ? '%Y' : '%Y-%m';
@@ -1 +1 @@
1
- {"version":3,"file":"MediaDBMixin.js","sourceRoot":"","sources":["../../../src/browse/db/MediaDBMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type DBConstructor } from '.';\nimport { type Downloadable, type Downloaded, type Post, type Campaign, type Product } from '../../entities';\nimport { PostType } from '../../entities/Post.js';\nimport { getYearMonthString } from '../../utils/Misc.js';\nimport { type ContentType } from '../types/Content.js';\nimport { type GetMediaListParams, type MediaList, type MediaListItem } from '../types/Media.js';\n\nexport type MediaDBConstructor = new (\n ...args: any[]\n) => InstanceType<ReturnType<typeof MediaDBMixin<DBConstructor>>>;\n\ntype DBMediaType = 'image' | 'video' | 'audio' | 'other';\n\nexport function MediaDBMixin<TBase extends DBConstructor>(Base: TBase) {\n return class MediaDB extends Base {\n saveMedia(\n media: Downloadable\n ) {\n if (!media.downloaded || !media.downloaded.path) {\n return;\n }\n let mediaType: DBMediaType;\n const mimeType = media.downloaded.mimeType || '';\n if (mimeType.startsWith('image/')) {\n mediaType = 'image';\n }\n else if (mimeType.startsWith('video/')) {\n mediaType = 'video';\n }\n else if (mimeType.startsWith('audio/')) {\n mediaType = 'audio';\n }\n else {\n mediaType = 'other';\n }\n this.log('debug', `Save media #${media.id} to DB`);\n try {\n const mediaExists = this.checkMediaExists(media);\n if (!mediaExists) {\n this.run(\n `\n INSERT INTO media (\n media_id,\n media_type,\n mime_type,\n thumbnail_mime_type,\n download_path,\n thumbnail_download_path,\n thumbnail_width,\n thumbnail_height\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `,\n [\n media.id,\n mediaType,\n media.downloaded.mimeType,\n media.downloaded.thumbnail?.mimeType || null,\n media.downloaded.path,\n media.downloaded.thumbnail?.path || null,\n media.downloaded.thumbnail?.width ?? null,\n media.downloaded.thumbnail?.height ?? null\n ]\n );\n }\n else {\n this.log('debug', `Media #${media.id} already exists in DB - update record`);\n this.run(\n `\n UPDATE media\n SET\n media_type = ?,\n mime_type = ?,\n thumbnail_mime_type = ?,\n download_path = ?,\n thumbnail_download_path = ?,\n thumbnail_width = ?,\n thumbnail_height = ?\n WHERE\n media_id = ?\n `,\n [\n mediaType,\n media.downloaded.mimeType,\n media.downloaded.thumbnail?.mimeType || null,\n media.downloaded.path,\n media.downloaded.thumbnail?.path || null,\n media.downloaded.thumbnail?.width ?? null,\n media.downloaded.thumbnail?.height ?? null,\n media.id,\n ]\n );\n }\n }\n catch (error) {\n this.log(\n 'error',\n `Failed to save media (media_id: ${media.id}) to DB:`,\n error\n );\n throw error;\n }\n }\n\n checkMediaExists(media: Downloadable) {\n this.log('debug', `Check if media #${media.id} exists in DB`);\n try {\n const result = this.get(\n `SELECT COUNT(*) as count FROM media WHERE media_id = ?`,\n [ media.id ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if media #${media.id} exists in DB:`,\n error\n );\n return false;\n }\n }\n\n checkContentMediaExists(content: Post | Product, media: Downloadable) {\n this.log(\n 'debug',\n `Check if content media exists in DB`,\n `(media ID: ${media.id})`,\n );\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM content_media\n WHERE\n media_id = ? AND\n campaign_id = ?\n `,\n [\n media.id,\n content.campaign?.id || '-1'\n ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if content media exists in DB:`,\n `(media ID: ${media.id})`,\n error\n );\n return false;\n }\n }\n\n getMediaByID(id: string): Downloaded | null {\n this.log('debug', `Get media #${id} from DB`);\n const result = this.get(\n `\n SELECT \n mime_type,\n thumbnail_mime_type,\n download_path,\n thumbnail_download_path,\n thumbnail_width,\n thumbnail_height\n FROM\n media\n WHERE\n media_id = ?\n `,\n [id]\n );\n return result ? {\n mimeType: result.mime_type,\n path: result.download_path,\n thumbnail: {\n mimeType: result.thumbnail_mime_type,\n path: result.thumbnail_download_path,\n width: result.thumbnail_width,\n height: result.thumbnail_height\n }\n } : null;\n }\n\n getMediaList<T extends ContentType>(params: GetMediaListParams<T>): MediaList<T> {\n const { campaign, sourceType, isViewable, datePublished, sortBy, limit, offset } = params;\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id );\n const tiers = params.sourceType === 'post' ? (params as GetMediaListParams<'post'>).tiers : null;\n const tierIds = tiers && tiers.length > 0 ? tiers.map((tier) => typeof tier === 'string' ? tier : tier.id) : null;\n this.log('debug', 'Get media list from DB:', {\n campaign: campaignId,\n sourceType,\n isViewable,\n tierIds,\n datePublished,\n sortBy,\n limit,\n offset\n });\n if (tierIds && !campaign) {\n throw Error('Invalid params: \"tiers\" must be used with \"campaign\"');\n }\n const join = tiers && tiers.length > 0 ? 'LEFT JOIN post_tier ON post_tier.post_id = content.content_id' : '';\n const whereEquals: { column: string; value: string | number; }[] = [];\n if (campaignId) {\n whereEquals.push({ column: 'content.campaign_id', value: campaignId });\n }\n if (sourceType) {\n whereEquals.push({ column: 'content.content_type', value: sourceType });\n }\n if (isViewable !== undefined) {\n whereEquals.push({ column: 'is_viewable', value: isViewable ? 1 : 0});\n }\n if (datePublished) {\n const strftimeFormat =\n /^\\d{4}$/.test(datePublished) ? '%Y' :\n /^\\d{4}-\\d{2}$/.test(datePublished) ? '%Y-%m'\n : null;\n if (!strftimeFormat) {\n throw Error('Invalid params: \"datePublished\" must be in format \"YYYY\" or \"YYYY-MM\" (e.g. \"2025-06\")');\n }\n whereEquals.push({\n column: `strftime('${strftimeFormat}', datetime(published_at / 1000, 'unixepoch'))`,\n value: datePublished\n });\n }\n const whereIns: { column: string; values: (string | number)[] }[] = [];\n if (tierIds) {\n whereIns.push({ column: 'tier_id', values: tierIds });\n }\n const whereClauseParts: string[] = [];\n if (whereEquals.length > 0) {\n whereClauseParts.push(...whereEquals.map(({column: field}) => `${field} = ?` ));\n }\n if (whereIns.length > 0) {\n whereClauseParts.push(...whereIns.map((wi) => `${wi.column} IN (${wi.values.map(() => '?').join(', ')})`));\n }\n const whereClause = whereClauseParts.join(' AND ');\n const whereValues = [\n ...whereEquals.map(({value}) => value),\n ...whereIns.reduce<(string | number)[]>((result, {values}) => {\n result.push(...values);\n return result;\n }, [])\n ];\n const orderByParts: string[] = []\n switch (sortBy) {\n case 'latest':\n orderByParts.push('published_at DESC');\n break;\n case 'oldest':\n orderByParts.push('published_at ASC');\n break;\n }\n orderByParts.push('media_index ASC');\n const orderByClause = orderByParts.join(', ');\n let limitOffsetClause = '';\n const limitOffsetValues: number[] = [];\n if (limit !== undefined && offset !== undefined) {\n limitOffsetClause = 'LIMIT ? OFFSET ?';\n limitOffsetValues.push(limit, offset);\n }\n else if (limit !== undefined) {\n limitOffsetClause = 'LIMIT ?';\n limitOffsetValues.push(limit);\n }\n const sql = this.getMediaListSQL({\n select: `DISTINCT\n media.media_id,\n media.media_type,\n media.mime_type,\n media.thumbnail_width,\n media.thumbnail_height,\n media.thumbnail_download_path,\n content.details`,\n join,\n where: whereClause,\n orderBy: orderByClause,\n limitOffset: limitOffsetClause\n });\n const rows = this.all(\n sql,\n [ ...whereValues, ...limitOffsetValues ]\n );\n const items = rows.map<MediaListItem<T>>((row) => ({\n id: row.media_id,\n mediaType: row.media_type,\n mimeType: row.mime_type ?? null,\n thumbnail: row.thumbnail_download_path ? {\n path: row.thumbnail_download_path,\n width: row.thumbnail_width || null,\n height: row.thumbnail_height || null\n } : null,\n source: JSON.parse(row.details)\n }));\n const totalSql = this.getMediaListSQL({\n select: 'COUNT(DISTINCT media.media_id) AS media_count',\n join,\n where: whereClause,\n });\n const totalResult = this.get(totalSql, whereValues);\n const total = totalResult ? (totalResult.media_count as number) : 0;\n return {\n items,\n total\n };\n }\n\n getMediaCountByDate(\n groupBy: 'year' | 'month',\n filter?: {\n campaign?: Campaign | string | null,\n date?: Date | null}\n ) {\n const campaign = filter?.campaign || null;\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id);\n this.log('debug', `Get media count by date:`, {\n groupBy,\n filter: !filter ? null : {\n campaign: campaignId,\n date: filter.date\n }\n });\n const date = filter?.date || null;\n const whereClauseParts = [];\n const whereValues: string[] = [];\n if (campaignId) {\n whereClauseParts.push('content_media.campaign_id = ?');\n whereValues.push(campaignId);\n }\n if (date) {\n whereClauseParts.push(`dt = ?`);\n const value = groupBy === 'year' ?\n String(date.getUTCFullYear())\n : getYearMonthString(date);\n whereValues.push(String(value));\n }\n const whereClause = whereClauseParts.join(' AND ');\n const strftimeFormat = groupBy === 'year' ? '%Y' : '%Y-%m'\n const sql = this.getMediaListSQL({\n select: `COUNT(media.media_id) AS media_count, strftime('${strftimeFormat}', datetime(published_at / 1000, 'unixepoch')) AS dt`,\n where: whereClause,\n groupBy: 'dt',\n orderBy: 'dt DESC'\n })\n const rows = this.all(sql, whereValues);\n return rows.map((row) => ({\n dt: row.dt as string,\n count: row.media_count as number\n }));\n }\n\n getMediaCountByContentType(campaign?: Campaign | string | null) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign?.id;\n this.log('debug', `Get media count by content type for campaign #${campaignId}`);\n const whereClauseParts: string[] = [];\n const whereValues: string[] = [];\n if (campaignId) {\n whereClauseParts.push('content_media.campaign_id = ?');\n whereValues.push(campaignId);\n }\n const whereClause = whereClauseParts.join(' AND ');\n const sql = this.getMediaListSQL({\n select: 'COUNT(media.media_id) AS media_count, content.content_type',\n where: whereClause,\n groupBy: 'content.content_type',\n orderBy: 'content.content_type DESC'\n });\n const rows = this.all(sql, whereValues);\n return rows.map((row) => ({\n contentType: row.content_type as 'post' | 'product',\n count: row.media_count as number\n }));\n }\n\n getMediaCountByTier(campaign: Campaign | string) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n this.log('debug', `Get media count by tier for campaign #${campaignId}`);\n const sql = this.getMediaListSQL({\n select: 'COUNT(media.media_id) as media_count, tier_id, reward.title',\n join: `LEFT JOIN post_tier ON post_tier.campaign_id = content_media.campaign_id AND post_tier.post_id = content_media.content_id\n RIGHT JOIN reward ON reward.reward_id = post_tier.tier_id AND reward.campaign_id = post_tier.campaign_id`,\n where: `content.content_type = 'post' AND\n post_tier.campaign_id = ?`,\n groupBy: 'post_tier.campaign_id, tier_id'\n })\n const rows = this.all(sql, [campaignId]);\n return rows.map((row) => ({\n tierId: row.tier_id as string,\n title: row.title as string,\n count: row.media_count as number\n }));\n }\n\n getMediaListSQL(params: {\n select: string;\n join?: string;\n where?: string;\n groupBy?: string;\n orderBy?: string;\n limitOffset?: string;\n }) {\n const finalJoin = `\n LEFT JOIN content_media ON content_media.media_id = media.media_id\n LEFT JOIN content ON content.content_id = content_media.content_id AND content.campaign_id = content_media.campaign_id\n ${params.join || ''}\n `;\n const finalWhere = `\n WHERE\n content_media.is_preview != content.is_viewable AND\n content.content_id IS NOT NULL AND\n (\n (\n content.content_type = 'product' AND\n (\n media_type IN ('image', 'video', 'audio')\n OR\n mime_type = 'application/pdf'\n )\n )\n OR\n (\n content.content_type = 'post' AND \n (\n (content.content_subtype IN ('${PostType.Audio}', '${PostType.Podcast}', '${PostType.Link}') AND media_type = 'audio') OR \n (content.content_subtype IN ('${PostType.Video}', '${PostType.VideoEmbed}', '${PostType.Podcast}', '${PostType.Link}') AND media_type = 'video') OR \n (content.content_subtype NOT IN ('${PostType.Audio}', '${PostType.Podcast}', '${PostType.Video}', '${PostType.VideoEmbed}', '${PostType.Link}') AND media_type IN ('image', 'video', 'audio'))\n )\n )\n )\n ${params.where ? `AND ${params.where}` : ''}\n `;\n return `\n SELECT ${params.select}\n FROM\n media\n ${finalJoin}\n ${finalWhere}\n ${params.groupBy ? `GROUP BY ${params.groupBy}` : ''}\n ${params.orderBy ? `ORDER BY ${params.orderBy}` : ''}\n ${params.limitOffset || ''}\n `;\n }\n };\n}\n"]}
1
+ {"version":3,"file":"MediaDBMixin.js","sourceRoot":"","sources":["../../../src/browse/db/MediaDBMixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type DBConstructor } from '.';\nimport { type Downloadable, type Downloaded, type Post, type Campaign, type Product } from '../../entities';\nimport { PostType } from '../../entities/Post.js';\nimport { getYearMonthString } from '../../utils/Misc.js';\nimport { type ContentType } from '../types/Content.js';\nimport { type GetMediaListParams, type MediaList, type MediaListItem } from '../types/Media.js';\n\nexport type MediaDBConstructor = new (\n ...args: any[]\n) => InstanceType<ReturnType<typeof MediaDBMixin<DBConstructor>>>;\n\ntype DBMediaType = 'image' | 'video' | 'audio' | 'other';\n\nexport function MediaDBMixin<TBase extends DBConstructor>(Base: TBase) {\n return class MediaDB extends Base {\n saveMedia(\n media: Downloadable\n ) {\n if (!media.downloaded || !media.downloaded.path) {\n return;\n }\n let mediaType: DBMediaType;\n const mimeType = media.downloaded.mimeType || '';\n if (mimeType.startsWith('image/')) {\n mediaType = 'image';\n }\n else if (mimeType.startsWith('video/')) {\n mediaType = 'video';\n }\n else if (mimeType.startsWith('audio/')) {\n mediaType = 'audio';\n }\n else {\n mediaType = 'other';\n }\n this.log('debug', `Save media #${media.id} to DB`);\n try {\n const mediaExists = this.checkMediaExists(media);\n if (!mediaExists) {\n this.run(\n `\n INSERT INTO media (\n media_id,\n media_type,\n mime_type,\n thumbnail_mime_type,\n download_path,\n thumbnail_download_path,\n thumbnail_width,\n thumbnail_height\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `,\n [\n media.id,\n mediaType,\n media.downloaded.mimeType,\n media.downloaded.thumbnail?.mimeType || null,\n media.downloaded.path,\n media.downloaded.thumbnail?.path || null,\n media.downloaded.thumbnail?.width ?? null,\n media.downloaded.thumbnail?.height ?? null\n ]\n );\n }\n else {\n this.log('debug', `Media #${media.id} already exists in DB - update record`);\n this.run(\n `\n UPDATE media\n SET\n media_type = ?,\n mime_type = ?,\n thumbnail_mime_type = ?,\n download_path = ?,\n thumbnail_download_path = ?,\n thumbnail_width = ?,\n thumbnail_height = ?\n WHERE\n media_id = ?\n `,\n [\n mediaType,\n media.downloaded.mimeType,\n media.downloaded.thumbnail?.mimeType || null,\n media.downloaded.path,\n media.downloaded.thumbnail?.path || null,\n media.downloaded.thumbnail?.width ?? null,\n media.downloaded.thumbnail?.height ?? null,\n media.id,\n ]\n );\n }\n }\n catch (error) {\n this.log(\n 'error',\n `Failed to save media (media_id: ${media.id}) to DB:`,\n error\n );\n throw error;\n }\n }\n\n checkMediaExists(media: Downloadable) {\n this.log('debug', `Check if media #${media.id} exists in DB`);\n try {\n const result = this.get(\n `SELECT COUNT(*) as count FROM media WHERE media_id = ?`,\n [ media.id ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if media #${media.id} exists in DB:`,\n error\n );\n return false;\n }\n }\n\n checkContentMediaExists(content: Post | Product, media: Downloadable) {\n this.log(\n 'debug',\n `Check if content media exists in DB`,\n `(media ID: ${media.id})`,\n );\n try {\n const result = this.get(\n `\n SELECT COUNT(*) as count\n FROM content_media\n WHERE\n media_id = ? AND\n campaign_id = ?\n `,\n [\n media.id,\n content.campaign?.id || '-1'\n ]\n );\n return result.count > 0;\n } catch (error) {\n this.log(\n 'error',\n `Failed to check if content media exists in DB:`,\n `(media ID: ${media.id})`,\n error\n );\n return false;\n }\n }\n\n getMediaByID(id: string): Downloaded | null {\n this.log('debug', `Get media #${id} from DB`);\n const result = this.get(\n `\n SELECT \n mime_type,\n thumbnail_mime_type,\n download_path,\n thumbnail_download_path,\n thumbnail_width,\n thumbnail_height\n FROM\n media\n WHERE\n media_id = ?\n `,\n [id]\n );\n return result ? {\n mimeType: result.mime_type,\n path: result.download_path,\n thumbnail: {\n mimeType: result.thumbnail_mime_type,\n path: result.thumbnail_download_path,\n width: result.thumbnail_width,\n height: result.thumbnail_height\n }\n } : null;\n }\n\n getMediaList<T extends ContentType>(params: GetMediaListParams<T>): MediaList<T> {\n const { campaign, sourceType, isViewable, datePublished, sortBy, limit, offset } = params;\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id );\n const tiers = params.sourceType === 'post' ? (params as GetMediaListParams<'post'>).tiers : null;\n const tierIds = tiers && tiers.length > 0 ? tiers.map((tier) => typeof tier === 'string' ? tier : tier.id) : null;\n this.log('debug', 'Get media list from DB:', {\n campaign: campaignId,\n sourceType,\n isViewable,\n tierIds,\n datePublished,\n sortBy,\n limit,\n offset\n });\n if (tierIds && !campaign) {\n throw Error('Invalid params: \"tiers\" must be used with \"campaign\"');\n }\n const join = tiers && tiers.length > 0 ? 'LEFT JOIN post_tier ON post_tier.post_id = content.content_id' : '';\n const whereEquals: { column: string; value: string | number; }[] = [];\n if (campaignId) {\n whereEquals.push({ column: 'content.campaign_id', value: campaignId });\n }\n if (sourceType) {\n whereEquals.push({ column: 'content.content_type', value: sourceType });\n }\n if (isViewable !== undefined) {\n whereEquals.push({ column: 'is_viewable', value: isViewable ? 1 : 0});\n }\n if (datePublished) {\n const strftimeFormat =\n /^\\d{4}$/.test(datePublished) ? '%Y' :\n /^\\d{4}-\\d{2}$/.test(datePublished) ? '%Y-%m'\n : null;\n if (!strftimeFormat) {\n throw Error('Invalid params: \"datePublished\" must be in format \"YYYY\" or \"YYYY-MM\" (e.g. \"2025-06\")');\n }\n whereEquals.push({\n column: `strftime('${strftimeFormat}', datetime(published_at / 1000, 'unixepoch'))`,\n value: datePublished\n });\n }\n const whereIns: { column: string; values: (string | number)[] }[] = [];\n if (tierIds) {\n whereIns.push({ column: 'tier_id', values: tierIds });\n }\n const whereClauseParts: string[] = [];\n if (whereEquals.length > 0) {\n whereClauseParts.push(...whereEquals.map(({column: field}) => `${field} = ?` ));\n }\n if (whereIns.length > 0) {\n whereClauseParts.push(...whereIns.map((wi) => `${wi.column} IN (${wi.values.map(() => '?').join(', ')})`));\n }\n const whereClause = whereClauseParts.join(' AND ');\n const whereValues = [\n ...whereEquals.map(({value}) => value),\n ...whereIns.reduce<(string | number)[]>((result, {values}) => {\n result.push(...values);\n return result;\n }, [])\n ];\n const orderByParts: string[] = []\n switch (sortBy) {\n case 'latest':\n orderByParts.push('published_at DESC');\n break;\n case 'oldest':\n orderByParts.push('published_at ASC');\n break;\n }\n orderByParts.push('media_index ASC');\n const orderByClause = orderByParts.join(', ');\n let limitOffsetClause = '';\n const limitOffsetValues: number[] = [];\n if (limit !== undefined && offset !== undefined) {\n limitOffsetClause = 'LIMIT ? OFFSET ?';\n limitOffsetValues.push(limit, offset);\n }\n else if (limit !== undefined) {\n limitOffsetClause = 'LIMIT ?';\n limitOffsetValues.push(limit);\n }\n const sql = this.getMediaListSQL({\n select: `DISTINCT\n media.media_id,\n media.media_type,\n media.mime_type,\n media.thumbnail_width,\n media.thumbnail_height,\n media.thumbnail_download_path,\n content.details`,\n join,\n where: whereClause,\n orderBy: orderByClause,\n limitOffset: limitOffsetClause\n });\n const rows = this.all(\n sql,\n [ ...whereValues, ...limitOffsetValues ]\n );\n const items = rows.map<MediaListItem<T>>((row) => ({\n id: row.media_id,\n mediaType: row.media_type,\n mimeType: row.mime_type ?? null,\n thumbnail: row.thumbnail_download_path ? {\n path: row.thumbnail_download_path,\n width: row.thumbnail_width || null,\n height: row.thumbnail_height || null\n } : null,\n source: JSON.parse(row.details)\n }));\n const totalSql = this.getMediaListSQL({\n select: 'COUNT(DISTINCT media.media_id) AS media_count',\n join,\n where: whereClause,\n });\n const totalResult = this.get(totalSql, whereValues);\n const total = totalResult ? (totalResult.media_count as number) : 0;\n return {\n items,\n total\n };\n }\n\n getMediaCountByDate(\n groupBy: 'year' | 'month',\n filter?: {\n campaign?: Campaign | string | null,\n date?: Date | null}\n ) {\n const campaign = filter?.campaign || null;\n const campaignId = !campaign ? null : (typeof campaign === 'string' ? campaign : campaign.id);\n this.log('debug', `Get media count by date:`, {\n groupBy,\n filter: !filter ? null : {\n campaign: campaignId,\n date: filter.date\n }\n });\n const date = filter?.date || null;\n const whereClauseParts = [];\n const whereValues: string[] = [];\n if (campaignId) {\n whereClauseParts.push('content_media.campaign_id = ?');\n whereValues.push(campaignId);\n }\n if (date) {\n whereClauseParts.push(`dt = ?`);\n const value = groupBy === 'year' ?\n String(date.getUTCFullYear())\n : getYearMonthString(date);\n whereValues.push(value);\n }\n const whereClause = whereClauseParts.join(' AND ');\n const strftimeFormat = groupBy === 'year' ? '%Y' : '%Y-%m'\n const sql = this.getMediaListSQL({\n select: `COUNT(media.media_id) AS media_count, strftime('${strftimeFormat}', datetime(published_at / 1000, 'unixepoch')) AS dt`,\n where: whereClause,\n groupBy: 'dt',\n orderBy: 'dt DESC'\n })\n const rows = this.all(sql, whereValues);\n return rows.map((row) => ({\n dt: row.dt as string,\n count: row.media_count as number\n }));\n }\n\n getMediaCountByContentType(campaign?: Campaign | string | null) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign?.id;\n this.log('debug', `Get media count by content type for campaign #${campaignId}`);\n const whereClauseParts: string[] = [];\n const whereValues: string[] = [];\n if (campaignId) {\n whereClauseParts.push('content_media.campaign_id = ?');\n whereValues.push(campaignId);\n }\n const whereClause = whereClauseParts.join(' AND ');\n const sql = this.getMediaListSQL({\n select: 'COUNT(media.media_id) AS media_count, content.content_type',\n where: whereClause,\n groupBy: 'content.content_type',\n orderBy: 'content.content_type DESC'\n });\n const rows = this.all(sql, whereValues);\n return rows.map((row) => ({\n contentType: row.content_type as 'post' | 'product',\n count: row.media_count as number\n }));\n }\n\n getMediaCountByTier(campaign: Campaign | string) {\n const campaignId = typeof campaign === 'string' ? campaign : campaign.id;\n this.log('debug', `Get media count by tier for campaign #${campaignId}`);\n const sql = this.getMediaListSQL({\n select: 'COUNT(media.media_id) as media_count, tier_id, reward.title',\n join: `LEFT JOIN post_tier ON post_tier.campaign_id = content_media.campaign_id AND post_tier.post_id = content_media.content_id\n RIGHT JOIN reward ON reward.reward_id = post_tier.tier_id AND reward.campaign_id = post_tier.campaign_id`,\n where: `content.content_type = 'post' AND\n post_tier.campaign_id = ?`,\n groupBy: 'post_tier.campaign_id, tier_id'\n })\n const rows = this.all(sql, [campaignId]);\n return rows.map((row) => ({\n tierId: row.tier_id as string,\n title: row.title as string,\n count: row.media_count as number\n }));\n }\n\n getMediaListSQL(params: {\n select: string;\n join?: string;\n where?: string;\n groupBy?: string;\n orderBy?: string;\n limitOffset?: string;\n }) {\n const finalJoin = `\n LEFT JOIN content_media ON content_media.media_id = media.media_id\n LEFT JOIN content ON content.content_id = content_media.content_id AND content.campaign_id = content_media.campaign_id\n ${params.join || ''}\n `;\n const finalWhere = `\n WHERE\n content_media.is_preview != content.is_viewable AND\n content.content_id IS NOT NULL AND\n (\n (\n content.content_type = 'product' AND\n (\n media_type IN ('image', 'video', 'audio')\n OR\n mime_type = 'application/pdf'\n )\n )\n OR\n (\n content.content_type = 'post' AND \n (\n (content.content_subtype IN ('${PostType.Audio}', '${PostType.Podcast}', '${PostType.Link}') AND media_type = 'audio') OR \n (content.content_subtype IN ('${PostType.Video}', '${PostType.VideoEmbed}', '${PostType.Podcast}', '${PostType.Link}') AND media_type = 'video') OR \n (content.content_subtype NOT IN ('${PostType.Audio}', '${PostType.Podcast}', '${PostType.Video}', '${PostType.VideoEmbed}', '${PostType.Link}') AND media_type IN ('image', 'video', 'audio'))\n )\n )\n )\n ${params.where ? `AND ${params.where}` : ''}\n `;\n return `\n SELECT ${params.select}\n FROM\n media\n ${finalJoin}\n ${finalWhere}\n ${params.groupBy ? `GROUP BY ${params.groupBy}` : ''}\n ${params.orderBy ? `ORDER BY ${params.orderBy}` : ''}\n ${params.limitOffset || ''}\n `;\n }\n };\n}\n"]}
@@ -252,7 +252,7 @@ class Downloader extends EventEmitter {
252
252
  if (downloader instanceof PostDownloader) {
253
253
  if (typeof params === 'object' && params.campaignId) {
254
254
  const { json } = await downloader.fetchCampaign(params.campaignId, signal);
255
- const parser = new PostParser(options instanceof Logger ? options : options?.logger);
255
+ const parser = new PostParser(downloader.getFetcher(), options instanceof Logger ? options : options?.logger);
256
256
  return parser.parseCampaignAPIResponse(json);
257
257
  }
258
258
  return downloader.__getCampaign(signal);