exports.id=9107,exports.ids=[9107],exports.modules={5069:(e,t,i)=>{"use strict";let r;i.d(t,{A:()=>u});var T=i(3498),o=i.n(T),n=i(29021),l=i.n(n),a=i(33873),E=i.n(a);try{r=i(46293)}catch(e){console.warn("sql.js not installed or failed to load")}let s=null,c=null;try{s=o().createPool({host:process.env.DB_HOST||"localhost",port:Number(process.env.DB_PORT)||3306,user:process.env.DB_USER||"root",password:process.env.DB_PASSWORD||"",database:process.env.DB_NAME||"mobile_insights",charset:"utf8mb4",waitForConnections:!0,connectionLimit:10,connectTimeout:1e3})}catch(e){console.warn("MySQL pool creation failed, using SQLite fallback:",e)}async function d(){if(c)return c;if(!r)throw Error("sql.js is not available");console.log("Initializing in-memory SQLite database...");let e=new(await r()).Database;for(let t of[`CREATE TABLE IF NOT EXISTS brands (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL UNIQUE,
      gsmarena_url TEXT NOT NULL,
      device_count INTEGER DEFAULT 0,
      scraped_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )`,`CREATE TABLE IF NOT EXISTS devices (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      brand_id INTEGER NOT NULL,
      name TEXT NOT NULL,
      gsmarena_url TEXT NOT NULL UNIQUE,
      thumbnail_url TEXT DEFAULT NULL,
      summary TEXT DEFAULT NULL,
      scraped_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )`,`CREATE TABLE IF NOT EXISTS device_specs (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      device_id INTEGER NOT NULL UNIQUE,
      announced TEXT, status TEXT, network TEXT, os TEXT,
      chipset TEXT, cpu TEXT, gpu TEXT,
      display_size TEXT, display_type TEXT, display_res TEXT,
      ram TEXT, storage TEXT,
      main_camera TEXT, selfie_camera TEXT,
      battery TEXT, charging TEXT,
      nfc TEXT, usb TEXT, bluetooth TEXT, wlan TEXT,
      colors TEXT, weight TEXT, dimensions TEXT,
      sim TEXT, sensors TEXT, popularity TEXT,
      fans TEXT, rating TEXT, full_specs_json TEXT,
      scraped_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )`,`CREATE TABLE IF NOT EXISTS device_pictures (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      device_id INTEGER NOT NULL,
      url TEXT NOT NULL,
      position INTEGER DEFAULT 0,
      UNIQUE(device_id, url)
    )`,`CREATE TABLE IF NOT EXISTS wishlist (
      user_id INTEGER NOT NULL,
      device_slug TEXT NOT NULL,
      PRIMARY KEY (user_id, device_slug)
    )`,`CREATE TABLE IF NOT EXISTS comparisons_log (
      slug1 TEXT NOT NULL,
      slug2 TEXT NOT NULL,
      count INTEGER DEFAULT 1,
      last_compared TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (slug1, slug2)
    )`,`CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      email TEXT NOT NULL UNIQUE,
      password_hash TEXT NOT NULL,
      is_admin INTEGER DEFAULT 0,
      avatar_url TEXT,
      wishlist TEXT DEFAULT '[]',
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )`,`CREATE TABLE IF NOT EXISTS seo_meta (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      page_key TEXT NOT NULL UNIQUE,
      title TEXT, description TEXT, keywords TEXT,
      og_title TEXT, og_image TEXT, canonical TEXT,
      json_ld TEXT, noindex INTEGER DEFAULT 0,
      twitter_card TEXT, twitter_title TEXT,
      twitter_description TEXT, twitter_image TEXT,
      schema_type TEXT
    )`,`CREATE TABLE IF NOT EXISTS site_settings (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      key_name TEXT NOT NULL UNIQUE,
      value TEXT
    )`,`CREATE TABLE IF NOT EXISTS news_articles (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      slug TEXT NOT NULL UNIQUE,
      title TEXT NOT NULL,
      excerpt TEXT,
      category TEXT DEFAULT 'news',
      author TEXT DEFAULT 'MobilePhoneCompare',
      thumbnail_url TEXT,
      related_device_slug TEXT,
      related_brand TEXT,
      published_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      is_featured INTEGER DEFAULT 0,
      views INTEGER DEFAULT 0
    )`,`CREATE TABLE IF NOT EXISTS upcoming_phones (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      slug TEXT NOT NULL UNIQUE,
      name TEXT NOT NULL,
      brand TEXT NOT NULL,
      brand_color TEXT DEFAULT '#ff6e14',
      expected_price TEXT,
      launch_quarter TEXT,
      launch_date TEXT,
      status TEXT DEFAULT 'Rumored',
      thumbnail_url TEXT,
      chipset TEXT, ram TEXT, camera TEXT, battery TEXT, display TEXT,
      hype INTEGER DEFAULT 0,
      followers TEXT DEFAULT '0',
      description TEXT,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )`])try{e.run(t)}catch(e){console.warn("CREATE TABLE warning:",e.message)}try{let t=E().join(process.cwd(),"mobile_insights.sql");if(l().existsSync(t)){console.log("Loading mobile_insights.sql into SQLite...");let i=l().readFileSync(t,"utf8"),r=[],T="",o=!1;for(let e=0;e<i.length;e++){let t=i[e];if("'"===t&&"\\"!==i[e-1]&&(o=!o),";"!==t||o)T+=t;else{let e=T.trim();e&&!e.startsWith("--")&&r.push(e),T=""}}let n=0;for(let t of r)if(t)try{e.run(t),n++}catch(e){t.trimStart().toUpperCase().startsWith("INSERT")||console.warn("SQL init warning:",t.substring(0,80),"|",e.message)}console.log(`Loaded ${n}/${r.length} statements from mobile_insights.sql`)}else console.warn("mobile_insights.sql not found — run: node scripts/csv_to_sql.mjs")}catch(e){console.error("Failed to load mobile_insights.sql:",e)}try{let i=E().join(process.cwd(),"seed.sql");if(l().existsSync(i)){var t;for(let t of l().readFileSync(i,"utf8").replace(/^\s*--.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").replace(/START TRANSACTION;/gi,"").replace(/COMMIT;/gi,"").replace(/LOCK TABLES `[^`]+` WRITE;/gi,"").replace(/UNLOCK TABLES;/gi,"").replace(/SET SQL_MODE[\s\S]*?;/gi,"").replace(/SET time_zone[\s\S]*?;/gi,"").replace(/ALTER TABLE `[^`]+`[\s\S]*?;/gi,"").replace(/ON UPDATE current_timestamp\(\)/gi,"").replace(/DEFAULT current_timestamp\(\)/gi,"DEFAULT CURRENT_TIMESTAMP").replace(/\b(?:int|integer|tinyint|smallint|mediumint|bigint)\(\d+\)(?:\s+unsigned)?/gi,"INTEGER").replace(/\b(?:double|decimal\(\d+,\d+\))\b/gi,"REAL").replace(/\bunsigned\b/gi,"").replace(/\bdatetime\b/gi,"TIMESTAMP").replace(/\blongtext\b/gi,"TEXT").replace(/COLLATE \w+/gi,"").replace(/CHARACTER SET \w+/gi,"").replace(/DEFAULT CHARSET=\w+/gi,"").replace(/ENGINE=InnoDB\b[^;]*;?/gi,";").replace(/\\'/g,"''").replace(/\\"/g,'"').replace(/INSERT IGNORE INTO/gi,"INSERT OR IGNORE INTO").split(";"))if(t=t.trim())try{e.run(t)}catch{}}}catch(e){console.error("Failed to load seed.sql:",e)}return c=e,console.log("In-memory SQLite database initialized successfully."),c}let u={execute:async(e,t=[])=>{if(s)try{return await s.execute(e,t)}catch(e){if(!("ECONNREFUSED"===e.code||"PROTOCOL_CONNECTION_LOST"===e.code||"ETIMEDOUT"===e.code||e.message?.includes("connect")))throw e;console.warn("MySQL connection failed. Falling back to SQLite database...")}let i=await d(),r=function(e){let t=e.replace(/\bUNSIGNED\b/gi,"INTEGER");return(t=t.replace(/\bNOW\(\)/gi,"datetime('now')")).replace(/ON DUPLICATE KEY UPDATE[\s\S]*$/gi,"")}(e);if(/^\s*(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|ALTER)/i.test(r)){i.run(r,t);let e=0,T=0;try{let t=i.exec("SELECT last_insert_rowid()");t.length>0&&(e=t[0].values[0][0]);let r=i.exec("SELECT changes()");r.length>0&&(T=r[0].values[0][0])}catch(e){}return[{insertId:e,affectedRows:T},void 0]}{let e=i.exec(r,t);if(0===e.length)return[[],void 0];let T=e[0].columns;return[e[0].values.map(e=>{let t={};return T.forEach((i,r)=>{t[i]=e[r]}),t}),void 0]}}}},12127:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),!function(e,t){for(var i in t)Object.defineProperty(e,i,{enumerable:!0,get:t[i]})}(t,{resolveManifest:function(){return n},resolveRobots:function(){return T},resolveRouteData:function(){return l},resolveSitemap:function(){return o}});let r=i(77341);function T(e){let t="";for(let i of Array.isArray(e.rules)?e.rules:[e.rules]){for(let e of(0,r.resolveArray)(i.userAgent||["*"]))t+=`User-Agent: ${e}
`;if(i.allow)for(let e of(0,r.resolveArray)(i.allow))t+=`Allow: ${e}
`;if(i.disallow)for(let e of(0,r.resolveArray)(i.disallow))t+=`Disallow: ${e}
`;i.crawlDelay&&(t+=`Crawl-delay: ${i.crawlDelay}
`),t+="\n"}return e.host&&(t+=`Host: ${e.host}
`),e.sitemap&&(0,r.resolveArray)(e.sitemap).forEach(e=>{t+=`Sitemap: ${e}
`}),t}function o(e){let t=e.some(e=>Object.keys(e.alternates??{}).length>0),i=e.some(e=>{var t;return!!(null==(t=e.images)?void 0:t.length)}),r=e.some(e=>{var t;return!!(null==(t=e.videos)?void 0:t.length)}),T="";for(let a of(T+='<?xml version="1.0" encoding="UTF-8"?>\n',T+='<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"',i&&(T+=' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"'),r&&(T+=' xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"'),t?T+=' xmlns:xhtml="http://www.w3.org/1999/xhtml">\n':T+=">\n",e)){var o,n,l;T+="<url>\n",T+=`<loc>${a.url}</loc>
`;let e=null==(o=a.alternates)?void 0:o.languages;if(e&&Object.keys(e).length)for(let t in e)T+=`<xhtml:link rel="alternate" hreflang="${t}" href="${e[t]}" />
`;if(null==(n=a.images)?void 0:n.length)for(let e of a.images)T+=`<image:image>
<image:loc>${e}</image:loc>
</image:image>
`;if(null==(l=a.videos)?void 0:l.length)for(let e of a.videos)T+=["<video:video>",`<video:title>${e.title}</video:title>`,`<video:thumbnail_loc>${e.thumbnail_loc}</video:thumbnail_loc>`,`<video:description>${e.description}</video:description>`,e.content_loc&&`<video:content_loc>${e.content_loc}</video:content_loc>`,e.player_loc&&`<video:player_loc>${e.player_loc}</video:player_loc>`,e.duration&&`<video:duration>${e.duration}</video:duration>`,e.view_count&&`<video:view_count>${e.view_count}</video:view_count>`,e.tag&&`<video:tag>${e.tag}</video:tag>`,e.rating&&`<video:rating>${e.rating}</video:rating>`,e.expiration_date&&`<video:expiration_date>${e.expiration_date}</video:expiration_date>`,e.publication_date&&`<video:publication_date>${e.publication_date}</video:publication_date>`,e.family_friendly&&`<video:family_friendly>${e.family_friendly}</video:family_friendly>`,e.requires_subscription&&`<video:requires_subscription>${e.requires_subscription}</video:requires_subscription>`,e.live&&`<video:live>${e.live}</video:live>`,e.restriction&&`<video:restriction relationship="${e.restriction.relationship}">${e.restriction.content}</video:restriction>`,e.platform&&`<video:platform relationship="${e.platform.relationship}">${e.platform.content}</video:platform>`,e.uploader&&`<video:uploader${e.uploader.info&&` info="${e.uploader.info}"`}>${e.uploader.content}</video:uploader>`,`</video:video>
`].filter(Boolean).join("\n");if(a.lastModified){let e=a.lastModified instanceof Date?a.lastModified.toISOString():a.lastModified;T+=`<lastmod>${e}</lastmod>
`}a.changeFrequency&&(T+=`<changefreq>${a.changeFrequency}</changefreq>
`),"number"==typeof a.priority&&(T+=`<priority>${a.priority}</priority>
`),T+="</url>\n"}return T+"</urlset>\n"}function n(e){return JSON.stringify(e)}function l(e,t){return"robots"===t?T(e):"sitemap"===t?o(e):"manifest"===t?n(e):""}},77341:(e,t)=>{"use strict";function i(e){return Array.isArray(e)?e:[e]}function r(e){if(null!=e)return i(e)}function T(e){let t;if("string"==typeof e)try{t=(e=new URL(e)).origin}catch{}return t}Object.defineProperty(t,"__esModule",{value:!0}),!function(e,t){for(var i in t)Object.defineProperty(e,i,{enumerable:!0,get:t[i]})}(t,{getOrigin:function(){return T},resolveArray:function(){return i},resolveAsArrayOrUndefined:function(){return r}})},78335:()=>{},96487:()=>{}};