UNPKG

diabetic-utils

Version:

Zero-bloat TypeScript utilities for diabetes data: glucose, A1C, conversions, time-in-range, and more.

638 lines (489 loc) β€’ 22.8 kB
# 🩸 Diabetic Utils Built and maintained by Mark Learst. **A TypeScript toolkit for diabetes analytics and health data.** ![Diabetic Utils Logo](https://raw.githubusercontent.com/marklearst/diabetic-utils/refs/heads/main/assets/dujs.png) A modern, strictly-typed utility library for glucose, A1C, insulin, and diabetes metrics. Designed for reliability and transparencyβ€”no bloat, no guesswork, just robust utilities with referenced formulas from published guidelines. > **Disclaimer**: This library is for **informational and educational purposes only**. > It does not constitute medical advice, diagnosis, or treatment. Always consult > a qualified healthcare provider for medical decisions. > **v1.5.0** adds a full advanced CGM metrics suite, CGM vendor adapters, and health data interoperability (FHIR, Open mHealth). --- ## πŸ“Š Status & Quality ![Status](https://img.shields.io/badge/status-stable-brightgreen) [![codecov](https://codecov.io/gh/marklearst/diabetic-utils/branch/main/graph/badge.svg)](https://codecov.io/gh/marklearst/diabetic-utils) ![CI](https://github.com/marklearst/diabetic-utils/actions/workflows/ci-cd.yml/badge.svg) ![TypeScript](https://img.shields.io/badge/TypeScript-100%25_Strict-blue?logo=typescript) ![Coverage](https://img.shields.io/badge/coverage-100%25-success) ![npm](https://img.shields.io/npm/v/diabetic-utils) ![npm downloads](https://img.shields.io/npm/dm/diabetic-utils) ![License](https://img.shields.io/github/license/marklearst/diabetic-utils) --- ## πŸš€ What's New in v1.5.0 ### πŸ“ˆ Advanced CGM Metrics Suite A complete set of published CGM analytics, each with peer-reviewed references: - **ADRR**: Average Daily Risk Range (Kovatchev 2006) - **GRADE**: Glycemic Risk Assessment Diabetes Equation with hypo/eu/hyper partitioning (Hill 2007) - **J-Index**: Composite mean + variability score (Wojcicki 1995) - **CONGA**: Continuous Overall Net Glycemic Action for intra-day variability (McDonnell 2005) - **Active Percent**: CGM wear-time tracking against clinical thresholds (Danne 2017) - **AGP Aggregate**: Single-call `calculateAGPMetrics()` computes all Tier 1 metrics at once - **LBGI / HBGI**: Low/High Blood Glucose Index (Kovatchev 2006) - **GRI**: Glycemia Risk Index with zone A-E classification (Klonoff 2023) - **MODD**: Mean of Daily Differences for day-to-day variability (Service 1980) ### πŸ”Œ CGM Connector Adapters Pure transformation helpers that normalize vendor payloads into a canonical `NormalizedCGMReading` type: - **Dexcom Share** β€” normalize Dexcom Share API responses - **Libre LinkUp** β€” normalize Libre LinkUp API responses - **Nightscout** β€” normalize Nightscout SGV entries ### πŸ₯ Health Data Interoperability Build standards-compliant payloads for health data exchange: - **FHIR CGM IG** β€” HL7 FHIR-aligned CGM summary and sensor reading observations - **Open mHealth** β€” OMH blood-glucose datapoints with full header support ### βœ… 337 Passing Tests - 100% coverage across lines, branches, functions, and statements - New edge-case coverage for out-of-order timestamps, mixed units, and cross-module interactions --- ## πŸ“¦ Installation ```bash npm install diabetic-utils # or pnpm add diabetic-utils # or yarn add diabetic-utils ``` **Requirements:** TypeScript 4.5+ or JavaScript (ES2020+) --- ## ⚑ Quick Start ### Basic Conversions & Calculations ```typescript import { mgDlToMmolL, mmolLToMgDl, estimateGMI, estimateA1CFromAverage } from 'diabetic-utils' // Glucose unit conversions mgDlToMmolL(180) // β†’ 10.0 mmolLToMgDl(5.5) // β†’ 99 // GMI calculation (multiple input formats) estimateGMI(100, 'mg/dL') // β†’ 5.4 estimateGMI('5.5 mmol/L') // β†’ 5.4 estimateGMI({ value: 100, unit: 'mg/dL' }) // β†’ 5.4 // A1C estimation estimateA1CFromAverage(154, 'mg/dL') // β†’ 7.0 ``` ### Enhanced Time-in-Range ```typescript import { calculateEnhancedTIR } from 'diabetic-utils' import type { GlucoseReading } from 'diabetic-utils' const readings: GlucoseReading[] = [ { value: 120, unit: 'mg/dL', timestamp: '2024-01-01T08:00:00Z' }, { value: 95, unit: 'mg/dL', timestamp: '2024-01-01T08:05:00Z' }, { value: 180, unit: 'mg/dL', timestamp: '2024-01-01T08:10:00Z' }, // ... more readings ] const result = calculateEnhancedTIR(readings) console.log(`TIR: ${result.inRange.percentage}%`) // TIR: 72.5% console.log(`Very Low: ${result.veryLow.percentage}%`) // Very Low: 0.5% console.log(`Assessment: ${result.meetsTargets.overallAssessment}`) // Assessment: good console.log(result.meetsTargets.recommendations) // ['All metrics meet consensus targets.'] ``` ### Pregnancy TIR ```typescript import { calculatePregnancyTIR } from 'diabetic-utils' const result = calculatePregnancyTIR(readings) console.log(`TIR (63-140 mg/dL): ${result.inRange.percentage}%`) // TIR (63-140 mg/dL): 85.2% console.log(`Meets pregnancy targets: ${result.meetsPregnancyTargets}`) // Meets pregnancy targets: true console.log(result.recommendations) // ['All metrics meet pregnancy consensus targets.', ...] ``` ### AGP Metrics (All-in-One) ```typescript import { calculateAGPMetrics } from 'diabetic-utils' import type { GlucoseReading } from 'diabetic-utils' const readings: GlucoseReading[] = [ { value: 120, unit: 'mg/dL', timestamp: '2024-01-01T08:00:00Z' }, { value: 95, unit: 'mg/dL', timestamp: '2024-01-01T08:05:00Z' }, { value: 180, unit: 'mg/dL', timestamp: '2024-01-01T08:10:00Z' }, // ... more readings across multiple days ] const agp = calculateAGPMetrics(readings) console.log(`Mean: ${agp.meanGlucose} mg/dL`) console.log(`SD: ${agp.sd}, CV: ${agp.cv}%`) console.log(`LBGI: ${agp.lbgi}, HBGI: ${agp.hbgi}`) console.log(`ADRR: ${agp.adrr}`) console.log(`GRADE: ${agp.grade.gradeScore}`) console.log(`GRI: ${agp.gri.gri} (Zone ${agp.gri.zone})`) console.log(`J-Index: ${agp.jIndex}`) console.log(`MODD: ${agp.modd} mg/dL`) console.log(`CONGA: ${agp.conga} mg/dL`) console.log(`Active: ${agp.activePercent.activePercent}%`) ``` ### CGM Connector Adapters ```typescript import { normalizeDexcomEntries, normalizeLibreEntries, normalizeNightscoutEntries } from 'diabetic-utils' // Normalize vendor data into a canonical format const dexcomReadings = normalizeDexcomEntries(dexcomShareResponse) const libreReadings = normalizeLibreEntries(libreLinkUpResponse) const nightscoutReadings = normalizeNightscoutEntries(nightscoutSGVEntries) // All return NormalizedCGMReading[] with: // { value, unit, timestamp, trend, source } // Ready to pass into any diabetic-utils analytics function ``` ### FHIR & Open mHealth Export ```typescript import { buildFHIRCGMSummary, buildFHIRSensorReading, buildOMHDataPoint } from 'diabetic-utils' // Build a FHIR CGM summary observation const fhirSummary = buildFHIRCGMSummary(tirResult, { start: '2024-01-01', end: '2024-01-14' }) // Build a FHIR sensor reading observation const fhirReading = buildFHIRSensorReading({ value: 120, unit: 'mg/dL', timestamp: '2024-01-01T08:00:00Z' }) // Build an Open mHealth blood-glucose datapoint const omhPoint = buildOMHDataPoint( { value: 120, unit: 'mg/dL', timestamp: '2024-01-01T08:00:00Z' }, 'reading-001' ) ``` ### Glucose Labeling & Validation ```typescript import { getGlucoseLabel, isHypo, isHyper, isValidGlucoseValue } from 'diabetic-utils' // Label glucose values getGlucoseLabel(60, 'mg/dL') // β†’ 'low' getGlucoseLabel(5.5, 'mmol/L') // β†’ 'normal' getGlucoseLabel(200, 'mg/dL') // β†’ 'high' // Threshold checks isHypo(65, 'mg/dL') // β†’ true isHyper(180, 'mg/dL') // β†’ false // Validation isValidGlucoseValue(120, 'mg/dL') // β†’ true isValidGlucoseValue(-10, 'mg/dL') // β†’ false ``` ### Variability Analytics ```typescript import { glucoseStandardDeviation, glucoseCoefficientOfVariation, glucosePercentiles, glucoseMAGE } from 'diabetic-utils' const data = [90, 100, 110, 120, 130, 140, 150, 160, 170, 180] // Standard deviation (unbiased sample SD, n-1) glucoseStandardDeviation(data) // β†’ 30.28 // Coefficient of variation (CV%) glucoseCoefficientOfVariation(data) // β†’ 22.43 // Percentiles (nearest-rank method) glucosePercentiles(data, [10, 50, 90]) // β†’ { 10: 90, 50: 130, 90: 170 } // MAGE (Mean Amplitude of Glycemic Excursions) const mage = glucoseMAGE([100, 120, 80, 160, 90, 140, 70, 180]) console.log(`MAGE: ${mage} mg/dL`) ``` ### Custom Thresholds ```typescript import { getGlucoseLabel, isHypo, getA1CCategory } from 'diabetic-utils' // Custom hypoglycemia threshold isHypo(75, 'mg/dL', { mgdl: 80 }) // β†’ true // Custom hyperglycemia threshold isHyper(9.0, 'mmol/L', { mmoll: 8.5 }) // β†’ true // Custom glucose label thresholds getGlucoseLabel(75, 'mg/dL', { hypo: { mgdl: 80 }, hyper: { mgdl: 160 } }) // β†’ 'low' // Custom A1C category cutoffs getA1CCategory(6.5, { normalMax: 6.0, prediabetesMax: 7.0 }) // β†’ 'prediabetes' ``` --- ## 🌟 Features ### Core Utilities - βœ… **Glucose Conversions**: mg/dL ⇄ mmol/L - βœ… **A1C Calculations**: GMI, eAG, A1C estimation - βœ… **Time-in-Range**: Enhanced TIR (5 ranges), Pregnancy TIR - βœ… **HOMA-IR**: Insulin resistance calculation - βœ… **Variability Metrics**: SD, CV, MAGE, percentiles - βœ… **Validation**: Input guards, string parsing - βœ… **Labeling**: Glucose status (low/normal/high) ### Advanced CGM Metrics - βœ… **LBGI / HBGI**: Low/High Blood Glucose Index (Kovatchev 2006) - βœ… **GRI**: Glycemia Risk Index with zone A-E classification (Klonoff 2023) - βœ… **MODD**: Mean of Daily Differences for day-to-day variability (Service 1980) - βœ… **ADRR**: Average Daily Risk Range (Kovatchev 2006) - βœ… **GRADE**: Glycemic Risk Assessment Diabetes Equation with partitioning (Hill 2007) - βœ… **J-Index**: Composite mean + variability score (Wojcicki 1995) - βœ… **CONGA**: Continuous Overall Net Glycemic Action (McDonnell 2005) - βœ… **Active Percent**: CGM wear-time tracking (Danne 2017) - βœ… **AGP Aggregate**: All Tier 1 metrics in a single call ### CGM Connector Adapters - βœ… **Dexcom Share**: Normalize Dexcom Share API responses - βœ… **Libre LinkUp**: Normalize Libre LinkUp API responses - βœ… **Nightscout**: Normalize Nightscout SGV entries - βœ… **Canonical Type**: `NormalizedCGMReading` with trend + source metadata ### Interoperability - βœ… **FHIR CGM IG**: Build HL7 FHIR-aligned CGM summary and sensor reading payloads - βœ… **Open mHealth**: Build OMH blood-glucose datapoints ### Quality & DX - βœ… **TypeScript-First**: 100% strict mode, zero `any` types - βœ… **100% Test Coverage**: 337 tests, all edge cases covered - βœ… **Zero Dependencies**: No bloat, tree-shakable - βœ… **Published References**: ADA, CDC, ISPAD, PubMed citations - βœ… **TSDoc**: Complete API documentation - βœ… **ESM + CJS**: Works everywhere - βœ… **Type Predicates**: Better type narrowing - βœ… **Named Constants**: Self-documenting formulas --- ## πŸ† Why Choose Diabetic Utils? ### Referenced Formulas Every formula, threshold, and calculation references published guidelines: - **International Consensus on Time in Range (2019)** - TIR calculations - **ADA Standards of Care (2024)** - Pregnancy targets, A1C guidelines - **ISPAD Guidelines (2018)** - Glucose variability metrics - **NIH/NIDDK** - HOMA-IR, eAG formulas - **Kovatchev et al. (2006)** - LBGI, HBGI, ADRR - **Hill et al. (2007)** - GRADE - **Klonoff et al. (2023)** - GRI - **Wojcicki (1995)** - J-Index - **McDonnell et al. (2005)** - CONGA - **Danne et al. (2017)** - Active Percent ### Production-Ready - **100% Test Coverage** - Every line tested - **Type-Safe** - Catch errors at compile time - **Zero Dependencies** - Small bundle, no supply chain risk - **Modern ESM** - Tree-shakable, works with Vite, Next.js, etc. ### Developer-Friendly - **Clear API** - Predictable function signatures - **Great DX** - Autocomplete with literal types - **Working Examples** - Copy-paste ready code - **Test Helpers** - Utilities for your own tests ### Unique Features **Only TypeScript/JavaScript library with:** - Full AGP metrics suite in a single call - Enhanced TIR (5-range breakdown) and Pregnancy TIR - MAGE calculation (Service 1970) - ADRR, GRADE, J-Index, CONGA, and Active Percent - CGM vendor adapters (Dexcom, Libre, Nightscout) - FHIR CGM IG-aligned export utilities - LBGI/HBGI, GRI, and MODD metrics - Type predicates for validation --- ## πŸ“š Full API Reference ### Glucose Conversions - `mgDlToMmolL(value)` - Convert mg/dL to mmol/L - `mmolLToMgDl(value)` - Convert mmol/L to mg/dL - `convertGlucoseUnit({ value, unit })` - Generic unit conversion ### A1C & GMI - `estimateA1CFromAverage(glucose, unit)` - A1C from average glucose - `estimateGMI(input, unit?)` - GMI from average glucose - `a1cToGMI(a1c)` - Convert A1C to GMI - `estimateAvgGlucoseFromA1C(a1c)` - A1C to estimated average glucose (mg/dL) ### Time-in-Range - `calculateTimeInRange(readings, low, high)` - Basic TIR - `calculateEnhancedTIR(readings, options?)` - 5-range TIR - `calculatePregnancyTIR(readings, options?)` - Pregnancy TIR ### Glucose Analysis - `getGlucoseLabel(value, unit, thresholds?)` - Label as low/normal/high - `isHypo(value, unit, threshold?)` - Check hypoglycemia - `isHyper(value, unit, threshold?)` - Check hyperglycemia - `isValidGlucoseValue(value, unit)` - Validate glucose value ### A1C Analysis - `getA1CCategory(a1c, cutoffs?)` - Categorize A1C - `isA1CInTarget(a1c, target?)` - Check if A1C meets target ### Variability Metrics - `glucoseStandardDeviation(readings)` - SD (unbiased) - `glucoseCoefficientOfVariation(readings)` - CV% - `glucosePercentiles(readings, percentiles)` - Percentile ranks - `glucoseMAGE(readings, options?)` - Mean Amplitude of Glycemic Excursions ### Insulin Metrics - `calculateHOMAIR(glucose, insulin, unit)` - HOMA-IR - `isValidInsulin(value)` - Validate insulin value ### Advanced CGM Metrics - `calculateAGPMetrics(readings, options?)` - All Tier 1 metrics in a single call - `glucoseLBGI(readings)` - Low Blood Glucose Index (Kovatchev 2006) - `glucoseHBGI(readings)` - High Blood Glucose Index (Kovatchev 2006) - `calculateADRR(readings)` - Average Daily Risk Range (Kovatchev 2006) - `calculateGRADE(readings)` - Glycemic Risk Assessment Diabetes Equation (Hill 2007) - `calculateGRI(input)` - Glycemia Risk Index with zone A-E (Klonoff 2023) - `calculateJIndex(readings)` - J-Index composite score (Wojcicki 1995) - `calculateMODD(readings, options?)` - Mean of Daily Differences (Service 1980) - `calculateCONGA(readings, options?)` - Continuous Overall Net Glycemic Action (McDonnell 2005) - `calculateActivePercent(readings, options?)` - CGM wear-time percentage (Danne 2017) ### CGM Connector Adapters - `normalizeDexcomEntries(entries)` - Dexcom Share β†’ NormalizedCGMReading[] - `normalizeLibreEntries(entries)` - Libre LinkUp β†’ NormalizedCGMReading[] - `normalizeNightscoutEntries(entries)` - Nightscout SGV β†’ NormalizedCGMReading[] ### Interoperability - `buildFHIRCGMSummary(tir, period, options?)` - FHIR CGM summary observation - `buildFHIRSensorReading(reading)` - FHIR sensor reading observation - `buildFHIRSensorReadings(readings)` - FHIR sensor reading observations from a list of readings - `buildOMHBloodGlucose(reading)` - Open mHealth blood-glucose body - `buildOMHBloodGlucoseList(readings)` - Open mHealth blood-glucose bodies from a list of readings - `buildOMHDataPoint(reading, id)` - Full OMH datapoint with header ### Utilities - `parseGlucoseString(str)` - Parse "120 mg/dL" β†’ { value, unit } - `formatGlucose(value, unit)` - Format glucose with unit - `isValidGlucoseString(str)` - Validate glucose string **[View Complete API Docs β†’](https://marklearst.github.io/diabetic-utils/)** --- ## πŸ§ͺ Test Helpers The repository includes test utilities in `tests/test-helpers.ts` for contributors and downstream developers: ```typescript // In your test files (not published to npm β€” copy as needed) import { createGlucoseReadings, COMMON_TEST_VALUES, TEST_TIMESTAMP_BASE } from './tests/test-helpers' // Create test data easily const readings = createGlucoseReadings([100, 110, 120], 'mg/dL', 5) // β†’ 3 readings at 5-minute intervals // Use common test values const { NORMAL_GLUCOSE_MGDL, HYPO_GLUCOSE_MGDL } = COMMON_TEST_VALUES ``` --- ## πŸ”¬ References All calculations reference peer-reviewed published sources: - **Time-in-Range**: [International Consensus (2019)](https://diabetesjournals.org/care/article/42/8/1593) - **Pregnancy TIR**: [ADA Standards of Care (2024)](https://diabetesjournals.org/care/article/47/Supplement_1/S282) - **ADA 2026 Standards**: [ADA Standards of Care (2026)](https://diabetesjournals.org/care/issue/49/Supplement_1) - **A1C/eAG**: [Nathan et al. (2008)](https://diabetesjournals.org/care/article/31/8/1473) - **HOMA-IR**: [Matthews et al. (1985)](https://diabetesjournals.org/diabetes/article/34/12/1212) - **MAGE**: [Service et al. (1970)](https://diabetesjournals.org/diabetes/article/19/9/644) - **LBGI/HBGI/ADRR**: [Kovatchev et al. (2006)](https://doi.org/10.2337/dc06-1085) - **GRI**: [Klonoff et al. (2023)](https://doi.org/10.1177/19322968221085273) - **MODD**: [Service & Nelson (1980)](https://doi.org/10.2337/diacare.3.1.58) - **GRADE**: [Hill et al. (2007)](https://doi.org/10.1111/j.1464-5491.2007.02119.x) - **J-Index**: [Wojcicki (1995)](https://doi.org/10.1055/s-2007-979906) - **CONGA**: [McDonnell et al. (2005)](https://doi.org/10.1089/dia.2005.7.253) - **Active Percent**: [Danne et al. (2017)](https://doi.org/10.2337/dc17-1600) - **Variability**: [ISPAD Guidelines (2018)](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7445493/) - **FHIR CGM IG**: [HL7 CGM IG v1.0.0](https://build.fhir.org/ig/HL7/cgm/index.html) --- ## πŸ—οΈ Architecture ``` diabetic-utils/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ index.ts # Main exports β”‚ β”œβ”€β”€ constants.ts # Clinical thresholds & formulas β”‚ β”œβ”€β”€ types.ts # TypeScript types β”‚ β”œβ”€β”€ conversions.ts # Glucose unit conversions β”‚ β”œβ”€β”€ a1c.ts # A1C & GMI calculations β”‚ β”œβ”€β”€ tir.ts # Basic time-in-range β”‚ β”œβ”€β”€ tir-enhanced.ts # Enhanced & pregnancy TIR β”‚ β”œβ”€β”€ glucose.ts # Glucose utilities β”‚ β”œβ”€β”€ alignment.ts # HOMA-IR β”‚ β”œβ”€β”€ variability.ts # SD, CV, percentiles β”‚ β”œβ”€β”€ mage.ts # MAGE calculation β”‚ β”œβ”€β”€ formatters.ts # String formatting β”‚ β”œβ”€β”€ guards.ts # Type guards β”‚ β”œβ”€β”€ validators.ts # Input validation β”‚ β”œβ”€β”€ connectors/ # CGM vendor adapters β”‚ β”‚ β”œβ”€β”€ dexcom.ts # Dexcom Share normalization β”‚ β”‚ β”œβ”€β”€ libre.ts # Libre LinkUp normalization β”‚ β”‚ β”œβ”€β”€ nightscout.ts # Nightscout SGV normalization β”‚ β”‚ └── types.ts # Vendor & canonical types β”‚ β”œβ”€β”€ interop/ # Health data interoperability β”‚ β”‚ β”œβ”€β”€ fhir.ts # FHIR CGM IG payload builders β”‚ β”‚ β”œβ”€β”€ openmhealth.ts # Open mHealth payload builders β”‚ β”‚ └── types.ts # Interop payload types β”‚ └── metrics/ # Advanced CGM metrics β”‚ β”œβ”€β”€ agp.ts # Aggregate AGP metrics β”‚ β”œβ”€β”€ bgi.ts # LBGI / HBGI β”‚ β”œβ”€β”€ adrr.ts # Average Daily Risk Range β”‚ β”œβ”€β”€ grade.ts # GRADE score β”‚ β”œβ”€β”€ gri.ts # Glycemia Risk Index β”‚ β”œβ”€β”€ jindex.ts # J-Index β”‚ β”œβ”€β”€ modd.ts # Mean of Daily Differences β”‚ β”œβ”€β”€ conga.ts # CONGA β”‚ └── active-percent.ts # CGM wear time β”œβ”€β”€ tests/ β”‚ β”œβ”€β”€ test-helpers.ts # Shared test utilities β”‚ └── *.test.ts # 100% coverage tests (337 tests) └── dist/ # Built output (ESM + CJS) ``` **Key Principles:** - βœ… Zero dependencies - βœ… Tree-shakable modules - βœ… Strict TypeScript - βœ… 100% test coverage - βœ… Published references in TSDoc --- ## 🀝 Contributing Contributions are welcome! Please follow these steps: 1. **Fork** the repository 2. **Create** your feature branch: `git checkout -b feat/my-feature` 3. **Add tests** for any new functionality 4. **Ensure** 100% coverage: `pnpm test:coverage` 5. **Commit** with [conventional commits](https://www.conventionalcommits.org/): `git commit -m "feat: add new feature"` 6. **Push** to your branch: `git push origin feat/my-feature` 7. **Open** a pull request ### Development Commands ```bash # Install dependencies pnpm install # Run tests pnpm test # Run tests with coverage pnpm test:coverage # Build library pnpm build ``` --- ## πŸ“ Changelog See [CHANGELOG.md](CHANGELOG.md) for detailed release notes and version history. --- ## πŸ“„ License This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details. Β© 2024–2026 [Mark Learst](https://marklearst.com) Use it, fork it, build something that matters. --- ## πŸ”— Links - πŸ“¦ [NPM Package](https://www.npmjs.com/package/diabetic-utils) - πŸ“š [API Documentation](https://marklearst.github.io/diabetic-utils/) - πŸ™ [GitHub Repository](https://github.com/marklearst/diabetic-utils) - 🌐 [Website](https://diabeticutils.com) _(coming soon)_ --- ## πŸ™‹β€β™‚οΈ Author **Mark Learst** Full-stack developer, diabetes advocate, and open source contributor. - 🐦 X (Twitter): [@marklearst](https://x.com/marklearst) - πŸ’Ό LinkedIn: [Mark Learst](https://linkedin.com/in/marklearst) - 🌐 Portfolio: [marklearst.com](https://marklearst.com) > πŸ’¬ Using diabetic-utils in your project? [Let me know](https://x.com/marklearst)β€”I'd love to feature it! > ⭐ Star the repo and help us build the best diabetes toolkit together! --- ## πŸ’¬ Support - πŸ› **Bug Reports**: [Open an issue](https://github.com/marklearst/diabetic-utils/issues) - πŸ’‘ **Feature Requests**: [Start a discussion](https://github.com/marklearst/diabetic-utils/discussions) - πŸ“§ **Email**: mark@marklearst.com --- ## πŸ“ A Personal Note I built diabetic-utils because I believe in the power of data-driven diabetes management. As someone who's lived with diabetes, I know how hard it can be to make sense of the numbers. That's why I've poured my heart into creating a library that's both **accurate** and **easy to use**. Whether you're building an app, working on research, or just trying to understand your own data, I hope diabetic-utils can help. Let's work together to make diabetes management better, one data point at a time. 🩸 --- **Built with ❀️ by the diabetes community, for the diabetes community.**