1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1818],{19372:function(e,t,r){r.d(t,{G:function(){return m}});var i=r(67294),n=r(55346),a=r(98568);let l="cutline.products.pending";function o(){try{let e=localStorage.getItem(l);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function u(e){try{localStorage.setItem(l,JSON.stringify(e))}catch{}}function s(e){let t=o();t.push({...e,timestamp:Date.now(),retries:0}),u(t)}function c(e,t){u(o().filter(r=>!(r.id===e&&r.type===t)))}function d(e,t){let r=o(),i=r.findIndex(r=>r.id===e&&r.type===t);return -1!==i&&((r[i].retries+=1,r[i].retries>=3)?(r.splice(i,1),u(r),!1):(u(r),!0))}function f(){return"undefined"==typeof navigator||!1!==navigator.onLine}let p="/api/products";function y(e,t){return{...e,bundle:t,_meta:{version:1,syncedAt:Date.now()}}}function m(){let{data:e}=(0,n.aF)(),{fetch:t}=(0,a.N)(),[r,l]=(0,i.useState)("idle"),[u,m]=(0,i.useState)(null),[g,h]=(0,i.useState)(null),w=(0,i.useRef)(new Map),v=(0,i.useCallback)(async()=>{if(!f()){l("offline");return}if(!e?.uid)return;let r=o();if(0!==r.length){for(let e of(l("syncing"),m(null),r))try{if("delete"===e.type){let r=await t(`${p}/${e.id}`,{method:"DELETE"});r.ok?c(e.id,e.type):r.status>=500&&!d(e.id,e.type)&&c(e.id,e.type)}else if(e.data){let r=await t(p,{method:"POST",body:{product:e.data}});if(r.ok)c(e.id,e.type),await r.json(),h(Date.now());else if(r.status>=500)d(e.id,e.type)||c(e.id,e.type);else{let e=await r.json().catch(()=>({}));console.warn("[productSync] queued update failed",{status:r.status,data:e})}}}catch(t){console.warn("Failed to process pending write:",e,t),d(e.id,e.type)||c(e.id,e.type)}0===o().length&&l("idle")}},[t,e?.uid]),E=(0,i.useCallback)(async(r,i,n)=>{if(!e?.uid)return;let a=w.current.get(r);a&&clearTimeout(a);let o=setTimeout(async()=>{if(w.current.delete(r),!f()){s({id:r,type:"update",data:y(i,n)}),l("offline");return}l("syncing"),m(null);try{let e=y(i,n),r=await t(p,{method:"POST",body:{product:e}});if(r.ok)h(Date.now()),l("idle");else{let e=await r.json().catch(()=>({}));throw console.warn("[productSync] syncProduct failed",{status:r.status,data:e}),Error(e.error||"Failed to sync product")}}catch(e){console.error("Failed to sync product:",e),e.message?.includes("fetch")||e.message?.includes("network")?(s({id:r,type:"update",data:y(i,n)}),l("offline")):(m(e),l("error"))}},750);w.current.set(r,o)},[t,e?.uid]),S=(0,i.useCallback)(async r=>{if(!e?.uid)return;let i=w.current.get(r);if(i&&(clearTimeout(i),w.current.delete(r)),!f()){s({id:r,type:"delete"}),l("offline");return}l("syncing"),m(null);try{let e=await t(`${p}/${r}`,{method:"DELETE"});if(e.ok)h(Date.now()),l("idle");else{let t=await e.json().catch(()=>({}));throw console.warn("[productSync] deleteProduct failed",{status:e.status,data:t}),Error(t.error||"Failed to delete product")}}catch(e){console.error("Failed to delete product:",e),e.message?.includes("fetch")||e.message?.includes("network")?(s({id:r,type:"delete"}),l("offline")):(m(e),l("error"))}},[t,e?.uid]),T=(0,i.useCallback)(async()=>{if(!e?.uid)return[];if(!f())return l("offline"),[];l("syncing"),m(null);try{let e=await t(p,{method:"GET"});if(e.ok){let t=await e.json();return h(Date.now()),l("idle"),t.products||[]}{let t=await e.json().catch(()=>({}));throw console.warn("[productSync] loadProductsFromFirestore failed",{status:e.status,data:t}),Error(t.error||"Failed to load products")}}catch(e){return console.error("Failed to load products:",e),m(e),l("error"),[]}},[t,e?.uid]);return(0,i.useEffect)(()=>{let e=()=>{l("idle"),v()},t=()=>{l("offline")};return window.addEventListener("online",e),window.addEventListener("offline",t),f()&&v(),()=>{window.removeEventListener("online",e),window.removeEventListener("offline",t)}},[v]),(0,i.useEffect)(()=>{let e=w.current;return()=>{e.forEach(e=>clearTimeout(e)),e.clear()}},[]),{syncStatus:r,syncError:u,syncProduct:E,deleteProduct:S,loadProductsFromFirestore:T,lastSyncedAt:g}}},64527:function(e,t,r){r.d(t,{L:function(){return i}});function i(e){try{let t=Array.isArray(e?.features)?e.features:[],r=Array.isArray(e?.feature_values)?e.feature_values:[];if(t.length>0){let e=Object.create(null);r.forEach(t=>{t&&"string"==typeof t?.featureId&&(e[t.featureId]=t)});let i=[];
1if(t.slice(0,40).forEach((t,r)=>{let n=String(t?.id||`f${r+1}`),a=String(t?.title||"").trim();if(!a)return;let l=e[n],o="string"==typeof l?.mocow?l.mocow:void 0,u="string"==typeof l?.rationale?l.rationale:void 0;i.push({id:n,text:a,priority:o,note:u})}),i.length>0)return i}}catch{}let t=[];try{let r=Array.isArray(e?.experiments)?e.experiments.map(e=>String(e?.name||"").trim()).filter(Boolean):[],i=Array.isArray(e?.assumptions)?e.assumptions.map(e=>String(e?.statement||"").trim()).filter(Boolean):[],n=Array.isArray(e?.competitors)?e.competitors.map(e=>`Competitive parity: ${String(e?.name||"").trim()}`).filter(Boolean):[];t.push(...r,...i.slice(0,3),...n.slice(0,3))}catch{}return Array.from(new Set(t)).slice(0,20).map((e,t)=>({id:`f${t+1}`,text:e}))}},18279:function(e,t,r){function i(e){return`cutline.product.${e}.bundle`}function n(e){try{let t=localStorage.getItem(i(e));return t?JSON.parse(t):null}catch{return null}}function a(e,t){try{localStorage.setItem(i(e),JSON.stringify(t))}catch{}}r.d(t,{C:function(){return n},H:function(){return a}})},9304:function(e,t,r){r.d(t,{Z:function(){return u}});var i=r(76102),n=r(67294),a=r(55346),l=r(4065),o=function(){let{status:e,data:t}=(0,a.aF)(),r=(0,a.$N)(),i=(0,n.useMemo)(()=>
1(0,l.ad)(r),[r]),[o,u]=(0,n.useState)({isTrialActive:!1,isTrialExpired:!1,hasNeverTrialed:!0,creditsRemaining:0,creditsTotal:20,endsAt:null,daysRemaining:null,hoursRemaining:null,loading:!0});return(0,n.useEffect)(()=>{if("loading"===e)return;if("success"!==e||!t?.uid){u(e=>({...e,loading:!1,hasNeverTrialed:!0}));return}let r=(0,l.JU)(i,"users",t.uid),n=(0,l.cf)(r,e=>{let t=e.data();if(!t?.trialStartedAt){u({isTrialActive:!1,isTrialExpired:!1,hasNeverTrialed:!0,creditsRemaining:0,creditsTotal:20,endsAt:null,daysRemaining:null,hoursRemaining:null,loading:!1});return}let r=t.trialStatus||"active",i=t.trialCreditsUsed||0,n=t.trialCreditsTotal||20,a=t.trialEndsAt?.toDate?.()||(t.trialEndsAt?new Date(t.trialEndsAt):null),l=null,o=null;if(a&&"active"===r){let e=a.getTime()-Date.now();e>0?(l=Math.ceil(e/864e5),o=Math.ceil(e/36e5)):(l=0,o=0)}let s=a&&a.getTime()<Date.now(),c=s||"expired"===r;u({isTrialActive:"active"===r&&!s,isTrialExpired:c,hasNeverTrialed:!1,creditsRemaining:Math.max(0,n-i),creditsTotal:n,endsAt:a,daysRemaining:c?0:l,hoursRemaining:c?0:o,loading:!1})},e=>{console.error("[useTrialStatus] Firestore error:",e),u(e=>({...e,loading:!1}))});return()=>n()},[e,t?.uid,i]),o},u=function(){let{active:e,loading:t}=(0,i.Z)(),r=o(),n=t||r.loading,a="none";e?a="premium":r.isTrialActive&&r.creditsRemaining>0&&(a="trial");let l="trial"===a,u="none"===a,s="none"!==a;return{level:a,isPremium:e,isTrial:l,hasNoAccess:u,canViewPremiumContent:s,trial:r,loading:n}}},76102:function(e,t,r){var i=r(67294),n=r(55346),a=r(4065);let l=["active","trialing"];t.Z=function(){let{status:e,data:t}=(0,n.aF)(),r=(0,n.$N)(),o=(0,i.useMemo)(()=>(0,a.ad)(r),[r]),[u,s]=(0,i.useState)(!1),[c,d]=(0,i.useState)(!0);return(0,i.useEffect)(()=>{if("loading"===e)return;if("success"!==e||!t?.uid){s(!1),d(!1);return}let r=(0,a.JU)(o,"users",t.uid),i=(0,a.cf)(r,e=>{d(!1);let t=e.data(),r=t?.subscription?.status,i=!!r&&l.includes(r),n=t?.subscriptionCancellationDate;if(n&&new Date(n)<=new Date){s(!1);return}s(i)},()=>{s(!1),d(!1)});return()=>i()},[e,t?.uid,o]),{active:u,loading:c}}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.