@threatcaptain/tc-reports 0.2.19 → 0.2.21

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/dist/index.cjs CHANGED
@@ -28765,24 +28765,24 @@ const Dashboard = ({
28765
28765
  };
28766
28766
  const getExecutiveSummaryTemplate = (industry) => {
28767
28767
  switch (industry) {
28768
- case "Healthcare":
28768
+ case "healthcare":
28769
28769
  return "Think of this like a malpractice insurance evaluation for your medical practice. Just as you wouldn't practice without malpractice coverage, you can't afford to practice without understanding your cyber risk exposure. One successful cyberattack could cost your practice more than your highest malpractice settlement.";
28770
- case "Legal":
28770
+ case "legal_services":
28771
28771
  return "Think of this like a malpractice insurance evaluation for your law firm. Just as you wouldn't practice without malpractice coverage, you can't afford to practice without understanding your cyber risk exposure. One successful cyberattack could cost your firm more than your highest case settlement.";
28772
- case "Financial Services":
28772
+ case "financial_services":
28773
28773
  return "Think of this like a regulatory compliance audit for your financial institution. Just as you wouldn't operate without proper compliance, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your institution more than your largest loan default.";
28774
- case "Education":
28774
+ case "education":
28775
28775
  return "Think of this like an accreditation review for your educational institution. Just as you wouldn't operate without proper accreditation, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your institution more than losing a major grant.";
28776
- case "Manufacturing":
28776
+ case "manufacturing":
28777
28777
  return "Think of this like a safety inspection for your manufacturing facility. Just as you wouldn't operate without proper safety protocols, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your facility more than your largest equipment failure.";
28778
- case "Retail":
28778
+ case "retail_consumer_goods":
28779
28779
  return "Think of this like a loss prevention audit for your retail business. Just as you wouldn't operate without proper inventory controls, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your business more than your highest shrinkage loss.";
28780
28780
  case "technology_software":
28781
28781
  return "Think of this like a code review for your software platform. Just as you wouldn't deploy without proper testing, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your company more than your largest system outage.";
28782
- case "Government":
28782
+ case 'government_public_sector"':
28783
28783
  return "Think of this like a security clearance review for your agency. Just as you wouldn't operate without proper clearances, you can't afford to operate without understanding your cyber risk exposure. One successful cyberattack could cost your agency more than your largest budget overrun.";
28784
28784
  default:
28785
- return "This cybersecurity financial impact analysis estimates the potential cost of a data breach for the client, using trusted, industry-standard data. Backed by sources like IBM Security and the Ponemon Institute, it provides a credible view of the financial risks organizations like yours face in today's threat landscape. Alongside relevant industry insights, this report outlines actionable considerations to support the client's cybersecurity planning, risk management, and executive decision-making—even ahead of a detailed security assessment.";
28785
+ return "Backed by sources like IBM Security and the Ponemon Institute, this analysis provides a credible view of the risks organizations like yours face in today's threat landscape. Alongside relevant industry insights, this report outlines actionable considerations to support the client's cybersecurity planning, risk management, and executive decision-making—even ahead of a detailed security assessment.";
28786
28786
  }
28787
28787
  };
28788
28788
  const formatCurrency = (value) => {
@@ -51214,7 +51214,7 @@ const getRadarData = ({ breachData }) => {
51214
51214
  }).map((phase) => {
51215
51215
  const visualCoverage = phase.coverage === 0 ? 2 : phase.coverage;
51216
51216
  return {
51217
- tactic: phase.phase.replace("TA00", "").replace("_", " ").substring(0, 8),
51217
+ tactic: phase.phase.replace("TA00", "").replace("_", " "),
51218
51218
  coverage: visualCoverage,
51219
51219
  // Use for chart rendering
51220
51220
  actualCoverage: phase.coverage,
@@ -51257,92 +51257,166 @@ const MitreAttack = ({ breachData, overallLikelihood }) => {
51257
51257
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51258
51258
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "MITRE ATT&CK Coverage" }),
51259
51259
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: "14 Tactics Protection Level" }),
51260
- /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: "h-72 w-72", children: /* @__PURE__ */ jsxRuntime.jsxs(
51261
- RadarChart,
51260
+ /* @__PURE__ */ jsxRuntime.jsx(
51261
+ ChartContainer,
51262
51262
  {
51263
- data: radarData,
51264
- margin: { top: 20, right: 20, bottom: 20, left: 20 },
51265
- children: [
51266
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: gradientId, cx: "50%", cy: "50%", r: "50%", children: [
51267
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: strokeColor, stopOpacity: 0.4 }),
51268
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "70%", stopColor: strokeColor, stopOpacity: 0.2 }),
51269
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: strokeColor, stopOpacity: 0.1 })
51270
- ] }) }),
51271
- /* @__PURE__ */ jsxRuntime.jsx(PolarGrid, { stroke: "#e5e5e5", strokeWidth: 1, radialLines: true }),
51272
- /* @__PURE__ */ jsxRuntime.jsx(
51273
- PolarAngleAxis,
51274
- {
51275
- dataKey: "tactic",
51276
- tick: { fontSize: 10, fill: "#6b7280" },
51277
- className: "text-xs"
51278
- }
51279
- ),
51280
- /* @__PURE__ */ jsxRuntime.jsx(
51281
- PolarRadiusAxis,
51282
- {
51283
- angle: 90,
51284
- domain: [0, 100],
51285
- tick: { fontSize: 8, fill: "#6b7280" },
51286
- tickCount: 6,
51287
- axisLine: false
51288
- }
51289
- ),
51290
- /* @__PURE__ */ jsxRuntime.jsx(
51291
- Radar,
51292
- {
51293
- name: "Coverage",
51294
- dataKey: "coverage",
51295
- stroke: strokeColor,
51296
- fill: `url(#${gradientId})`,
51297
- strokeWidth: 2.5,
51298
- dot: {
51299
- r: 4,
51300
- fill: strokeColor,
51301
- strokeWidth: 2,
51302
- stroke: "#ffffff"
51303
- },
51304
- activeDot: {
51305
- r: 6,
51306
- fill: strokeColor,
51307
- strokeWidth: 2,
51308
- stroke: "#ffffff"
51309
- }
51310
- }
51311
- ),
51312
- /* @__PURE__ */ jsxRuntime.jsx(
51313
- ChartTooltip,
51314
- {
51315
- content: ({ active, payload }) => {
51316
- if (active && payload && payload.length) {
51317
- const data = payload[0].payload;
51318
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white p-3 border rounded-lg shadow-lg", children: [
51319
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: data.fullName }),
51320
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", children: [
51321
- "Coverage: ",
51322
- data.actualCoverage,
51323
- "%"
51324
- ] }),
51325
- /* @__PURE__ */ jsxRuntime.jsxs(
51326
- "p",
51263
+ config: chartConfig,
51264
+ className: "h-[420px] w-[420px] min-h-[420px] min-w-[420px] mb-0",
51265
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
51266
+ RadarChart,
51267
+ {
51268
+ data: radarData,
51269
+ margin: { top: 50, right: 80, bottom: 50, left: 80 },
51270
+ children: [
51271
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: gradientId, cx: "50%", cy: "50%", r: "50%", children: [
51272
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: strokeColor, stopOpacity: 0.4 }),
51273
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "70%", stopColor: strokeColor, stopOpacity: 0.2 }),
51274
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: strokeColor, stopOpacity: 0.1 })
51275
+ ] }) }),
51276
+ /* @__PURE__ */ jsxRuntime.jsx(PolarGrid, { stroke: "#e5e5e5", strokeWidth: 1, radialLines: true }),
51277
+ /* @__PURE__ */ jsxRuntime.jsx(
51278
+ PolarAngleAxis,
51279
+ {
51280
+ dataKey: "tactic",
51281
+ tick: (props) => {
51282
+ const { payload, x: x2, y: y2, textAnchor } = props;
51283
+ const label = payload.value;
51284
+ const centerX = 210;
51285
+ const centerY = 210;
51286
+ const dx = x2 - centerX;
51287
+ const dy = y2 - centerY;
51288
+ const distance = Math.sqrt(dx * dx + dy * dy);
51289
+ const unitX = dx / distance;
51290
+ const unitY = dy / distance;
51291
+ const offset2 = 15;
51292
+ const offsetX = x2 + unitX * offset2;
51293
+ const offsetY = y2 + unitY * offset2;
51294
+ if (label.length >= 12) {
51295
+ const words = label.split(" ");
51296
+ let line1 = "";
51297
+ let line2 = "";
51298
+ let bestSplit = Math.ceil(words.length / 2);
51299
+ for (let i = 0; i < words.length; i++) {
51300
+ if (words[i].toLowerCase() === "and" && i > 0 && i < words.length - 1) {
51301
+ bestSplit = i;
51302
+ break;
51303
+ }
51304
+ }
51305
+ line1 = words.slice(0, bestSplit).join(" ");
51306
+ line2 = words.slice(bestSplit).join(" ");
51307
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${offsetX},${offsetY})`, children: [
51308
+ /* @__PURE__ */ jsxRuntime.jsx(
51309
+ "text",
51310
+ {
51311
+ x: 0,
51312
+ y: -4,
51313
+ textAnchor,
51314
+ fontSize: 10,
51315
+ fill: "#6b7280",
51316
+ className: "text-xs",
51317
+ style: { dominantBaseline: "middle" },
51318
+ children: line1
51319
+ }
51320
+ ),
51321
+ /* @__PURE__ */ jsxRuntime.jsx(
51322
+ "text",
51323
+ {
51324
+ x: 0,
51325
+ y: 8,
51326
+ textAnchor,
51327
+ fontSize: 10,
51328
+ fill: "#6b7280",
51329
+ className: "text-xs",
51330
+ style: { dominantBaseline: "middle" },
51331
+ children: line2
51332
+ }
51333
+ )
51334
+ ] });
51335
+ }
51336
+ return /* @__PURE__ */ jsxRuntime.jsx(
51337
+ "text",
51327
51338
  {
51328
- className: "text-sm",
51329
- style: { color: getRiskLevelColor(data.riskLevel) },
51330
- children: [
51331
- "Risk Level:",
51332
- " ",
51333
- data.riskLevel.charAt(0).toUpperCase() + data.riskLevel.slice(1)
51334
- ]
51339
+ x: offsetX,
51340
+ y: offsetY,
51341
+ textAnchor,
51342
+ fontSize: 10,
51343
+ fill: "#6b7280",
51344
+ className: "text-xs",
51345
+ children: label
51335
51346
  }
51336
- )
51337
- ] });
51347
+ );
51348
+ },
51349
+ className: "text-xs"
51338
51350
  }
51339
- return null;
51340
- }
51341
- }
51342
- )
51343
- ]
51351
+ ),
51352
+ /* @__PURE__ */ jsxRuntime.jsx(
51353
+ PolarRadiusAxis,
51354
+ {
51355
+ angle: 90,
51356
+ domain: [0, 100],
51357
+ tick: { fontSize: 8, fill: "#6b7280" },
51358
+ tickCount: 6,
51359
+ axisLine: false
51360
+ }
51361
+ ),
51362
+ /* @__PURE__ */ jsxRuntime.jsx(
51363
+ Radar,
51364
+ {
51365
+ name: "Coverage",
51366
+ dataKey: "coverage",
51367
+ stroke: strokeColor,
51368
+ fill: `url(#${gradientId})`,
51369
+ strokeWidth: 2.5,
51370
+ dot: {
51371
+ r: 4,
51372
+ fill: strokeColor,
51373
+ strokeWidth: 2,
51374
+ stroke: "#ffffff"
51375
+ },
51376
+ activeDot: {
51377
+ r: 6,
51378
+ fill: strokeColor,
51379
+ strokeWidth: 2,
51380
+ stroke: "#ffffff"
51381
+ }
51382
+ }
51383
+ ),
51384
+ /* @__PURE__ */ jsxRuntime.jsx(
51385
+ ChartTooltip,
51386
+ {
51387
+ content: ({ active, payload }) => {
51388
+ if (active && payload && payload.length) {
51389
+ const data = payload[0].payload;
51390
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white p-3 border rounded-lg shadow-lg", children: [
51391
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: data.fullName }),
51392
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", children: [
51393
+ "Coverage: ",
51394
+ data.actualCoverage,
51395
+ "%"
51396
+ ] }),
51397
+ /* @__PURE__ */ jsxRuntime.jsxs(
51398
+ "p",
51399
+ {
51400
+ className: "text-sm",
51401
+ style: { color: getRiskLevelColor(data.riskLevel) },
51402
+ children: [
51403
+ "Risk Level:",
51404
+ " ",
51405
+ data.riskLevel.charAt(0).toUpperCase() + data.riskLevel.slice(1)
51406
+ ]
51407
+ }
51408
+ )
51409
+ ] });
51410
+ }
51411
+ return null;
51412
+ }
51413
+ }
51414
+ )
51415
+ ]
51416
+ }
51417
+ )
51344
51418
  }
51345
- ) }),
51419
+ ),
51346
51420
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
51347
51421
  /* @__PURE__ */ jsxRuntime.jsxs(
51348
51422
  "div",
@@ -51900,7 +51974,7 @@ const BreachLikelihood = ({ reportData }) => {
51900
51974
  overallLikelihood: attackLikelihood
51901
51975
  }
51902
51976
  ) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Getting breach data..." }) }),
51903
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-rows-3 gap-4", children: [
51977
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-center gap-4", children: [
51904
51978
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center p-4 rounded-md bg-slate-50", children: [
51905
51979
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle, { className: "w-6 h-6 mr-4 text-green-600" }),
51906
51980
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
@@ -52329,83 +52403,83 @@ const FinancialImpact = ({ reportData }) => {
52329
52403
  const dynamicCostBreakdown = createCostBreakdownFromSimulation(simulationData);
52330
52404
  const calculatedCost = simulationData.use_calculated_downtime === false ? simulationData.total_cost : simulationData.adjusted_total_cost;
52331
52405
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
52332
- /* @__PURE__ */ jsxRuntime.jsx(
52406
+ /* @__PURE__ */ jsxRuntime.jsxs(
52333
52407
  "section",
52334
52408
  {
52335
52409
  id: "financial-impact",
52336
52410
  className: "report-page text-center space-y-6 pb-8 border-b border-slate-200",
52337
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
52338
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl font-bold text-slate-900", children: "Cyber Financial Impact Analysis" }),
52339
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xl text-slate-600", children: "Quantifying Your Organization's Cyber Risk Exposure" })
52340
- ] })
52411
+ children: [
52412
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
52413
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl font-bold text-slate-900", children: "Cyber Financial Impact Analysis" }),
52414
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xl text-slate-600", children: "Quantifying Your Organization's Cyber Risk Exposure" })
52415
+ ] }),
52416
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-red-600 rounded-lg p-6 text-white text-center", children: [
52417
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 mb-2", children: [
52418
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DollarSign, { className: "w-8 h-8" }),
52419
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xl font-bold", children: "TOTAL POTENTIAL IMPACT" })
52420
+ ] }),
52421
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-4xl font-bold", children: formatCurrency(calculatedCost) }),
52422
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm opacity-75 mt-2", children: [
52423
+ "Cost Range:  ",
52424
+ formatCurrency(calculatedCost * 0.8),
52425
+ " -  ",
52426
+ formatCurrency(calculatedCost * 1.2)
52427
+ ] })
52428
+ ] }),
52429
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
52430
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Top Industry Threats" }),
52431
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 print:grid-cols-3 gap-4", children: getIndustryThreats(clientData.industry).map((threat, index2) => /* @__PURE__ */ jsxRuntime.jsxs(
52432
+ "div",
52433
+ {
52434
+ className: "bg-red-50 border border-red-200 rounded-lg p-4 flex items-center space-x-3",
52435
+ children: [
52436
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "w-5 h-5 text-red-500" }) }),
52437
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-red-900", children: threat })
52438
+ ]
52439
+ },
52440
+ index2
52441
+ )) })
52442
+ ] }),
52443
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-6", children: [
52444
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
52445
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Industry Risk Profile" }),
52446
+ /* @__PURE__ */ jsxRuntime.jsxs(
52447
+ "div",
52448
+ {
52449
+ className: `inline-flex px-3 py-1 rounded-full text-sm font-medium ${riskLevel.color}`,
52450
+ children: [
52451
+ riskLevel.level,
52452
+ " Risk"
52453
+ ]
52454
+ }
52455
+ ),
52456
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-slate-600", children: [
52457
+ clientData.industry === "Healthcare" && "Healthcare organizations face elevated cyber risks due to valuable PHI data that commands high prices on dark web markets.",
52458
+ clientData.industry === "Financial Services" && "Financial institutions are prime targets due to direct access to funds and sensitive financial data.",
52459
+ clientData.industry === "Manufacturing" && "Manufacturing companies face operational technology risks that can halt production and supply chains.",
52460
+ !["Healthcare", "Financial Services", "Manufacturing"].includes(
52461
+ clientData.industry
52462
+ ) && "Your industry faces specific cyber risks that require tailored protection strategies."
52463
+ ] })
52464
+ ] }),
52465
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
52466
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Key Risk Factors" }),
52467
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: getIndustryThreats(clientData.industry).map((threat, index2) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
52468
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "w-4 h-4 text-red-500" }),
52469
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: threat })
52470
+ ] }, index2)) })
52471
+ ] })
52472
+ ] })
52473
+ ]
52341
52474
  }
52342
52475
  ),
52343
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page space-y-6", children: [
52344
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-red-600 rounded-lg p-6 text-white text-center", children: [
52345
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 mb-2", children: [
52346
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DollarSign, { className: "w-8 h-8" }),
52347
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xl font-bold", children: "TOTAL POTENTIAL IMPACT" })
52348
- ] }),
52349
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-4xl font-bold", children: formatCurrency(calculatedCost) }),
52350
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm opacity-75 mt-2", children: [
52351
- "Cost Range:  ",
52352
- formatCurrency(calculatedCost * 0.8),
52353
- " -  ",
52354
- formatCurrency(calculatedCost * 1.2)
52355
- ] })
52356
- ] }),
52357
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
52358
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Top Industry Threats" }),
52359
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: getIndustryThreats(clientData.industry).map((threat, index2) => /* @__PURE__ */ jsxRuntime.jsxs(
52360
- "div",
52361
- {
52362
- className: "bg-red-50 border border-red-200 rounded-lg p-4 flex items-center space-x-3",
52363
- children: [
52364
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "w-5 h-5 text-red-500" }) }),
52365
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-red-900", children: threat })
52366
- ]
52367
- },
52368
- index2
52369
- )) })
52370
- ] }),
52371
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
52372
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
52373
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Industry Risk Profile" }),
52374
- /* @__PURE__ */ jsxRuntime.jsxs(
52375
- "div",
52376
- {
52377
- className: `inline-flex px-3 py-1 rounded-full text-sm font-medium ${riskLevel.color}`,
52378
- children: [
52379
- riskLevel.level,
52380
- " Risk"
52381
- ]
52382
- }
52383
- ),
52384
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-slate-600", children: [
52385
- clientData.industry === "Healthcare" && "Healthcare organizations face elevated cyber risks due to valuable PHI data that commands high prices on dark web markets.",
52386
- clientData.industry === "Financial Services" && "Financial institutions are prime targets due to direct access to funds and sensitive financial data.",
52387
- clientData.industry === "Manufacturing" && "Manufacturing companies face operational technology risks that can halt production and supply chains.",
52388
- !["Healthcare", "Financial Services", "Manufacturing"].includes(
52389
- clientData.industry
52390
- ) && "Your industry faces specific cyber risks that require tailored protection strategies."
52391
- ] })
52392
- ] }),
52393
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
52394
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-lg font-semibold text-slate-900", children: "Key Risk Factors" }),
52395
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: getIndustryThreats(clientData.industry).map((threat, index2) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
52396
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "w-4 h-4 text-red-500" }),
52397
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: threat })
52398
- ] }, index2)) })
52399
- ] })
52400
- ] })
52401
- ] }),
52402
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page space-y-6 border-t border-slate-200 pt-8", children: [
52476
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page space-y-6 border-b border-slate-200 pt-8", children: [
52403
52477
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
52404
52478
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-slate-900 mb-2", children: "Detailed Financial Breakdown" }),
52405
52479
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-600", children: "Understanding the components of the total potential cost" })
52406
52480
  ] }),
52407
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-6 gap-8", children: [
52408
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:col-span-3 space-y-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "impact-chart", className: "chart-container", children: /* @__PURE__ */ jsxRuntime.jsx(
52481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-6 gap-8 print:grid-cols-6", children: [
52482
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:col-span-3 print:col-span-3 space-y-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "impact-chart", className: "chart-container", children: /* @__PURE__ */ jsxRuntime.jsx(
52409
52483
  UnifiedCostBreakdownChart,
52410
52484
  {
52411
52485
  hard_costs: dynamicCostBreakdown.hard_costs,
@@ -52415,7 +52489,7 @@ const FinancialImpact = ({ reportData }) => {
52415
52489
  totalCost: calculatedCost
52416
52490
  }
52417
52491
  ) }) }),
52418
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-3 space-y-4", children: [
52492
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-3 print:col-span-3 space-y-4", children: [
52419
52493
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900", children: "Cost Categories" }),
52420
52494
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: getIndustrySpecificCosts(
52421
52495
  clientData.industry,
@@ -52456,7 +52530,7 @@ const FinancialImpact = ({ reportData }) => {
52456
52530
  }) })
52457
52531
  ] })
52458
52532
  ] }),
52459
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
52533
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-6", children: [
52460
52534
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white border border-slate-200 rounded-lg p-6", children: [
52461
52535
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900 mb-4", children: "Attack Scenario" }),
52462
52536
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 text-sm", children: [
@@ -52505,7 +52579,7 @@ const FinancialImpact = ({ reportData }) => {
52505
52579
  ] })
52506
52580
  ] })
52507
52581
  ] }),
52508
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page space-y-6 border-t border-slate-200 pt-8", children: [
52582
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page space-y-6 border-b border-slate-200 pt-8", children: [
52509
52583
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-3", children: [
52510
52584
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-white text-lg", children: "?" }) }),
52511
52585
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -52552,26 +52626,26 @@ const FinancialImpact = ({ reportData }) => {
52552
52626
  ] }) })
52553
52627
  ] }),
52554
52628
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 mt-4", children: "This ensures the analysis reflects both likelihood and financial impact, helping you prioritize the risks most relevant to your clients." })
52629
+ ] })
52630
+ ] })
52631
+ ] }),
52632
+ /* @__PURE__ */ jsxRuntime.jsx("section", { className: "report-page space-y-6 pt-8", children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-6", children: [
52633
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900 mb-2", children: "Important Notes" }),
52634
+ /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "text-slate-700 space-y-2", children: [
52635
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start space-x-2", children: [
52636
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 mt-1", children: "•" }),
52637
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "This analysis is based on industry norms and common threat patterns." })
52555
52638
  ] }),
52556
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-6", children: [
52557
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900 mb-2", children: "Important Notes" }),
52558
- /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "text-slate-700 space-y-2", children: [
52559
- /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start space-x-2", children: [
52560
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 mt-1", children: "•" }),
52561
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "This analysis is based on industry norms and common threat patterns." })
52562
- ] }),
52563
- /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start space-x-2", children: [
52564
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 mt-1", children: "•" }),
52565
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Actual breach outcomes and costs may vary based on the event's scope and response quality." })
52566
- ] }),
52567
- /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start space-x-2", children: [
52568
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 mt-1", children: "•" }),
52569
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "This report is intended to guide investment and preparedness—not to predict specific future events." })
52570
- ] })
52571
- ] })
52639
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start space-x-2", children: [
52640
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 mt-1", children: "" }),
52641
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Actual breach outcomes and costs may vary based on the event's scope and response quality." })
52642
+ ] }),
52643
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start space-x-2", children: [
52644
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 mt-1", children: "•" }),
52645
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "This report is intended to guide investment and preparedness—not to predict specific future events." })
52572
52646
  ] })
52573
52647
  ] })
52574
- ] })
52648
+ ] }) }) })
52575
52649
  ] });
52576
52650
  };
52577
52651
  const ASSESSMENT_CATEGORIES = {
@@ -53056,7 +53130,7 @@ const InsuranceHealthScore = ({ reportData }) => {
53056
53130
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-slate-50 rounded-lg p-6", children: [
53057
53131
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-slate-900 mb-4", children: "How We Calculate Your Score" }),
53058
53132
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 mb-4", children: "Your Insurance Health Score is calculated based on industry-standard cybersecurity frameworks and real insurance company requirements. Each category is weighted according to its importance in determining cyber insurance coverage and pricing." }),
53059
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
53133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-4", children: [
53060
53134
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
53061
53135
  /* @__PURE__ */ jsxRuntime.jsx("h5", { className: "font-medium text-slate-900 mb-2", children: "Score Ranges:" }),
53062
53136
  /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "text-sm text-slate-700 space-y-1", children: [
@@ -53109,7 +53183,7 @@ const InsuranceHealthScore = ({ reportData }) => {
53109
53183
  ] })
53110
53184
  ] })
53111
53185
  ] }),
53112
- /* @__PURE__ */ jsxRuntime.jsx("section", { className: "report-page space-y-6 border-t border-slate-200 pt-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
53186
+ /* @__PURE__ */ jsxRuntime.jsx("section", { className: "report-page space-y-6 border-t border-slate-200 pt-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-6", children: [
53113
53187
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
53114
53188
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-green-600 mb-3", children: "What This Report IS:" }),
53115
53189
  /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "text-slate-700 space-y-2 text-sm", children: [
@@ -53162,6 +53236,7 @@ const ReportBuilder = ({
53162
53236
  simulationData,
53163
53237
  mspInfo
53164
53238
  }) => {
53239
+ const [editExecutiveSummary, setEditExecutiveSummary] = React.useState(false);
53165
53240
  const [searchParams] = reactRouterDom.useSearchParams();
53166
53241
  const reportTemplate = searchParams.get("template");
53167
53242
  const templateArray = (reportTemplate == null ? void 0 : reportTemplate.split(",").map((item) => item.trim())) || [];
@@ -53185,42 +53260,57 @@ const ReportBuilder = ({
53185
53260
  if (items.length === 2) return `${items[0]} and ${items[1]}`;
53186
53261
  return `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
53187
53262
  };
53263
+ const onConfigChange = (key, value) => {
53264
+ console.log(`Config changed: ${key} = ${value}`);
53265
+ };
53188
53266
  return /* @__PURE__ */ jsxRuntime.jsxs(
53189
53267
  "article",
53190
53268
  {
53191
53269
  id: "print-report",
53192
- className: "report-wrapper max-w-4xl mx-auto bg-white p-8 space-y-8",
53270
+ className: "report-wrapper max-w-4xl mx-auto bg-white p-8 space-y-8 print:font-sans",
53193
53271
  children: [
53194
- /* @__PURE__ */ jsxRuntime.jsx("figure", { className: "bg-slate-200 max-w-40 flex object-contain rounded-lg items-center justify-center mx-auto", children: mspInfo.company_logo ? /* @__PURE__ */ jsxRuntime.jsx(
53195
- "img",
53196
- {
53197
- src: mspInfo.company_logo,
53198
- alt: "MSP Logo",
53199
- className: "w-full h-auto m-auto"
53200
- }
53201
- ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "w-10 h-10 text-slate-500" }) }),
53202
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-md mx-auto bg-slate-50 rounded-lg p-6 space-y-3", children: [
53203
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53204
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared For:" }),
53205
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.company_name || "Client Company" })
53206
- ] }),
53207
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53208
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Industry Sector:" }),
53209
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.industry || "Industry" })
53210
- ] }),
53211
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53212
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared By:" }),
53213
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: mspInfo.company_name || /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "red", fontWeight: "bold" }, children: "NEEDS ACTUAL MSP NAME" }) })
53272
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "report-page", children: [
53273
+ /* @__PURE__ */ jsxRuntime.jsx("figure", { className: "bg-slate-200 max-w-40 print:max-w-40 flex object-contain rounded-lg items-center justify-center mx-auto", children: mspInfo.company_logo ? /* @__PURE__ */ jsxRuntime.jsx(
53274
+ "img",
53275
+ {
53276
+ src: mspInfo.company_logo,
53277
+ alt: "MSP Logo",
53278
+ className: "w-full h-auto m-auto print:w-40 print:h-auto"
53279
+ }
53280
+ ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "w-10 h-10 text-slate-500" }) }),
53281
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-md mx-auto bg-slate-50 rounded-lg p-6 space-y-3", children: [
53282
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53283
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared For:" }),
53284
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.company_name || "Client Company" })
53285
+ ] }),
53286
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53287
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Industry Sector:" }),
53288
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: clientData.industry || "Industry" })
53289
+ ] }),
53290
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53291
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Prepared By:" }),
53292
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: mspInfo.company_name || /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "red", fontWeight: "bold" }, children: "NEEDS ACTUAL MSP NAME" }) })
53293
+ ] }),
53294
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53295
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Assessment Date:" }),
53296
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: (/* @__PURE__ */ new Date()).toLocaleDateString() })
53297
+ ] })
53214
53298
  ] }),
53215
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
53216
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-slate-700", children: "Assessment Date:" }),
53217
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-900", children: (/* @__PURE__ */ new Date()).toLocaleDateString() })
53218
- ] })
53219
- ] }),
53220
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 text-left space-y-2", children: [
53221
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold text-slate-900 text-left", children: "Executive Summary" }),
53299
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold text-slate-900 text-left mb-2", children: "Executive Summary" }),
53222
53300
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-slate-900", children: "Why This Assessment Matters" }),
53223
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 leading-relaxed whitespace-pre-line text-sm", children: displayExecutiveSummary(clientData) })
53301
+ editExecutiveSummary ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
53302
+ /* @__PURE__ */ jsxRuntime.jsx(
53303
+ Textarea,
53304
+ {
53305
+ value: displayExecutiveSummary(clientData),
53306
+ onChange: (e) => onConfigChange("executiveSummary", e.target.value),
53307
+ placeholder: "Executive summary content...",
53308
+ rows: 6,
53309
+ className: "resize-none"
53310
+ }
53311
+ ),
53312
+ /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: () => setEditExecutiveSummary(false), children: "Save" })
53313
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-slate-700 leading-relaxed whitespace-pre-line text-sm", children: displayExecutiveSummary(clientData) }) })
53224
53314
  ] }),
53225
53315
  showFinancialImpact && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: financialSimulationData && Object.keys(financialSimulationData).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
53226
53316
  FinancialImpact,
@@ -53244,7 +53334,7 @@ const ReportBuilder = ({
53244
53334
  reportData: { clientData, insuranceHealthData, mspInfo }
53245
53335
  }
53246
53336
  ) : /* @__PURE__ */ jsxRuntime.jsx(Warning, { children: "We can't find an insurance assessment. Are you sure you ran this assessment?" }) }),
53247
- /* @__PURE__ */ jsxRuntime.jsxs("footer", { className: "report-page text-center pt-8 border-t border-slate-200", children: [
53337
+ /* @__PURE__ */ jsxRuntime.jsxs("footer", { className: "text-center pt-8 border-t border-slate-200", children: [
53248
53338
  /* @__PURE__ */ jsxRuntime.jsx("h4", { children: "Professional Recommendation" }),
53249
53339
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-slate-500", children: [
53250
53340
  "This assessment uses ",