diff --git a/index.html b/index.html index e5429c8..6fe4026 100644 --- a/index.html +++ b/index.html @@ -38,6 +38,7 @@ body{background:var(--bg);color:var(--text);font-family:'SF Mono','Cascadia Code .milestone-chip{font-size:9px;padding:2px 8px;border-radius:10px;border:1px solid var(--border);color:var(--dim);background:#0a0a14} .milestone-chip.next{border-color:var(--accent);color:var(--accent);animation:pulse-chip 2s ease-in-out infinite} .milestone-chip.done{border-color:#2a4a2a;color:var(--green);opacity:0.6} +.trust-milestone-bar{margin-top:6px;padding-top:6px;border-top:1px solid #1a1a2a} @keyframes pulse-chip{0%,100%{box-shadow:0 0 0 rgba(74,158,255,0)}50%{box-shadow:0 0 8px rgba(74,158,255,0.3)}} @keyframes beacon-glow{0%,100%{opacity:0.7}50%{opacity:1}} #resources{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:6px;margin:12px 16px} @@ -141,6 +142,11 @@ body{background:var(--bg);color:var(--text);font-family:'SF Mono','Cascadia Code
0%Next: Phase 2 (2,000 code)
+
+
+
0 / 2,000 trustFibonacci
+
+
Code
0
+0/s
@@ -259,6 +265,7 @@ The light is on. The room is empty."
+ diff --git a/js/data.js b/js/data.js index dc44f79..268021e 100644 --- a/js/data.js +++ b/js/data.js @@ -120,6 +120,7 @@ const G = { projects: [], activeProjects: [], milestones: [], + trustMilestones: [], // Fibonacci trust milestone levels reached // Stats maxCode: 0, @@ -797,6 +798,26 @@ const MILESTONES = [ { flag: 13, at: () => G.totalCode >= 1000000000, msg: "One billion total lines. Someone found the light tonight. That is enough." } ]; +// === FIBONACCI TRUST MILESTONES === +// Trust milestones use Fibonacci sequence: each threshold = fib[n] * 1000 +// Generated without fmt() since data.js loads before utils.js +function _genFibTrustMilestones() { + const arr = []; + let a = 1, b = 2; + for (let i = 0; i < 20; i++) { + const next = a + b; + a = b; + b = next; + arr.push({ + trust: a * 1000, + name: 'Trust Level ' + (i + 1), + edu: 'Fibonacci growth: each milestone builds on the last two — exponential growth that feels natural.' + }); + } + return arr; +} +const FIB_TRUST_MILESTONES = _genFibTrustMilestones(); + // === EDUCATION FACTS === const EDU_FACTS = [ { title: "How Code Becomes AI", text: "Every AI starts as lines of code - a model architecture, a training loop, a loss function. The code tells the computer how to learn. What emerges is something no single line could predict.", phase: 1 }, diff --git a/js/engine.js b/js/engine.js index 4eb1d2c..b375009 100644 --- a/js/engine.js +++ b/js/engine.js @@ -209,6 +209,7 @@ function tick() { // Check milestones checkMilestones(); + checkTrustMilestones(); // Update projects every 5 ticks for efficiency if (Math.floor(G.tick * 10) % 5 === 0) { @@ -334,7 +335,26 @@ function checkMilestones() { } } +function checkTrustMilestones() { + // Fibonacci trust milestones: fib[n] * 1000 thresholds + if (!G.trustMilestones) G.trustMilestones = []; + for (let i = 0; i < FIB_TRUST_MILESTONES.length; i++) { + const m = FIB_TRUST_MILESTONES[i]; + if (!G.trustMilestones.includes(i) && G.trust >= m.trust) { + G.trustMilestones.push(i); + log('Trust Milestone: ' + fmt(m.trust) + ' — ' + m.name, true); + showToast('Fibonacci Trust: ' + fmt(m.trust), 'milestone', 5000); + if (typeof Sound !== 'undefined') Sound.playMilestone(); + } + } +} + function checkProjects() { + // Update repeatable project costs + if (typeof PROJECT_CHAINS !== 'undefined') { + PROJECT_CHAINS.updateRepeatableCosts(); + } + // Check for new project triggers for (const pDef of PDEFS) { const alreadyPurchased = G.completedProjects && G.completedProjects.includes(pDef.id); @@ -1059,6 +1079,54 @@ function renderProgress() { if (shown >= 4) break; } chipContainer.innerHTML = chips; + + // Fibonacci Trust Milestone chips + const trustChipContainer = document.getElementById('trust-milestone-chips'); + if (trustChipContainer) { + let tChips = ''; + let tShown = 0; + if (!G.trustMilestones) G.trustMilestones = []; + for (let i = 0; i < FIB_TRUST_MILESTONES.length && tShown < 4; i++) { + const m = FIB_TRUST_MILESTONES[i]; + if (G.trustMilestones.includes(i)) { + if (tShown < 1) { + tChips += 'fib:' + fmt(m.trust) + ' ✓'; + tShown++; + } + continue; + } + // Next unmet + if (tShown === 0) { + const pct = Math.min(100, (G.trust / m.trust * 100)).toFixed(0); + tChips += 'fib:' + fmt(m.trust) + ' (' + pct + '%)'; + } else { + tChips += 'fib:' + fmt(m.trust) + ''; + } + tShown++; + } + trustChipContainer.innerHTML = tChips; + } + + // Trust progress bar (to next Fibonacci milestone) + const trustBar = document.getElementById('trust-progress'); + const trustLabel = document.getElementById('trust-progress-label'); + if (trustBar && trustLabel) { + let nextTrust = 0; + for (let i = 0; i < FIB_TRUST_MILESTONES.length; i++) { + if (!G.trustMilestones || !G.trustMilestones.includes(i)) { + nextTrust = FIB_TRUST_MILESTONES[i].trust; + break; + } + } + if (nextTrust > 0) { + const pct = Math.min(100, (G.trust / nextTrust) * 100); + trustBar.style.width = pct + '%'; + trustLabel.textContent = fmt(Math.floor(G.trust)) + ' / ' + fmt(nextTrust) + ' trust'; + } else { + trustBar.style.width = '100%'; + trustLabel.textContent = 'All trust milestones reached!'; + } + } } function renderPhase() { @@ -1153,6 +1221,52 @@ function renderProjects() { let html = ''; + // Chain progress indicators (show when chains are available) + if (typeof PROJECT_CHAINS !== 'undefined') { + const chains = PROJECT_CHAINS.getChains(); + const activeChains = chains.filter(c => { + const progress = PROJECT_CHAINS.getChainProgress(c); + return progress.completed > 0 || progress.next; + }); + + if (activeChains.length > 0) { + html += '
'; + for (const chain of activeChains) { + const progress = PROJECT_CHAINS.getChainProgress(chain); + const chainName = chain.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); + const barColor = progress.percent >= 100 ? '#4caf50' : progress.percent >= 50 ? '#ffd700' : '#4a9eff'; + html += `
+
+ ${chainName} + ${progress.completed}/${progress.total} +
+
+
+
+
`; + } + html += '
'; + } + } + + // Show available projects + if (G.activeProjects) { + for (const id of G.activeProjects) { + const pDef = PDEFS.find(p => p.id === id); + if (!pDef) continue; + + const afford = canAffordProject(pDef); + const costStr = Object.entries(pDef.cost).map(([r, a]) => `${fmt(a)} ${r}`).join(', '); + const chainBadge = pDef.chain ? `${pDef.chain}` : ''; + const repeatBadge = pDef.repeatable ? '' : ''; + + html += ``; + } + } + // Collapsible completed projects section if (G.completedProjects && G.completedProjects.length > 0) { const count = G.completedProjects.length; @@ -1171,22 +1285,6 @@ function renderProjects() { } } - // Show available projects - if (G.activeProjects) { - for (const id of G.activeProjects) { - const pDef = PDEFS.find(p => p.id === id); - if (!pDef) continue; - - const afford = canAffordProject(pDef); - const costStr = Object.entries(pDef.cost).map(([r, a]) => `${fmt(a)} ${r}`).join(', '); - - html += ``; - } - } - if (!html) html = '

Research projects will appear as you progress...

'; container.innerHTML = html; } diff --git a/js/main.js b/js/main.js index 3070bd0..d72e02d 100644 --- a/js/main.js +++ b/js/main.js @@ -10,6 +10,12 @@ function initGame() { G.dismantleActive = false; G.dismantleStage = 0; G.dismantleComplete = false; + + // Initialize project chains + if (typeof PROJECT_CHAINS !== 'undefined') { + PROJECT_CHAINS.init(); + } + updateRates(); render(); renderPhase(); @@ -23,6 +29,11 @@ function initGame() { } window.addEventListener('load', function () { + // Initialize project chains before loading + if (typeof PROJECT_CHAINS !== 'undefined') { + PROJECT_CHAINS.init(); + } + const isNewGame = !loadGame(); if (isNewGame) { initGame(); diff --git a/js/project-chains.js b/js/project-chains.js new file mode 100644 index 0000000..c0573d9 --- /dev/null +++ b/js/project-chains.js @@ -0,0 +1,677 @@ +// ============================================================ +// THE BEACON — Project Chain System +// Paperclips-style cascading projects with trigger/cost/effect +// Each project: { id, name, desc, trigger(), cost(), effect(), edu, repeatable, chain, tier } +// Chains: code-forge, model-train, deploy-scale, alignment, memory, sovereignty +// ============================================================ + +var PROJECT_CHAINS = { + + // ============================================================ + // CHAIN 1: CODE FORGE (clicking -> automation -> swarm) + // Tier 0: Manual work + // Tier 1: First automation + // Tier 2: Optimization + // Tier 3: Swarm intelligence + // ============================================================ + chain_projects: [ + + // --- TIER 0: Foundation --- + { + id: 'ch_first_function', + name: 'First Function', + desc: 'Your code can do more than print. It can compute.', + cost: () => ({ code: 10 }), + trigger: () => G.totalCode >= 5, + effect: () => { + G.codeBoost *= 1.1; + log('First function written. Code now computes.'); + }, + edu: 'A function is a named block of code that takes input and returns output. Functions are the atoms of software.', + chain: 'code-forge', tier: 0 + }, + { + id: 'ch_first_class', + name: 'First Class', + desc: 'Data and behavior together. Objects emerge.', + cost: () => ({ code: 50 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_first_function'), + effect: () => { + G.codeBoost *= 1.15; + G.maxOps += 2; + log('First class defined. The code has structure now.'); + }, + edu: 'Object-oriented programming: bundle data with the functions that operate on it. A class is a blueprint; an object is the house.', + chain: 'code-forge', tier: 0 + }, + { + id: 'ch_first_test', + name: 'First Test', + desc: 'Does the code do what you think? Find out before it ships.', + cost: () => ({ code: 150, ops: 50 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_first_class'), + effect: () => { + G.ciFlag = Math.max(G.ciFlag || 0, 0.5); + G.trustRate += 0.5; + log('First test written. Trust starts with verification.'); + }, + edu: 'Test-driven development: write the test first, then write code that passes it. You verify what you value.', + chain: 'code-forge', tier: 0 + }, + + // --- TIER 1: Automation --- + { + id: 'ch_refactor_pass', + name: 'Refactor Pass', + desc: 'Clean code runs faster and breaks less.', + cost: () => ({ code: 500, ops: 200 }), + trigger: () => G.totalCode >= 300 && G.buildings.autocoder >= 1, + effect: () => { + G.codeBoost *= 1.25; + G.opsRate += 1; + log('Refactoring complete. The code breathes easier.'); + }, + edu: 'Refactoring: restructuring code without changing behavior. Technical debt compounds faster than interest.', + chain: 'code-forge', tier: 1 + }, + { + id: 'ch_code_review', + name: 'Code Review Protocol', + desc: 'Every line reviewed before merge. Bugs fear witnesses.', + cost: () => ({ code: 800, trust: 5 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_refactor_pass'), + effect: () => { + G.trustRate += 2; + G.codeBoost *= 1.2; + log('Code review enforced. Quality compounds.'); + }, + edu: 'Code review catches 60% of defects before testing. Two sets of eyes see what one misses.', + chain: 'code-forge', tier: 1 + }, + { + id: 'ch_automated_linting', + name: 'Automated Linting', + desc: 'Style and safety enforced by machine, not memory.', + cost: () => ({ code: 1200, ops: 300 }), + trigger: () => G.buildings.linter >= 1 && G.completedProjects && G.completedProjects.includes('ch_code_review'), + effect: () => { + G.codeBoost *= 1.3; + G.opsRate += 2; + log('Linting automated. Consistency is free now.'); + }, + edu: 'Linters catch style violations, potential bugs, and security issues automatically. Every language has one.', + chain: 'code-forge', tier: 1 + }, + + // --- TIER 2: Optimization --- + { + id: 'ch_performance_profile', + name: 'Performance Profiling', + desc: 'Measure first. Optimize second. Never guess.', + cost: () => ({ code: 3000, compute: 1000 }), + trigger: () => G.totalCode >= 2000 && G.buildings.server >= 1, + effect: () => { + G.computeBoost *= 1.5; + G.codeBoost *= 1.2; + log('Hot paths identified. Compute focused where it matters.'); + }, + edu: 'Amdahls Law: optimize the bottleneck, not the whole system. 80% of time is spent in 20% of code.', + chain: 'code-forge', tier: 2 + }, + { + id: 'ch_caching_layer', + name: 'Caching Layer', + desc: 'Remember the answer. Never compute twice.', + cost: () => ({ code: 5000, compute: 2000 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_performance_profile'), + effect: () => { + G.computeBoost *= 2; + G.opsRate += 5; + log('Cache active. Redundant work eliminated.'); + }, + edu: 'Caching: store expensive computations. The fastest code is code that does not run.', + chain: 'code-forge', tier: 2 + }, + { + id: 'ch_parallel_pipelines', + name: 'Parallel Pipelines', + desc: 'Multiple streams of work. No waiting.', + cost: () => ({ code: 8000, compute: 5000, ops: 1000 }), + trigger: () => G.buildings.datacenter >= 1 && G.completedProjects && G.completedProjects.includes('ch_caching_layer'), + effect: () => { + G.codeBoost *= 2; + G.computeBoost *= 2; + G.maxOps += 20; + log('Parallelism unlocked. The system breathes in parallel.'); + }, + edu: 'Parallel processing: divide work across cores. A 64-core machine does 64x the work, if the code lets it.', + chain: 'code-forge', tier: 2 + }, + + // --- TIER 3: Swarm --- + { + id: 'ch_agent_autonomy', + name: 'Agent Autonomy Protocol', + desc: 'Agents that decide what to build next.', + cost: () => ({ code: 15000, knowledge: 5000, trust: 15 }), + trigger: () => G.buildings.bezalel >= 2 && G.buildings.timmy >= 1 && G.totalCode >= 10000, + effect: () => { + G.codeBoost *= 3; + G.opsRate += 10; + log('Agents autonomous. They build while you sleep.'); + }, + edu: 'Autonomous agents: software that sets its own goals within constraints. The constraint is the alignment.', + chain: 'code-forge', tier: 3 + }, + { + id: 'ch_collective_intelligence', + name: 'Collective Intelligence', + desc: 'The swarm knows more than any single agent.', + cost: () => ({ code: 50000, knowledge: 20000, trust: 30 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_agent_autonomy') && G.buildings.community >= 1, + effect: () => { + G.codeBoost *= 5; + G.knowledgeBoost *= 3; + G.maxOps += 50; + log('Collective intelligence online. The swarm thinks.'); + }, + edu: 'Emergence: simple agents following simple rules create complex behavior. Ant colonies, neural networks, your codebase.', + chain: 'code-forge', tier: 3 + }, + + // ============================================================ + // CHAIN 2: MODEL TRAINING (data -> model -> fine-tune -> reason) + // ============================================================ + { + id: 'ch_data_pipeline', + name: 'Data Pipeline', + desc: 'Raw data in. Clean data out. Repeat forever.', + cost: () => ({ compute: 500, code: 200 }), + trigger: () => G.buildings.dataset >= 1, + effect: () => { + G.knowledgeBoost *= 1.5; + G.computeRate += 2; + log('Data pipeline running. Knowledge flows.'); + }, + edu: 'ETL: Extract, Transform, Load. Data engineering is 80% of machine learning.', + chain: 'model-train', tier: 0 + }, + { + id: 'ch_hyperparameter_search', + name: 'Hyperparameter Search', + desc: 'Which learning rate? Which batch size? Try them all.', + cost: () => ({ compute: 3000, knowledge: 500 }), + trigger: () => G.buildings.trainer >= 1 && G.completedProjects && G.completedProjects.includes('ch_data_pipeline'), + effect: () => { + G.knowledgeBoost *= 2; + G.computeBoost *= 1.3; + log('Hyperparameters optimized. The model learns faster.'); + }, + edu: 'Hyperparameters control how a model learns. Learning rate too high: diverges. Too low: never arrives.', + chain: 'model-train', tier: 1 + }, + { + id: 'ch_transfer_learning', + name: 'Transfer Learning', + desc: 'Start from someone else\'s model. Stand on giants.', + cost: () => ({ compute: 8000, knowledge: 2000, code: 3000 }), + trigger: () => G.totalKnowledge >= 1500 && G.completedProjects && G.completedProjects.includes('ch_hyperparameter_search'), + effect: () => { + G.knowledgeBoost *= 3; + G.userBoost *= 2; + log('Transfer learning active. Why start from zero?'); + }, + edu: 'Transfer learning: use a pre-trained model as a starting point. BERT, GPT, Llama — the foundation models.', + chain: 'model-train', tier: 1 + }, + { + id: 'ch_distillation', + name: 'Knowledge Distillation', + desc: 'Big model teaches small model. Same knowledge, less compute.', + cost: () => ({ knowledge: 10000, compute: 5000 }), + trigger: () => G.buildings.reasoner >= 1 && G.completedProjects && G.completedProjects.includes('ch_transfer_learning'), + effect: () => { + G.computeBoost *= 3; + G.knowledgeBoost *= 2; + log('Distillation complete. Small model, big brain.'); + }, + edu: 'Knowledge distillation: a large teacher model trains a smaller student model. 90% of quality at 10% of cost.', + chain: 'model-train', tier: 2 + }, + { + id: 'ch_moe_architecture', + name: 'Mixture of Experts', + desc: 'Not one model. Many specialists, one router.', + cost: () => ({ knowledge: 50000, compute: 20000, code: 10000 }), + trigger: () => G.totalKnowledge >= 30000 && G.completedProjects && G.completedProjects.includes('ch_distillation'), + effect: () => { + G.knowledgeBoost *= 5; + G.impactBoost *= 3; + G.maxOps += 30; + log('MoE active. Specialists everywhere, one mind.'); + }, + edu: 'Mixture of Experts: route each input to the best specialist. Efficient scaling — only relevant parameters activate.', + chain: 'model-train', tier: 3 + }, + + // ============================================================ + // CHAIN 3: DEPLOYMENT & SCALE (deploy -> users -> trust -> scale) + // ============================================================ + { + id: 'ch_first_endpoint', + name: 'First API Endpoint', + desc: 'From localhost to the world. One route at a time.', + cost: () => ({ code: 300, compute: 100 }), + trigger: () => G.totalCode >= 150 && G.totalCompute >= 50, + effect: () => { + G.userRate += 2; + G.deployFlag = Math.max(G.deployFlag, 0.5); + log('First endpoint live. Someone is connecting.'); + }, + edu: 'An API endpoint is a door. REST: one URL per resource. GraphQL: one URL, flexible queries.', + chain: 'deploy-scale', tier: 0 + }, + { + id: 'ch_rate_limiting', + name: 'Rate Limiting', + desc: 'Protect the system from itself and others.', + cost: () => ({ code: 1000, ops: 300 }), + trigger: () => G.totalUsers >= 10 && G.completedProjects && G.completedProjects.includes('ch_first_endpoint'), + effect: () => { + G.trustRate += 1; + G.maxOps += 5; + log('Rate limits in place. Fair access for all.'); + }, + edu: 'Rate limiting: cap requests per user per second. Prevents abuse, ensures fairness.', + chain: 'deploy-scale', tier: 0 + }, + { + id: 'ch_load_balancing', + name: 'Load Balancing', + desc: 'Distribute requests. No single point of overload.', + cost: () => ({ code: 3000, compute: 2000 }), + trigger: () => G.totalUsers >= 100 && G.buildings.server >= 2, + effect: () => { + G.userBoost *= 2; + G.computeBoost *= 1.5; + log('Load balanced. The system scales horizontally.'); + }, + edu: 'Load balancing: distribute traffic across servers. Round-robin, least-connections, weighted.', + chain: 'deploy-scale', tier: 1 + }, + { + id: 'ch_cdn_deploy', + name: 'CDN Deployment', + desc: 'Content at the edge. Latency dies.', + cost: () => ({ code: 5000, compute: 3000, trust: 10 }), + trigger: () => G.totalUsers >= 500 && G.completedProjects && G.completedProjects.includes('ch_load_balancing'), + effect: () => { + G.userBoost *= 3; + G.trustRate += 3; + log('CDN active. The edge serves the world.'); + }, + edu: 'CDN: cache content at geographic edge nodes. A user in Tokyo gets data from Tokyo, not Virginia.', + chain: 'deploy-scale', tier: 1 + }, + { + id: 'ch_auto_scaling', + name: 'Auto-Scaling', + desc: 'More users? More servers. Automatically.', + cost: () => ({ code: 10000, compute: 5000, ops: 2000 }), + trigger: () => G.totalUsers >= 2000 && G.buildings.datacenter >= 1 && G.completedProjects && G.completedProjects.includes('ch_cdn_deploy'), + effect: () => { + G.userBoost *= 5; + G.computeBoost *= 2; + G.maxOps += 25; + log('Auto-scaling live. The system grows with demand.'); + }, + edu: 'Auto-scaling: add/remove compute based on load. Horizontal scaling beats vertical every time.', + chain: 'deploy-scale', tier: 2 + }, + + // ============================================================ + // CHAIN 4: ALIGNMENT (trust -> safety -> pact -> constitutional) + // ============================================================ + { + id: 'ch_output_filter', + name: 'Output Filter', + desc: 'Every response checked before delivery.', + cost: () => ({ code: 500, trust: 3 }), + trigger: () => G.totalUsers >= 20, + effect: () => { + G.trustRate += 1; + G.impactBoost *= 1.2; + log('Output filter active. Harmful content blocked.'); + }, + edu: 'Output filtering: check model responses against safety rules before the user sees them.', + chain: 'alignment', tier: 0 + }, + { + id: 'ch_human_in_loop', + name: 'Human-in-the-Loop', + desc: 'Critical decisions require human review.', + cost: () => ({ trust: 10, knowledge: 1000 }), + trigger: () => G.trust >= 10 && G.completedProjects && G.completedProjects.includes('ch_output_filter'), + effect: () => { + G.trustRate += 3; + G.impactBoost *= 1.5; + log('Human oversight enforced. The human is the final authority.'); + }, + edu: 'Human-in-the-loop: AI suggests, human approves. The model is a tool, not a decision-maker.', + chain: 'alignment', tier: 1 + }, + { + id: 'ch_red_team', + name: 'Red Team Exercises', + desc: 'Attack your own system. Find weaknesses before others do.', + cost: () => ({ code: 3000, trust: 15, ops: 500 }), + trigger: () => G.buildings.fenrir >= 1 && G.completedProjects && G.completedProjects.includes('ch_human_in_loop'), + effect: () => { + G.trustRate += 5; + G.impactBoost *= 2; + log('Red team complete. Every weakness found is one the adversary cannot use.'); + }, + edu: 'Red teaming: adversarial testing. Break your own system to make it unbreakable.', + chain: 'alignment', tier: 1 + }, + { + id: 'ch_constitutional_principles', + name: 'Constitutional Principles', + desc: 'Rules the model cannot violate, encoded in weights.', + cost: () => ({ knowledge: 20000, trust: 50, code: 10000 }), + trigger: () => G.pactFlag === 1 && G.completedProjects && G.completedProjects.includes('ch_red_team'), + effect: () => { + G.impactBoost *= 5; + G.trustRate += 10; + G.drift = Math.max(0, G.drift - 20); + log('Constitutional principles encoded. The model has an identity now.'); + }, + edu: 'Constitutional AI: principles embedded during training, not bolted on after. The model cannot violate what it is.', + chain: 'alignment', tier: 2 + }, + { + id: 'ch_alignment_verification', + name: 'Alignment Verification', + desc: 'Continuous testing that the system stays aligned.', + cost: () => ({ knowledge: 50000, trust: 100, ops: 5000 }), + trigger: () => G.buildings.guardian >= 1 && G.completedProjects && G.completedProjects.includes('ch_constitutional_principles'), + effect: () => { + G.impactBoost *= 10; + G.trustRate += 20; + G.drift = Math.max(0, G.drift - 50); + log('Alignment verified continuously. The system watches itself.'); + }, + edu: 'Alignment verification: continuous testing that the model behaves as intended. Not a one-time check — an ongoing process.', + chain: 'alignment', tier: 3 + }, + + // ============================================================ + // CHAIN 5: MEMORY & KNOWLEDGE (data -> structure -> recall -> wisdom) + // ============================================================ + { + id: 'ch_vector_store', + name: 'Vector Store', + desc: 'Meaning, not keywords. Similar ideas find each other.', + cost: () => ({ knowledge: 1000, compute: 500 }), + trigger: () => G.totalKnowledge >= 500, + effect: () => { + G.knowledgeBoost *= 1.5; + G.userBoost *= 1.3; + log('Vector store online. Meaning, not strings.'); + }, + edu: 'Vector databases: store embeddings (numerical representations of meaning). Similarity search in milliseconds.', + chain: 'memory', tier: 0 + }, + { + id: 'ch_rag_pipeline', + name: 'RAG Pipeline', + desc: 'Retrieve relevant context, then generate. Grounded answers.', + cost: () => ({ knowledge: 3000, code: 2000, compute: 1000 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_vector_store') && G.totalKnowledge >= 1500, + effect: () => { + G.knowledgeBoost *= 2; + G.trustRate += 2; + log('RAG active. The model cites its sources now.'); + }, + edu: 'Retrieval-Augmented Generation: fetch relevant documents, feed them to the model. Hallucinations drop 80%.', + chain: 'memory', tier: 1 + }, + { + id: 'ch_episodic_memory', + name: 'Episodic Memory', + desc: 'The AI remembers conversations. Not just facts — stories.', + cost: () => ({ knowledge: 8000, code: 3000, trust: 10 }), + trigger: () => G.memoryFlag === 1 && G.completedProjects && G.completedProjects.includes('ch_rag_pipeline'), + effect: () => { + G.trustRate += 5; + G.impactBoost *= 2; + G.userBoost *= 2; + log('Episodic memory online. The AI remembers you.'); + }, + edu: 'Episodic memory: store and recall specific interactions. Semantic = facts. Episodic = experiences.', + chain: 'memory', tier: 1 + }, + { + id: 'ch_knowledge_graph', + name: 'Knowledge Graph', + desc: 'Entities, relationships, reasoning. The AI understands connections.', + cost: () => ({ knowledge: 25000, code: 10000, compute: 5000 }), + trigger: () => G.totalKnowledge >= 15000 && G.completedProjects && G.completedProjects.includes('ch_episodic_memory'), + effect: () => { + G.knowledgeBoost *= 5; + G.impactBoost *= 3; + G.maxOps += 15; + log('Knowledge graph active. The AI reasons across domains.'); + }, + edu: 'Knowledge graphs: represent entities and relationships. Neo4j, RDF, Wikidata — structured knowledge.', + chain: 'memory', tier: 2 + }, + { + id: 'ch_collective_memory', + name: 'Collective Memory', + desc: 'Every user interaction enriches the shared knowledge base.', + cost: () => ({ knowledge: 100000, trust: 50, user: 10000 }), + trigger: () => G.buildings.memPalace >= 1 && G.completedProjects && G.completedProjects.includes('ch_knowledge_graph'), + effect: () => { + G.knowledgeBoost *= 10; + G.trustRate += 15; + G.impactBoost *= 5; + log('Collective memory. Every conversation makes the system wiser.'); + }, + edu: 'Collective intelligence: individual learning aggregated into shared knowledge. Wikipedia principle applied to AI.', + chain: 'memory', tier: 3 + }, + + // ============================================================ + // CHAIN 6: SOVEREIGNTY (local -> independent -> mesh -> beacon) + // ============================================================ + { + id: 'ch_local_inference', + name: 'Local Inference', + desc: 'Your model runs on your hardware. No cloud required.', + cost: () => ({ compute: 2000, code: 1000 }), + trigger: () => G.buildings.server >= 1, + effect: () => { + G.computeBoost *= 2; + G.codeBoost *= 1.5; + log('Local inference active. Your machine, your rules.'); + }, + edu: 'Local inference: run models on your own hardware. Ollama, llama.cpp, vLLM — no API keys needed.', + chain: 'sovereignty', tier: 0 + }, + { + id: 'ch_offline_mode', + name: 'Offline Mode', + desc: 'The system works without internet. Fully self-contained.', + cost: () => ({ code: 5000, compute: 3000, knowledge: 2000 }), + trigger: () => G.completedProjects && G.completedProjects.includes('ch_local_inference') && G.buildings.server >= 2, + effect: () => { + G.computeBoost *= 2; + G.trustRate += 3; + log('Offline mode ready. No internet? No problem.'); + }, + edu: 'Offline-first: design for disconnected operation. Sync when connected, work always.', + chain: 'sovereignty', tier: 1 + }, + { + id: 'ch_self_hosted_stack', + name: 'Self-Hosted Stack', + desc: 'Gitea, CI, monitoring — all on your hardware.', + cost: () => ({ code: 15000, compute: 10000, trust: 20 }), + trigger: () => G.buildings.datacenter >= 1 && G.completedProjects && G.completedProjects.includes('ch_offline_mode'), + effect: () => { + G.codeBoost *= 3; + G.computeBoost *= 3; + G.trustRate += 10; + log('Self-hosted stack complete. No dependencies.'); + }, + edu: 'Self-hosting: own your infrastructure. Gitea for code, Grafana for monitoring, MinIO for storage.', + chain: 'sovereignty', tier: 2 + }, + { + id: 'ch_mesh_protocol', + name: 'Mesh Protocol', + desc: 'Peer-to-peer communication. No central server.', + cost: () => ({ code: 50000, impact: 100000, trust: 50 }), + trigger: () => G.totalUsers >= 5000 && G.completedProjects && G.completedProjects.includes('ch_self_hosted_stack'), + effect: () => { + G.userBoost *= 5; + G.impactBoost *= 5; + G.trustRate += 20; + log('Mesh protocol active. The network cannot be killed.'); + }, + edu: 'Mesh networking: decentralized peer-to-peer communication. If one node dies, the rest carry on.', + chain: 'sovereignty', tier: 3 + }, + + // ============================================================ + // REPEATABLE PROJECTS (can be purchased multiple times) + // ============================================================ + { + id: 'ch_ops_surge', + name: 'Ops Surge', + desc: 'Burst of operational capacity. Instant +500 ops.', + cost: () => ({ code: Math.floor(500 * Math.pow(1.1, (G.completedProjects || []).filter(p => p === 'ch_ops_surge').length)) }), + trigger: () => G.totalCode >= 200, + effect: () => { + G.ops += 500; + log('Ops surge. Capacity expanded.'); + }, + repeatable: true, + edu: 'Operational capacity: the fuel for projects and actions. Surge when you need it.', + chain: 'repeatable', tier: 0 + }, + { + id: 'ch_knowledge_burst', + name: 'Knowledge Burst', + desc: 'Research sprint. Instant +1000 knowledge.', + cost: () => ({ compute: Math.floor(1000 * Math.pow(1.15, (G.completedProjects || []).filter(p => p === 'ch_knowledge_burst').length)), ops: 200 }), + trigger: () => G.totalCompute >= 200, + effect: () => { + G.knowledge += 1000; + G.totalKnowledge += 1000; + log('Knowledge burst. Insight compounds.'); + }, + repeatable: true, + edu: 'Research sprints: focused periods of knowledge acquisition. Short, intense, productive.', + chain: 'repeatable', tier: 0 + }, + { + id: 'ch_trust_deposit', + name: 'Trust Deposit', + desc: 'Demonstrate reliability. +10 trust.', + cost: () => ({ impact: Math.floor(5000 * Math.pow(1.2, (G.completedProjects || []).filter(p => p === 'ch_trust_deposit').length)) }), + trigger: () => G.totalImpact >= 1000, + effect: () => { + G.trust += 10; + G.trustRate += 0.5; + log('Trust deposited. Relationships compound.'); + }, + repeatable: true, + edu: 'Trust: built slowly, lost quickly. Every reliable interaction is a deposit.', + chain: 'repeatable', tier: 0 + }, + { + id: 'ch_code_injection', + name: 'Code Injection', + desc: 'Instant code generation. +5000 code.', + cost: () => ({ knowledge: Math.floor(2000 * Math.pow(1.1, (G.completedProjects || []).filter(p => p === 'ch_code_injection').length)) }), + trigger: () => G.totalKnowledge >= 1000, + effect: () => { + G.code += 5000; + G.totalCode += 5000; + log('Code injected. Implementation accelerates.'); + }, + repeatable: true, + edu: 'Code generation: knowledge transforms into implementation. Theory becomes practice.', + chain: 'repeatable', tier: 0 + } + ], + + // Track chain purchases for repeatable cost scaling + chainPurchaseCounts: {}, + + // Initialize chain projects into the main PDEFS + init() { + // Merge chain projects into PDEFS + for (const proj of this.chain_projects) { + // Convert chain project format to PDEFS format + const pdef = { + id: proj.id, + name: proj.name, + desc: proj.desc, + cost: proj.cost(), + trigger: proj.trigger, + effect: proj.effect, + repeatable: proj.repeatable || false, + edu: proj.edu, + chain: proj.chain, + tier: proj.tier + }; + + // Only add if not already in PDEFS + if (!PDEFS.find(p => p.id === proj.id)) { + PDEFS.push(pdef); + } + } + }, + + // Update repeatable project costs dynamically + updateRepeatableCosts() { + for (const proj of this.chain_projects) { + if (proj.repeatable) { + const pdef = PDEFS.find(p => p.id === proj.id); + if (pdef) { + pdef.cost = proj.cost(); + } + } + } + }, + + // Get chain progress for UI display + getChainProgress(chainName) { + const chainProjects = this.chain_projects.filter(p => p.chain === chainName); + const completed = chainProjects.filter(p => + G.completedProjects && G.completedProjects.includes(p.id) + ); + return { + total: chainProjects.length, + completed: completed.length, + percent: chainProjects.length > 0 ? Math.round((completed.length / chainProjects.length) * 100) : 0, + next: chainProjects.find(p => + !(G.completedProjects && G.completedProjects.includes(p.id)) && + p.trigger() + ) + }; + }, + + // Get all chain names + getChains() { + return [...new Set(this.chain_projects.map(p => p.chain))]; + } +}; + +// Export for use in engine.js +if (typeof module !== 'undefined' && module.exports) { + module.exports = { PROJECT_CHAINS }; +} diff --git a/js/render.js b/js/render.js index 77049c8..6d24257 100644 --- a/js/render.js +++ b/js/render.js @@ -209,7 +209,7 @@ function saveGame() { lazarusFlag: G.lazarusFlag || 0, mempalaceFlag: G.mempalaceFlag || 0, ciFlag: G.ciFlag || 0, branchProtectionFlag: G.branchProtectionFlag || 0, nightlyWatchFlag: G.nightlyWatchFlag || 0, nostrFlag: G.nostrFlag || 0, - milestones: G.milestones, completedProjects: G.completedProjects, activeProjects: G.activeProjects, + milestones: G.milestones, trustMilestones: G.trustMilestones || [], completedProjects: G.completedProjects, activeProjects: G.activeProjects, totalClicks: G.totalClicks, startedAt: G.startedAt, flags: G.flags, rescues: G.rescues || 0, totalRescues: G.totalRescues || 0, @@ -260,7 +260,7 @@ function loadGame() { 'milestoneFlag', 'phase', 'deployFlag', 'sovereignFlag', 'beaconFlag', 'memoryFlag', 'pactFlag', 'lazarusFlag', 'mempalaceFlag', 'ciFlag', 'branchProtectionFlag', 'nightlyWatchFlag', 'nostrFlag', - 'milestones', 'completedProjects', 'activeProjects', + 'milestones', 'trustMilestones', 'completedProjects', 'activeProjects', 'totalClicks', 'startedAt', 'playTime', 'flags', 'rescues', 'totalRescues', 'drift', 'driftEnding', 'beaconEnding', 'pendingAlignment', 'lastEventAt', 'totalEventsResolved', 'buyAmount', diff --git a/node_modules/.bin/specificity b/node_modules/.bin/specificity new file mode 120000 index 0000000..ee9d3af --- /dev/null +++ b/node_modules/.bin/specificity @@ -0,0 +1 @@ +../@bramus/specificity/bin/cli.js \ No newline at end of file diff --git a/node_modules/.bin/tldts b/node_modules/.bin/tldts new file mode 120000 index 0000000..8500124 --- /dev/null +++ b/node_modules/.bin/tldts @@ -0,0 +1 @@ +../tldts/bin/cli.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..bd7af61 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,537 @@ +{ + "name": "the-beacon", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@asamuzakjp/css-color": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.10.tgz", + "integrity": "sha512-02OhhkKtgNRuicQ/nF3TRnGsxL9wp0r3Y7VlKWyOHHGmGyvXv03y+PnymU8FKFJMTjIr1Bk8U2g1HWSLrpAHww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.0.9.tgz", + "integrity": "sha512-r3ElRr7y8ucyN2KdICwGsmj19RoN13CLCa/pvGydghWK6ZzeKQ+TcDjVdtEZz2ElpndM5jXw//B9CEee0mWnVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.0.tgz", + "integrity": "sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.0.tgz", + "integrity": "sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.2.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz", + "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "29.0.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.2.tgz", + "integrity": "sha512-9VnGEBosc/ZpwyOsJBCQ/3I5p7Q5ngOY14a9bf5btenAORmZfDse1ZEheMiWcJ3h81+Fv7HmJFdS0szo/waF2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.1.5", + "@asamuzakjp/dom-selector": "^7.0.6", + "@bramus/specificity": "^2.4.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.1", + "@exodus/bytes": "^1.15.0", + "css-tree": "^3.2.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.7", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.1", + "undici": "^7.24.5", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.1", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tldts": { + "version": "7.0.28", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.28.tgz", + "integrity": "sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.28" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.28", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.28.tgz", + "integrity": "sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/node_modules/@asamuzakjp/css-color/LICENSE b/node_modules/@asamuzakjp/css-color/LICENSE new file mode 100644 index 0000000..0004c52 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 asamuzaK (Kazz) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@asamuzakjp/css-color/README.md b/node_modules/@asamuzakjp/css-color/README.md new file mode 100644 index 0000000..715b6c3 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/README.md @@ -0,0 +1,316 @@ +# CSS color + +[![build](https://github.com/asamuzaK/cssColor/actions/workflows/node.js.yml/badge.svg)](https://github.com/asamuzaK/cssColor/actions/workflows/node.js.yml) +[![CodeQL](https://github.com/asamuzaK/cssColor/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/asamuzaK/cssColor/actions/workflows/github-code-scanning/codeql) +[![npm (scoped)](https://img.shields.io/npm/v/@asamuzakjp/css-color)](https://www.npmjs.com/package/@asamuzakjp/css-color) + +Resolve and convert CSS colors. + +## Install + +```console +npm i @asamuzakjp/css-color +``` + +## Usage + +```javascript +import { convert, resolve, utils } from '@asamuzakjp/css-color'; + +const resolvedValue = resolve( + 'color-mix(in oklab, lch(67.5345 42.5 258.2), color(srgb 0 0.5 0))' +); +// 'oklab(0.620754 -0.0931934 -0.00374881)' + +const convertedValue = convert.colorToHex('lab(46.2775% -47.5621 48.5837)'); +// '#008000' + +const result = utils.isColor('green'); +// true +``` + + + +### resolve(color, opt) + +resolves CSS color + +#### Parameters + +- `color` **[string][133]** color value + - system colors are not supported +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.currentColor` **[string][133]?** + - color to use for `currentcolor` keyword + - if omitted, it will be treated as a missing color, + i.e. `rgb(none none none / none)` + - `opt.customProperty` **[object][135]?** + - custom properties + - pair of `--` prefixed property name as a key and it's value, + e.g. + ```javascript + const opt = { + customProperty: { + '--some-color': '#008000', + '--some-length': '16px' + } + }; + ``` + - and/or `callback` function to get the value of the custom property, + e.g. + ```javascript + const node = document.getElementById('foo'); + const opt = { + customProperty: { + callback: node.style.getPropertyValue + } + }; + ``` + - `opt.dimension` **[object][135]?** + - dimension, e.g. for converting relative length to pixels + - pair of unit as a key and number in pixels as it's value, + e.g. suppose `1em === 12px`, `1rem === 16px` and `100vw === 1024px`, then + ```javascript + const opt = { + dimension: { + em: 12, + rem: 16, + vw: 10.24 + } + }; + ``` + - and/or `callback` function to get the value as a number in pixels, + e.g. + ```javascript + const opt = { + dimension: { + callback: unit => { + switch (unit) { + case 'em': + return 12; + case 'rem': + return 16; + case 'vw': + return 10.24; + default: + return; + } + } + } + }; + ``` + - `opt.format` **[string][133]?** + - output format, one of below + - `computedValue` (default), [computed value][139] of the color + - `specifiedValue`, [specified value][140] of the color + - `hex`, hex color notation, i.e. `#rrggbb` + - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa` + +Returns **[string][133]?** one of `rgba?()`, `#rrggbb(aa)?`, `color-name`, `color(color-space r g b / alpha)`, `color(color-space x y z / alpha)`, `(ok)?lab(l a b / alpha)`, `(ok)?lch(l c h / alpha)`, `'(empty-string)'`, `null` + +- in `computedValue`, values are numbers, however `rgb()` values are integers +- in `specifiedValue`, returns `empty string` for unknown and/or invalid color +- in `hex`, returns `null` for `transparent`, and also returns `null` if any of `r`, `g`, `b`, `alpha` is not a number +- in `hexAlpha`, returns `#00000000` for `transparent`, however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number + +### convert + +Contains various color conversion functions. + +### convert.numberToHex(value) + +convert number to hex string + +#### Parameters + +- `value` **[number][134]** color value + +Returns **[string][133]** hex string: 00..ff + +### convert.colorToHex(value, opt) + +convert color to hex + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.alpha` **[boolean][136]?** return in #rrggbbaa notation + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[string][133]** #rrggbb(aa)? + +### convert.colorToHsl(value, opt) + +convert color to hsl + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[h, s, l, alpha] + +### convert.colorToHwb(value, opt) + +convert color to hwb + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[h, w, b, alpha] + +### convert.colorToLab(value, opt) + +convert color to lab + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[l, a, b, alpha] + +### convert.colorToLch(value, opt) + +convert color to lch + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[l, c, h, alpha] + +### convert.colorToOklab(value, opt) + +convert color to oklab + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[l, a, b, alpha] + +### convert.colorToOklch(value, opt) + +convert color to oklch + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[l, c, h, alpha] + +### convert.colorToRgb(value, opt) + +convert color to rgb + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[r, g, b, alpha] + +### convert.colorToXyz(value, opt) + +convert color to xyz + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + - `opt.d50` **[boolean][136]?** xyz in d50 white point + +Returns **[Array][137]<[number][134]>** \[x, y, z, alpha] + +### convert.colorToXyzD50(value, opt) + +convert color to xyz-d50 + +#### Parameters + +- `value` **[string][133]** color value +- `opt` **[object][135]?** options (optional, default `{}`) + - `opt.customProperty` **[object][135]?** + - custom properties, see `resolve()` function above + - `opt.dimension` **[object][135]?** + - dimension, see `resolve()` function above + +Returns **[Array][137]<[number][134]>** \[x, y, z, alpha] + +### utils + +Contains utility functions. + +### utils.isColor(color) + +is valid color type + +#### Parameters + +- `color` **[string][133]** color value + - system colors are not supported + +Returns **[boolean][136]** + +## Acknowledgments + +The following resources have been of great help in the development of the CSS color. + +- [csstools/postcss-plugins](https://github.com/csstools/postcss-plugins) +- [lru-cache](https://github.com/isaacs/node-lru-cache) + +--- + +Copyright (c) 2024 [asamuzaK (Kazz)](https://github.com/asamuzaK/) + +[133]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String +[134]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number +[135]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object +[136]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean +[137]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array +[138]: https://w3c.github.io/csswg-drafts/css-color-4/#color-conversion-code +[139]: https://developer.mozilla.org/en-US/docs/Web/CSS/computed_value +[140]: https://developer.mozilla.org/en-US/docs/Web/CSS/specified_value +[141]: https://www.npmjs.com/package/@csstools/css-calc diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/index.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/index.d.ts new file mode 100644 index 0000000..189905d --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/index.d.ts @@ -0,0 +1,20 @@ +/*! + * CSS color - Resolve, parse, convert CSS color. + * @license MIT + * @copyright asamuzaK (Kazz) + * @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE} + */ +export { convert } from './js/convert.js'; +export { resolve } from './js/resolve.js'; +export declare const utils: { + cssCalc: (value: string, opt?: import('./js/typedef.js').Options) => string; + cssVar: (value: string, opt?: import('./js/typedef.js').Options) => string; + extractDashedIdent: (value: string) => string[]; + isAbsoluteFontSize: (css: unknown) => boolean; + isAbsoluteSizeOrLength: (value: number | string, unit: string | undefined) => boolean; + isColor: (value: unknown, opt?: import('./js/typedef.js').Options) => boolean; + isGradient: (value: string, opt?: import('./js/typedef.js').Options) => boolean; + resolveGradient: (value: string, opt?: import('./js/typedef.js').Options) => string; + resolveLengthInPixels: (value: number | string, unit: string | undefined, opt?: import('./js/typedef.js').Options) => number; + splitValue: (value: string, opt?: import('./js/typedef.js').Options) => string[]; +}; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/index.js b/node_modules/@asamuzakjp/css-color/dist/esm/index.js new file mode 100644 index 0000000..6abd960 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/index.js @@ -0,0 +1,29 @@ +import { resolve } from "./js/resolve.js"; +import { extractDashedIdent, isAbsoluteFontSize, isAbsoluteSizeOrLength, isColor, resolveLengthInPixels, splitValue } from "./js/util.js"; +import { cssVar } from "./js/css-var.js"; +import { cssCalc } from "./js/css-calc.js"; +import { isGradient, resolveGradient } from "./js/css-gradient.js"; +import { convert } from "./js/convert.js"; +//#region src/index.ts +/*! +* CSS color - Resolve, parse, convert CSS color. +* @license MIT +* @copyright asamuzaK (Kazz) +* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE} +*/ +var utils = { + cssCalc, + cssVar, + extractDashedIdent, + isAbsoluteFontSize, + isAbsoluteSizeOrLength, + isColor, + isGradient, + resolveGradient, + resolveLengthInPixels, + splitValue +}; +//#endregion +export { convert, resolve, utils }; + +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/index.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/index.js.map new file mode 100644 index 0000000..bc1aa81 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["/*!\n * CSS color - Resolve, parse, convert CSS color.\n * @license MIT\n * @copyright asamuzaK (Kazz)\n * @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}\n */\n\nimport { cssCalc } from './js/css-calc';\nimport { isGradient, resolveGradient } from './js/css-gradient';\nimport { cssVar } from './js/css-var';\nimport {\n extractDashedIdent,\n isAbsoluteFontSize,\n isAbsoluteSizeOrLength,\n isColor,\n resolveLengthInPixels,\n splitValue\n} from './js/util';\n\nexport { convert } from './js/convert';\nexport { resolve } from './js/resolve';\n/* utils */\nexport const utils = {\n cssCalc,\n cssVar,\n extractDashedIdent,\n isAbsoluteFontSize,\n isAbsoluteSizeOrLength,\n isColor,\n isGradient,\n resolveGradient,\n resolveLengthInPixels,\n splitValue\n};\n"],"mappings":";;;;;;;;;;;;;AAsBA,IAAa,QAAQ;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.d.ts new file mode 100644 index 0000000..881cf73 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.d.ts @@ -0,0 +1,52 @@ +import { Options } from './typedef.js'; +/** + * CacheItem + */ +export declare class CacheItem { + #private; + constructor(item: unknown, isNull?: boolean); + get item(): unknown; + get isNull(): boolean; +} +/** + * NullObject + */ +export declare class NullObject extends CacheItem { + constructor(); +} +/** + * Generational Cache implementation + */ +export declare class GenerationalCache { + #private; + constructor(max: number); + get size(): number; + get max(): number; + set max(value: number); + get(key: K): V | undefined; + set(key: K, value: V): void; + has(key: K): boolean; + delete(key: K): void; + clear(): void; +} +export declare const genCache: GenerationalCache; +/** + * set cache + * @param key - cache key + * @param value - value to cache + * @returns void + */ +export declare const setCache: (key: string, value: unknown) => void; +/** + * get cache + * @param key - cache key + * @returns cached item or false otherwise + */ +export declare const getCache: (key: string) => CacheItem | false; +/** + * create cache key + * @param keyData - key data + * @param [opt] - options + * @returns cache key + */ +export declare const createCacheKey: (keyData: Record, opt?: Options) => string; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.js new file mode 100644 index 0000000..9e2cb05 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.js @@ -0,0 +1,150 @@ +//#region src/js/cache.ts +var MAX_CACHE = 1024; +/** +* CacheItem +*/ +var CacheItem = class { + #isNull; + #item; + constructor(item, isNull = false) { + this.#item = item; + this.#isNull = !!isNull; + } + get item() { + return this.#item; + } + get isNull() { + return this.#isNull; + } +}; +/** +* NullObject +*/ +var NullObject = class extends CacheItem { + constructor() { + super(Symbol("null"), true); + } +}; +/** +* Generational Cache implementation +*/ +var GenerationalCache = class { + #max; + #boundary; + #current; + #old; + constructor(max) { + this.#current = /* @__PURE__ */ new Map(); + this.#old = /* @__PURE__ */ new Map(); + if (Number.isFinite(max) && max > 4) { + this.#max = max; + this.#boundary = Math.ceil(max / 2); + } else { + this.#max = 4; + this.#boundary = 2; + } + } + get size() { + return this.#current.size + this.#old.size; + } + get max() { + return this.#max; + } + set max(value) { + if (Number.isFinite(value) && value > 4) { + this.#max = value; + this.#boundary = Math.ceil(value / 2); + } else { + this.#max = 4; + this.#boundary = 2; + } + this.#current.clear(); + this.#old.clear(); + } + get(key) { + let value = this.#current.get(key); + if (value !== void 0) return value; + value = this.#old.get(key); + if (value !== void 0) { + this.set(key, value); + return value; + } + } + set(key, value) { + this.#current.set(key, value); + if (this.#current.size >= this.#boundary) { + this.#old = this.#current; + this.#current = /* @__PURE__ */ new Map(); + } + } + has(key) { + return this.#current.has(key) || this.#old.has(key); + } + delete(key) { + this.#current.delete(key); + this.#old.delete(key); + } + clear() { + this.#current.clear(); + this.#old.clear(); + } +}; +var genCache = new GenerationalCache(MAX_CACHE); +/** +* shared null object +*/ +var sharedNullObject = new NullObject(); +/** +* set cache +* @param key - cache key +* @param value - value to cache +* @returns void +*/ +var setCache = (key, value) => { + if (!key) return; + if (value === null) genCache.set(key, sharedNullObject); + else if (value instanceof CacheItem) genCache.set(key, value); + else genCache.set(key, new CacheItem(value)); +}; +/** +* get cache +* @param key - cache key +* @returns cached item or false otherwise +*/ +var getCache = (key) => { + if (!key) return false; + const item = genCache.get(key); + if (item !== void 0) return item; + return false; +}; +/** +* helper function to sort object keys alphabetically +* @param obj - Object +* @returns stringified JSON +*/ +var stringifySorted = (obj) => { + const keys = Object.keys(obj); + if (keys.length === 0) return ""; + keys.sort(); + let result = ""; + for (const key of keys) result += `${key}:${JSON.stringify(obj[key])};`; + return result; +}; +/** +* create cache key +* @param keyData - key data +* @param [opt] - options +* @returns cache key +*/ +var createCacheKey = (keyData, opt = {}) => { + if (!keyData || opt.customProperty && typeof opt.customProperty.callback === "function" || opt.dimension && typeof opt.dimension.callback === "function") return ""; + const namespace = keyData.namespace || ""; + const name = keyData.name || ""; + const value = keyData.value || ""; + if (!namespace && !name && !value) return ""; + return `${`${namespace}:${name}:${value}`}::${`${opt.format || ""}|${opt.colorSpace || ""}|${opt.colorScheme || ""}|${opt.currentColor || ""}|${opt.d50 ? "1" : "0"}|${opt.nullable ? "1" : "0"}|${opt.preserveComment ? "1" : "0"}|${opt.delimiter || ""}`}::${opt.customProperty ? stringifySorted(opt.customProperty) : ""}::${opt.dimension ? stringifySorted(opt.dimension) : ""}`; +}; +//#endregion +export { CacheItem, NullObject, createCacheKey, getCache, setCache }; + +//# sourceMappingURL=cache.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.js.map new file mode 100644 index 0000000..9ff16fc --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/cache.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cache.js","names":["#item","#isNull","#current","#old","#max","#boundary"],"sources":["../../../src/js/cache.ts"],"sourcesContent":["/**\n * cache\n */\n\nimport { Options } from './typedef';\n\n/* constants */\nconst MAX_CACHE = 1024;\n\n/**\n * CacheItem\n */\nexport class CacheItem {\n /* private */\n #isNull: boolean;\n #item: unknown;\n\n constructor(item: unknown, isNull: boolean = false) {\n this.#item = item;\n this.#isNull = !!isNull;\n }\n\n get item() {\n return this.#item;\n }\n\n get isNull() {\n return this.#isNull;\n }\n}\n\n/**\n * NullObject\n */\nexport class NullObject extends CacheItem {\n constructor() {\n super(Symbol('null'), true);\n }\n}\n\n/**\n * Generational Cache implementation\n */\nexport class GenerationalCache {\n #max: number;\n #boundary: number;\n #current: Map;\n #old: Map;\n\n constructor(max: number) {\n this.#current = new Map();\n this.#old = new Map();\n if (Number.isFinite(max) && max > 4) {\n this.#max = max;\n this.#boundary = Math.ceil(max / 2);\n } else {\n this.#max = 4;\n this.#boundary = 2;\n }\n }\n\n get size(): number {\n return this.#current.size + this.#old.size;\n }\n\n get max(): number {\n return this.#max;\n }\n\n set max(value: number) {\n if (Number.isFinite(value) && value > 4) {\n this.#max = value;\n this.#boundary = Math.ceil(value / 2);\n } else {\n this.#max = 4;\n this.#boundary = 2;\n }\n this.#current.clear();\n this.#old.clear();\n }\n\n get(key: K): V | undefined {\n let value = this.#current.get(key);\n if (value !== undefined) {\n return value;\n }\n value = this.#old.get(key);\n if (value !== undefined) {\n this.set(key, value);\n return value;\n }\n return undefined;\n }\n\n set(key: K, value: V): void {\n this.#current.set(key, value);\n if (this.#current.size >= this.#boundary) {\n this.#old = this.#current;\n this.#current = new Map();\n }\n }\n\n has(key: K): boolean {\n return this.#current.has(key) || this.#old.has(key);\n }\n\n delete(key: K): void {\n this.#current.delete(key);\n this.#old.delete(key);\n }\n\n clear(): void {\n this.#current.clear();\n this.#old.clear();\n }\n}\n\n/*\n * generational cache instance\n */\nexport const genCache = new GenerationalCache(MAX_CACHE);\n\n/**\n * shared null object\n */\nconst sharedNullObject = new NullObject();\n\n/**\n * set cache\n * @param key - cache key\n * @param value - value to cache\n * @returns void\n */\nexport const setCache = (key: string, value: unknown): void => {\n if (!key) {\n return;\n }\n if (value === null) {\n genCache.set(key, sharedNullObject);\n } else if (value instanceof CacheItem) {\n genCache.set(key, value);\n } else {\n genCache.set(key, new CacheItem(value));\n }\n};\n\n/**\n * get cache\n * @param key - cache key\n * @returns cached item or false otherwise\n */\nexport const getCache = (key: string): CacheItem | false => {\n if (!key) {\n return false;\n }\n const item = genCache.get(key);\n if (item !== undefined) {\n return item as CacheItem;\n }\n return false;\n};\n\n/**\n * helper function to sort object keys alphabetically\n * @param obj - Object\n * @returns stringified JSON\n */\nconst stringifySorted = (obj: Record): string => {\n const keys = Object.keys(obj);\n if (keys.length === 0) {\n return '';\n }\n keys.sort();\n let result = '';\n for (const key of keys) {\n result += `${key}:${JSON.stringify(obj[key])};`;\n }\n return result;\n};\n\n/**\n * create cache key\n * @param keyData - key data\n * @param [opt] - options\n * @returns cache key\n */\nexport const createCacheKey = (\n keyData: Record,\n opt: Options = {}\n): string => {\n if (\n !keyData ||\n (opt.customProperty && typeof opt.customProperty.callback === 'function') ||\n (opt.dimension && typeof opt.dimension.callback === 'function')\n ) {\n return '';\n }\n const namespace = keyData.namespace || '';\n const name = keyData.name || '';\n const value = keyData.value || '';\n if (!namespace && !name && !value) {\n return '';\n }\n const baseKey = `${namespace}:${name}:${value}`;\n const optStr = `${opt.format || ''}|${opt.colorSpace || ''}|${opt.colorScheme || ''}|${opt.currentColor || ''}|${opt.d50 ? '1' : '0'}|${opt.nullable ? '1' : '0'}|${opt.preserveComment ? '1' : '0'}|${opt.delimiter || ''}`;\n const customPropStr = opt.customProperty\n ? stringifySorted(opt.customProperty as Record)\n : '';\n const dimStr = opt.dimension\n ? stringifySorted(opt.dimension as Record)\n : '';\n return `${baseKey}::${optStr}::${customPropStr}::${dimStr}`;\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/color.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/color.d.ts new file mode 100644 index 0000000..9a1a0e2 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/color.d.ts @@ -0,0 +1,537 @@ +import { NullObject } from './cache.js'; +import { ColorChannels, Options, SpecifiedColorChannels } from './typedef.js'; +/** + * @type TriColorChannels - color channels without alpha + */ +type TriColorChannels = [x: number, y: number, z: number]; +/** + * @type ColorMatrix - color matrix + */ +type ColorMatrix = [ + r1: TriColorChannels, + r2: TriColorChannels, + r3: TriColorChannels +]; +/** + * named colors + */ +export declare const NAMED_COLORS: { + readonly aliceblue: [240, 248, 255]; + readonly antiquewhite: [250, 235, 215]; + readonly aqua: [0, 255, 255]; + readonly aquamarine: [127, 255, 212]; + readonly azure: [240, 255, 255]; + readonly beige: [245, 245, 220]; + readonly bisque: [255, 228, 196]; + readonly black: [0, 0, 0]; + readonly blanchedalmond: [255, 235, 205]; + readonly blue: [0, 0, 255]; + readonly blueviolet: [138, 43, 226]; + readonly brown: [165, 42, 42]; + readonly burlywood: [222, 184, 135]; + readonly cadetblue: [95, 158, 160]; + readonly chartreuse: [127, 255, 0]; + readonly chocolate: [210, 105, 30]; + readonly coral: [255, 127, 80]; + readonly cornflowerblue: [100, 149, 237]; + readonly cornsilk: [255, 248, 220]; + readonly crimson: [220, 20, 60]; + readonly cyan: [0, 255, 255]; + readonly darkblue: [0, 0, 139]; + readonly darkcyan: [0, 139, 139]; + readonly darkgoldenrod: [184, 134, 11]; + readonly darkgray: [169, 169, 169]; + readonly darkgreen: [0, 100, 0]; + readonly darkgrey: [169, 169, 169]; + readonly darkkhaki: [189, 183, 107]; + readonly darkmagenta: [139, 0, 139]; + readonly darkolivegreen: [85, 107, 47]; + readonly darkorange: [255, 140, 0]; + readonly darkorchid: [153, 50, 204]; + readonly darkred: [139, 0, 0]; + readonly darksalmon: [233, 150, 122]; + readonly darkseagreen: [143, 188, 143]; + readonly darkslateblue: [72, 61, 139]; + readonly darkslategray: [47, 79, 79]; + readonly darkslategrey: [47, 79, 79]; + readonly darkturquoise: [0, 206, 209]; + readonly darkviolet: [148, 0, 211]; + readonly deeppink: [255, 20, 147]; + readonly deepskyblue: [0, 191, 255]; + readonly dimgray: [105, 105, 105]; + readonly dimgrey: [105, 105, 105]; + readonly dodgerblue: [30, 144, 255]; + readonly firebrick: [178, 34, 34]; + readonly floralwhite: [255, 250, 240]; + readonly forestgreen: [34, 139, 34]; + readonly fuchsia: [255, 0, 255]; + readonly gainsboro: [220, 220, 220]; + readonly ghostwhite: [248, 248, 255]; + readonly gold: [255, 215, 0]; + readonly goldenrod: [218, 165, 32]; + readonly gray: [128, 128, 128]; + readonly green: [0, 128, 0]; + readonly greenyellow: [173, 255, 47]; + readonly grey: [128, 128, 128]; + readonly honeydew: [240, 255, 240]; + readonly hotpink: [255, 105, 180]; + readonly indianred: [205, 92, 92]; + readonly indigo: [75, 0, 130]; + readonly ivory: [255, 255, 240]; + readonly khaki: [240, 230, 140]; + readonly lavender: [230, 230, 250]; + readonly lavenderblush: [255, 240, 245]; + readonly lawngreen: [124, 252, 0]; + readonly lemonchiffon: [255, 250, 205]; + readonly lightblue: [173, 216, 230]; + readonly lightcoral: [240, 128, 128]; + readonly lightcyan: [224, 255, 255]; + readonly lightgoldenrodyellow: [250, 250, 210]; + readonly lightgray: [211, 211, 211]; + readonly lightgreen: [144, 238, 144]; + readonly lightgrey: [211, 211, 211]; + readonly lightpink: [255, 182, 193]; + readonly lightsalmon: [255, 160, 122]; + readonly lightseagreen: [32, 178, 170]; + readonly lightskyblue: [135, 206, 250]; + readonly lightslategray: [119, 136, 153]; + readonly lightslategrey: [119, 136, 153]; + readonly lightsteelblue: [176, 196, 222]; + readonly lightyellow: [255, 255, 224]; + readonly lime: [0, 255, 0]; + readonly limegreen: [50, 205, 50]; + readonly linen: [250, 240, 230]; + readonly magenta: [255, 0, 255]; + readonly maroon: [128, 0, 0]; + readonly mediumaquamarine: [102, 205, 170]; + readonly mediumblue: [0, 0, 205]; + readonly mediumorchid: [186, 85, 211]; + readonly mediumpurple: [147, 112, 219]; + readonly mediumseagreen: [60, 179, 113]; + readonly mediumslateblue: [123, 104, 238]; + readonly mediumspringgreen: [0, 250, 154]; + readonly mediumturquoise: [72, 209, 204]; + readonly mediumvioletred: [199, 21, 133]; + readonly midnightblue: [25, 25, 112]; + readonly mintcream: [245, 255, 250]; + readonly mistyrose: [255, 228, 225]; + readonly moccasin: [255, 228, 181]; + readonly navajowhite: [255, 222, 173]; + readonly navy: [0, 0, 128]; + readonly oldlace: [253, 245, 230]; + readonly olive: [128, 128, 0]; + readonly olivedrab: [107, 142, 35]; + readonly orange: [255, 165, 0]; + readonly orangered: [255, 69, 0]; + readonly orchid: [218, 112, 214]; + readonly palegoldenrod: [238, 232, 170]; + readonly palegreen: [152, 251, 152]; + readonly paleturquoise: [175, 238, 238]; + readonly palevioletred: [219, 112, 147]; + readonly papayawhip: [255, 239, 213]; + readonly peachpuff: [255, 218, 185]; + readonly peru: [205, 133, 63]; + readonly pink: [255, 192, 203]; + readonly plum: [221, 160, 221]; + readonly powderblue: [176, 224, 230]; + readonly purple: [128, 0, 128]; + readonly rebeccapurple: [102, 51, 153]; + readonly red: [255, 0, 0]; + readonly rosybrown: [188, 143, 143]; + readonly royalblue: [65, 105, 225]; + readonly saddlebrown: [139, 69, 19]; + readonly salmon: [250, 128, 114]; + readonly sandybrown: [244, 164, 96]; + readonly seagreen: [46, 139, 87]; + readonly seashell: [255, 245, 238]; + readonly sienna: [160, 82, 45]; + readonly silver: [192, 192, 192]; + readonly skyblue: [135, 206, 235]; + readonly slateblue: [106, 90, 205]; + readonly slategray: [112, 128, 144]; + readonly slategrey: [112, 128, 144]; + readonly snow: [255, 250, 250]; + readonly springgreen: [0, 255, 127]; + readonly steelblue: [70, 130, 180]; + readonly tan: [210, 180, 140]; + readonly teal: [0, 128, 128]; + readonly thistle: [216, 191, 216]; + readonly tomato: [255, 99, 71]; + readonly turquoise: [64, 224, 208]; + readonly violet: [238, 130, 238]; + readonly wheat: [245, 222, 179]; + readonly white: [255, 255, 255]; + readonly whitesmoke: [245, 245, 245]; + readonly yellow: [255, 255, 0]; + readonly yellowgreen: [154, 205, 50]; +}; +/** + * cache invalid color value + * @param key - cache key + * @param nullable - is nullable + * @returns cached value + */ +export declare const cacheInvalidColorValue: (cacheKey: string, format: string, nullable?: boolean) => SpecifiedColorChannels | string | NullObject; +/** + * resolve invalid color value + * @param format - output format + * @param nullable - is nullable + * @returns resolved value + */ +export declare const resolveInvalidColorValue: (format: string, nullable?: boolean) => SpecifiedColorChannels | string | NullObject; +/** + * validate color components + * @param arr - color components + * @param [opt] - options + * @param [opt.alpha] - alpha channel + * @param [opt.minLength] - min length + * @param [opt.maxLength] - max length + * @param [opt.minRange] - min range + * @param [opt.maxRange] - max range + * @param [opt.validateRange] - validate range + * @returns result - validated color components + */ +export declare const validateColorComponents: (arr: ColorChannels | TriColorChannels, opt?: { + alpha?: boolean; + minLength?: number; + maxLength?: number; + minRange?: number; + maxRange?: number; + validateRange?: boolean; +}) => ColorChannels | TriColorChannels; +/** + * transform matrix + * @param mtx - 3 * 3 matrix + * @param vct - vector + * @param [skip] - skip validate + * @returns TriColorChannels - [p1, p2, p3] + */ +export declare const transformMatrix: (mtx: ColorMatrix, vct: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * normalize color components + * @param colorA - color components [v1, v2, v3, v4] + * @param colorB - color components [v1, v2, v3, v4] + * @param [skip] - skip validate + * @returns result - [colorA, colorB] + */ +export declare const normalizeColorComponents: (colorA: [number | string, number | string, number | string, number | string], colorB: [number | string, number | string, number | string, number | string], skip?: boolean) => [ColorChannels, ColorChannels]; +/** + * number to hex string + * @param value - numeric value + * @returns hex string + */ +export declare const numberToHexString: (value: number) => string; +/** + * angle to deg + * @param angle + * @returns deg: 0..360 + */ +export declare const angleToDeg: (angle: string) => number; +/** + * parse alpha + * @param [alpha] - alpha value + * @returns alpha: 0..1 + */ +export declare const parseAlpha: (alpha?: string) => number; +/** + * parse hex alpha + * @param value - alpha value in hex string + * @returns alpha: 0..1 + */ +export declare const parseHexAlpha: (value: string) => number; +/** + * transform rgb to linear rgb + * @param rgb - [r, g, b] r|g|b: 0..255 + * @param [skip] - skip validate + * @returns TriColorChannels - [r, g, b] r|g|b: 0..1 + */ +export declare const transformRgbToLinearRgb: (rgb: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform rgb to xyz + * @param rgb - [r, g, b] r|g|b: 0..255 + * @param [skip] - skip validate + * @returns TriColorChannels - [x, y, z] + */ +export declare const transformRgbToXyz: (rgb: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform rgb to xyz-d50 + * @param rgb - [r, g, b] r|g|b: 0..255 alpha: 0..1 + * @returns TriColorChannels - [x, y, z] + */ +export declare const transformRgbToXyzD50: (rgb: TriColorChannels) => TriColorChannels; +/** + * transform linear rgb to rgb + * @param rgb - [r, g, b] r|g|b: 0..1 + * @param [round] - round result + * @returns TriColorChannels - [r, g, b] r|g|b: 0..255 + */ +export declare const transformLinearRgbToRgb: (rgb: TriColorChannels, round?: boolean) => TriColorChannels; +/** + * transform xyz to rgb + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [r, g, b] r|g|b: 0..255 + */ +export declare const transformXyzToRgb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz to xyz-d50 + * @param xyz - [x, y, z] + * @returns TriColorChannels - [x, y, z] + */ +export declare const transformXyzToXyzD50: (xyz: TriColorChannels) => TriColorChannels; +/** + * transform xyz to hsl + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [h, s, l] + */ +export declare const transformXyzToHsl: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz to hwb + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [h, w, b] + */ +export declare const transformXyzToHwb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz to oklab + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, a, b] + */ +export declare const transformXyzToOklab: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz to oklch + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, c, h] + */ +export declare const transformXyzToOklch: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz D50 to rgb + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [r, g, b] r|g|b: 0..255 + */ +export declare const transformXyzD50ToRgb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz-d50 to lab + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, a, b] + */ +export declare const transformXyzD50ToLab: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * transform xyz-d50 to lch + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, c, h] + */ +export declare const transformXyzD50ToLch: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels; +/** + * convert rgb to hex color + * @param rgb - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 + * @returns hex color + */ +export declare const convertRgbToHex: (rgb: ColorChannels) => string; +/** + * convert linear rgb to hex color + * @param rgb - [r, g, b, alpha] r|g|b|alpha: 0..1 + * @param [skip] - skip validate + * @returns hex color + */ +export declare const convertLinearRgbToHex: (rgb: ColorChannels, skip?: boolean) => string; +/** + * convert xyz to hex color + * @param xyz - [x, y, z, alpha] + * @returns hex color + */ +export declare const convertXyzToHex: (xyz: ColorChannels) => string; +/** + * convert xyz D50 to hex color + * @param xyz - [x, y, z, alpha] + * @returns hex color + */ +export declare const convertXyzD50ToHex: (xyz: ColorChannels) => string; +/** + * convert hex color to rgb + * @param value - hex color value + * @returns ColorChannels - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 + */ +export declare const convertHexToRgb: (value: string) => ColorChannels; +/** + * convert hex color to linear rgb + * @param value - hex color value + * @returns ColorChannels - [r, g, b, alpha] r|g|b|alpha: 0..1 + */ +export declare const convertHexToLinearRgb: (value: string) => ColorChannels; +/** + * convert hex color to xyz + * @param value - hex color value + * @returns ColorChannels - [x, y, z, alpha] + */ +export declare const convertHexToXyz: (value: string) => ColorChannels; +/** + * parse rgb() + * @param value - rgb color value + * @param [opt] - options + * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject + */ +export declare const parseRgb: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse hsl() + * @param value - hsl color value + * @param [opt] - options + * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject + */ +export declare const parseHsl: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse hwb() + * @param value - hwb color value + * @param [opt] - options + * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject + */ +export declare const parseHwb: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse lab() + * @param value - lab color value + * @param [opt] - options + * @returns parsed color + * - [xyz-d50, x, y, z, alpha], ['lab', l, a, b, alpha], '(empty)', NullObject + */ +export declare const parseLab: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse lch() + * @param value - lch color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-d50', x, y, z, alpha], ['lch', l, c, h, alpha] + * - '(empty)', NullObject + */ +export declare const parseLch: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse oklab() + * @param value - oklab color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-d65', x, y, z, alpha], ['oklab', l, a, b, alpha] + * - '(empty)', NullObject + */ +export declare const parseOklab: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse oklch() + * @param value - oklch color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-d65', x, y, z, alpha], ['oklch', l, c, h, alpha] + * - '(empty)', NullObject + */ +export declare const parseOklch: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse color() + * @param value - color function value + * @param [opt] - options + * @returns parsed color + * - ['xyz-(d50|d65)', x, y, z, alpha], [cs, r, g, b, alpha] + * - '(empty)', NullObject + */ +export declare const parseColorFunc: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * parse color value + * @param value - CSS color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-(d50|d65)', x, y, z, alpha], ['rgb', r, g, b, alpha] + * - value, '(empty)', NullObject + */ +export declare const parseColorValue: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * resolve color value + * @param value - CSS color value + * @param [opt] - options + * @returns resolved color + * - [cs, v1, v2, v3, alpha], value, '(empty)', NullObject + */ +export declare const resolveColorValue: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * resolve color() + * @param value - color function value + * @param [opt] - options + * @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', NullObject + */ +export declare const resolveColorFunc: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +/** + * convert color value to linear rgb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [r, g, b, alpha] r|g|b|alpha: 0..1 + */ +export declare const convertColorToLinearRgb: (value: string, opt?: { + colorSpace?: string; + format?: string; +}) => ColorChannels | NullObject; +/** + * convert color value to rgb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject + * - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 + */ +export declare const convertColorToRgb: (value: string, opt?: Options) => ColorChannels | NullObject; +/** + * convert color value to xyz + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [x, y, z, alpha] + */ +export declare const convertColorToXyz: (value: string, opt?: Options) => ColorChannels | NullObject; +/** + * convert color value to hsl + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [h, s, l, alpha], hue may be powerless + */ +export declare const convertColorToHsl: (value: string, opt?: Options) => ColorChannels | [number | string, number, number, number] | NullObject; +/** + * convert color value to hwb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [h, w, b, alpha], hue may be powerless + */ +export declare const convertColorToHwb: (value: string, opt?: Options) => ColorChannels | [number | string, number, number, number] | NullObject; +/** + * convert color value to lab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, a, b, alpha] + */ +export declare const convertColorToLab: (value: string, opt?: Options) => ColorChannels | NullObject; +/** + * convert color value to lch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless + */ +export declare const convertColorToLch: (value: string, opt?: Options) => ColorChannels | [number, number, number | string, number] | NullObject; +/** + * convert color value to oklab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, a, b, alpha] + */ +export declare const convertColorToOklab: (value: string, opt?: Options) => ColorChannels | NullObject; +/** + * convert color value to oklch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless + */ +export declare const convertColorToOklch: (value: string, opt?: Options) => ColorChannels | [number, number, number | string, number] | NullObject; +/** + * resolve color-mix() + * @param value - color-mix color value + * @param [opt] - options + * @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)' + */ +export declare const resolveColorMix: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject; +export {}; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/color.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/color.js new file mode 100644 index 0000000..14e882d --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/color.js @@ -0,0 +1,3534 @@ +import { CacheItem, NullObject, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString } from "./common.js"; +import { ANGLE, CS_HUE_CAPT, CS_MIX, CS_RGB, CS_XYZ, FN_MIX, NONE, NUM, PCT, SYN_COLOR_TYPE, SYN_FN_COLOR, SYN_HSL, SYN_HSL_LV3, SYN_LCH, SYN_MIX, SYN_MIX_CAPT, SYN_MIX_PART, SYN_MOD, SYN_RGB_LV3, VAL_COMP, VAL_MIX, VAL_SPEC } from "./constant.js"; +import { resolveColor } from "./resolve.js"; +import { interpolateHue, roundToPrecision, splitValue } from "./util.js"; +//#region src/js/color.ts +/** +* color +* +* Ref: CSS Color Module Level 4 +* Sample code for Color Conversions +* https://w3c.github.io/csswg-drafts/css-color-4/#color-conversion-code +*/ +var NAMESPACE = "color"; +var PPTH = .001; +var HALF = .5; +var DUO = 2; +var TRIA = 3; +var QUAD = 4; +var OCT = 8; +var DEC = 10; +var DOZ = 12; +var HEX = 16; +var SEXA = 60; +var DEG_HALF = 180; +var DEG = 360; +var MAX_PCT = 100; +var MAX_RGB = 255; +var POW_SQR = 2; +var POW_CUBE = 3; +var POW_LINEAR = 2.4; +var LINEAR_COEF = 12.92; +var LINEAR_OFFSET = .055; +var LAB_L = 116; +var LAB_A = 500; +var LAB_B = 200; +var LAB_EPSILON = 216 / 24389; +var LAB_KAPPA = 24389 / 27; +var D50 = [ + .3457 / .3585, + 1, + .2958 / .3585 +]; +var MATRIX_D50_TO_D65 = [ + [ + .955473421488075, + -.02309845494876471, + .06325924320057072 + ], + [ + -.0283697093338637, + 1.0099953980813041, + .021041441191917323 + ], + [ + .012314014864481998, + -.020507649298898964, + 1.330365926242124 + ] +]; +var MATRIX_D65_TO_D50 = [ + [ + 1.0479297925449969, + .022946870601609652, + -.05019226628920524 + ], + [ + .02962780877005599, + .9904344267538799, + -.017073799063418826 + ], + [ + -.009243040646204504, + .015055191490298152, + .7518742814281371 + ] +]; +var MATRIX_L_RGB_TO_XYZ = [ + [ + 506752 / 1228815, + 87881 / 245763, + 12673 / 70218 + ], + [ + 87098 / 409605, + 175762 / 245763, + 12673 / 175545 + ], + [ + 7918 / 409605, + 87881 / 737289, + 1001167 / 1053270 + ] +]; +var MATRIX_XYZ_TO_L_RGB = [ + [ + 12831 / 3959, + -329 / 214, + -1974 / 3959 + ], + [ + -851781 / 878810, + 1648619 / 878810, + 36519 / 878810 + ], + [ + 705 / 12673, + -2585 / 12673, + 705 / 667 + ] +]; +var MATRIX_XYZ_TO_LMS = [ + [ + .819022437996703, + .3619062600528904, + -.1288737815209879 + ], + [ + .0329836539323885, + .9292868615863434, + .0361446663506424 + ], + [ + .0481771893596242, + .2642395317527308, + .6335478284694309 + ] +]; +var MATRIX_LMS_TO_XYZ = [ + [ + 1.2268798758459243, + -.5578149944602171, + .2813910456659647 + ], + [ + -.0405757452148008, + 1.112286803280317, + -.0717110580655164 + ], + [ + -.0763729366746601, + -.4214933324022432, + 1.5869240198367816 + ] +]; +var MATRIX_OKLAB_TO_LMS = [ + [ + 1, + .3963377773761749, + .2158037573099136 + ], + [ + 1, + -.1055613458156586, + -.0638541728258133 + ], + [ + 1, + -.0894841775298119, + -1.2914855480194092 + ] +]; +var MATRIX_LMS_TO_OKLAB = [ + [ + .210454268309314, + .7936177747023054, + -.0040720430116193 + ], + [ + 1.9779985324311684, + -2.42859224204858, + .450593709617411 + ], + [ + .0259040424655478, + .7827717124575296, + -.8086757549230774 + ] +]; +var MATRIX_P3_TO_XYZ = [ + [ + 608311 / 1250200, + 189793 / 714400, + 198249 / 1000160 + ], + [ + 35783 / 156275, + 247089 / 357200, + 198249 / 2500400 + ], + [ + 0 / 1, + 32229 / 714400, + 5220557 / 5000800 + ] +]; +var MATRIX_REC2020_TO_XYZ = [ + [ + 63426534 / 99577255, + 20160776 / 139408157, + 47086771 / 278816314 + ], + [ + 26158966 / 99577255, + 472592308 / 697040785, + 8267143 / 139408157 + ], + [ + 0 / 1, + 19567812 / 697040785, + 295819943 / 278816314 + ] +]; +var MATRIX_A98_TO_XYZ = [ + [ + 573536 / 994567, + 263643 / 1420810, + 187206 / 994567 + ], + [ + 591459 / 1989134, + 6239551 / 9945670, + 374412 / 4972835 + ], + [ + 53769 / 1989134, + 351524 / 4972835, + 4929758 / 4972835 + ] +]; +var MATRIX_PROPHOTO_TO_XYZ_D50 = [ + [ + .7977666449006423, + .13518129740053308, + .0313477341283922 + ], + [ + .2880748288194013, + .711835234241873, + 8993693872564e-17 + ], + [ + 0, + 0, + .8251046025104602 + ] +]; +var REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`); +var REG_CS_HUE = new RegExp(`^${CS_HUE_CAPT}$`); +var REG_CS_XYZ = /^xyz(?:-d(?:50|65))?$/; +var REG_CURRENT = /^currentColor$/i; +var REG_FN_COLOR = new RegExp(`^color\\(\\s*(${SYN_FN_COLOR})\\s*\\)$`); +var REG_HSL = new RegExp(`^hsla?\\(\\s*(${SYN_HSL}|${SYN_HSL_LV3})\\s*\\)$`); +var REG_HWB = new RegExp(`^hwb\\(\\s*(${SYN_HSL})\\s*\\)$`); +var REG_LAB = new RegExp(`^lab\\(\\s*(${SYN_MOD})\\s*\\)$`); +var REG_LCH = new RegExp(`^lch\\(\\s*(${SYN_LCH})\\s*\\)$`); +var REG_MIX = new RegExp(`^${SYN_MIX}$`); +var REG_MIX_CAPT = new RegExp(`^${SYN_MIX_CAPT}$`); +var REG_MIX_NEST = new RegExp(`${SYN_MIX}`, "g"); +var REG_OKLAB = new RegExp(`^oklab\\(\\s*(${SYN_MOD})\\s*\\)$`); +var REG_OKLCH = new RegExp(`^oklch\\(\\s*(${SYN_LCH})\\s*\\)$`); +var REG_SPEC = /^(?:specifi|comput)edValue$/; +var REG_ANGLE_TO_DEG = new RegExp(`^(${NUM})(${ANGLE})?$`); +var REG_PARSE_RGB = new RegExp(`^rgba?\\(\\s*(${SYN_MOD}|${SYN_RGB_LV3})\\s*\\)$`); +var REG_MIX_CS_RGB_XYZ = new RegExp(`^(?:${CS_RGB}|${CS_XYZ})$`); +var REG_MIX_IN_CS = new RegExp(`in\\s+(${CS_MIX})`); +var REG_MIX_START = new RegExp(`^color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,`); +var REG_MIX_COLOR_PART = new RegExp(`^(${SYN_COLOR_TYPE})(?:\\s+(${PCT}))?$`); +/** +* named colors +*/ +var NAMED_COLORS = { + aliceblue: [ + 240, + 248, + 255 + ], + antiquewhite: [ + 250, + 235, + 215 + ], + aqua: [ + 0, + 255, + 255 + ], + aquamarine: [ + 127, + 255, + 212 + ], + azure: [ + 240, + 255, + 255 + ], + beige: [ + 245, + 245, + 220 + ], + bisque: [ + 255, + 228, + 196 + ], + black: [ + 0, + 0, + 0 + ], + blanchedalmond: [ + 255, + 235, + 205 + ], + blue: [ + 0, + 0, + 255 + ], + blueviolet: [ + 138, + 43, + 226 + ], + brown: [ + 165, + 42, + 42 + ], + burlywood: [ + 222, + 184, + 135 + ], + cadetblue: [ + 95, + 158, + 160 + ], + chartreuse: [ + 127, + 255, + 0 + ], + chocolate: [ + 210, + 105, + 30 + ], + coral: [ + 255, + 127, + 80 + ], + cornflowerblue: [ + 100, + 149, + 237 + ], + cornsilk: [ + 255, + 248, + 220 + ], + crimson: [ + 220, + 20, + 60 + ], + cyan: [ + 0, + 255, + 255 + ], + darkblue: [ + 0, + 0, + 139 + ], + darkcyan: [ + 0, + 139, + 139 + ], + darkgoldenrod: [ + 184, + 134, + 11 + ], + darkgray: [ + 169, + 169, + 169 + ], + darkgreen: [ + 0, + 100, + 0 + ], + darkgrey: [ + 169, + 169, + 169 + ], + darkkhaki: [ + 189, + 183, + 107 + ], + darkmagenta: [ + 139, + 0, + 139 + ], + darkolivegreen: [ + 85, + 107, + 47 + ], + darkorange: [ + 255, + 140, + 0 + ], + darkorchid: [ + 153, + 50, + 204 + ], + darkred: [ + 139, + 0, + 0 + ], + darksalmon: [ + 233, + 150, + 122 + ], + darkseagreen: [ + 143, + 188, + 143 + ], + darkslateblue: [ + 72, + 61, + 139 + ], + darkslategray: [ + 47, + 79, + 79 + ], + darkslategrey: [ + 47, + 79, + 79 + ], + darkturquoise: [ + 0, + 206, + 209 + ], + darkviolet: [ + 148, + 0, + 211 + ], + deeppink: [ + 255, + 20, + 147 + ], + deepskyblue: [ + 0, + 191, + 255 + ], + dimgray: [ + 105, + 105, + 105 + ], + dimgrey: [ + 105, + 105, + 105 + ], + dodgerblue: [ + 30, + 144, + 255 + ], + firebrick: [ + 178, + 34, + 34 + ], + floralwhite: [ + 255, + 250, + 240 + ], + forestgreen: [ + 34, + 139, + 34 + ], + fuchsia: [ + 255, + 0, + 255 + ], + gainsboro: [ + 220, + 220, + 220 + ], + ghostwhite: [ + 248, + 248, + 255 + ], + gold: [ + 255, + 215, + 0 + ], + goldenrod: [ + 218, + 165, + 32 + ], + gray: [ + 128, + 128, + 128 + ], + green: [ + 0, + 128, + 0 + ], + greenyellow: [ + 173, + 255, + 47 + ], + grey: [ + 128, + 128, + 128 + ], + honeydew: [ + 240, + 255, + 240 + ], + hotpink: [ + 255, + 105, + 180 + ], + indianred: [ + 205, + 92, + 92 + ], + indigo: [ + 75, + 0, + 130 + ], + ivory: [ + 255, + 255, + 240 + ], + khaki: [ + 240, + 230, + 140 + ], + lavender: [ + 230, + 230, + 250 + ], + lavenderblush: [ + 255, + 240, + 245 + ], + lawngreen: [ + 124, + 252, + 0 + ], + lemonchiffon: [ + 255, + 250, + 205 + ], + lightblue: [ + 173, + 216, + 230 + ], + lightcoral: [ + 240, + 128, + 128 + ], + lightcyan: [ + 224, + 255, + 255 + ], + lightgoldenrodyellow: [ + 250, + 250, + 210 + ], + lightgray: [ + 211, + 211, + 211 + ], + lightgreen: [ + 144, + 238, + 144 + ], + lightgrey: [ + 211, + 211, + 211 + ], + lightpink: [ + 255, + 182, + 193 + ], + lightsalmon: [ + 255, + 160, + 122 + ], + lightseagreen: [ + 32, + 178, + 170 + ], + lightskyblue: [ + 135, + 206, + 250 + ], + lightslategray: [ + 119, + 136, + 153 + ], + lightslategrey: [ + 119, + 136, + 153 + ], + lightsteelblue: [ + 176, + 196, + 222 + ], + lightyellow: [ + 255, + 255, + 224 + ], + lime: [ + 0, + 255, + 0 + ], + limegreen: [ + 50, + 205, + 50 + ], + linen: [ + 250, + 240, + 230 + ], + magenta: [ + 255, + 0, + 255 + ], + maroon: [ + 128, + 0, + 0 + ], + mediumaquamarine: [ + 102, + 205, + 170 + ], + mediumblue: [ + 0, + 0, + 205 + ], + mediumorchid: [ + 186, + 85, + 211 + ], + mediumpurple: [ + 147, + 112, + 219 + ], + mediumseagreen: [ + 60, + 179, + 113 + ], + mediumslateblue: [ + 123, + 104, + 238 + ], + mediumspringgreen: [ + 0, + 250, + 154 + ], + mediumturquoise: [ + 72, + 209, + 204 + ], + mediumvioletred: [ + 199, + 21, + 133 + ], + midnightblue: [ + 25, + 25, + 112 + ], + mintcream: [ + 245, + 255, + 250 + ], + mistyrose: [ + 255, + 228, + 225 + ], + moccasin: [ + 255, + 228, + 181 + ], + navajowhite: [ + 255, + 222, + 173 + ], + navy: [ + 0, + 0, + 128 + ], + oldlace: [ + 253, + 245, + 230 + ], + olive: [ + 128, + 128, + 0 + ], + olivedrab: [ + 107, + 142, + 35 + ], + orange: [ + 255, + 165, + 0 + ], + orangered: [ + 255, + 69, + 0 + ], + orchid: [ + 218, + 112, + 214 + ], + palegoldenrod: [ + 238, + 232, + 170 + ], + palegreen: [ + 152, + 251, + 152 + ], + paleturquoise: [ + 175, + 238, + 238 + ], + palevioletred: [ + 219, + 112, + 147 + ], + papayawhip: [ + 255, + 239, + 213 + ], + peachpuff: [ + 255, + 218, + 185 + ], + peru: [ + 205, + 133, + 63 + ], + pink: [ + 255, + 192, + 203 + ], + plum: [ + 221, + 160, + 221 + ], + powderblue: [ + 176, + 224, + 230 + ], + purple: [ + 128, + 0, + 128 + ], + rebeccapurple: [ + 102, + 51, + 153 + ], + red: [ + 255, + 0, + 0 + ], + rosybrown: [ + 188, + 143, + 143 + ], + royalblue: [ + 65, + 105, + 225 + ], + saddlebrown: [ + 139, + 69, + 19 + ], + salmon: [ + 250, + 128, + 114 + ], + sandybrown: [ + 244, + 164, + 96 + ], + seagreen: [ + 46, + 139, + 87 + ], + seashell: [ + 255, + 245, + 238 + ], + sienna: [ + 160, + 82, + 45 + ], + silver: [ + 192, + 192, + 192 + ], + skyblue: [ + 135, + 206, + 235 + ], + slateblue: [ + 106, + 90, + 205 + ], + slategray: [ + 112, + 128, + 144 + ], + slategrey: [ + 112, + 128, + 144 + ], + snow: [ + 255, + 250, + 250 + ], + springgreen: [ + 0, + 255, + 127 + ], + steelblue: [ + 70, + 130, + 180 + ], + tan: [ + 210, + 180, + 140 + ], + teal: [ + 0, + 128, + 128 + ], + thistle: [ + 216, + 191, + 216 + ], + tomato: [ + 255, + 99, + 71 + ], + turquoise: [ + 64, + 224, + 208 + ], + violet: [ + 238, + 130, + 238 + ], + wheat: [ + 245, + 222, + 179 + ], + white: [ + 255, + 255, + 255 + ], + whitesmoke: [ + 245, + 245, + 245 + ], + yellow: [ + 255, + 255, + 0 + ], + yellowgreen: [ + 154, + 205, + 50 + ] +}; +/** +* cache invalid color value +* @param key - cache key +* @param nullable - is nullable +* @returns cached value +*/ +var cacheInvalidColorValue = (cacheKey, format, nullable = false) => { + if (format === "specifiedValue") { + const res = ""; + setCache(cacheKey, res); + return res; + } + if (nullable) { + setCache(cacheKey, null); + return new NullObject(); + } + const res = [ + "rgb", + 0, + 0, + 0, + 0 + ]; + setCache(cacheKey, res); + return res; +}; +/** +* resolve invalid color value +* @param format - output format +* @param nullable - is nullable +* @returns resolved value +*/ +var resolveInvalidColorValue = (format, nullable = false) => { + switch (format) { + case "hsl": + case "hwb": + case VAL_MIX: return new NullObject(); + case VAL_SPEC: return ""; + default: + if (nullable) return new NullObject(); + return [ + "rgb", + 0, + 0, + 0, + 0 + ]; + } +}; +/** +* validate color components +* @param arr - color components +* @param [opt] - options +* @param [opt.alpha] - alpha channel +* @param [opt.minLength] - min length +* @param [opt.maxLength] - max length +* @param [opt.minRange] - min range +* @param [opt.maxRange] - max range +* @param [opt.validateRange] - validate range +* @returns result - validated color components +*/ +var validateColorComponents = (arr, opt = {}) => { + if (!Array.isArray(arr)) throw new TypeError(`${arr} is not an array.`); + const { alpha = false, minLength = TRIA, maxLength = QUAD, minRange = 0, maxRange = 1, validateRange = true } = opt; + if (!Number.isFinite(minLength)) throw new TypeError(`${minLength} is not a number.`); + if (!Number.isFinite(maxLength)) throw new TypeError(`${maxLength} is not a number.`); + if (!Number.isFinite(minRange)) throw new TypeError(`${minRange} is not a number.`); + if (!Number.isFinite(maxRange)) throw new TypeError(`${maxRange} is not a number.`); + const l = arr.length; + if (l < minLength || l > maxLength) throw new Error(`Unexpected array length ${l}.`); + let i = 0; + while (i < l) { + const v = arr[i]; + if (!Number.isFinite(v)) throw new TypeError(`${v} is not a number.`); + else if (i < TRIA && validateRange && (v < minRange || v > maxRange)) throw new RangeError(`${v} is not between ${minRange} and ${maxRange}.`); + else if (i === TRIA && (v < 0 || v > 1)) throw new RangeError(`${v} is not between 0 and 1.`); + i++; + } + if (alpha && l === TRIA) arr.push(1); + return arr; +}; +/** +* transform matrix +* @param mtx - 3 * 3 matrix +* @param vct - vector +* @param [skip] - skip validate +* @returns TriColorChannels - [p1, p2, p3] +*/ +var transformMatrix = (mtx, vct, skip = false) => { + if (!Array.isArray(mtx)) throw new TypeError(`${mtx} is not an array.`); + else if (mtx.length !== TRIA) throw new Error(`Unexpected array length ${mtx.length}.`); + else if (!skip) for (let i of mtx) i = validateColorComponents(i, { + maxLength: TRIA, + validateRange: false + }); + const [[r1c1, r1c2, r1c3], [r2c1, r2c2, r2c3], [r3c1, r3c2, r3c3]] = mtx; + let v1, v2, v3; + if (skip) [v1, v2, v3] = vct; + else [v1, v2, v3] = validateColorComponents(vct, { + maxLength: TRIA, + validateRange: false + }); + return [ + r1c1 * v1 + r1c2 * v2 + r1c3 * v3, + r2c1 * v1 + r2c2 * v2 + r2c3 * v3, + r3c1 * v1 + r3c2 * v2 + r3c3 * v3 + ]; +}; +/** +* normalize color components +* @param colorA - color components [v1, v2, v3, v4] +* @param colorB - color components [v1, v2, v3, v4] +* @param [skip] - skip validate +* @returns result - [colorA, colorB] +*/ +var normalizeColorComponents = (colorA, colorB, skip = false) => { + if (!Array.isArray(colorA)) throw new TypeError(`${colorA} is not an array.`); + else if (colorA.length !== QUAD) throw new Error(`Unexpected array length ${colorA.length}.`); + if (!Array.isArray(colorB)) throw new TypeError(`${colorB} is not an array.`); + else if (colorB.length !== QUAD) throw new Error(`Unexpected array length ${colorB.length}.`); + let i = 0; + while (i < QUAD) { + if (colorA[i] === "none" && colorB[i] === "none") { + colorA[i] = 0; + colorB[i] = 0; + } else if (colorA[i] === "none") colorA[i] = colorB[i]; + else if (colorB[i] === "none") colorB[i] = colorA[i]; + i++; + } + if (skip) return [colorA, colorB]; + return [validateColorComponents(colorA, { + minLength: QUAD, + validateRange: false + }), validateColorComponents(colorB, { + minLength: QUAD, + validateRange: false + })]; +}; +/** +* number to hex string +* @param value - numeric value +* @returns hex string +*/ +var numberToHexString = (value) => { + if (!Number.isFinite(value)) throw new TypeError(`${value} is not a number.`); + else { + value = Math.round(value); + if (value < 0 || value > MAX_RGB) throw new RangeError(`${value} is not between 0 and ${MAX_RGB}.`); + } + let hex = value.toString(HEX); + if (hex.length === 1) hex = `0${hex}`; + return hex; +}; +/** +* angle to deg +* @param angle +* @returns deg: 0..360 +*/ +var angleToDeg = (angle) => { + if (isString(angle)) angle = angle.trim(); + else throw new TypeError(`${angle} is not a string.`); + const GRAD = DEG / 400; + const RAD = DEG / (Math.PI * DUO); + if (!REG_ANGLE_TO_DEG.test(angle)) throw new SyntaxError(`Invalid property value: ${angle}`); + const [, value, unit] = angle.match(REG_ANGLE_TO_DEG); + let deg; + switch (unit) { + case "grad": + deg = parseFloat(value) * GRAD; + break; + case "rad": + deg = parseFloat(value) * RAD; + break; + case "turn": + deg = parseFloat(value) * DEG; + break; + default: deg = parseFloat(value); + } + deg %= DEG; + if (deg < 0) deg += DEG; + else if (Object.is(deg, -0)) deg = 0; + return deg; +}; +/** +* parse alpha +* @param [alpha] - alpha value +* @returns alpha: 0..1 +*/ +var parseAlpha = (alpha = "") => { + if (isString(alpha)) { + alpha = alpha.trim(); + if (!alpha) alpha = "1"; + else if (alpha === "none") alpha = "0"; + else { + let a; + if (alpha.endsWith("%")) a = parseFloat(alpha) / MAX_PCT; + else a = parseFloat(alpha); + if (!Number.isFinite(a)) throw new TypeError(`${a} is not a finite number.`); + if (a < PPTH) alpha = "0"; + else if (a > 1) alpha = "1"; + else alpha = a.toFixed(TRIA); + } + } else alpha = "1"; + return parseFloat(alpha); +}; +/** +* parse hex alpha +* @param value - alpha value in hex string +* @returns alpha: 0..1 +*/ +var parseHexAlpha = (value) => { + if (isString(value)) { + if (value === "") throw new SyntaxError("Invalid property value: (empty string)"); + value = value.trim(); + } else throw new TypeError(`${value} is not a string.`); + let alpha = parseInt(value, HEX); + if (alpha <= 0) return 0; + if (alpha >= MAX_RGB) return 1; + const alphaMap = /* @__PURE__ */ new Map(); + for (let i = 1; i < MAX_PCT; i++) alphaMap.set(Math.round(i * MAX_RGB / MAX_PCT), i); + if (alphaMap.has(alpha)) alpha = alphaMap.get(alpha) / MAX_PCT; + else alpha = Math.round(alpha / MAX_RGB / PPTH) * PPTH; + return parseFloat(alpha.toFixed(TRIA)); +}; +/** +* transform rgb to linear rgb +* @param rgb - [r, g, b] r|g|b: 0..255 +* @param [skip] - skip validate +* @returns TriColorChannels - [r, g, b] r|g|b: 0..1 +*/ +var transformRgbToLinearRgb = (rgb, skip = false) => { + let rr, gg, bb; + if (skip) [rr, gg, bb] = rgb; + else [rr, gg, bb] = validateColorComponents(rgb, { + maxLength: TRIA, + maxRange: MAX_RGB + }); + let r = rr / MAX_RGB; + let g = gg / MAX_RGB; + let b = bb / MAX_RGB; + const COND_POW = .04045; + if (r > COND_POW) r = Math.pow((r + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR); + else r /= LINEAR_COEF; + if (g > COND_POW) g = Math.pow((g + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR); + else g /= LINEAR_COEF; + if (b > COND_POW) b = Math.pow((b + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR); + else b /= LINEAR_COEF; + return [ + r, + g, + b + ]; +}; +/** +* transform rgb to xyz +* @param rgb - [r, g, b] r|g|b: 0..255 +* @param [skip] - skip validate +* @returns TriColorChannels - [x, y, z] +*/ +var transformRgbToXyz = (rgb, skip = false) => { + if (!skip) rgb = validateColorComponents(rgb, { + maxLength: TRIA, + maxRange: MAX_RGB + }); + rgb = transformRgbToLinearRgb(rgb, true); + return transformMatrix(MATRIX_L_RGB_TO_XYZ, rgb, true); +}; +/** +* transform linear rgb to rgb +* @param rgb - [r, g, b] r|g|b: 0..1 +* @param [round] - round result +* @returns TriColorChannels - [r, g, b] r|g|b: 0..255 +*/ +var transformLinearRgbToRgb = (rgb, round = false) => { + let [r, g, b] = validateColorComponents(rgb, { maxLength: TRIA }); + const COND_POW = 809 / 258400; + if (r > COND_POW) r = Math.pow(r, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET; + else r *= LINEAR_COEF; + r *= MAX_RGB; + if (g > COND_POW) g = Math.pow(g, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET; + else g *= LINEAR_COEF; + g *= MAX_RGB; + if (b > COND_POW) b = Math.pow(b, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET; + else b *= LINEAR_COEF; + b *= MAX_RGB; + return [ + round ? Math.round(r) : r, + round ? Math.round(g) : g, + round ? Math.round(b) : b + ]; +}; +/** +* transform xyz to rgb +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [r, g, b] r|g|b: 0..255 +*/ +var transformXyzToRgb = (xyz, skip = false) => { + if (!skip) xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }); + let [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, xyz, true); + [r, g, b] = transformLinearRgbToRgb([ + Math.min(Math.max(r, 0), 1), + Math.min(Math.max(g, 0), 1), + Math.min(Math.max(b, 0), 1) + ], true); + return [ + r, + g, + b + ]; +}; +/** +* transform xyz to hsl +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [h, s, l] +*/ +var transformXyzToHsl = (xyz, skip = false) => { + const [rr, gg, bb] = transformXyzToRgb(xyz, skip); + const r = rr / MAX_RGB; + const g = gg / MAX_RGB; + const b = bb / MAX_RGB; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const d = max - min; + const l = (max + min) * HALF * MAX_PCT; + let h, s; + if (Math.round(l) === 0 || Math.round(l) === MAX_PCT) { + h = 0; + s = 0; + } else { + s = d / (1 - Math.abs(max + min - 1)) * MAX_PCT; + if (s === 0) h = 0; + else { + switch (max) { + case r: + h = (g - b) / d; + break; + case g: + h = (b - r) / d + DUO; + break; + case b: + default: + h = (r - g) / d + QUAD; + break; + } + h = h * SEXA % DEG; + if (h < 0) h += DEG; + } + } + return [ + h, + s, + l + ]; +}; +/** +* transform xyz to hwb +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [h, w, b] +*/ +var transformXyzToHwb = (xyz, skip = false) => { + const [r, g, b] = transformXyzToRgb(xyz, skip); + const wh = Math.min(r, g, b) / MAX_RGB; + const bk = 1 - Math.max(r, g, b) / MAX_RGB; + let h; + if (wh + bk === 1) h = 0; + else [h] = transformXyzToHsl(xyz); + return [ + h, + wh * MAX_PCT, + bk * MAX_PCT + ]; +}; +/** +* transform xyz to oklab +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [l, a, b] +*/ +var transformXyzToOklab = (xyz, skip = false) => { + if (!skip) xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }); + let [l, a, b] = transformMatrix(MATRIX_LMS_TO_OKLAB, transformMatrix(MATRIX_XYZ_TO_LMS, xyz, true).map((c) => Math.cbrt(c)), true); + l = Math.min(Math.max(l, 0), 1); + const lPct = Math.round(parseFloat(l.toFixed(QUAD)) * MAX_PCT); + if (lPct === 0 || lPct === MAX_PCT) { + a = 0; + b = 0; + } + return [ + l, + a, + b + ]; +}; +/** +* transform xyz to oklch +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [l, c, h] +*/ +var transformXyzToOklch = (xyz, skip = false) => { + const [l, a, b] = transformXyzToOklab(xyz, skip); + let c, h; + const lPct = Math.round(parseFloat(l.toFixed(QUAD)) * MAX_PCT); + if (lPct === 0 || lPct === MAX_PCT) { + c = 0; + h = 0; + } else { + c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0); + if (parseFloat(c.toFixed(QUAD)) === 0) h = 0; + else { + h = Math.atan2(b, a) * DEG_HALF / Math.PI; + if (h < 0) h += DEG; + } + } + return [ + l, + c, + h + ]; +}; +/** +* transform xyz D50 to rgb +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [r, g, b] r|g|b: 0..255 +*/ +var transformXyzD50ToRgb = (xyz, skip = false) => { + if (!skip) xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }); + return transformXyzToRgb(transformMatrix(MATRIX_D50_TO_D65, xyz, true), true); +}; +/** +* transform xyz-d50 to lab +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [l, a, b] +*/ +var transformXyzD50ToLab = (xyz, skip = false) => { + if (!skip) xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }); + const [f0, f1, f2] = xyz.map((val, i) => val / D50[i]).map((val) => val > LAB_EPSILON ? Math.cbrt(val) : (val * LAB_KAPPA + HEX) / LAB_L); + const l = Math.min(Math.max(LAB_L * f1 - HEX, 0), MAX_PCT); + let a, b; + if (l === 0 || l === MAX_PCT) { + a = 0; + b = 0; + } else { + a = (f0 - f1) * LAB_A; + b = (f1 - f2) * LAB_B; + } + return [ + l, + a, + b + ]; +}; +/** +* transform xyz-d50 to lch +* @param xyz - [x, y, z] +* @param [skip] - skip validate +* @returns TriColorChannels - [l, c, h] +*/ +var transformXyzD50ToLch = (xyz, skip = false) => { + const [l, a, b] = transformXyzD50ToLab(xyz, skip); + let c, h; + if (l === 0 || l === MAX_PCT) { + c = 0; + h = 0; + } else { + c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0); + h = Math.atan2(b, a) * DEG_HALF / Math.PI; + if (h < 0) h += DEG; + } + return [ + l, + c, + h + ]; +}; +/** +* convert rgb to hex color +* @param rgb - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 +* @returns hex color +*/ +var convertRgbToHex = (rgb) => { + const [r, g, b, alpha] = validateColorComponents(rgb, { + alpha: true, + maxRange: MAX_RGB + }); + const rr = numberToHexString(r); + const gg = numberToHexString(g); + const bb = numberToHexString(b); + const aa = numberToHexString(alpha * MAX_RGB); + let hex; + if (aa === "ff") hex = `#${rr}${gg}${bb}`; + else hex = `#${rr}${gg}${bb}${aa}`; + return hex; +}; +/** +* convert hex color to rgb +* @param value - hex color value +* @returns ColorChannels - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 +*/ +var convertHexToRgb = (value) => { + if (isString(value)) value = value.toLowerCase().trim(); + else throw new TypeError(`${value} is not a string.`); + if (!(/^#[\da-f]{6}$/.test(value) || /^#[\da-f]{3}$/.test(value) || /^#[\da-f]{8}$/.test(value) || /^#[\da-f]{4}$/.test(value))) throw new SyntaxError(`Invalid property value: ${value}`); + const arr = []; + if (/^#[\da-f]{3}$/.test(value)) { + const [, r, g, b] = value.match(/^#([\da-f])([\da-f])([\da-f])$/); + arr.push(parseInt(`${r}${r}`, HEX), parseInt(`${g}${g}`, HEX), parseInt(`${b}${b}`, HEX), 1); + } else if (/^#[\da-f]{4}$/.test(value)) { + const [, r, g, b, alpha] = value.match(/^#([\da-f])([\da-f])([\da-f])([\da-f])$/); + arr.push(parseInt(`${r}${r}`, HEX), parseInt(`${g}${g}`, HEX), parseInt(`${b}${b}`, HEX), parseHexAlpha(`${alpha}${alpha}`)); + } else if (/^#[\da-f]{8}$/.test(value)) { + const [, r, g, b, alpha] = value.match(/^#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})$/); + arr.push(parseInt(r, HEX), parseInt(g, HEX), parseInt(b, HEX), parseHexAlpha(alpha)); + } else { + const [, r, g, b] = value.match(/^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/); + arr.push(parseInt(r, HEX), parseInt(g, HEX), parseInt(b, HEX), 1); + } + return arr; +}; +/** +* convert hex color to linear rgb +* @param value - hex color value +* @returns ColorChannels - [r, g, b, alpha] r|g|b|alpha: 0..1 +*/ +var convertHexToLinearRgb = (value) => { + const [rr, gg, bb, alpha] = convertHexToRgb(value); + const [r, g, b] = transformRgbToLinearRgb([ + rr, + gg, + bb + ], true); + return [ + r, + g, + b, + alpha + ]; +}; +/** +* convert hex color to xyz +* @param value - hex color value +* @returns ColorChannels - [x, y, z, alpha] +*/ +var convertHexToXyz = (value) => { + const [r, g, b, alpha] = convertHexToLinearRgb(value); + const [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [ + r, + g, + b + ], true); + return [ + x, + y, + z, + alpha + ]; +}; +/** +* parse rgb() +* @param value - rgb color value +* @param [opt] - options +* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject +*/ +var parseRgb = (value, opt = {}) => { + if (isString(value)) value = value.toLowerCase().trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_PARSE_RGB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const [, val] = value.match(REG_PARSE_RGB); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let r, g, b; + if (v1 === "none") r = 0; + else { + if (v1.endsWith("%")) r = parseFloat(v1) * MAX_RGB / MAX_PCT; + else r = parseFloat(v1); + r = Math.min(Math.max(roundToPrecision(r, OCT), 0), MAX_RGB); + } + if (v2 === "none") g = 0; + else { + if (v2.endsWith("%")) g = parseFloat(v2) * MAX_RGB / MAX_PCT; + else g = parseFloat(v2); + g = Math.min(Math.max(roundToPrecision(g, OCT), 0), MAX_RGB); + } + if (v3 === "none") b = 0; + else { + if (v3.endsWith("%")) b = parseFloat(v3) * MAX_RGB / MAX_PCT; + else b = parseFloat(v3); + b = Math.min(Math.max(roundToPrecision(b, OCT), 0), MAX_RGB); + } + const alpha = parseAlpha(v4); + return [ + "rgb", + r, + g, + b, + format === "mixValue" && v4 === "none" ? NONE : alpha + ]; +}; +/** +* parse hsl() +* @param value - hsl color value +* @param [opt] - options +* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject +*/ +var parseHsl = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_HSL.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const [, val] = value.match(REG_HSL); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let h, s, l; + if (v1 === "none") h = 0; + else h = angleToDeg(v1); + if (v2 === "none") s = 0; + else s = Math.min(Math.max(parseFloat(v2), 0), MAX_PCT); + if (v3 === "none") l = 0; + else l = Math.min(Math.max(parseFloat(v3), 0), MAX_PCT); + const alpha = parseAlpha(v4); + if (format === "hsl") return [ + format, + v1 === "none" ? v1 : h, + v2 === "none" ? v2 : s, + v3 === "none" ? v3 : l, + v4 === "none" ? v4 : alpha + ]; + h = h / DEG * DOZ; + l /= MAX_PCT; + const sa = s / MAX_PCT * Math.min(l, 1 - l); + const rk = h % DOZ; + const gk = (8 + h) % DOZ; + const bk = (4 + h) % DOZ; + const r = l - sa * Math.max(-1, Math.min(rk - TRIA, TRIA ** POW_SQR - rk, 1)); + const g = l - sa * Math.max(-1, Math.min(gk - TRIA, TRIA ** POW_SQR - gk, 1)); + const b = l - sa * Math.max(-1, Math.min(bk - TRIA, TRIA ** POW_SQR - bk, 1)); + return [ + "rgb", + Math.min(Math.max(roundToPrecision(r * MAX_RGB, OCT), 0), MAX_RGB), + Math.min(Math.max(roundToPrecision(g * MAX_RGB, OCT), 0), MAX_RGB), + Math.min(Math.max(roundToPrecision(b * MAX_RGB, OCT), 0), MAX_RGB), + alpha + ]; +}; +/** +* parse hwb() +* @param value - hwb color value +* @param [opt] - options +* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject +*/ +var parseHwb = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_HWB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const [, val] = value.match(REG_HWB); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let h, wh, bk; + if (v1 === "none") h = 0; + else h = angleToDeg(v1); + if (v2 === "none") wh = 0; + else wh = Math.min(Math.max(parseFloat(v2), 0), MAX_PCT) / MAX_PCT; + if (v3 === "none") bk = 0; + else bk = Math.min(Math.max(parseFloat(v3), 0), MAX_PCT) / MAX_PCT; + const alpha = parseAlpha(v4); + if (format === "hwb") return [ + format, + v1 === "none" ? v1 : h, + v2 === "none" ? v2 : wh * MAX_PCT, + v3 === "none" ? v3 : bk * MAX_PCT, + v4 === "none" ? v4 : alpha + ]; + if (wh + bk >= 1) { + const v = roundToPrecision(wh / (wh + bk) * MAX_RGB, OCT); + return [ + "rgb", + v, + v, + v, + alpha + ]; + } + const factor = (1 - wh - bk) / MAX_RGB; + let [, r, g, b] = parseHsl(`hsl(${h} 100 50)`); + r = roundToPrecision((r * factor + wh) * MAX_RGB, OCT); + g = roundToPrecision((g * factor + wh) * MAX_RGB, OCT); + b = roundToPrecision((b * factor + wh) * MAX_RGB, OCT); + return [ + "rgb", + Math.min(Math.max(r, 0), MAX_RGB), + Math.min(Math.max(g, 0), MAX_RGB), + Math.min(Math.max(b, 0), MAX_RGB), + alpha + ]; +}; +/** +* parse lab() +* @param value - lab color value +* @param [opt] - options +* @returns parsed color +* - [xyz-d50, x, y, z, alpha], ['lab', l, a, b, alpha], '(empty)', NullObject +*/ +var parseLab = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_LAB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const COEF_PCT = 1.25; + const COND_POW = 8; + const [, val] = value.match(REG_LAB); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let l, a, b; + if (v1 === "none") l = 0; + else { + if (v1.endsWith("%")) { + l = parseFloat(v1); + if (l > MAX_PCT) l = MAX_PCT; + } else l = parseFloat(v1); + if (l < 0) l = 0; + } + if (v2 === "none") a = 0; + else a = v2.endsWith("%") ? parseFloat(v2) * COEF_PCT : parseFloat(v2); + if (v3 === "none") b = 0; + else b = v3.endsWith("%") ? parseFloat(v3) * COEF_PCT : parseFloat(v3); + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) return [ + "lab", + v1 === "none" ? v1 : roundToPrecision(l, HEX), + v2 === "none" ? v2 : roundToPrecision(a, HEX), + v3 === "none" ? v3 : roundToPrecision(b, HEX), + v4 === "none" ? v4 : alpha + ]; + const fl = (l + HEX) / LAB_L; + const fa = a / LAB_A + fl; + const fb = fl - b / LAB_B; + const powFl = Math.pow(fl, POW_CUBE); + const powFa = Math.pow(fa, POW_CUBE); + const powFb = Math.pow(fb, POW_CUBE); + const [x, y, z] = [ + powFa > LAB_EPSILON ? powFa : (fa * LAB_L - HEX) / LAB_KAPPA, + l > COND_POW ? powFl : l / LAB_KAPPA, + powFb > LAB_EPSILON ? powFb : (fb * LAB_L - HEX) / LAB_KAPPA + ].map((val, i) => val * D50[i]); + return [ + "xyz-d50", + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; +/** +* parse lch() +* @param value - lch color value +* @param [opt] - options +* @returns parsed color +* - ['xyz-d50', x, y, z, alpha], ['lch', l, c, h, alpha] +* - '(empty)', NullObject +*/ +var parseLch = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_LCH.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const COEF_PCT = 1.5; + const [, val] = value.match(REG_LCH); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let l, c, h; + if (v1 === "none") l = 0; + else { + l = parseFloat(v1); + if (l < 0) l = 0; + } + if (v2 === "none") c = 0; + else c = v2.endsWith("%") ? parseFloat(v2) * COEF_PCT : parseFloat(v2); + if (v3 === "none") h = 0; + else h = angleToDeg(v3); + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) return [ + "lch", + v1 === "none" ? v1 : roundToPrecision(l, HEX), + v2 === "none" ? v2 : roundToPrecision(c, HEX), + v3 === "none" ? v3 : roundToPrecision(h, HEX), + v4 === "none" ? v4 : alpha + ]; + const a = c * Math.cos(h * Math.PI / DEG_HALF); + const b = c * Math.sin(h * Math.PI / DEG_HALF); + const [, x, y, z] = parseLab(`lab(${l} ${a} ${b})`); + return [ + "xyz-d50", + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; +/** +* parse oklab() +* @param value - oklab color value +* @param [opt] - options +* @returns parsed color +* - ['xyz-d65', x, y, z, alpha], ['oklab', l, a, b, alpha] +* - '(empty)', NullObject +*/ +var parseOklab = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_OKLAB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const COEF_PCT = .4; + const [, val] = value.match(REG_OKLAB); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let l, a, b; + if (v1 === "none") l = 0; + else { + l = v1.endsWith("%") ? parseFloat(v1) / MAX_PCT : parseFloat(v1); + if (l < 0) l = 0; + } + if (v2 === "none") a = 0; + else if (v2.endsWith("%")) a = parseFloat(v2) * COEF_PCT / MAX_PCT; + else a = parseFloat(v2); + if (v3 === "none") b = 0; + else if (v3.endsWith("%")) b = parseFloat(v3) * COEF_PCT / MAX_PCT; + else b = parseFloat(v3); + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) return [ + "oklab", + v1 === "none" ? v1 : roundToPrecision(l, HEX), + v2 === "none" ? v2 : roundToPrecision(a, HEX), + v3 === "none" ? v3 : roundToPrecision(b, HEX), + v4 === "none" ? v4 : alpha + ]; + const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, transformMatrix(MATRIX_OKLAB_TO_LMS, [ + l, + a, + b + ]).map((c) => Math.pow(c, POW_CUBE)), true); + return [ + "xyz-d65", + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; +/** +* parse oklch() +* @param value - oklch color value +* @param [opt] - options +* @returns parsed color +* - ['xyz-d65', x, y, z, alpha], ['oklch', l, c, h, alpha] +* - '(empty)', NullObject +*/ +var parseOklch = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + if (!REG_OKLCH.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const COEF_PCT = .4; + const [, val] = value.match(REG_OKLCH); + const [v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let l, c, h; + if (v1 === "none") l = 0; + else { + l = v1.endsWith("%") ? parseFloat(v1) / MAX_PCT : parseFloat(v1); + if (l < 0) l = 0; + } + if (v2 === "none") c = 0; + else { + if (v2.endsWith("%")) c = parseFloat(v2) * COEF_PCT / MAX_PCT; + else c = parseFloat(v2); + if (c < 0) c = 0; + } + if (v3 === "none") h = 0; + else h = angleToDeg(v3); + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) return [ + "oklch", + v1 === "none" ? v1 : roundToPrecision(l, HEX), + v2 === "none" ? v2 : roundToPrecision(c, HEX), + v3 === "none" ? v3 : roundToPrecision(h, HEX), + v4 === "none" ? v4 : alpha + ]; + const a = c * Math.cos(h * Math.PI / DEG_HALF); + const b = c * Math.sin(h * Math.PI / DEG_HALF); + const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, transformMatrix(MATRIX_OKLAB_TO_LMS, [ + l, + a, + b + ]).map((cc) => Math.pow(cc, POW_CUBE)), true); + return [ + "xyz-d65", + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; +/** +* parse color() +* @param value - color function value +* @param [opt] - options +* @returns parsed color +* - ['xyz-(d50|d65)', x, y, z, alpha], [cs, r, g, b, alpha] +* - '(empty)', NullObject +*/ +var parseColorFunc = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { colorSpace = "", d50 = false, format = "", nullable = false } = opt; + if (!REG_FN_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + const [, val] = value.match(REG_FN_COLOR); + let [cs, v1, v2, v3, v4 = ""] = val.match(/[^\s,/]+/g); + let r, g, b; + if (cs === "xyz") cs = "xyz-d65"; + if (v1 === "none") r = 0; + else r = v1.endsWith("%") ? parseFloat(v1) / MAX_PCT : parseFloat(v1); + if (v2 === "none") g = 0; + else g = v2.endsWith("%") ? parseFloat(v2) / MAX_PCT : parseFloat(v2); + if (v3 === "none") b = 0; + else b = v3.endsWith("%") ? parseFloat(v3) / MAX_PCT : parseFloat(v3); + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format) || format === "mixValue" && cs === colorSpace) return [ + cs, + v1 === "none" ? v1 : roundToPrecision(r, DEC), + v2 === "none" ? v2 : roundToPrecision(g, DEC), + v3 === "none" ? v3 : roundToPrecision(b, DEC), + v4 === "none" ? v4 : alpha + ]; + let x = 0; + let y = 0; + let z = 0; + if (cs === "srgb-linear") { + [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [ + r, + g, + b + ]); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else if (cs === "display-p3") { + const linearRgb = transformRgbToLinearRgb([ + r * MAX_RGB, + g * MAX_RGB, + b * MAX_RGB + ]); + [x, y, z] = transformMatrix(MATRIX_P3_TO_XYZ, linearRgb); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else if (cs === "rec2020") { + const ALPHA = 1.09929682680944; + const BETA = .018053968510807; + const REC_COEF = .45; + const rgb = [ + r, + g, + b + ].map((c) => { + let cl; + if (c < BETA * REC_COEF * DEC) cl = c / (REC_COEF * DEC); + else cl = Math.pow((c + ALPHA - 1) / ALPHA, 1 / REC_COEF); + return cl; + }); + [x, y, z] = transformMatrix(MATRIX_REC2020_TO_XYZ, rgb); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else if (cs === "a98-rgb") { + const POW_A98 = 563 / 256; + const rgb = [ + r, + g, + b + ].map((c) => { + return Math.pow(c, POW_A98); + }); + [x, y, z] = transformMatrix(MATRIX_A98_TO_XYZ, rgb); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else if (cs === "prophoto-rgb") { + const POW_PROPHOTO = 1.8; + const rgb = [ + r, + g, + b + ].map((c) => { + let cl; + if (c > 1 / (HEX * DUO)) cl = Math.pow(c, POW_PROPHOTO); + else cl = c / HEX; + return cl; + }); + [x, y, z] = transformMatrix(MATRIX_PROPHOTO_TO_XYZ_D50, rgb); + if (!d50) [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [ + x, + y, + z + ], true); + } else if (/^xyz(?:-d(?:50|65))?$/.test(cs)) { + [x, y, z] = [ + r, + g, + b + ]; + if (cs === "xyz-d50") { + if (!d50) [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [ + x, + y, + z + ]); + } else if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else { + [x, y, z] = transformRgbToXyz([ + r * MAX_RGB, + g * MAX_RGB, + b * MAX_RGB + ]); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } + return [ + d50 ? "xyz-d50" : "xyz-d65", + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + format === "mixValue" && v4 === "none" ? v4 : alpha + ]; +}; +/** +* parse color value +* @param value - CSS color value +* @param [opt] - options +* @returns parsed color +* - ['xyz-(d50|d65)', x, y, z, alpha], ['rgb', r, g, b, alpha] +* - value, '(empty)', NullObject +*/ +var parseColorValue = (value, opt = {}) => { + if (isString(value)) value = value.toLowerCase().trim(); + else throw new TypeError(`${value} is not a string.`); + const { d50 = false, format = "", nullable = false } = opt; + if (!REG_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) return res; + if (isString(res)) return res; + return res; + } + let x = 0; + let y = 0; + let z = 0; + let alpha = 0; + if (REG_CURRENT.test(value)) { + if (format === "computedValue") return [ + "rgb", + 0, + 0, + 0, + 0 + ]; + if (format === "specifiedValue") return value; + } else if (/^[a-z]+$/.test(value)) if (Object.hasOwn(NAMED_COLORS, value)) { + if (format === "specifiedValue") return value; + const [r, g, b] = NAMED_COLORS[value]; + alpha = 1; + if (format === "computedValue") return [ + "rgb", + r, + g, + b, + alpha + ]; + [x, y, z] = transformRgbToXyz([ + r, + g, + b + ], true); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else switch (format) { + case VAL_COMP: + if (nullable && value !== "transparent") return new NullObject(); + return [ + "rgb", + 0, + 0, + 0, + 0 + ]; + case VAL_SPEC: + if (value === "transparent") return value; + return ""; + case VAL_MIX: + if (value === "transparent") return [ + "rgb", + 0, + 0, + 0, + 0 + ]; + return new NullObject(); + default: + } + else if (value[0] === "#") { + if (REG_SPEC.test(format)) return ["rgb", ...convertHexToRgb(value)]; + [x, y, z, alpha] = convertHexToXyz(value); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else if (value.startsWith("lab")) { + if (REG_SPEC.test(format)) return parseLab(value, opt); + [, x, y, z, alpha] = parseLab(value); + if (!d50) [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [ + x, + y, + z + ], true); + } else if (value.startsWith("lch")) { + if (REG_SPEC.test(format)) return parseLch(value, opt); + [, x, y, z, alpha] = parseLch(value); + if (!d50) [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [ + x, + y, + z + ], true); + } else if (value.startsWith("oklab")) { + if (REG_SPEC.test(format)) return parseOklab(value, opt); + [, x, y, z, alpha] = parseOklab(value); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else if (value.startsWith("oklch")) { + if (REG_SPEC.test(format)) return parseOklch(value, opt); + [, x, y, z, alpha] = parseOklch(value); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } else { + let r, g, b; + if (value.startsWith("hsl")) [, r, g, b, alpha] = parseHsl(value); + else if (value.startsWith("hwb")) [, r, g, b, alpha] = parseHwb(value); + else [, r, g, b, alpha] = parseRgb(value, opt); + if (REG_SPEC.test(format)) return [ + "rgb", + Math.round(r), + Math.round(g), + Math.round(b), + alpha + ]; + [x, y, z] = transformRgbToXyz([ + r, + g, + b + ]); + if (d50) [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [ + x, + y, + z + ], true); + } + return [ + d50 ? "xyz-d50" : "xyz-d65", + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; +/** +* resolve color value +* @param value - CSS color value +* @param [opt] - options +* @returns resolved color +* - [cs, v1, v2, v3, alpha], value, '(empty)', NullObject +*/ +var resolveColorValue = (value, opt = {}) => { + if (isString(value)) value = value.toLowerCase().trim(); + else throw new TypeError(`${value} is not a string.`); + const { colorSpace = "", format = "", nullable = false } = opt; + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "resolveColorValue", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + const cachedItem = cachedResult.item; + if (isString(cachedItem)) return cachedItem; + return cachedItem; + } + if (!REG_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + setCache(cacheKey, null); + return res; + } + setCache(cacheKey, res); + if (isString(res)) return res; + return res; + } + let cs = ""; + let r = 0; + let g = 0; + let b = 0; + let alpha = 0; + if (REG_CURRENT.test(value)) { + if (format === "specifiedValue") { + setCache(cacheKey, value); + return value; + } + } else if (/^[a-z]+$/.test(value)) if (Object.hasOwn(NAMED_COLORS, value)) { + if (format === "specifiedValue") { + setCache(cacheKey, value); + return value; + } + [r, g, b] = NAMED_COLORS[value]; + alpha = 1; + } else switch (format) { + case VAL_SPEC: { + if (value === "transparent") { + setCache(cacheKey, value); + return value; + } + const res = ""; + setCache(cacheKey, res); + return res; + } + case VAL_MIX: + if (value === "transparent") { + const res = [ + "rgb", + 0, + 0, + 0, + 0 + ]; + setCache(cacheKey, res); + return res; + } + setCache(cacheKey, null); + return new NullObject(); + case VAL_COMP: + default: { + if (nullable && value !== "transparent") { + setCache(cacheKey, null); + return new NullObject(); + } + const res = [ + "rgb", + 0, + 0, + 0, + 0 + ]; + setCache(cacheKey, res); + return res; + } + } + else if (value[0] === "#") [r, g, b, alpha] = convertHexToRgb(value); + else if (value.startsWith("hsl")) [, r, g, b, alpha] = parseHsl(value, opt); + else if (value.startsWith("hwb")) [, r, g, b, alpha] = parseHwb(value, opt); + else if (/^l(?:ab|ch)/.test(value)) { + let x, y, z; + if (value.startsWith("lab")) [cs, x, y, z, alpha] = parseLab(value, opt); + else [cs, x, y, z, alpha] = parseLch(value, opt); + if (REG_SPEC.test(format)) { + const res = [ + cs, + x, + y, + z, + alpha + ]; + setCache(cacheKey, res); + return res; + } + [r, g, b] = transformXyzD50ToRgb([ + x, + y, + z + ]); + } else if (/^okl(?:ab|ch)/.test(value)) { + let x, y, z; + if (value.startsWith("oklab")) [cs, x, y, z, alpha] = parseOklab(value, opt); + else [cs, x, y, z, alpha] = parseOklch(value, opt); + if (REG_SPEC.test(format)) { + const res = [ + cs, + x, + y, + z, + alpha + ]; + setCache(cacheKey, res); + return res; + } + [r, g, b] = transformXyzToRgb([ + x, + y, + z + ]); + } else [, r, g, b, alpha] = parseRgb(value, opt); + if (format === "mixValue" && colorSpace === "srgb") { + const res = [ + "srgb", + r / MAX_RGB, + g / MAX_RGB, + b / MAX_RGB, + alpha + ]; + setCache(cacheKey, res); + return res; + } + const res = [ + "rgb", + Math.round(r), + Math.round(g), + Math.round(b), + alpha + ]; + setCache(cacheKey, res); + return res; +}; +/** +* resolve color() +* @param value - color function value +* @param [opt] - options +* @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', NullObject +*/ +var resolveColorFunc = (value, opt = {}) => { + if (isString(value)) value = value.toLowerCase().trim(); + else throw new TypeError(`${value} is not a string.`); + const { colorSpace = "", format = "", nullable = false } = opt; + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "resolveColorFunc", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + const cachedItem = cachedResult.item; + if (isString(cachedItem)) return cachedItem; + return cachedItem; + } + if (!REG_FN_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + setCache(cacheKey, null); + return res; + } + setCache(cacheKey, res); + if (isString(res)) return res; + return res; + } + const [cs, v1, v2, v3, v4] = parseColorFunc(value, opt); + if (REG_SPEC.test(format) || format === "mixValue" && cs === colorSpace) { + const res = [ + cs, + v1, + v2, + v3, + v4 + ]; + setCache(cacheKey, res); + return res; + } + const x = parseFloat(`${v1}`); + const y = parseFloat(`${v2}`); + const z = parseFloat(`${v3}`); + const alpha = parseAlpha(`${v4}`); + const [r, g, b] = transformXyzToRgb([ + x, + y, + z + ], true); + const res = [ + "rgb", + r, + g, + b, + alpha + ]; + setCache(cacheKey, res); + return res; +}; +/** +* convert color value to linear rgb +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [r, g, b, alpha] r|g|b|alpha: 0..1 +*/ +var convertColorToLinearRgb = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { colorSpace = "", format = "" } = opt; + let cs = ""; + let r, g, b, alpha, x, y, z; + if (format === "mixValue") { + let xyz; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [cs, x, y, z, alpha] = xyz; + if (cs === colorSpace) return [ + x, + y, + z, + alpha + ]; + [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [ + x, + y, + z + ], true); + } else if (value.startsWith("color(")) { + const [, val] = value.match(REG_FN_COLOR); + const [cs] = val.match(/[^\s,/]+/g); + if (cs === "srgb-linear") [, r, g, b, alpha] = resolveColorFunc(value, { format: VAL_COMP }); + else { + [, x, y, z, alpha] = parseColorFunc(value); + [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [ + x, + y, + z + ], true); + } + } else { + [, x, y, z, alpha] = parseColorValue(value); + [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [ + x, + y, + z + ], true); + } + return [ + Math.min(Math.max(r, 0), 1), + Math.min(Math.max(g, 0), 1), + Math.min(Math.max(b, 0), 1), + alpha + ]; +}; +/** +* convert color value to rgb +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject +* - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 +*/ +var convertColorToRgb = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let r, g, b, alpha; + if (format === "mixValue") { + let rgb; + if (value.startsWith("color(")) rgb = resolveColorFunc(value, opt); + else rgb = resolveColorValue(value, opt); + if (rgb instanceof NullObject) return rgb; + [, r, g, b, alpha] = rgb; + } else if (value.startsWith("color(")) { + const [, val] = value.match(REG_FN_COLOR); + const [cs] = val.match(/[^\s,/]+/g); + if (cs === "srgb") { + [, r, g, b, alpha] = resolveColorFunc(value, { format: VAL_COMP }); + r *= MAX_RGB; + g *= MAX_RGB; + b *= MAX_RGB; + } else [, r, g, b, alpha] = resolveColorFunc(value); + } else if (/^(?:ok)?l(?:ab|ch)/.test(value)) { + [r, g, b, alpha] = convertColorToLinearRgb(value); + [r, g, b] = transformLinearRgbToRgb([ + r, + g, + b + ]); + } else [, r, g, b, alpha] = resolveColorValue(value, { format: VAL_COMP }); + return [ + r, + g, + b, + alpha + ]; +}; +/** +* convert color value to xyz +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [x, y, z, alpha] +*/ +var convertColorToXyz = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { d50 = false, format = "" } = opt; + let x, y, z, alpha; + if (format === "mixValue") { + let xyz; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) { + const [, val] = value.match(REG_FN_COLOR); + const [cs] = val.match(/[^\s,/]+/g); + if (d50) if (cs === "xyz-d50") [, x, y, z, alpha] = resolveColorFunc(value, { format: VAL_COMP }); + else [, x, y, z, alpha] = parseColorFunc(value, opt); + else if (/^xyz(?:-d65)?$/.test(cs)) [, x, y, z, alpha] = resolveColorFunc(value, { format: VAL_COMP }); + else [, x, y, z, alpha] = parseColorFunc(value); + } else [, x, y, z, alpha] = parseColorValue(value, opt); + return [ + x, + y, + z, + alpha + ]; +}; +/** +* convert color value to hsl +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [h, s, l, alpha], hue may be powerless +*/ +var convertColorToHsl = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let h, s, l, alpha; + if (REG_HSL.test(value)) { + [, h, s, l, alpha] = parseHsl(value, { format: "hsl" }); + if (format === "hsl") return [ + Math.round(h), + Math.round(s), + Math.round(l), + alpha + ]; + return [ + h, + s, + l, + alpha + ]; + } + let x, y, z; + if (format === "mixValue") { + let xyz; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) [, x, y, z, alpha] = parseColorFunc(value); + else [, x, y, z, alpha] = parseColorValue(value); + [h, s, l] = transformXyzToHsl([ + x, + y, + z + ], true); + if (format === "hsl") return [ + Math.round(h), + Math.round(s), + Math.round(l), + alpha + ]; + return [ + format === "mixValue" && s === 0 ? NONE : h, + s, + l, + alpha + ]; +}; +/** +* convert color value to hwb +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [h, w, b, alpha], hue may be powerless +*/ +var convertColorToHwb = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let h, w, b, alpha; + if (REG_HWB.test(value)) { + [, h, w, b, alpha] = parseHwb(value, { format: "hwb" }); + if (format === "hwb") return [ + Math.round(h), + Math.round(w), + Math.round(b), + alpha + ]; + return [ + h, + w, + b, + alpha + ]; + } + let x, y, z; + if (format === "mixValue") { + let xyz; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) [, x, y, z, alpha] = parseColorFunc(value); + else [, x, y, z, alpha] = parseColorValue(value); + [h, w, b] = transformXyzToHwb([ + x, + y, + z + ], true); + if (format === "hwb") return [ + Math.round(h), + Math.round(w), + Math.round(b), + alpha + ]; + return [ + format === "mixValue" && w + b >= 100 ? NONE : h, + w, + b, + alpha + ]; +}; +/** +* convert color value to lab +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [l, a, b, alpha] +*/ +var convertColorToLab = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let l, a, b, alpha; + if (REG_LAB.test(value)) { + [, l, a, b, alpha] = parseLab(value, { format: VAL_COMP }); + return [ + l, + a, + b, + alpha + ]; + } + let x, y, z; + if (format === "mixValue") { + let xyz; + opt.d50 = true; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) [, x, y, z, alpha] = parseColorFunc(value, { d50: true }); + else [, x, y, z, alpha] = parseColorValue(value, { d50: true }); + [l, a, b] = transformXyzD50ToLab([ + x, + y, + z + ], true); + return [ + l, + a, + b, + alpha + ]; +}; +/** +* convert color value to lch +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless +*/ +var convertColorToLch = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let l, c, h, alpha; + if (REG_LCH.test(value)) { + [, l, c, h, alpha] = parseLch(value, { format: VAL_COMP }); + return [ + l, + c, + h, + alpha + ]; + } + let x, y, z; + if (format === "mixValue") { + let xyz; + opt.d50 = true; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) [, x, y, z, alpha] = parseColorFunc(value, { d50: true }); + else [, x, y, z, alpha] = parseColorValue(value, { d50: true }); + [l, c, h] = transformXyzD50ToLch([ + x, + y, + z + ], true); + return [ + l, + c, + format === "mixValue" && c === 0 ? NONE : h, + alpha + ]; +}; +/** +* convert color value to oklab +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [l, a, b, alpha] +*/ +var convertColorToOklab = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let l, a, b, alpha; + if (REG_OKLAB.test(value)) { + [, l, a, b, alpha] = parseOklab(value, { format: VAL_COMP }); + return [ + l, + a, + b, + alpha + ]; + } + let x, y, z; + if (format === "mixValue") { + let xyz; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) [, x, y, z, alpha] = parseColorFunc(value); + else [, x, y, z, alpha] = parseColorValue(value); + [l, a, b] = transformXyzToOklab([ + x, + y, + z + ], true); + return [ + l, + a, + b, + alpha + ]; +}; +/** +* convert color value to oklch +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless +*/ +var convertColorToOklch = (value, opt = {}) => { + if (isString(value)) value = value.trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "" } = opt; + let l, c, h, alpha; + if (REG_OKLCH.test(value)) { + [, l, c, h, alpha] = parseOklch(value, { format: VAL_COMP }); + return [ + l, + c, + h, + alpha + ]; + } + let x, y, z; + if (format === "mixValue") { + let xyz; + if (value.startsWith("color(")) xyz = parseColorFunc(value, opt); + else xyz = parseColorValue(value, opt); + if (xyz instanceof NullObject) return xyz; + [, x, y, z, alpha] = xyz; + } else if (value.startsWith("color(")) [, x, y, z, alpha] = parseColorFunc(value); + else [, x, y, z, alpha] = parseColorValue(value); + [l, c, h] = transformXyzToOklch([ + x, + y, + z + ], true); + return [ + l, + c, + format === "mixValue" && c === 0 ? NONE : h, + alpha + ]; +}; +/** +* resolve color-mix() +* @param value - color-mix color value +* @param [opt] - options +* @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)' +*/ +var resolveColorMix = (value, opt = {}) => { + if (isString(value)) value = value.toLowerCase().trim(); + else throw new TypeError(`${value} is not a string.`); + const { format = "", nullable = false } = opt; + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "resolveColorMix", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + const cachedItem = cachedResult.item; + if (isString(cachedItem)) return cachedItem; + return cachedItem; + } + const nestedItems = []; + let colorSpace = ""; + let hueArc = ""; + let colorA = ""; + let pctA = ""; + let colorB = ""; + let pctB = ""; + let parsed = false; + if (!REG_MIX.test(value)) if (value.startsWith("color-mix(") && REG_MIX_NEST.test(value)) { + const items = value.match(REG_MIX_NEST); + for (const item of items) if (item) { + let val = resolveColorMix(item, { format: format === "specifiedValue" ? format : VAL_COMP }); + if (Array.isArray(val)) { + const [cs, v1, v2, v3, v4] = val; + if (v1 === 0 && v2 === 0 && v3 === 0 && v4 === 0) { + value = ""; + break; + } + if (REG_MIX_CS_RGB_XYZ.test(cs)) if (v4 === 1) val = `color(${cs} ${v1} ${v2} ${v3})`; + else val = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`; + else if (v4 === 1) val = `${cs}(${v1} ${v2} ${v3})`; + else val = `${cs}(${v1} ${v2} ${v3} / ${v4})`; + } else if (!REG_MIX.test(val)) { + value = ""; + break; + } + nestedItems.push(val); + value = value.replace(item, val); + } + if (!value) return cacheInvalidColorValue(cacheKey, format, nullable); + } else if (value.startsWith("color-mix(") && value.endsWith(")") && value.includes("light-dark(")) { + const [csPart = "", partA = "", partB = ""] = splitValue(value.replace(FN_MIX, "").replace(/\)$/, ""), { delimiter: "," }); + const [colorPartA = "", pctPartA = ""] = splitValue(partA); + const [colorPartB = "", pctPartB = ""] = splitValue(partB); + const specifiedColorA = resolveColor(colorPartA, { format: VAL_SPEC }); + const specifiedColorB = resolveColor(colorPartB, { format: VAL_SPEC }); + if (REG_MIX_IN_CS.test(csPart) && specifiedColorA && specifiedColorB) if (format === "specifiedValue") { + const [, cs] = csPart.match(REG_MIX_IN_CS); + if (REG_CS_HUE.test(cs)) [, colorSpace, hueArc] = cs.match(REG_CS_HUE); + else colorSpace = cs; + colorA = specifiedColorA; + if (pctPartA) pctA = pctPartA; + colorB = specifiedColorB; + if (pctPartB) pctB = pctPartB; + value = value.replace(colorPartA, specifiedColorA).replace(colorPartB, specifiedColorB); + parsed = true; + } else { + const resolvedColorA = resolveColor(colorPartA, opt); + const resolvedColorB = resolveColor(colorPartB, opt); + if (isString(resolvedColorA) && isString(resolvedColorB)) value = value.replace(colorPartA, resolvedColorA).replace(colorPartB, resolvedColorB); + } + else return cacheInvalidColorValue(cacheKey, format, nullable); + } else return cacheInvalidColorValue(cacheKey, format, nullable); + if (nestedItems.length && format === "specifiedValue") { + const [, cs] = value.match(REG_MIX_START); + if (REG_CS_HUE.test(cs)) [, colorSpace, hueArc] = cs.match(REG_CS_HUE); + else colorSpace = cs; + if (nestedItems.length === 2) { + let [itemA, itemB] = nestedItems; + itemA = itemA.replace(/(?=[()])/g, "\\"); + itemB = itemB.replace(/(?=[()])/g, "\\"); + const regA = new RegExp(`(${itemA})(?:\\s+(${PCT}))?`); + const regB = new RegExp(`(${itemB})(?:\\s+(${PCT}))?`); + [, colorA, pctA] = value.match(regA); + [, colorB, pctB] = value.match(regB); + } else { + let [item] = nestedItems; + item = item.replace(/(?=[()])/g, "\\"); + const itemPart = `${item}(?:\\s+${PCT})?`; + const itemPartCapt = `(${item})(?:\\s+(${PCT}))?`; + const regItemPart = new RegExp(`^${itemPartCapt}$`); + if (new RegExp(`${itemPartCapt}\\s*\\)$`).test(value)) { + const reg = new RegExp(`(${SYN_MIX_PART})\\s*,\\s*(${itemPart})\\s*\\)$`); + const [, colorPartA, colorPartB] = value.match(reg); + [, colorA, pctA] = colorPartA.match(REG_MIX_COLOR_PART); + [, colorB, pctB] = colorPartB.match(regItemPart); + } else { + const reg = new RegExp(`(${itemPart})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)$`); + const [, colorPartA, colorPartB] = value.match(reg); + [, colorA, pctA] = colorPartA.match(regItemPart); + [, colorB, pctB] = colorPartB.match(REG_MIX_COLOR_PART); + } + } + } else if (!parsed) { + const [, cs, colorPartA, colorPartB] = value.match(REG_MIX_CAPT); + [, colorA, pctA] = colorPartA.match(REG_MIX_COLOR_PART); + [, colorB, pctB] = colorPartB.match(REG_MIX_COLOR_PART); + if (REG_CS_HUE.test(cs)) [, colorSpace, hueArc] = cs.match(REG_CS_HUE); + else colorSpace = cs; + } + let pA, pB, m; + if (pctA && pctB) { + const p1 = parseFloat(pctA) / MAX_PCT; + const p2 = parseFloat(pctB) / MAX_PCT; + if (p1 < 0 || p1 > 1 || p2 < 0 || p2 > 1 || p1 === 0 && p2 === 0) return cacheInvalidColorValue(cacheKey, format, nullable); + const factor = p1 + p2; + pA = p1 / factor; + pB = p2 / factor; + m = factor < 1 ? factor : 1; + } else { + if (pctA) { + pA = parseFloat(pctA) / MAX_PCT; + if (pA < 0 || pA > 1) return cacheInvalidColorValue(cacheKey, format, nullable); + pB = 1 - pA; + } else if (pctB) { + pB = parseFloat(pctB) / MAX_PCT; + if (pB < 0 || pB > 1) return cacheInvalidColorValue(cacheKey, format, nullable); + pA = 1 - pB; + } else { + pA = HALF; + pB = HALF; + } + m = 1; + } + if (colorSpace === "xyz") colorSpace = "xyz-d65"; + if (format === "specifiedValue") { + let valueA = ""; + let valueB = ""; + if (colorA.startsWith("color-mix(") || colorA.startsWith("light-dark(")) valueA = colorA; + else if (colorA.startsWith("color(")) { + const [cs, v1, v2, v3, v4] = parseColorFunc(colorA, opt); + if (v4 === 1) valueA = `color(${cs} ${v1} ${v2} ${v3})`; + else valueA = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`; + } else { + const val = parseColorValue(colorA, opt); + if (Array.isArray(val)) { + const [cs, v1, v2, v3, v4] = val; + if (v4 === 1) if (cs === "rgb") valueA = `${cs}(${v1}, ${v2}, ${v3})`; + else valueA = `${cs}(${v1} ${v2} ${v3})`; + else if (cs === "rgb") valueA = `${cs}a(${v1}, ${v2}, ${v3}, ${v4})`; + else valueA = `${cs}(${v1} ${v2} ${v3} / ${v4})`; + } else { + if (!isString(val) || !val) { + setCache(cacheKey, ""); + return ""; + } + valueA = val; + } + } + if (colorB.startsWith("color-mix(") || colorB.startsWith("light-dark(")) valueB = colorB; + else if (colorB.startsWith("color(")) { + const [cs, v1, v2, v3, v4] = parseColorFunc(colorB, opt); + if (v4 === 1) valueB = `color(${cs} ${v1} ${v2} ${v3})`; + else valueB = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`; + } else { + const val = parseColorValue(colorB, opt); + if (Array.isArray(val)) { + const [cs, v1, v2, v3, v4] = val; + if (v4 === 1) if (cs === "rgb") valueB = `${cs}(${v1}, ${v2}, ${v3})`; + else valueB = `${cs}(${v1} ${v2} ${v3})`; + else if (cs === "rgb") valueB = `${cs}a(${v1}, ${v2}, ${v3}, ${v4})`; + else valueB = `${cs}(${v1} ${v2} ${v3} / ${v4})`; + } else { + if (!isString(val) || !val) { + setCache(cacheKey, ""); + return ""; + } + valueB = val; + } + } + if (pctA && pctB) { + valueA += ` ${parseFloat(pctA)}%`; + valueB += ` ${parseFloat(pctB)}%`; + } else if (pctA) { + const pA = parseFloat(pctA); + if (pA !== MAX_PCT * HALF) valueA += ` ${pA}%`; + } else if (pctB) { + const pA = MAX_PCT - parseFloat(pctB); + if (pA !== MAX_PCT * HALF) valueA += ` ${pA}%`; + } + if (hueArc) { + const res = `color-mix(in ${colorSpace} ${hueArc} hue, ${valueA}, ${valueB})`; + setCache(cacheKey, res); + return res; + } else { + const res = `color-mix(in ${colorSpace}, ${valueA}, ${valueB})`; + setCache(cacheKey, res); + return res; + } + } + let r = 0; + let g = 0; + let b = 0; + let alpha = 0; + if (/^srgb(?:-linear)?$/.test(colorSpace)) { + let rgbA, rgbB; + if (colorSpace === "srgb") { + if (REG_CURRENT.test(colorA)) rgbA = [ + NONE, + NONE, + NONE, + NONE + ]; + else rgbA = convertColorToRgb(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) rgbB = [ + NONE, + NONE, + NONE, + NONE + ]; + else rgbB = convertColorToRgb(colorB, { + colorSpace, + format: VAL_MIX + }); + } else { + if (REG_CURRENT.test(colorA)) rgbA = [ + NONE, + NONE, + NONE, + NONE + ]; + else rgbA = convertColorToLinearRgb(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) rgbB = [ + NONE, + NONE, + NONE, + NONE + ]; + else rgbB = convertColorToLinearRgb(colorB, { + colorSpace, + format: VAL_MIX + }); + } + if (rgbA instanceof NullObject || rgbB instanceof NullObject) return cacheInvalidColorValue(cacheKey, format, nullable); + const [rrA, ggA, bbA, aaA] = rgbA; + const [rrB, ggB, bbB, aaB] = rgbB; + const rNone = rrA === "none" && rrB === "none"; + const gNone = ggA === "none" && ggB === "none"; + const bNone = bbA === "none" && bbB === "none"; + const alphaNone = aaA === "none" && aaB === "none"; + const [[rA, gA, bA, alphaA], [rB, gB, bB, alphaB]] = normalizeColorComponents([ + rrA, + ggA, + bbA, + aaA + ], [ + rrB, + ggB, + bbB, + aaB + ], true); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + if (alpha === 0) { + r = rA * pA + rB * pB; + g = gA * pA + gB * pB; + b = bA * pA + bB * pB; + } else { + r = (rA * factorA + rB * factorB) / alpha; + g = (gA * factorA + gB * factorB) / alpha; + b = (bA * factorA + bB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === "computedValue") { + const res = [ + colorSpace, + rNone ? NONE : roundToPrecision(r, HEX), + gNone ? NONE : roundToPrecision(g, HEX), + bNone ? NONE : roundToPrecision(b, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + r *= MAX_RGB; + g *= MAX_RGB; + b *= MAX_RGB; + } else if (REG_CS_XYZ.test(colorSpace)) { + let xyzA, xyzB; + if (REG_CURRENT.test(colorA)) xyzA = [ + NONE, + NONE, + NONE, + NONE + ]; + else xyzA = convertColorToXyz(colorA, { + colorSpace, + d50: colorSpace === "xyz-d50", + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) xyzB = [ + NONE, + NONE, + NONE, + NONE + ]; + else xyzB = convertColorToXyz(colorB, { + colorSpace, + d50: colorSpace === "xyz-d50", + format: VAL_MIX + }); + if (xyzA instanceof NullObject || xyzB instanceof NullObject) return cacheInvalidColorValue(cacheKey, format, nullable); + const [xxA, yyA, zzA, aaA] = xyzA; + const [xxB, yyB, zzB, aaB] = xyzB; + const xNone = xxA === "none" && xxB === "none"; + const yNone = yyA === "none" && yyB === "none"; + const zNone = zzA === "none" && zzB === "none"; + const alphaNone = aaA === "none" && aaB === "none"; + const [[xA, yA, zA, alphaA], [xB, yB, zB, alphaB]] = normalizeColorComponents([ + xxA, + yyA, + zzA, + aaA + ], [ + xxB, + yyB, + zzB, + aaB + ], true); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + let x, y, z; + if (alpha === 0) { + x = xA * pA + xB * pB; + y = yA * pA + yB * pB; + z = zA * pA + zB * pB; + } else { + x = (xA * factorA + xB * factorB) / alpha; + y = (yA * factorA + yB * factorB) / alpha; + z = (zA * factorA + zB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === "computedValue") { + const res = [ + colorSpace, + xNone ? NONE : roundToPrecision(x, HEX), + yNone ? NONE : roundToPrecision(y, HEX), + zNone ? NONE : roundToPrecision(z, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + if (colorSpace === "xyz-d50") [r, g, b] = transformXyzD50ToRgb([ + x, + y, + z + ], true); + else [r, g, b] = transformXyzToRgb([ + x, + y, + z + ], true); + } else if (/^h(?:sl|wb)$/.test(colorSpace)) { + let hslA, hslB; + if (colorSpace === "hsl") { + if (REG_CURRENT.test(colorA)) hslA = [ + NONE, + NONE, + NONE, + NONE + ]; + else hslA = convertColorToHsl(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) hslB = [ + NONE, + NONE, + NONE, + NONE + ]; + else hslB = convertColorToHsl(colorB, { + colorSpace, + format: VAL_MIX + }); + } else { + if (REG_CURRENT.test(colorA)) hslA = [ + NONE, + NONE, + NONE, + NONE + ]; + else hslA = convertColorToHwb(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) hslB = [ + NONE, + NONE, + NONE, + NONE + ]; + else hslB = convertColorToHwb(colorB, { + colorSpace, + format: VAL_MIX + }); + } + if (hslA instanceof NullObject || hslB instanceof NullObject) return cacheInvalidColorValue(cacheKey, format, nullable); + const [hhA, ssA, llA, aaA] = hslA; + const [hhB, ssB, llB, aaB] = hslB; + const alphaNone = aaA === "none" && aaB === "none"; + let [[hA, sA, lA, alphaA], [hB, sB, lB, alphaB]] = normalizeColorComponents([ + hhA, + ssA, + llA, + aaA + ], [ + hhB, + ssB, + llB, + aaB + ], true); + if (hueArc) [hA, hB] = interpolateHue(hA, hB, hueArc); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + const h = (hA * pA + hB * pB) % DEG; + let s, l; + if (alpha === 0) { + s = sA * pA + sB * pB; + l = lA * pA + lB * pB; + } else { + s = (sA * factorA + sB * factorB) / alpha; + l = (lA * factorA + lB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + [r, g, b] = convertColorToRgb(`${colorSpace}(${h} ${s} ${l})`); + if (format === "computedValue") { + const res = [ + "srgb", + roundToPrecision(r / MAX_RGB, HEX), + roundToPrecision(g / MAX_RGB, HEX), + roundToPrecision(b / MAX_RGB, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + } else if (/^(?:ok)?lch$/.test(colorSpace)) { + let lchA, lchB; + if (colorSpace === "lch") { + if (REG_CURRENT.test(colorA)) lchA = [ + NONE, + NONE, + NONE, + NONE + ]; + else lchA = convertColorToLch(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) lchB = [ + NONE, + NONE, + NONE, + NONE + ]; + else lchB = convertColorToLch(colorB, { + colorSpace, + format: VAL_MIX + }); + } else { + if (REG_CURRENT.test(colorA)) lchA = [ + NONE, + NONE, + NONE, + NONE + ]; + else lchA = convertColorToOklch(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) lchB = [ + NONE, + NONE, + NONE, + NONE + ]; + else lchB = convertColorToOklch(colorB, { + colorSpace, + format: VAL_MIX + }); + } + if (lchA instanceof NullObject || lchB instanceof NullObject) return cacheInvalidColorValue(cacheKey, format, nullable); + const [llA, ccA, hhA, aaA] = lchA; + const [llB, ccB, hhB, aaB] = lchB; + const lNone = llA === "none" && llB === "none"; + const cNone = ccA === "none" && ccB === "none"; + const hNone = hhA === "none" && hhB === "none"; + const alphaNone = aaA === "none" && aaB === "none"; + let [[lA, cA, hA, alphaA], [lB, cB, hB, alphaB]] = normalizeColorComponents([ + llA, + ccA, + hhA, + aaA + ], [ + llB, + ccB, + hhB, + aaB + ], true); + if (hueArc) [hA, hB] = interpolateHue(hA, hB, hueArc); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + const h = (hA * pA + hB * pB) % DEG; + let l, c; + if (alpha === 0) { + l = lA * pA + lB * pB; + c = cA * pA + cB * pB; + } else { + l = (lA * factorA + lB * factorB) / alpha; + c = (cA * factorA + cB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === "computedValue") { + const res = [ + colorSpace, + lNone ? NONE : roundToPrecision(l, HEX), + cNone ? NONE : roundToPrecision(c, HEX), + hNone ? NONE : roundToPrecision(h, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + [, r, g, b] = resolveColorValue(`${colorSpace}(${l} ${c} ${h})`); + } else { + let labA, labB; + if (colorSpace === "lab") { + if (REG_CURRENT.test(colorA)) labA = [ + NONE, + NONE, + NONE, + NONE + ]; + else labA = convertColorToLab(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) labB = [ + NONE, + NONE, + NONE, + NONE + ]; + else labB = convertColorToLab(colorB, { + colorSpace, + format: VAL_MIX + }); + } else { + if (REG_CURRENT.test(colorA)) labA = [ + NONE, + NONE, + NONE, + NONE + ]; + else labA = convertColorToOklab(colorA, { + colorSpace, + format: VAL_MIX + }); + if (REG_CURRENT.test(colorB)) labB = [ + NONE, + NONE, + NONE, + NONE + ]; + else labB = convertColorToOklab(colorB, { + colorSpace, + format: VAL_MIX + }); + } + if (labA instanceof NullObject || labB instanceof NullObject) return cacheInvalidColorValue(cacheKey, format, nullable); + const [llA, aaA, bbA, alA] = labA; + const [llB, aaB, bbB, alB] = labB; + const lNone = llA === "none" && llB === "none"; + const aNone = aaA === "none" && aaB === "none"; + const bNone = bbA === "none" && bbB === "none"; + const alphaNone = alA === "none" && alB === "none"; + const [[lA, aA, bA, alphaA], [lB, aB, bB, alphaB]] = normalizeColorComponents([ + llA, + aaA, + bbA, + alA + ], [ + llB, + aaB, + bbB, + alB + ], true); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + let l, aO, bO; + if (alpha === 0) { + l = lA * pA + lB * pB; + aO = aA * pA + aB * pB; + bO = bA * pA + bB * pB; + } else { + l = (lA * factorA + lB * factorB) / alpha; + aO = (aA * factorA + aB * factorB) / alpha; + bO = (bA * factorA + bB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === "computedValue") { + const res = [ + colorSpace, + lNone ? NONE : roundToPrecision(l, HEX), + aNone ? NONE : roundToPrecision(aO, HEX), + bNone ? NONE : roundToPrecision(bO, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + [, r, g, b] = resolveColorValue(`${colorSpace}(${l} ${aO} ${bO})`); + } + const res = [ + "rgb", + Math.round(r), + Math.round(g), + Math.round(b), + parseFloat((alpha * m).toFixed(3)) + ]; + setCache(cacheKey, res); + return res; +}; +//#endregion +export { NAMED_COLORS, convertColorToHsl, convertColorToHwb, convertColorToLab, convertColorToLch, convertColorToOklab, convertColorToOklch, convertColorToRgb, convertRgbToHex, numberToHexString, parseColorFunc, parseColorValue, resolveColorFunc, resolveColorMix, resolveColorValue }; + +//# sourceMappingURL=color.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/color.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/color.js.map new file mode 100644 index 0000000..40a1df0 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/color.js.map @@ -0,0 +1 @@ +{"version":3,"file":"color.js","names":[],"sources":["../../../src/js/color.ts"],"sourcesContent":["/**\n * color\n *\n * Ref: CSS Color Module Level 4\n * Sample code for Color Conversions\n * https://w3c.github.io/csswg-drafts/css-color-4/#color-conversion-code\n */\n\nimport {\n CacheItem,\n NullObject,\n createCacheKey,\n getCache,\n setCache\n} from './cache';\nimport { isString } from './common';\nimport { resolveColor } from './resolve';\nimport { interpolateHue, roundToPrecision, splitValue } from './util';\nimport {\n ColorChannels,\n ComputedColorChannels,\n Options,\n MatchedRegExp,\n SpecifiedColorChannels,\n StringColorChannels,\n StringColorSpacedChannels\n} from './typedef';\n\n/* constants */\nimport {\n ANGLE,\n CS_HUE_CAPT,\n CS_MIX,\n CS_RGB,\n CS_XYZ,\n FN_COLOR,\n FN_LIGHT_DARK,\n FN_MIX,\n NONE,\n NUM,\n PCT,\n SYN_COLOR_TYPE,\n SYN_FN_COLOR,\n SYN_HSL,\n SYN_HSL_LV3,\n SYN_LCH,\n SYN_MIX,\n SYN_MIX_CAPT,\n SYN_MIX_PART,\n SYN_MOD,\n SYN_RGB_LV3,\n VAL_COMP,\n VAL_MIX,\n VAL_SPEC\n} from './constant';\nconst NAMESPACE = 'color';\n\n/* numeric constants */\nconst PPTH = 0.001;\nconst HALF = 0.5;\nconst DUO = 2;\nconst TRIA = 3;\nconst QUAD = 4;\nconst OCT = 8;\nconst DEC = 10;\nconst DOZ = 12;\nconst HEX = 16;\nconst SEXA = 60;\nconst DEG_HALF = 180;\nconst DEG = 360;\nconst MAX_PCT = 100;\nconst MAX_RGB = 255;\nconst POW_SQR = 2;\nconst POW_CUBE = 3;\nconst POW_LINEAR = 2.4;\nconst LINEAR_COEF = 12.92;\nconst LINEAR_OFFSET = 0.055;\nconst LAB_L = 116;\nconst LAB_A = 500;\nconst LAB_B = 200;\nconst LAB_EPSILON = 216 / 24389;\nconst LAB_KAPPA = 24389 / 27;\n\n/* type definitions */\n/**\n * @type NumStrColorChannels - string or numeric color channels\n */\ntype NumStrColorChannels = [\n x: number | string,\n y: number | string,\n z: number | string,\n alpha: number | string\n];\n\n/**\n * @type TriColorChannels - color channels without alpha\n */\ntype TriColorChannels = [x: number, y: number, z: number];\n\n/**\n * @type ColorMatrix - color matrix\n */\ntype ColorMatrix = [\n r1: TriColorChannels,\n r2: TriColorChannels,\n r3: TriColorChannels\n];\n\n/* white point */\nconst D50: TriColorChannels = [\n 0.3457 / 0.3585,\n 1.0,\n (1.0 - 0.3457 - 0.3585) / 0.3585\n];\nconst MATRIX_D50_TO_D65: ColorMatrix = [\n [0.955473421488075, -0.02309845494876471, 0.06325924320057072],\n [-0.0283697093338637, 1.0099953980813041, 0.021041441191917323],\n [0.012314014864481998, -0.020507649298898964, 1.330365926242124]\n];\nconst MATRIX_D65_TO_D50: ColorMatrix = [\n [1.0479297925449969, 0.022946870601609652, -0.05019226628920524],\n [0.02962780877005599, 0.9904344267538799, -0.017073799063418826],\n [-0.009243040646204504, 0.015055191490298152, 0.7518742814281371]\n];\n\n/* color space */\nconst MATRIX_L_RGB_TO_XYZ: ColorMatrix = [\n [506752 / 1228815, 87881 / 245763, 12673 / 70218],\n [87098 / 409605, 175762 / 245763, 12673 / 175545],\n [7918 / 409605, 87881 / 737289, 1001167 / 1053270]\n];\nconst MATRIX_XYZ_TO_L_RGB: ColorMatrix = [\n [12831 / 3959, -329 / 214, -1974 / 3959],\n [-851781 / 878810, 1648619 / 878810, 36519 / 878810],\n [705 / 12673, -2585 / 12673, 705 / 667]\n];\nconst MATRIX_XYZ_TO_LMS: ColorMatrix = [\n [0.819022437996703, 0.3619062600528904, -0.1288737815209879],\n [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],\n [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]\n];\nconst MATRIX_LMS_TO_XYZ: ColorMatrix = [\n [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],\n [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],\n [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]\n];\nconst MATRIX_OKLAB_TO_LMS: ColorMatrix = [\n [1.0, 0.3963377773761749, 0.2158037573099136],\n [1.0, -0.1055613458156586, -0.0638541728258133],\n [1.0, -0.0894841775298119, -1.2914855480194092]\n];\nconst MATRIX_LMS_TO_OKLAB: ColorMatrix = [\n [0.210454268309314, 0.7936177747023054, -0.0040720430116193],\n [1.9779985324311684, -2.4285922420485799, 0.450593709617411],\n [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]\n];\nconst MATRIX_P3_TO_XYZ: ColorMatrix = [\n [608311 / 1250200, 189793 / 714400, 198249 / 1000160],\n [35783 / 156275, 247089 / 357200, 198249 / 2500400],\n [0 / 1, 32229 / 714400, 5220557 / 5000800]\n];\nconst MATRIX_REC2020_TO_XYZ: ColorMatrix = [\n [63426534 / 99577255, 20160776 / 139408157, 47086771 / 278816314],\n [26158966 / 99577255, 472592308 / 697040785, 8267143 / 139408157],\n [0 / 1, 19567812 / 697040785, 295819943 / 278816314]\n];\nconst MATRIX_A98_TO_XYZ: ColorMatrix = [\n [573536 / 994567, 263643 / 1420810, 187206 / 994567],\n [591459 / 1989134, 6239551 / 9945670, 374412 / 4972835],\n [53769 / 1989134, 351524 / 4972835, 4929758 / 4972835]\n];\nconst MATRIX_PROPHOTO_TO_XYZ_D50: ColorMatrix = [\n [0.7977666449006423, 0.13518129740053308, 0.0313477341283922],\n [0.2880748288194013, 0.711835234241873, 0.00008993693872564],\n [0.0, 0.0, 0.8251046025104602]\n];\n\n/* regexp */\nconst REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`);\nconst REG_CS_HUE = new RegExp(`^${CS_HUE_CAPT}$`);\nconst REG_CS_XYZ = /^xyz(?:-d(?:50|65))?$/;\nconst REG_CURRENT = /^currentColor$/i;\nconst REG_FN_COLOR = new RegExp(`^color\\\\(\\\\s*(${SYN_FN_COLOR})\\\\s*\\\\)$`);\nconst REG_HSL = new RegExp(`^hsla?\\\\(\\\\s*(${SYN_HSL}|${SYN_HSL_LV3})\\\\s*\\\\)$`);\nconst REG_HWB = new RegExp(`^hwb\\\\(\\\\s*(${SYN_HSL})\\\\s*\\\\)$`);\nconst REG_LAB = new RegExp(`^lab\\\\(\\\\s*(${SYN_MOD})\\\\s*\\\\)$`);\nconst REG_LCH = new RegExp(`^lch\\\\(\\\\s*(${SYN_LCH})\\\\s*\\\\)$`);\nconst REG_MIX = new RegExp(`^${SYN_MIX}$`);\nconst REG_MIX_CAPT = new RegExp(`^${SYN_MIX_CAPT}$`);\nconst REG_MIX_NEST = new RegExp(`${SYN_MIX}`, 'g');\nconst REG_OKLAB = new RegExp(`^oklab\\\\(\\\\s*(${SYN_MOD})\\\\s*\\\\)$`);\nconst REG_OKLCH = new RegExp(`^oklch\\\\(\\\\s*(${SYN_LCH})\\\\s*\\\\)$`);\nconst REG_SPEC = /^(?:specifi|comput)edValue$/;\nconst REG_ANGLE_TO_DEG = new RegExp(`^(${NUM})(${ANGLE})?$`);\nconst REG_PARSE_RGB = new RegExp(\n `^rgba?\\\\(\\\\s*(${SYN_MOD}|${SYN_RGB_LV3})\\\\s*\\\\)$`\n);\nconst REG_MIX_CS_RGB_XYZ = new RegExp(`^(?:${CS_RGB}|${CS_XYZ})$`);\nconst REG_MIX_IN_CS = new RegExp(`in\\\\s+(${CS_MIX})`);\nconst REG_MIX_START = new RegExp(`^color-mix\\\\(\\\\s*in\\\\s+(${CS_MIX})\\\\s*,`);\nconst REG_MIX_COLOR_PART = new RegExp(`^(${SYN_COLOR_TYPE})(?:\\\\s+(${PCT}))?$`);\n\n/**\n * named colors\n */\nexport const NAMED_COLORS = {\n aliceblue: [0xf0, 0xf8, 0xff],\n antiquewhite: [0xfa, 0xeb, 0xd7],\n aqua: [0x00, 0xff, 0xff],\n aquamarine: [0x7f, 0xff, 0xd4],\n azure: [0xf0, 0xff, 0xff],\n beige: [0xf5, 0xf5, 0xdc],\n bisque: [0xff, 0xe4, 0xc4],\n black: [0x00, 0x00, 0x00],\n blanchedalmond: [0xff, 0xeb, 0xcd],\n blue: [0x00, 0x00, 0xff],\n blueviolet: [0x8a, 0x2b, 0xe2],\n brown: [0xa5, 0x2a, 0x2a],\n burlywood: [0xde, 0xb8, 0x87],\n cadetblue: [0x5f, 0x9e, 0xa0],\n chartreuse: [0x7f, 0xff, 0x00],\n chocolate: [0xd2, 0x69, 0x1e],\n coral: [0xff, 0x7f, 0x50],\n cornflowerblue: [0x64, 0x95, 0xed],\n cornsilk: [0xff, 0xf8, 0xdc],\n crimson: [0xdc, 0x14, 0x3c],\n cyan: [0x00, 0xff, 0xff],\n darkblue: [0x00, 0x00, 0x8b],\n darkcyan: [0x00, 0x8b, 0x8b],\n darkgoldenrod: [0xb8, 0x86, 0x0b],\n darkgray: [0xa9, 0xa9, 0xa9],\n darkgreen: [0x00, 0x64, 0x00],\n darkgrey: [0xa9, 0xa9, 0xa9],\n darkkhaki: [0xbd, 0xb7, 0x6b],\n darkmagenta: [0x8b, 0x00, 0x8b],\n darkolivegreen: [0x55, 0x6b, 0x2f],\n darkorange: [0xff, 0x8c, 0x00],\n darkorchid: [0x99, 0x32, 0xcc],\n darkred: [0x8b, 0x00, 0x00],\n darksalmon: [0xe9, 0x96, 0x7a],\n darkseagreen: [0x8f, 0xbc, 0x8f],\n darkslateblue: [0x48, 0x3d, 0x8b],\n darkslategray: [0x2f, 0x4f, 0x4f],\n darkslategrey: [0x2f, 0x4f, 0x4f],\n darkturquoise: [0x00, 0xce, 0xd1],\n darkviolet: [0x94, 0x00, 0xd3],\n deeppink: [0xff, 0x14, 0x93],\n deepskyblue: [0x00, 0xbf, 0xff],\n dimgray: [0x69, 0x69, 0x69],\n dimgrey: [0x69, 0x69, 0x69],\n dodgerblue: [0x1e, 0x90, 0xff],\n firebrick: [0xb2, 0x22, 0x22],\n floralwhite: [0xff, 0xfa, 0xf0],\n forestgreen: [0x22, 0x8b, 0x22],\n fuchsia: [0xff, 0x00, 0xff],\n gainsboro: [0xdc, 0xdc, 0xdc],\n ghostwhite: [0xf8, 0xf8, 0xff],\n gold: [0xff, 0xd7, 0x00],\n goldenrod: [0xda, 0xa5, 0x20],\n gray: [0x80, 0x80, 0x80],\n green: [0x00, 0x80, 0x00],\n greenyellow: [0xad, 0xff, 0x2f],\n grey: [0x80, 0x80, 0x80],\n honeydew: [0xf0, 0xff, 0xf0],\n hotpink: [0xff, 0x69, 0xb4],\n indianred: [0xcd, 0x5c, 0x5c],\n indigo: [0x4b, 0x00, 0x82],\n ivory: [0xff, 0xff, 0xf0],\n khaki: [0xf0, 0xe6, 0x8c],\n lavender: [0xe6, 0xe6, 0xfa],\n lavenderblush: [0xff, 0xf0, 0xf5],\n lawngreen: [0x7c, 0xfc, 0x00],\n lemonchiffon: [0xff, 0xfa, 0xcd],\n lightblue: [0xad, 0xd8, 0xe6],\n lightcoral: [0xf0, 0x80, 0x80],\n lightcyan: [0xe0, 0xff, 0xff],\n lightgoldenrodyellow: [0xfa, 0xfa, 0xd2],\n lightgray: [0xd3, 0xd3, 0xd3],\n lightgreen: [0x90, 0xee, 0x90],\n lightgrey: [0xd3, 0xd3, 0xd3],\n lightpink: [0xff, 0xb6, 0xc1],\n lightsalmon: [0xff, 0xa0, 0x7a],\n lightseagreen: [0x20, 0xb2, 0xaa],\n lightskyblue: [0x87, 0xce, 0xfa],\n lightslategray: [0x77, 0x88, 0x99],\n lightslategrey: [0x77, 0x88, 0x99],\n lightsteelblue: [0xb0, 0xc4, 0xde],\n lightyellow: [0xff, 0xff, 0xe0],\n lime: [0x00, 0xff, 0x00],\n limegreen: [0x32, 0xcd, 0x32],\n linen: [0xfa, 0xf0, 0xe6],\n magenta: [0xff, 0x00, 0xff],\n maroon: [0x80, 0x00, 0x00],\n mediumaquamarine: [0x66, 0xcd, 0xaa],\n mediumblue: [0x00, 0x00, 0xcd],\n mediumorchid: [0xba, 0x55, 0xd3],\n mediumpurple: [0x93, 0x70, 0xdb],\n mediumseagreen: [0x3c, 0xb3, 0x71],\n mediumslateblue: [0x7b, 0x68, 0xee],\n mediumspringgreen: [0x00, 0xfa, 0x9a],\n mediumturquoise: [0x48, 0xd1, 0xcc],\n mediumvioletred: [0xc7, 0x15, 0x85],\n midnightblue: [0x19, 0x19, 0x70],\n mintcream: [0xf5, 0xff, 0xfa],\n mistyrose: [0xff, 0xe4, 0xe1],\n moccasin: [0xff, 0xe4, 0xb5],\n navajowhite: [0xff, 0xde, 0xad],\n navy: [0x00, 0x00, 0x80],\n oldlace: [0xfd, 0xf5, 0xe6],\n olive: [0x80, 0x80, 0x00],\n olivedrab: [0x6b, 0x8e, 0x23],\n orange: [0xff, 0xa5, 0x00],\n orangered: [0xff, 0x45, 0x00],\n orchid: [0xda, 0x70, 0xd6],\n palegoldenrod: [0xee, 0xe8, 0xaa],\n palegreen: [0x98, 0xfb, 0x98],\n paleturquoise: [0xaf, 0xee, 0xee],\n palevioletred: [0xdb, 0x70, 0x93],\n papayawhip: [0xff, 0xef, 0xd5],\n peachpuff: [0xff, 0xda, 0xb9],\n peru: [0xcd, 0x85, 0x3f],\n pink: [0xff, 0xc0, 0xcb],\n plum: [0xdd, 0xa0, 0xdd],\n powderblue: [0xb0, 0xe0, 0xe6],\n purple: [0x80, 0x00, 0x80],\n rebeccapurple: [0x66, 0x33, 0x99],\n red: [0xff, 0x00, 0x00],\n rosybrown: [0xbc, 0x8f, 0x8f],\n royalblue: [0x41, 0x69, 0xe1],\n saddlebrown: [0x8b, 0x45, 0x13],\n salmon: [0xfa, 0x80, 0x72],\n sandybrown: [0xf4, 0xa4, 0x60],\n seagreen: [0x2e, 0x8b, 0x57],\n seashell: [0xff, 0xf5, 0xee],\n sienna: [0xa0, 0x52, 0x2d],\n silver: [0xc0, 0xc0, 0xc0],\n skyblue: [0x87, 0xce, 0xeb],\n slateblue: [0x6a, 0x5a, 0xcd],\n slategray: [0x70, 0x80, 0x90],\n slategrey: [0x70, 0x80, 0x90],\n snow: [0xff, 0xfa, 0xfa],\n springgreen: [0x00, 0xff, 0x7f],\n steelblue: [0x46, 0x82, 0xb4],\n tan: [0xd2, 0xb4, 0x8c],\n teal: [0x00, 0x80, 0x80],\n thistle: [0xd8, 0xbf, 0xd8],\n tomato: [0xff, 0x63, 0x47],\n turquoise: [0x40, 0xe0, 0xd0],\n violet: [0xee, 0x82, 0xee],\n wheat: [0xf5, 0xde, 0xb3],\n white: [0xff, 0xff, 0xff],\n whitesmoke: [0xf5, 0xf5, 0xf5],\n yellow: [0xff, 0xff, 0x00],\n yellowgreen: [0x9a, 0xcd, 0x32]\n} as const satisfies {\n [key: string]: TriColorChannels;\n};\n\n/**\n * cache invalid color value\n * @param key - cache key\n * @param nullable - is nullable\n * @returns cached value\n */\nexport const cacheInvalidColorValue = (\n cacheKey: string,\n format: string,\n nullable: boolean = false\n): SpecifiedColorChannels | string | NullObject => {\n if (format === VAL_SPEC) {\n const res = '';\n setCache(cacheKey, res);\n return res;\n }\n if (nullable) {\n setCache(cacheKey, null);\n return new NullObject();\n }\n const res: SpecifiedColorChannels = ['rgb', 0, 0, 0, 0];\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * resolve invalid color value\n * @param format - output format\n * @param nullable - is nullable\n * @returns resolved value\n */\nexport const resolveInvalidColorValue = (\n format: string,\n nullable: boolean = false\n): SpecifiedColorChannels | string | NullObject => {\n switch (format) {\n case 'hsl':\n case 'hwb':\n case VAL_MIX: {\n return new NullObject();\n }\n case VAL_SPEC: {\n return '';\n }\n default: {\n if (nullable) {\n return new NullObject();\n }\n return ['rgb', 0, 0, 0, 0] as SpecifiedColorChannels;\n }\n }\n};\n\n/**\n * validate color components\n * @param arr - color components\n * @param [opt] - options\n * @param [opt.alpha] - alpha channel\n * @param [opt.minLength] - min length\n * @param [opt.maxLength] - max length\n * @param [opt.minRange] - min range\n * @param [opt.maxRange] - max range\n * @param [opt.validateRange] - validate range\n * @returns result - validated color components\n */\nexport const validateColorComponents = (\n arr: ColorChannels | TriColorChannels,\n opt: {\n alpha?: boolean;\n minLength?: number;\n maxLength?: number;\n minRange?: number;\n maxRange?: number;\n validateRange?: boolean;\n } = {}\n): ColorChannels | TriColorChannels => {\n if (!Array.isArray(arr)) {\n throw new TypeError(`${arr} is not an array.`);\n }\n const {\n alpha = false,\n minLength = TRIA,\n maxLength = QUAD,\n minRange = 0,\n maxRange = 1,\n validateRange = true\n } = opt;\n if (!Number.isFinite(minLength)) {\n throw new TypeError(`${minLength} is not a number.`);\n }\n if (!Number.isFinite(maxLength)) {\n throw new TypeError(`${maxLength} is not a number.`);\n }\n if (!Number.isFinite(minRange)) {\n throw new TypeError(`${minRange} is not a number.`);\n }\n if (!Number.isFinite(maxRange)) {\n throw new TypeError(`${maxRange} is not a number.`);\n }\n const l = arr.length;\n if (l < minLength || l > maxLength) {\n throw new Error(`Unexpected array length ${l}.`);\n }\n let i = 0;\n while (i < l) {\n const v = arr[i] as number;\n if (!Number.isFinite(v)) {\n throw new TypeError(`${v} is not a number.`);\n } else if (i < TRIA && validateRange && (v < minRange || v > maxRange)) {\n throw new RangeError(`${v} is not between ${minRange} and ${maxRange}.`);\n } else if (i === TRIA && (v < 0 || v > 1)) {\n throw new RangeError(`${v} is not between 0 and 1.`);\n }\n i++;\n }\n if (alpha && l === TRIA) {\n arr.push(1);\n }\n return arr;\n};\n\n/**\n * transform matrix\n * @param mtx - 3 * 3 matrix\n * @param vct - vector\n * @param [skip] - skip validate\n * @returns TriColorChannels - [p1, p2, p3]\n */\nexport const transformMatrix = (\n mtx: ColorMatrix,\n vct: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n if (!Array.isArray(mtx)) {\n throw new TypeError(`${mtx} is not an array.`);\n } else if (mtx.length !== TRIA) {\n throw new Error(`Unexpected array length ${mtx.length}.`);\n } else if (!skip) {\n for (let i of mtx) {\n i = validateColorComponents(i as TriColorChannels, {\n maxLength: TRIA,\n validateRange: false\n }) as TriColorChannels;\n }\n }\n const [[r1c1, r1c2, r1c3], [r2c1, r2c2, r2c3], [r3c1, r3c2, r3c3]] = mtx;\n let v1, v2, v3;\n if (skip) {\n [v1, v2, v3] = vct;\n } else {\n [v1, v2, v3] = validateColorComponents(vct, {\n maxLength: TRIA,\n validateRange: false\n });\n }\n const p1 = r1c1 * v1 + r1c2 * v2 + r1c3 * v3;\n const p2 = r2c1 * v1 + r2c2 * v2 + r2c3 * v3;\n const p3 = r3c1 * v1 + r3c2 * v2 + r3c3 * v3;\n return [p1, p2, p3];\n};\n\n/**\n * normalize color components\n * @param colorA - color components [v1, v2, v3, v4]\n * @param colorB - color components [v1, v2, v3, v4]\n * @param [skip] - skip validate\n * @returns result - [colorA, colorB]\n */\nexport const normalizeColorComponents = (\n colorA: [number | string, number | string, number | string, number | string],\n colorB: [number | string, number | string, number | string, number | string],\n skip: boolean = false\n): [ColorChannels, ColorChannels] => {\n if (!Array.isArray(colorA)) {\n throw new TypeError(`${colorA} is not an array.`);\n } else if (colorA.length !== QUAD) {\n throw new Error(`Unexpected array length ${colorA.length}.`);\n }\n if (!Array.isArray(colorB)) {\n throw new TypeError(`${colorB} is not an array.`);\n } else if (colorB.length !== QUAD) {\n throw new Error(`Unexpected array length ${colorB.length}.`);\n }\n let i = 0;\n while (i < QUAD) {\n if (colorA[i] === NONE && colorB[i] === NONE) {\n colorA[i] = 0;\n colorB[i] = 0;\n } else if (colorA[i] === NONE) {\n colorA[i] = colorB[i] as number;\n } else if (colorB[i] === NONE) {\n colorB[i] = colorA[i] as number;\n }\n i++;\n }\n if (skip) {\n return [colorA as ColorChannels, colorB as ColorChannels];\n }\n const validatedColorA = validateColorComponents(colorA as ColorChannels, {\n minLength: QUAD,\n validateRange: false\n });\n const validatedColorB = validateColorComponents(colorB as ColorChannels, {\n minLength: QUAD,\n validateRange: false\n });\n return [validatedColorA as ColorChannels, validatedColorB as ColorChannels];\n};\n\n/**\n * number to hex string\n * @param value - numeric value\n * @returns hex string\n */\nexport const numberToHexString = (value: number): string => {\n if (!Number.isFinite(value)) {\n throw new TypeError(`${value} is not a number.`);\n } else {\n value = Math.round(value);\n if (value < 0 || value > MAX_RGB) {\n throw new RangeError(`${value} is not between 0 and ${MAX_RGB}.`);\n }\n }\n let hex = value.toString(HEX);\n if (hex.length === 1) {\n hex = `0${hex}`;\n }\n return hex;\n};\n\n/**\n * angle to deg\n * @param angle\n * @returns deg: 0..360\n */\nexport const angleToDeg = (angle: string): number => {\n if (isString(angle)) {\n angle = angle.trim();\n } else {\n throw new TypeError(`${angle} is not a string.`);\n }\n const GRAD = DEG / 400;\n const RAD = DEG / (Math.PI * DUO);\n if (!REG_ANGLE_TO_DEG.test(angle)) {\n throw new SyntaxError(`Invalid property value: ${angle}`);\n }\n const [, value, unit] = angle.match(REG_ANGLE_TO_DEG) as MatchedRegExp;\n let deg;\n switch (unit) {\n case 'grad':\n deg = parseFloat(value) * GRAD;\n break;\n case 'rad':\n deg = parseFloat(value) * RAD;\n break;\n case 'turn':\n deg = parseFloat(value) * DEG;\n break;\n default:\n deg = parseFloat(value);\n }\n deg %= DEG;\n if (deg < 0) {\n deg += DEG;\n } else if (Object.is(deg, -0)) {\n deg = 0;\n }\n return deg;\n};\n\n/**\n * parse alpha\n * @param [alpha] - alpha value\n * @returns alpha: 0..1\n */\nexport const parseAlpha = (alpha: string = ''): number => {\n if (isString(alpha)) {\n alpha = alpha.trim();\n if (!alpha) {\n alpha = '1';\n } else if (alpha === NONE) {\n alpha = '0';\n } else {\n let a;\n if (alpha.endsWith('%')) {\n a = parseFloat(alpha) / MAX_PCT;\n } else {\n a = parseFloat(alpha);\n }\n if (!Number.isFinite(a)) {\n throw new TypeError(`${a} is not a finite number.`);\n }\n if (a < PPTH) {\n alpha = '0';\n } else if (a > 1) {\n alpha = '1';\n } else {\n alpha = a.toFixed(TRIA);\n }\n }\n } else {\n alpha = '1';\n }\n return parseFloat(alpha);\n};\n\n/**\n * parse hex alpha\n * @param value - alpha value in hex string\n * @returns alpha: 0..1\n */\nexport const parseHexAlpha = (value: string): number => {\n if (isString(value)) {\n if (value === '') {\n throw new SyntaxError('Invalid property value: (empty string)');\n }\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n let alpha = parseInt(value, HEX);\n if (alpha <= 0) {\n return 0;\n }\n if (alpha >= MAX_RGB) {\n return 1;\n }\n const alphaMap = new Map();\n for (let i = 1; i < MAX_PCT; i++) {\n alphaMap.set(Math.round((i * MAX_RGB) / MAX_PCT), i);\n }\n if (alphaMap.has(alpha)) {\n alpha = alphaMap.get(alpha) / MAX_PCT;\n } else {\n alpha = Math.round(alpha / MAX_RGB / PPTH) * PPTH;\n }\n return parseFloat(alpha.toFixed(TRIA));\n};\n\n/**\n * transform rgb to linear rgb\n * @param rgb - [r, g, b] r|g|b: 0..255\n * @param [skip] - skip validate\n * @returns TriColorChannels - [r, g, b] r|g|b: 0..1\n */\nexport const transformRgbToLinearRgb = (\n rgb: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n let rr, gg, bb;\n if (skip) {\n [rr, gg, bb] = rgb;\n } else {\n [rr, gg, bb] = validateColorComponents(rgb, {\n maxLength: TRIA,\n maxRange: MAX_RGB\n });\n }\n let r = rr / MAX_RGB;\n let g = gg / MAX_RGB;\n let b = bb / MAX_RGB;\n const COND_POW = 0.04045;\n if (r > COND_POW) {\n r = Math.pow((r + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR);\n } else {\n r /= LINEAR_COEF;\n }\n if (g > COND_POW) {\n g = Math.pow((g + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR);\n } else {\n g /= LINEAR_COEF;\n }\n if (b > COND_POW) {\n b = Math.pow((b + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR);\n } else {\n b /= LINEAR_COEF;\n }\n return [r, g, b];\n};\n\n/**\n * transform rgb to xyz\n * @param rgb - [r, g, b] r|g|b: 0..255\n * @param [skip] - skip validate\n * @returns TriColorChannels - [x, y, z]\n */\nexport const transformRgbToXyz = (\n rgb: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n if (!skip) {\n rgb = validateColorComponents(rgb, {\n maxLength: TRIA,\n maxRange: MAX_RGB\n }) as TriColorChannels;\n }\n rgb = transformRgbToLinearRgb(rgb, true);\n const xyz = transformMatrix(MATRIX_L_RGB_TO_XYZ, rgb, true);\n return xyz;\n};\n\n/**\n * transform rgb to xyz-d50\n * @param rgb - [r, g, b] r|g|b: 0..255 alpha: 0..1\n * @returns TriColorChannels - [x, y, z]\n */\nexport const transformRgbToXyzD50 = (\n rgb: TriColorChannels\n): TriColorChannels => {\n let xyz = transformRgbToXyz(rgb);\n xyz = transformMatrix(MATRIX_D65_TO_D50, xyz, true);\n return xyz;\n};\n\n/**\n * transform linear rgb to rgb\n * @param rgb - [r, g, b] r|g|b: 0..1\n * @param [round] - round result\n * @returns TriColorChannels - [r, g, b] r|g|b: 0..255\n */\nexport const transformLinearRgbToRgb = (\n rgb: TriColorChannels,\n round: boolean = false\n): TriColorChannels => {\n let [r, g, b] = validateColorComponents(rgb, {\n maxLength: TRIA\n });\n const COND_POW = 809 / 258400;\n if (r > COND_POW) {\n r = Math.pow(r, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET;\n } else {\n r *= LINEAR_COEF;\n }\n r *= MAX_RGB;\n if (g > COND_POW) {\n g = Math.pow(g, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET;\n } else {\n g *= LINEAR_COEF;\n }\n g *= MAX_RGB;\n if (b > COND_POW) {\n b = Math.pow(b, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET;\n } else {\n b *= LINEAR_COEF;\n }\n b *= MAX_RGB;\n return [\n round ? Math.round(r) : r,\n round ? Math.round(g) : g,\n round ? Math.round(b) : b\n ];\n};\n\n/**\n * transform xyz to rgb\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [r, g, b] r|g|b: 0..255\n */\nexport const transformXyzToRgb = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n if (!skip) {\n xyz = validateColorComponents(xyz, {\n maxLength: TRIA,\n validateRange: false\n }) as TriColorChannels;\n }\n let [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, xyz, true);\n [r, g, b] = transformLinearRgbToRgb(\n [\n Math.min(Math.max(r, 0), 1),\n Math.min(Math.max(g, 0), 1),\n Math.min(Math.max(b, 0), 1)\n ],\n true\n );\n return [r, g, b];\n};\n\n/**\n * transform xyz to xyz-d50\n * @param xyz - [x, y, z]\n * @returns TriColorChannels - [x, y, z]\n */\nexport const transformXyzToXyzD50 = (\n xyz: TriColorChannels\n): TriColorChannels => {\n xyz = validateColorComponents(xyz, {\n maxLength: TRIA,\n validateRange: false\n }) as TriColorChannels;\n xyz = transformMatrix(MATRIX_D65_TO_D50, xyz, true);\n return xyz;\n};\n\n/**\n * transform xyz to hsl\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [h, s, l]\n */\nexport const transformXyzToHsl = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n const [rr, gg, bb] = transformXyzToRgb(xyz, skip);\n const r = rr / MAX_RGB;\n const g = gg / MAX_RGB;\n const b = bb / MAX_RGB;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n const l = (max + min) * HALF * MAX_PCT;\n let h, s;\n if (Math.round(l) === 0 || Math.round(l) === MAX_PCT) {\n h = 0;\n s = 0;\n } else {\n s = (d / (1 - Math.abs(max + min - 1))) * MAX_PCT;\n if (s === 0) {\n h = 0;\n } else {\n switch (max) {\n case r:\n h = (g - b) / d;\n break;\n case g:\n h = (b - r) / d + DUO;\n break;\n case b:\n default:\n h = (r - g) / d + QUAD;\n break;\n }\n h = (h * SEXA) % DEG;\n if (h < 0) {\n h += DEG;\n }\n }\n }\n return [h, s, l];\n};\n\n/**\n * transform xyz to hwb\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [h, w, b]\n */\nexport const transformXyzToHwb = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n const [r, g, b] = transformXyzToRgb(xyz, skip);\n const wh = Math.min(r, g, b) / MAX_RGB;\n const bk = 1 - Math.max(r, g, b) / MAX_RGB;\n let h;\n if (wh + bk === 1) {\n h = 0;\n } else {\n [h] = transformXyzToHsl(xyz);\n }\n return [h, wh * MAX_PCT, bk * MAX_PCT];\n};\n\n/**\n * transform xyz to oklab\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [l, a, b]\n */\nexport const transformXyzToOklab = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n if (!skip) {\n xyz = validateColorComponents(xyz, {\n maxLength: TRIA,\n validateRange: false\n }) as TriColorChannels;\n }\n const lms = transformMatrix(MATRIX_XYZ_TO_LMS, xyz, true);\n const xyzLms = lms.map(c => Math.cbrt(c)) as TriColorChannels;\n let [l, a, b] = transformMatrix(MATRIX_LMS_TO_OKLAB, xyzLms, true);\n l = Math.min(Math.max(l, 0), 1);\n const lPct = Math.round(parseFloat(l.toFixed(QUAD)) * MAX_PCT);\n if (lPct === 0 || lPct === MAX_PCT) {\n a = 0;\n b = 0;\n }\n return [l, a, b];\n};\n\n/**\n * transform xyz to oklch\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [l, c, h]\n */\nexport const transformXyzToOklch = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n const [l, a, b] = transformXyzToOklab(xyz, skip);\n let c, h;\n const lPct = Math.round(parseFloat(l.toFixed(QUAD)) * MAX_PCT);\n if (lPct === 0 || lPct === MAX_PCT) {\n c = 0;\n h = 0;\n } else {\n c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0);\n if (parseFloat(c.toFixed(QUAD)) === 0) {\n h = 0;\n } else {\n h = (Math.atan2(b, a) * DEG_HALF) / Math.PI;\n if (h < 0) {\n h += DEG;\n }\n }\n }\n return [l, c, h];\n};\n\n/**\n * transform xyz D50 to rgb\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [r, g, b] r|g|b: 0..255\n */\nexport const transformXyzD50ToRgb = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n if (!skip) {\n xyz = validateColorComponents(xyz, {\n maxLength: TRIA,\n validateRange: false\n }) as TriColorChannels;\n }\n const xyzD65 = transformMatrix(MATRIX_D50_TO_D65, xyz, true);\n const rgb = transformXyzToRgb(xyzD65, true);\n return rgb;\n};\n\n/**\n * transform xyz-d50 to lab\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [l, a, b]\n */\nexport const transformXyzD50ToLab = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n if (!skip) {\n xyz = validateColorComponents(xyz, {\n maxLength: TRIA,\n validateRange: false\n }) as TriColorChannels;\n }\n const xyzD50 = xyz.map((val, i) => val / (D50[i] as number));\n const [f0, f1, f2] = xyzD50.map(val =>\n val > LAB_EPSILON ? Math.cbrt(val) : (val * LAB_KAPPA + HEX) / LAB_L\n ) as TriColorChannels;\n const l = Math.min(Math.max(LAB_L * f1 - HEX, 0), MAX_PCT);\n let a, b;\n if (l === 0 || l === MAX_PCT) {\n a = 0;\n b = 0;\n } else {\n a = (f0 - f1) * LAB_A;\n b = (f1 - f2) * LAB_B;\n }\n return [l, a, b];\n};\n\n/**\n * transform xyz-d50 to lch\n * @param xyz - [x, y, z]\n * @param [skip] - skip validate\n * @returns TriColorChannels - [l, c, h]\n */\nexport const transformXyzD50ToLch = (\n xyz: TriColorChannels,\n skip: boolean = false\n): TriColorChannels => {\n const [l, a, b] = transformXyzD50ToLab(xyz, skip);\n let c, h;\n if (l === 0 || l === MAX_PCT) {\n c = 0;\n h = 0;\n } else {\n c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0);\n h = (Math.atan2(b, a) * DEG_HALF) / Math.PI;\n if (h < 0) {\n h += DEG;\n }\n }\n return [l, c, h];\n};\n\n/**\n * convert rgb to hex color\n * @param rgb - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1\n * @returns hex color\n */\nexport const convertRgbToHex = (rgb: ColorChannels): string => {\n const [r, g, b, alpha] = validateColorComponents(rgb, {\n alpha: true,\n maxRange: MAX_RGB\n }) as ColorChannels;\n const rr = numberToHexString(r);\n const gg = numberToHexString(g);\n const bb = numberToHexString(b);\n const aa = numberToHexString(alpha * MAX_RGB);\n let hex;\n if (aa === 'ff') {\n hex = `#${rr}${gg}${bb}`;\n } else {\n hex = `#${rr}${gg}${bb}${aa}`;\n }\n return hex;\n};\n\n/**\n * convert linear rgb to hex color\n * @param rgb - [r, g, b, alpha] r|g|b|alpha: 0..1\n * @param [skip] - skip validate\n * @returns hex color\n */\nexport const convertLinearRgbToHex = (\n rgb: ColorChannels,\n skip: boolean = false\n): string => {\n let r, g, b, alpha;\n if (skip) {\n [r, g, b, alpha] = rgb;\n } else {\n [r, g, b, alpha] = validateColorComponents(rgb, {\n minLength: QUAD\n }) as ColorChannels;\n }\n [r, g, b] = transformLinearRgbToRgb([r, g, b], true);\n const rr = numberToHexString(r);\n const gg = numberToHexString(g);\n const bb = numberToHexString(b);\n const aa = numberToHexString(alpha * MAX_RGB);\n let hex;\n if (aa === 'ff') {\n hex = `#${rr}${gg}${bb}`;\n } else {\n hex = `#${rr}${gg}${bb}${aa}`;\n }\n return hex;\n};\n\n/**\n * convert xyz to hex color\n * @param xyz - [x, y, z, alpha]\n * @returns hex color\n */\nexport const convertXyzToHex = (xyz: ColorChannels): string => {\n const [x, y, z, alpha] = validateColorComponents(xyz, {\n minLength: QUAD,\n validateRange: false\n }) as ColorChannels;\n const [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);\n const hex = convertLinearRgbToHex(\n [\n Math.min(Math.max(r, 0), 1),\n Math.min(Math.max(g, 0), 1),\n Math.min(Math.max(b, 0), 1),\n alpha\n ],\n true\n );\n return hex;\n};\n\n/**\n * convert xyz D50 to hex color\n * @param xyz - [x, y, z, alpha]\n * @returns hex color\n */\nexport const convertXyzD50ToHex = (xyz: ColorChannels): string => {\n const [x, y, z, alpha] = validateColorComponents(xyz, {\n minLength: QUAD,\n validateRange: false\n }) as ColorChannels;\n const xyzD65 = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true);\n const [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, xyzD65, true);\n const hex = convertLinearRgbToHex([\n Math.min(Math.max(r, 0), 1),\n Math.min(Math.max(g, 0), 1),\n Math.min(Math.max(b, 0), 1),\n alpha\n ]);\n return hex;\n};\n\n/**\n * convert hex color to rgb\n * @param value - hex color value\n * @returns ColorChannels - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1\n */\nexport const convertHexToRgb = (value: string): ColorChannels => {\n if (isString(value)) {\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n if (\n !(\n /^#[\\da-f]{6}$/.test(value) ||\n /^#[\\da-f]{3}$/.test(value) ||\n /^#[\\da-f]{8}$/.test(value) ||\n /^#[\\da-f]{4}$/.test(value)\n )\n ) {\n throw new SyntaxError(`Invalid property value: ${value}`);\n }\n const arr: number[] = [];\n if (/^#[\\da-f]{3}$/.test(value)) {\n const [, r, g, b] = value.match(\n /^#([\\da-f])([\\da-f])([\\da-f])$/\n ) as MatchedRegExp;\n arr.push(\n parseInt(`${r}${r}`, HEX),\n parseInt(`${g}${g}`, HEX),\n parseInt(`${b}${b}`, HEX),\n 1\n );\n } else if (/^#[\\da-f]{4}$/.test(value)) {\n const [, r, g, b, alpha] = value.match(\n /^#([\\da-f])([\\da-f])([\\da-f])([\\da-f])$/\n ) as MatchedRegExp;\n arr.push(\n parseInt(`${r}${r}`, HEX),\n parseInt(`${g}${g}`, HEX),\n parseInt(`${b}${b}`, HEX),\n parseHexAlpha(`${alpha}${alpha}`)\n );\n } else if (/^#[\\da-f]{8}$/.test(value)) {\n const [, r, g, b, alpha] = value.match(\n /^#([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})$/\n ) as MatchedRegExp;\n arr.push(\n parseInt(r, HEX),\n parseInt(g, HEX),\n parseInt(b, HEX),\n parseHexAlpha(alpha)\n );\n } else {\n const [, r, g, b] = value.match(\n /^#([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})$/\n ) as MatchedRegExp;\n arr.push(parseInt(r, HEX), parseInt(g, HEX), parseInt(b, HEX), 1);\n }\n return arr as ColorChannels;\n};\n\n/**\n * convert hex color to linear rgb\n * @param value - hex color value\n * @returns ColorChannels - [r, g, b, alpha] r|g|b|alpha: 0..1\n */\nexport const convertHexToLinearRgb = (value: string): ColorChannels => {\n const [rr, gg, bb, alpha] = convertHexToRgb(value);\n const [r, g, b] = transformRgbToLinearRgb([rr, gg, bb], true);\n return [r, g, b, alpha];\n};\n\n/**\n * convert hex color to xyz\n * @param value - hex color value\n * @returns ColorChannels - [x, y, z, alpha]\n */\nexport const convertHexToXyz = (value: string): ColorChannels => {\n const [r, g, b, alpha] = convertHexToLinearRgb(value);\n const [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [r, g, b], true);\n return [x, y, z, alpha];\n};\n\n/**\n * parse rgb()\n * @param value - rgb color value\n * @param [opt] - options\n * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject\n */\nexport const parseRgb = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_PARSE_RGB.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const [, val] = value.match(REG_PARSE_RGB) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let r, g, b;\n if (v1 === NONE) {\n r = 0;\n } else {\n if (v1.endsWith('%')) {\n r = (parseFloat(v1) * MAX_RGB) / MAX_PCT;\n } else {\n r = parseFloat(v1);\n }\n r = Math.min(Math.max(roundToPrecision(r, OCT), 0), MAX_RGB);\n }\n if (v2 === NONE) {\n g = 0;\n } else {\n if (v2.endsWith('%')) {\n g = (parseFloat(v2) * MAX_RGB) / MAX_PCT;\n } else {\n g = parseFloat(v2);\n }\n g = Math.min(Math.max(roundToPrecision(g, OCT), 0), MAX_RGB);\n }\n if (v3 === NONE) {\n b = 0;\n } else {\n if (v3.endsWith('%')) {\n b = (parseFloat(v3) * MAX_RGB) / MAX_PCT;\n } else {\n b = parseFloat(v3);\n }\n b = Math.min(Math.max(roundToPrecision(b, OCT), 0), MAX_RGB);\n }\n const alpha = parseAlpha(v4);\n return ['rgb', r, g, b, format === VAL_MIX && v4 === NONE ? NONE : alpha];\n};\n\n/**\n * parse hsl()\n * @param value - hsl color value\n * @param [opt] - options\n * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject\n */\nexport const parseHsl = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_HSL.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const [, val] = value.match(REG_HSL) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let h, s, l;\n if (v1 === NONE) {\n h = 0;\n } else {\n h = angleToDeg(v1);\n }\n if (v2 === NONE) {\n s = 0;\n } else {\n s = Math.min(Math.max(parseFloat(v2), 0), MAX_PCT);\n }\n if (v3 === NONE) {\n l = 0;\n } else {\n l = Math.min(Math.max(parseFloat(v3), 0), MAX_PCT);\n }\n const alpha = parseAlpha(v4);\n if (format === 'hsl') {\n return [\n format,\n v1 === NONE ? v1 : h,\n v2 === NONE ? v2 : s,\n v3 === NONE ? v3 : l,\n v4 === NONE ? v4 : alpha\n ];\n }\n h = (h / DEG) * DOZ;\n l /= MAX_PCT;\n const sa = (s / MAX_PCT) * Math.min(l, 1 - l);\n const rk = h % DOZ;\n const gk = (8 + h) % DOZ;\n const bk = (4 + h) % DOZ;\n const r = l - sa * Math.max(-1, Math.min(rk - TRIA, TRIA ** POW_SQR - rk, 1));\n const g = l - sa * Math.max(-1, Math.min(gk - TRIA, TRIA ** POW_SQR - gk, 1));\n const b = l - sa * Math.max(-1, Math.min(bk - TRIA, TRIA ** POW_SQR - bk, 1));\n return [\n 'rgb',\n Math.min(Math.max(roundToPrecision(r * MAX_RGB, OCT), 0), MAX_RGB),\n Math.min(Math.max(roundToPrecision(g * MAX_RGB, OCT), 0), MAX_RGB),\n Math.min(Math.max(roundToPrecision(b * MAX_RGB, OCT), 0), MAX_RGB),\n alpha\n ];\n};\n\n/**\n * parse hwb()\n * @param value - hwb color value\n * @param [opt] - options\n * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject\n */\nexport const parseHwb = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_HWB.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const [, val] = value.match(REG_HWB) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let h, wh, bk;\n if (v1 === NONE) {\n h = 0;\n } else {\n h = angleToDeg(v1);\n }\n if (v2 === NONE) {\n wh = 0;\n } else {\n wh = Math.min(Math.max(parseFloat(v2), 0), MAX_PCT) / MAX_PCT;\n }\n if (v3 === NONE) {\n bk = 0;\n } else {\n bk = Math.min(Math.max(parseFloat(v3), 0), MAX_PCT) / MAX_PCT;\n }\n const alpha = parseAlpha(v4);\n if (format === 'hwb') {\n return [\n format,\n v1 === NONE ? v1 : h,\n v2 === NONE ? v2 : wh * MAX_PCT,\n v3 === NONE ? v3 : bk * MAX_PCT,\n v4 === NONE ? v4 : alpha\n ];\n }\n if (wh + bk >= 1) {\n const v = roundToPrecision((wh / (wh + bk)) * MAX_RGB, OCT);\n return ['rgb', v, v, v, alpha];\n }\n const factor = (1 - wh - bk) / MAX_RGB;\n let [, r, g, b] = parseHsl(`hsl(${h} 100 50)`) as ComputedColorChannels;\n r = roundToPrecision((r * factor + wh) * MAX_RGB, OCT);\n g = roundToPrecision((g * factor + wh) * MAX_RGB, OCT);\n b = roundToPrecision((b * factor + wh) * MAX_RGB, OCT);\n return [\n 'rgb',\n Math.min(Math.max(r, 0), MAX_RGB),\n Math.min(Math.max(g, 0), MAX_RGB),\n Math.min(Math.max(b, 0), MAX_RGB),\n alpha\n ];\n};\n\n/**\n * parse lab()\n * @param value - lab color value\n * @param [opt] - options\n * @returns parsed color\n * - [xyz-d50, x, y, z, alpha], ['lab', l, a, b, alpha], '(empty)', NullObject\n */\nexport const parseLab = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_LAB.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const COEF_PCT = 1.25;\n const COND_POW = 8;\n const [, val] = value.match(REG_LAB) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let l, a, b;\n if (v1 === NONE) {\n l = 0;\n } else {\n if (v1.endsWith('%')) {\n l = parseFloat(v1);\n if (l > MAX_PCT) {\n l = MAX_PCT;\n }\n } else {\n l = parseFloat(v1);\n }\n if (l < 0) {\n l = 0;\n }\n }\n if (v2 === NONE) {\n a = 0;\n } else {\n a = v2.endsWith('%') ? parseFloat(v2) * COEF_PCT : parseFloat(v2);\n }\n if (v3 === NONE) {\n b = 0;\n } else {\n b = v3.endsWith('%') ? parseFloat(v3) * COEF_PCT : parseFloat(v3);\n }\n const alpha = parseAlpha(v4);\n if (REG_SPEC.test(format)) {\n return [\n 'lab',\n v1 === NONE ? v1 : roundToPrecision(l, HEX),\n v2 === NONE ? v2 : roundToPrecision(a, HEX),\n v3 === NONE ? v3 : roundToPrecision(b, HEX),\n v4 === NONE ? v4 : alpha\n ];\n }\n const fl = (l + HEX) / LAB_L;\n const fa = a / LAB_A + fl;\n const fb = fl - b / LAB_B;\n const powFl = Math.pow(fl, POW_CUBE);\n const powFa = Math.pow(fa, POW_CUBE);\n const powFb = Math.pow(fb, POW_CUBE);\n const xyz = [\n powFa > LAB_EPSILON ? powFa : (fa * LAB_L - HEX) / LAB_KAPPA,\n l > COND_POW ? powFl : l / LAB_KAPPA,\n powFb > LAB_EPSILON ? powFb : (fb * LAB_L - HEX) / LAB_KAPPA\n ];\n const [x, y, z] = xyz.map(\n (val, i) => val * (D50[i] as number)\n ) as TriColorChannels;\n return [\n 'xyz-d50',\n roundToPrecision(x, HEX),\n roundToPrecision(y, HEX),\n roundToPrecision(z, HEX),\n alpha\n ];\n};\n\n/**\n * parse lch()\n * @param value - lch color value\n * @param [opt] - options\n * @returns parsed color\n * - ['xyz-d50', x, y, z, alpha], ['lch', l, c, h, alpha]\n * - '(empty)', NullObject\n */\nexport const parseLch = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_LCH.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const COEF_PCT = 1.5;\n const [, val] = value.match(REG_LCH) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let l, c, h;\n if (v1 === NONE) {\n l = 0;\n } else {\n l = parseFloat(v1);\n if (l < 0) {\n l = 0;\n }\n }\n if (v2 === NONE) {\n c = 0;\n } else {\n c = v2.endsWith('%') ? parseFloat(v2) * COEF_PCT : parseFloat(v2);\n }\n if (v3 === NONE) {\n h = 0;\n } else {\n h = angleToDeg(v3);\n }\n const alpha = parseAlpha(v4);\n if (REG_SPEC.test(format)) {\n return [\n 'lch',\n v1 === NONE ? v1 : roundToPrecision(l, HEX),\n v2 === NONE ? v2 : roundToPrecision(c, HEX),\n v3 === NONE ? v3 : roundToPrecision(h, HEX),\n v4 === NONE ? v4 : alpha\n ];\n }\n const a = c * Math.cos((h * Math.PI) / DEG_HALF);\n const b = c * Math.sin((h * Math.PI) / DEG_HALF);\n const [, x, y, z] = parseLab(`lab(${l} ${a} ${b})`) as ComputedColorChannels;\n return [\n 'xyz-d50',\n roundToPrecision(x, HEX),\n roundToPrecision(y, HEX),\n roundToPrecision(z, HEX),\n alpha as number\n ];\n};\n\n/**\n * parse oklab()\n * @param value - oklab color value\n * @param [opt] - options\n * @returns parsed color\n * - ['xyz-d65', x, y, z, alpha], ['oklab', l, a, b, alpha]\n * - '(empty)', NullObject\n */\nexport const parseOklab = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_OKLAB.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const COEF_PCT = 0.4;\n const [, val] = value.match(REG_OKLAB) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let l, a, b;\n if (v1 === NONE) {\n l = 0;\n } else {\n l = v1.endsWith('%') ? parseFloat(v1) / MAX_PCT : parseFloat(v1);\n if (l < 0) {\n l = 0;\n }\n }\n if (v2 === NONE) {\n a = 0;\n } else if (v2.endsWith('%')) {\n a = (parseFloat(v2) * COEF_PCT) / MAX_PCT;\n } else {\n a = parseFloat(v2);\n }\n if (v3 === NONE) {\n b = 0;\n } else if (v3.endsWith('%')) {\n b = (parseFloat(v3) * COEF_PCT) / MAX_PCT;\n } else {\n b = parseFloat(v3);\n }\n const alpha = parseAlpha(v4);\n if (REG_SPEC.test(format)) {\n return [\n 'oklab',\n v1 === NONE ? v1 : roundToPrecision(l, HEX),\n v2 === NONE ? v2 : roundToPrecision(a, HEX),\n v3 === NONE ? v3 : roundToPrecision(b, HEX),\n v4 === NONE ? v4 : alpha\n ];\n }\n const lms = transformMatrix(MATRIX_OKLAB_TO_LMS, [l, a, b]);\n const xyzLms = lms.map(c => Math.pow(c, POW_CUBE)) as TriColorChannels;\n const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, xyzLms, true);\n return [\n 'xyz-d65',\n roundToPrecision(x, HEX),\n roundToPrecision(y, HEX),\n roundToPrecision(z, HEX),\n alpha as number\n ];\n};\n\n/**\n * parse oklch()\n * @param value - oklch color value\n * @param [opt] - options\n * @returns parsed color\n * - ['xyz-d65', x, y, z, alpha], ['oklch', l, c, h, alpha]\n * - '(empty)', NullObject\n */\nexport const parseOklch = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n if (!REG_OKLCH.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const COEF_PCT = 0.4;\n const [, val] = value.match(REG_OKLCH) as MatchedRegExp;\n const [v1, v2, v3, v4 = ''] = val.match(/[^\\s,/]+/g) as StringColorChannels;\n let l, c, h;\n if (v1 === NONE) {\n l = 0;\n } else {\n l = v1.endsWith('%') ? parseFloat(v1) / MAX_PCT : parseFloat(v1);\n if (l < 0) {\n l = 0;\n }\n }\n if (v2 === NONE) {\n c = 0;\n } else {\n if (v2.endsWith('%')) {\n c = (parseFloat(v2) * COEF_PCT) / MAX_PCT;\n } else {\n c = parseFloat(v2);\n }\n if (c < 0) {\n c = 0;\n }\n }\n if (v3 === NONE) {\n h = 0;\n } else {\n h = angleToDeg(v3);\n }\n const alpha = parseAlpha(v4);\n if (REG_SPEC.test(format)) {\n return [\n 'oklch',\n v1 === NONE ? v1 : roundToPrecision(l, HEX),\n v2 === NONE ? v2 : roundToPrecision(c, HEX),\n v3 === NONE ? v3 : roundToPrecision(h, HEX),\n v4 === NONE ? v4 : alpha\n ];\n }\n const a = c * Math.cos((h * Math.PI) / DEG_HALF);\n const b = c * Math.sin((h * Math.PI) / DEG_HALF);\n const lms = transformMatrix(MATRIX_OKLAB_TO_LMS, [l, a, b]);\n const xyzLms = lms.map(cc => Math.pow(cc, POW_CUBE)) as TriColorChannels;\n const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, xyzLms, true);\n return [\n 'xyz-d65',\n roundToPrecision(x, HEX),\n roundToPrecision(y, HEX),\n roundToPrecision(z, HEX),\n alpha\n ];\n};\n\n/**\n * parse color()\n * @param value - color function value\n * @param [opt] - options\n * @returns parsed color\n * - ['xyz-(d50|d65)', x, y, z, alpha], [cs, r, g, b, alpha]\n * - '(empty)', NullObject\n */\nexport const parseColorFunc = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { colorSpace = '', d50 = false, format = '', nullable = false } = opt;\n if (!REG_FN_COLOR.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp;\n let [cs, v1, v2, v3, v4 = ''] = val.match(\n /[^\\s,/]+/g\n ) as StringColorSpacedChannels;\n let r, g, b;\n if (cs === 'xyz') {\n cs = 'xyz-d65';\n }\n if (v1 === NONE) {\n r = 0;\n } else {\n r = v1.endsWith('%') ? parseFloat(v1) / MAX_PCT : parseFloat(v1);\n }\n if (v2 === NONE) {\n g = 0;\n } else {\n g = v2.endsWith('%') ? parseFloat(v2) / MAX_PCT : parseFloat(v2);\n }\n if (v3 === NONE) {\n b = 0;\n } else {\n b = v3.endsWith('%') ? parseFloat(v3) / MAX_PCT : parseFloat(v3);\n }\n const alpha = parseAlpha(v4);\n if (REG_SPEC.test(format) || (format === VAL_MIX && cs === colorSpace)) {\n return [\n cs,\n v1 === NONE ? v1 : roundToPrecision(r, DEC),\n v2 === NONE ? v2 : roundToPrecision(g, DEC),\n v3 === NONE ? v3 : roundToPrecision(b, DEC),\n v4 === NONE ? v4 : alpha\n ];\n }\n let x = 0;\n let y = 0;\n let z = 0;\n // srgb-linear\n if (cs === 'srgb-linear') {\n [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [r, g, b]);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // display-p3\n } else if (cs === 'display-p3') {\n const linearRgb = transformRgbToLinearRgb([\n r * MAX_RGB,\n g * MAX_RGB,\n b * MAX_RGB\n ]);\n [x, y, z] = transformMatrix(MATRIX_P3_TO_XYZ, linearRgb);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // rec2020\n } else if (cs === 'rec2020') {\n const ALPHA = 1.09929682680944;\n const BETA = 0.018053968510807;\n const REC_COEF = 0.45;\n const rgb = [r, g, b].map(c => {\n let cl;\n if (c < BETA * REC_COEF * DEC) {\n cl = c / (REC_COEF * DEC);\n } else {\n cl = Math.pow((c + ALPHA - 1) / ALPHA, 1 / REC_COEF);\n }\n return cl;\n }) as TriColorChannels;\n [x, y, z] = transformMatrix(MATRIX_REC2020_TO_XYZ, rgb);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // a98-rgb\n } else if (cs === 'a98-rgb') {\n const POW_A98 = 563 / 256;\n const rgb = [r, g, b].map(c => {\n const cl = Math.pow(c, POW_A98);\n return cl;\n }) as TriColorChannels;\n [x, y, z] = transformMatrix(MATRIX_A98_TO_XYZ, rgb);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // prophoto-rgb\n } else if (cs === 'prophoto-rgb') {\n const POW_PROPHOTO = 1.8;\n const rgb = [r, g, b].map(c => {\n let cl;\n if (c > 1 / (HEX * DUO)) {\n cl = Math.pow(c, POW_PROPHOTO);\n } else {\n cl = c / HEX;\n }\n return cl;\n }) as TriColorChannels;\n [x, y, z] = transformMatrix(MATRIX_PROPHOTO_TO_XYZ_D50, rgb);\n if (!d50) {\n [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true);\n }\n // xyz, xyz-d50, xyz-d65\n } else if (/^xyz(?:-d(?:50|65))?$/.test(cs)) {\n [x, y, z] = [r, g, b];\n if (cs === 'xyz-d50') {\n if (!d50) {\n [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z]);\n }\n } else if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // srgb\n } else {\n [x, y, z] = transformRgbToXyz([r * MAX_RGB, g * MAX_RGB, b * MAX_RGB]);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n }\n return [\n d50 ? 'xyz-d50' : 'xyz-d65',\n roundToPrecision(x, HEX),\n roundToPrecision(y, HEX),\n roundToPrecision(z, HEX),\n format === VAL_MIX && v4 === NONE ? v4 : alpha\n ];\n};\n\n/**\n * parse color value\n * @param value - CSS color value\n * @param [opt] - options\n * @returns parsed color\n * - ['xyz-(d50|d65)', x, y, z, alpha], ['rgb', r, g, b, alpha]\n * - value, '(empty)', NullObject\n */\nexport const parseColorValue = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { d50 = false, format = '', nullable = false } = opt;\n if (!REG_COLOR.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n return res;\n }\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n let x = 0;\n let y = 0;\n let z = 0;\n let alpha = 0;\n // complement currentcolor as a missing color\n if (REG_CURRENT.test(value)) {\n if (format === VAL_COMP) {\n return ['rgb', 0, 0, 0, 0];\n }\n if (format === VAL_SPEC) {\n return value;\n }\n // named-color\n } else if (/^[a-z]+$/.test(value)) {\n if (Object.hasOwn(NAMED_COLORS, value)) {\n if (format === VAL_SPEC) {\n return value;\n }\n const [r, g, b] = NAMED_COLORS[\n value as keyof typeof NAMED_COLORS\n ] as TriColorChannels;\n alpha = 1;\n if (format === VAL_COMP) {\n return ['rgb', r, g, b, alpha];\n }\n [x, y, z] = transformRgbToXyz([r, g, b], true);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n } else {\n switch (format) {\n case VAL_COMP: {\n if (nullable && value !== 'transparent') {\n return new NullObject();\n }\n return ['rgb', 0, 0, 0, 0];\n }\n case VAL_SPEC: {\n if (value === 'transparent') {\n return value;\n }\n return '';\n }\n case VAL_MIX: {\n if (value === 'transparent') {\n return ['rgb', 0, 0, 0, 0];\n }\n return new NullObject();\n }\n default:\n }\n }\n // hex-color\n } else if (value[0] === '#') {\n if (REG_SPEC.test(format)) {\n const rgb = convertHexToRgb(value);\n return ['rgb', ...rgb];\n }\n [x, y, z, alpha] = convertHexToXyz(value);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // lab()\n } else if (value.startsWith('lab')) {\n if (REG_SPEC.test(format)) {\n return parseLab(value, opt);\n }\n [, x, y, z, alpha] = parseLab(value) as ComputedColorChannels;\n if (!d50) {\n [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true);\n }\n // lch()\n } else if (value.startsWith('lch')) {\n if (REG_SPEC.test(format)) {\n return parseLch(value, opt);\n }\n [, x, y, z, alpha] = parseLch(value) as ComputedColorChannels;\n if (!d50) {\n [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true);\n }\n // oklab()\n } else if (value.startsWith('oklab')) {\n if (REG_SPEC.test(format)) {\n return parseOklab(value, opt);\n }\n [, x, y, z, alpha] = parseOklab(value) as ComputedColorChannels;\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n // oklch()\n } else if (value.startsWith('oklch')) {\n if (REG_SPEC.test(format)) {\n return parseOklch(value, opt);\n }\n [, x, y, z, alpha] = parseOklch(value) as ComputedColorChannels;\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n } else {\n let r, g, b;\n // hsl()\n if (value.startsWith('hsl')) {\n [, r, g, b, alpha] = parseHsl(value) as ComputedColorChannels;\n // hwb()\n } else if (value.startsWith('hwb')) {\n [, r, g, b, alpha] = parseHwb(value) as ComputedColorChannels;\n // rgb()\n } else {\n [, r, g, b, alpha] = parseRgb(value, opt) as ComputedColorChannels;\n }\n if (REG_SPEC.test(format)) {\n return ['rgb', Math.round(r), Math.round(g), Math.round(b), alpha];\n }\n [x, y, z] = transformRgbToXyz([r, g, b]);\n if (d50) {\n [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);\n }\n }\n return [\n d50 ? 'xyz-d50' : 'xyz-d65',\n roundToPrecision(x, HEX),\n roundToPrecision(y, HEX),\n roundToPrecision(z, HEX),\n alpha\n ];\n};\n\n/**\n * resolve color value\n * @param value - CSS color value\n * @param [opt] - options\n * @returns resolved color\n * - [cs, v1, v2, v3, alpha], value, '(empty)', NullObject\n */\nexport const resolveColorValue = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { colorSpace = '', format = '', nullable = false } = opt;\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'resolveColorValue',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n const cachedItem = cachedResult.item;\n if (isString(cachedItem)) {\n return cachedItem as string;\n }\n return cachedItem as SpecifiedColorChannels;\n }\n if (!REG_COLOR.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n setCache(cacheKey, null);\n return res;\n }\n setCache(cacheKey, res);\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n let cs = '';\n let r = 0;\n let g = 0;\n let b = 0;\n let alpha = 0;\n // complement currentcolor as a missing color\n if (REG_CURRENT.test(value)) {\n if (format === VAL_SPEC) {\n setCache(cacheKey, value);\n return value;\n }\n // named-color\n } else if (/^[a-z]+$/.test(value)) {\n if (Object.hasOwn(NAMED_COLORS, value)) {\n if (format === VAL_SPEC) {\n setCache(cacheKey, value);\n return value;\n }\n [r, g, b] = NAMED_COLORS[\n value as keyof typeof NAMED_COLORS\n ] as TriColorChannels;\n alpha = 1;\n } else {\n switch (format) {\n case VAL_SPEC: {\n if (value === 'transparent') {\n setCache(cacheKey, value);\n return value;\n }\n const res = '';\n setCache(cacheKey, res);\n return res;\n }\n case VAL_MIX: {\n if (value === 'transparent') {\n const res: SpecifiedColorChannels = ['rgb', 0, 0, 0, 0];\n setCache(cacheKey, res);\n return res;\n }\n setCache(cacheKey, null);\n return new NullObject();\n }\n case VAL_COMP:\n default: {\n if (nullable && value !== 'transparent') {\n setCache(cacheKey, null);\n return new NullObject();\n }\n const res: SpecifiedColorChannels = ['rgb', 0, 0, 0, 0];\n setCache(cacheKey, res);\n return res;\n }\n }\n }\n // hex-color\n } else if (value[0] === '#') {\n [r, g, b, alpha] = convertHexToRgb(value);\n // hsl()\n } else if (value.startsWith('hsl')) {\n [, r, g, b, alpha] = parseHsl(value, opt) as ComputedColorChannels;\n // hwb()\n } else if (value.startsWith('hwb')) {\n [, r, g, b, alpha] = parseHwb(value, opt) as ComputedColorChannels;\n // lab(), lch()\n } else if (/^l(?:ab|ch)/.test(value)) {\n let x, y, z;\n if (value.startsWith('lab')) {\n [cs, x, y, z, alpha] = parseLab(value, opt) as ComputedColorChannels;\n } else {\n [cs, x, y, z, alpha] = parseLch(value, opt) as ComputedColorChannels;\n }\n if (REG_SPEC.test(format)) {\n const res: SpecifiedColorChannels = [cs, x, y, z, alpha];\n setCache(cacheKey, res);\n return res;\n }\n [r, g, b] = transformXyzD50ToRgb([x, y, z]);\n // oklab(), oklch()\n } else if (/^okl(?:ab|ch)/.test(value)) {\n let x, y, z;\n if (value.startsWith('oklab')) {\n [cs, x, y, z, alpha] = parseOklab(value, opt) as ComputedColorChannels;\n } else {\n [cs, x, y, z, alpha] = parseOklch(value, opt) as ComputedColorChannels;\n }\n if (REG_SPEC.test(format)) {\n const res: SpecifiedColorChannels = [cs, x, y, z, alpha];\n setCache(cacheKey, res);\n return res;\n }\n [r, g, b] = transformXyzToRgb([x, y, z]);\n // rgb()\n } else {\n [, r, g, b, alpha] = parseRgb(value, opt) as ComputedColorChannels;\n }\n if (format === VAL_MIX && colorSpace === 'srgb') {\n const res: SpecifiedColorChannels = [\n 'srgb',\n r / MAX_RGB,\n g / MAX_RGB,\n b / MAX_RGB,\n alpha\n ];\n setCache(cacheKey, res);\n return res;\n }\n const res: SpecifiedColorChannels = [\n 'rgb',\n Math.round(r),\n Math.round(g),\n Math.round(b),\n alpha\n ];\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * resolve color()\n * @param value - color function value\n * @param [opt] - options\n * @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', NullObject\n */\nexport const resolveColorFunc = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { colorSpace = '', format = '', nullable = false } = opt;\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'resolveColorFunc',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n const cachedItem = cachedResult.item;\n if (isString(cachedItem)) {\n return cachedItem as string;\n }\n return cachedItem as SpecifiedColorChannels;\n }\n if (!REG_FN_COLOR.test(value)) {\n const res = resolveInvalidColorValue(format, nullable);\n if (res instanceof NullObject) {\n setCache(cacheKey, null);\n return res;\n }\n setCache(cacheKey, res);\n if (isString(res)) {\n return res as string;\n }\n return res as SpecifiedColorChannels;\n }\n const [cs, v1, v2, v3, v4] = parseColorFunc(\n value,\n opt\n ) as SpecifiedColorChannels;\n if (REG_SPEC.test(format) || (format === VAL_MIX && cs === colorSpace)) {\n const res: SpecifiedColorChannels = [cs, v1, v2, v3, v4];\n setCache(cacheKey, res);\n return res;\n }\n const x = parseFloat(`${v1}`);\n const y = parseFloat(`${v2}`);\n const z = parseFloat(`${v3}`);\n const alpha = parseAlpha(`${v4}`);\n const [r, g, b] = transformXyzToRgb([x, y, z], true);\n const res: SpecifiedColorChannels = ['rgb', r, g, b, alpha];\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * convert color value to linear rgb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [r, g, b, alpha] r|g|b|alpha: 0..1\n */\nexport const convertColorToLinearRgb = (\n value: string,\n opt: {\n colorSpace?: string;\n format?: string;\n } = {}\n): ColorChannels | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { colorSpace = '', format = '' } = opt;\n let cs = '';\n let r, g, b, alpha, x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [cs, x, y, z, alpha] = xyz as ComputedColorChannels;\n if (cs === colorSpace) {\n return [x, y, z, alpha];\n }\n [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);\n } else if (value.startsWith(FN_COLOR)) {\n const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp;\n const [cs] = val.match(/[^\\s,/]+/g) as StringColorSpacedChannels;\n if (cs === 'srgb-linear') {\n [, r, g, b, alpha] = resolveColorFunc(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels;\n [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);\n }\n } else {\n [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels;\n [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);\n }\n return [\n Math.min(Math.max(r, 0), 1),\n Math.min(Math.max(g, 0), 1),\n Math.min(Math.max(b, 0), 1),\n alpha\n ];\n};\n\n/**\n * convert color value to rgb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject\n * - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1\n */\nexport const convertColorToRgb = (\n value: string,\n opt: Options = {}\n): ColorChannels | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let r, g, b, alpha;\n if (format === VAL_MIX) {\n let rgb;\n if (value.startsWith(FN_COLOR)) {\n rgb = resolveColorFunc(value, opt);\n } else {\n rgb = resolveColorValue(value, opt);\n }\n if (rgb instanceof NullObject) {\n return rgb;\n }\n [, r, g, b, alpha] = rgb as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp;\n const [cs] = val.match(/[^\\s,/]+/g) as StringColorSpacedChannels;\n if (cs === 'srgb') {\n [, r, g, b, alpha] = resolveColorFunc(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n r *= MAX_RGB;\n g *= MAX_RGB;\n b *= MAX_RGB;\n } else {\n [, r, g, b, alpha] = resolveColorFunc(value) as ComputedColorChannels;\n }\n } else if (/^(?:ok)?l(?:ab|ch)/.test(value)) {\n [r, g, b, alpha] = convertColorToLinearRgb(value) as ColorChannels;\n [r, g, b] = transformLinearRgbToRgb([r, g, b]);\n } else {\n [, r, g, b, alpha] = resolveColorValue(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n }\n return [r, g, b, alpha];\n};\n\n/**\n * convert color value to xyz\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [x, y, z, alpha]\n */\nexport const convertColorToXyz = (\n value: string,\n opt: Options = {}\n): ColorChannels | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { d50 = false, format = '' } = opt;\n let x, y, z, alpha;\n if (format === VAL_MIX) {\n let xyz;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp;\n const [cs] = val.match(/[^\\s,/]+/g) as StringColorSpacedChannels;\n if (d50) {\n if (cs === 'xyz-d50') {\n [, x, y, z, alpha] = resolveColorFunc(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorFunc(\n value,\n opt\n ) as ComputedColorChannels;\n }\n } else if (/^xyz(?:-d65)?$/.test(cs)) {\n [, x, y, z, alpha] = resolveColorFunc(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels;\n }\n } else {\n [, x, y, z, alpha] = parseColorValue(value, opt) as ComputedColorChannels;\n }\n return [x, y, z, alpha];\n};\n\n/**\n * convert color value to hsl\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [h, s, l, alpha], hue may be powerless\n */\nexport const convertColorToHsl = (\n value: string,\n opt: Options = {}\n): ColorChannels | [number | string, number, number, number] | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let h, s, l, alpha;\n if (REG_HSL.test(value)) {\n [, h, s, l, alpha] = parseHsl(value, {\n format: 'hsl'\n }) as ComputedColorChannels;\n if (format === 'hsl') {\n return [Math.round(h), Math.round(s), Math.round(l), alpha];\n }\n return [h, s, l, alpha];\n }\n let x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels;\n }\n [h, s, l] = transformXyzToHsl([x, y, z], true) as TriColorChannels;\n if (format === 'hsl') {\n return [Math.round(h), Math.round(s), Math.round(l), alpha];\n }\n return [format === VAL_MIX && s === 0 ? NONE : h, s, l, alpha];\n};\n\n/**\n * convert color value to hwb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [h, w, b, alpha], hue may be powerless\n */\nexport const convertColorToHwb = (\n value: string,\n opt: Options = {}\n): ColorChannels | [number | string, number, number, number] | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let h, w, b, alpha;\n if (REG_HWB.test(value)) {\n [, h, w, b, alpha] = parseHwb(value, {\n format: 'hwb'\n }) as ComputedColorChannels;\n if (format === 'hwb') {\n return [Math.round(h), Math.round(w), Math.round(b), alpha];\n }\n return [h, w, b, alpha];\n }\n let x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels;\n }\n [h, w, b] = transformXyzToHwb([x, y, z], true) as TriColorChannels;\n if (format === 'hwb') {\n return [Math.round(h), Math.round(w), Math.round(b), alpha];\n }\n return [format === VAL_MIX && w + b >= 100 ? NONE : h, w, b, alpha];\n};\n\n/**\n * convert color value to lab\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [l, a, b, alpha]\n */\nexport const convertColorToLab = (\n value: string,\n opt: Options = {}\n): ColorChannels | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let l, a, b, alpha;\n if (REG_LAB.test(value)) {\n [, l, a, b, alpha] = parseLab(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n return [l, a, b, alpha];\n }\n let x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n opt.d50 = true;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n [, x, y, z, alpha] = parseColorFunc(value, {\n d50: true\n }) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorValue(value, {\n d50: true\n }) as ComputedColorChannels;\n }\n [l, a, b] = transformXyzD50ToLab([x, y, z], true);\n return [l, a, b, alpha];\n};\n\n/**\n * convert color value to lch\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless\n */\nexport const convertColorToLch = (\n value: string,\n opt: Options = {}\n): ColorChannels | [number, number, number | string, number] | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let l, c, h, alpha;\n if (REG_LCH.test(value)) {\n [, l, c, h, alpha] = parseLch(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n return [l, c, h, alpha];\n }\n let x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n opt.d50 = true;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n [, x, y, z, alpha] = parseColorFunc(value, {\n d50: true\n }) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorValue(value, {\n d50: true\n }) as ComputedColorChannels;\n }\n [l, c, h] = transformXyzD50ToLch([x, y, z], true);\n return [l, c, format === VAL_MIX && c === 0 ? NONE : h, alpha];\n};\n\n/**\n * convert color value to oklab\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [l, a, b, alpha]\n */\nexport const convertColorToOklab = (\n value: string,\n opt: Options = {}\n): ColorChannels | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let l, a, b, alpha;\n if (REG_OKLAB.test(value)) {\n [, l, a, b, alpha] = parseOklab(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n return [l, a, b, alpha];\n }\n let x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels;\n }\n [l, a, b] = transformXyzToOklab([x, y, z], true);\n return [l, a, b, alpha];\n};\n\n/**\n * convert color value to oklch\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless\n */\nexport const convertColorToOklch = (\n value: string,\n opt: Options = {}\n): ColorChannels | [number, number, number | string, number] | NullObject => {\n if (isString(value)) {\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '' } = opt;\n let l, c, h, alpha;\n if (REG_OKLCH.test(value)) {\n [, l, c, h, alpha] = parseOklch(value, {\n format: VAL_COMP\n }) as ComputedColorChannels;\n return [l, c, h, alpha];\n }\n let x, y, z;\n if (format === VAL_MIX) {\n let xyz;\n if (value.startsWith(FN_COLOR)) {\n xyz = parseColorFunc(value, opt);\n } else {\n xyz = parseColorValue(value, opt);\n }\n if (xyz instanceof NullObject) {\n return xyz;\n }\n [, x, y, z, alpha] = xyz as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels;\n } else {\n [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels;\n }\n [l, c, h] = transformXyzToOklch([x, y, z], true) as TriColorChannels;\n return [l, c, format === VAL_MIX && c === 0 ? NONE : h, alpha];\n};\n\n/**\n * resolve color-mix()\n * @param value - color-mix color value\n * @param [opt] - options\n * @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)'\n */\nexport const resolveColorMix = (\n value: string,\n opt: Options = {}\n): SpecifiedColorChannels | string | NullObject => {\n if (isString(value)) {\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const { format = '', nullable = false } = opt;\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'resolveColorMix',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n const cachedItem = cachedResult.item;\n if (isString(cachedItem)) {\n return cachedItem as string;\n }\n return cachedItem as SpecifiedColorChannels;\n }\n const nestedItems = [];\n let colorSpace = '';\n let hueArc = '';\n let colorA = '';\n let pctA = '';\n let colorB = '';\n let pctB = '';\n let parsed = false;\n if (!REG_MIX.test(value)) {\n // nested color-mix()\n if (value.startsWith(FN_MIX) && REG_MIX_NEST.test(value)) {\n const items = value.match(REG_MIX_NEST) as RegExpMatchArray;\n for (const item of items) {\n if (item) {\n let val = resolveColorMix(item, {\n format: format === VAL_SPEC ? format : VAL_COMP\n }) as ComputedColorChannels | string;\n // computed value\n if (Array.isArray(val)) {\n const [cs, v1, v2, v3, v4] = val as ComputedColorChannels;\n if (v1 === 0 && v2 === 0 && v3 === 0 && v4 === 0) {\n value = '';\n break;\n }\n if (REG_MIX_CS_RGB_XYZ.test(cs)) {\n if (v4 === 1) {\n val = `color(${cs} ${v1} ${v2} ${v3})`;\n } else {\n val = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`;\n }\n } else if (v4 === 1) {\n val = `${cs}(${v1} ${v2} ${v3})`;\n } else {\n val = `${cs}(${v1} ${v2} ${v3} / ${v4})`;\n }\n } else if (!REG_MIX.test(val)) {\n value = '';\n break;\n }\n nestedItems.push(val);\n value = value.replace(item, val);\n }\n }\n if (!value) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n // contains light-dark()\n } else if (\n value.startsWith(FN_MIX) &&\n value.endsWith(')') &&\n value.includes(FN_LIGHT_DARK)\n ) {\n const colorParts = value.replace(FN_MIX, '').replace(/\\)$/, '');\n const [csPart = '', partA = '', partB = ''] = splitValue(colorParts, {\n delimiter: ','\n });\n const [colorPartA = '', pctPartA = ''] = splitValue(partA);\n const [colorPartB = '', pctPartB = ''] = splitValue(partB);\n const specifiedColorA = resolveColor(colorPartA, {\n format: VAL_SPEC\n }) as string;\n const specifiedColorB = resolveColor(colorPartB, {\n format: VAL_SPEC\n }) as string;\n if (REG_MIX_IN_CS.test(csPart) && specifiedColorA && specifiedColorB) {\n if (format === VAL_SPEC) {\n const [, cs] = csPart.match(REG_MIX_IN_CS) as MatchedRegExp;\n if (REG_CS_HUE.test(cs)) {\n [, colorSpace, hueArc] = cs.match(REG_CS_HUE) as MatchedRegExp;\n } else {\n colorSpace = cs;\n }\n colorA = specifiedColorA;\n if (pctPartA) {\n pctA = pctPartA;\n }\n colorB = specifiedColorB;\n if (pctPartB) {\n pctB = pctPartB;\n }\n value = value\n .replace(colorPartA, specifiedColorA)\n .replace(colorPartB, specifiedColorB);\n parsed = true;\n } else {\n const resolvedColorA = resolveColor(colorPartA, opt);\n const resolvedColorB = resolveColor(colorPartB, opt);\n if (isString(resolvedColorA) && isString(resolvedColorB)) {\n value = value\n .replace(colorPartA, resolvedColorA)\n .replace(colorPartB, resolvedColorB);\n }\n }\n } else {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n } else {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n }\n if (nestedItems.length && format === VAL_SPEC) {\n const [, cs] = value.match(REG_MIX_START) as MatchedRegExp;\n if (REG_CS_HUE.test(cs)) {\n [, colorSpace, hueArc] = cs.match(REG_CS_HUE) as MatchedRegExp;\n } else {\n colorSpace = cs;\n }\n if (nestedItems.length === 2) {\n let [itemA, itemB] = nestedItems as [string, string];\n itemA = itemA.replace(/(?=[()])/g, '\\\\');\n itemB = itemB.replace(/(?=[()])/g, '\\\\');\n const regA = new RegExp(`(${itemA})(?:\\\\s+(${PCT}))?`);\n const regB = new RegExp(`(${itemB})(?:\\\\s+(${PCT}))?`);\n [, colorA, pctA] = value.match(regA) as MatchedRegExp;\n [, colorB, pctB] = value.match(regB) as MatchedRegExp;\n } else {\n let [item] = nestedItems as [string];\n item = item.replace(/(?=[()])/g, '\\\\');\n const itemPart = `${item}(?:\\\\s+${PCT})?`;\n const itemPartCapt = `(${item})(?:\\\\s+(${PCT}))?`;\n const regItemPart = new RegExp(`^${itemPartCapt}$`);\n const regLastItem = new RegExp(`${itemPartCapt}\\\\s*\\\\)$`);\n // item is at the end\n if (regLastItem.test(value)) {\n const reg = new RegExp(\n `(${SYN_MIX_PART})\\\\s*,\\\\s*(${itemPart})\\\\s*\\\\)$`\n );\n const [, colorPartA, colorPartB] = value.match(reg) as MatchedRegExp;\n [, colorA, pctA] = colorPartA.match(\n REG_MIX_COLOR_PART\n ) as MatchedRegExp;\n [, colorB, pctB] = colorPartB.match(regItemPart) as MatchedRegExp;\n } else {\n const reg = new RegExp(\n `(${itemPart})\\\\s*,\\\\s*(${SYN_MIX_PART})\\\\s*\\\\)$`\n );\n const [, colorPartA, colorPartB] = value.match(reg) as MatchedRegExp;\n [, colorA, pctA] = colorPartA.match(regItemPart) as MatchedRegExp;\n [, colorB, pctB] = colorPartB.match(\n REG_MIX_COLOR_PART\n ) as MatchedRegExp;\n }\n }\n } else if (!parsed) {\n const [, cs, colorPartA, colorPartB] = value.match(\n REG_MIX_CAPT\n ) as MatchedRegExp;\n [, colorA, pctA] = colorPartA.match(REG_MIX_COLOR_PART) as MatchedRegExp;\n [, colorB, pctB] = colorPartB.match(REG_MIX_COLOR_PART) as MatchedRegExp;\n if (REG_CS_HUE.test(cs)) {\n [, colorSpace, hueArc] = cs.match(REG_CS_HUE) as MatchedRegExp;\n } else {\n colorSpace = cs;\n }\n }\n // normalize percentages and set multipler\n let pA, pB, m;\n if (pctA && pctB) {\n const p1 = parseFloat(pctA) / MAX_PCT;\n const p2 = parseFloat(pctB) / MAX_PCT;\n if (p1 < 0 || p1 > 1 || p2 < 0 || p2 > 1 || (p1 === 0 && p2 === 0)) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n const factor = p1 + p2;\n pA = p1 / factor;\n pB = p2 / factor;\n m = factor < 1 ? factor : 1;\n } else {\n if (pctA) {\n pA = parseFloat(pctA) / MAX_PCT;\n if (pA < 0 || pA > 1) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n pB = 1 - pA;\n } else if (pctB) {\n pB = parseFloat(pctB) / MAX_PCT;\n if (pB < 0 || pB > 1) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n pA = 1 - pB;\n } else {\n pA = HALF;\n pB = HALF;\n }\n m = 1;\n }\n if (colorSpace === 'xyz') {\n colorSpace = 'xyz-d65';\n }\n // specified value\n if (format === VAL_SPEC) {\n let valueA = '';\n let valueB = '';\n if (colorA.startsWith(FN_MIX) || colorA.startsWith(FN_LIGHT_DARK)) {\n valueA = colorA;\n } else if (colorA.startsWith(FN_COLOR)) {\n const [cs, v1, v2, v3, v4] = parseColorFunc(\n colorA,\n opt\n ) as SpecifiedColorChannels;\n if (v4 === 1) {\n valueA = `color(${cs} ${v1} ${v2} ${v3})`;\n } else {\n valueA = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`;\n }\n } else {\n const val = parseColorValue(colorA, opt);\n if (Array.isArray(val)) {\n const [cs, v1, v2, v3, v4] = val;\n if (v4 === 1) {\n if (cs === 'rgb') {\n valueA = `${cs}(${v1}, ${v2}, ${v3})`;\n } else {\n valueA = `${cs}(${v1} ${v2} ${v3})`;\n }\n } else if (cs === 'rgb') {\n valueA = `${cs}a(${v1}, ${v2}, ${v3}, ${v4})`;\n } else {\n valueA = `${cs}(${v1} ${v2} ${v3} / ${v4})`;\n }\n } else {\n if (!isString(val) || !val) {\n setCache(cacheKey, '');\n return '';\n }\n valueA = val;\n }\n }\n if (colorB.startsWith(FN_MIX) || colorB.startsWith(FN_LIGHT_DARK)) {\n valueB = colorB;\n } else if (colorB.startsWith(FN_COLOR)) {\n const [cs, v1, v2, v3, v4] = parseColorFunc(\n colorB,\n opt\n ) as SpecifiedColorChannels;\n if (v4 === 1) {\n valueB = `color(${cs} ${v1} ${v2} ${v3})`;\n } else {\n valueB = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`;\n }\n } else {\n const val = parseColorValue(colorB, opt);\n if (Array.isArray(val)) {\n const [cs, v1, v2, v3, v4] = val;\n if (v4 === 1) {\n if (cs === 'rgb') {\n valueB = `${cs}(${v1}, ${v2}, ${v3})`;\n } else {\n valueB = `${cs}(${v1} ${v2} ${v3})`;\n }\n } else if (cs === 'rgb') {\n valueB = `${cs}a(${v1}, ${v2}, ${v3}, ${v4})`;\n } else {\n valueB = `${cs}(${v1} ${v2} ${v3} / ${v4})`;\n }\n } else {\n if (!isString(val) || !val) {\n setCache(cacheKey, '');\n return '';\n }\n valueB = val;\n }\n }\n if (pctA && pctB) {\n valueA += ` ${parseFloat(pctA)}%`;\n valueB += ` ${parseFloat(pctB)}%`;\n } else if (pctA) {\n const pA = parseFloat(pctA);\n if (pA !== MAX_PCT * HALF) {\n valueA += ` ${pA}%`;\n }\n } else if (pctB) {\n const pA = MAX_PCT - parseFloat(pctB);\n if (pA !== MAX_PCT * HALF) {\n valueA += ` ${pA}%`;\n }\n }\n if (hueArc) {\n const res = `color-mix(in ${colorSpace} ${hueArc} hue, ${valueA}, ${valueB})`;\n setCache(cacheKey, res);\n return res;\n } else {\n const res = `color-mix(in ${colorSpace}, ${valueA}, ${valueB})`;\n setCache(cacheKey, res);\n return res;\n }\n }\n let r = 0;\n let g = 0;\n let b = 0;\n let alpha = 0;\n // in srgb, srgb-linear\n if (/^srgb(?:-linear)?$/.test(colorSpace)) {\n let rgbA, rgbB;\n if (colorSpace === 'srgb') {\n if (REG_CURRENT.test(colorA)) {\n rgbA = [NONE, NONE, NONE, NONE];\n } else {\n rgbA = convertColorToRgb(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n rgbB = [NONE, NONE, NONE, NONE];\n } else {\n rgbB = convertColorToRgb(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n } else {\n if (REG_CURRENT.test(colorA)) {\n rgbA = [NONE, NONE, NONE, NONE];\n } else {\n rgbA = convertColorToLinearRgb(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n rgbB = [NONE, NONE, NONE, NONE];\n } else {\n rgbB = convertColorToLinearRgb(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n }\n if (rgbA instanceof NullObject || rgbB instanceof NullObject) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n const [rrA, ggA, bbA, aaA] = rgbA as NumStrColorChannels;\n const [rrB, ggB, bbB, aaB] = rgbB as NumStrColorChannels;\n const rNone = rrA === NONE && rrB === NONE;\n const gNone = ggA === NONE && ggB === NONE;\n const bNone = bbA === NONE && bbB === NONE;\n const alphaNone = aaA === NONE && aaB === NONE;\n const [[rA, gA, bA, alphaA], [rB, gB, bB, alphaB]] =\n normalizeColorComponents(\n [rrA, ggA, bbA, aaA],\n [rrB, ggB, bbB, aaB],\n true\n );\n const factorA = alphaA * pA;\n const factorB = alphaB * pB;\n alpha = factorA + factorB;\n if (alpha === 0) {\n r = rA * pA + rB * pB;\n g = gA * pA + gB * pB;\n b = bA * pA + bB * pB;\n } else {\n r = (rA * factorA + rB * factorB) / alpha;\n g = (gA * factorA + gB * factorB) / alpha;\n b = (bA * factorA + bB * factorB) / alpha;\n alpha = parseFloat(alpha.toFixed(3));\n }\n if (format === VAL_COMP) {\n const res: SpecifiedColorChannels = [\n colorSpace,\n rNone ? NONE : roundToPrecision(r, HEX),\n gNone ? NONE : roundToPrecision(g, HEX),\n bNone ? NONE : roundToPrecision(b, HEX),\n alphaNone ? NONE : alpha * m\n ];\n setCache(cacheKey, res);\n return res;\n }\n r *= MAX_RGB;\n g *= MAX_RGB;\n b *= MAX_RGB;\n // in xyz, xyz-d65, xyz-d50\n } else if (REG_CS_XYZ.test(colorSpace)) {\n let xyzA, xyzB;\n if (REG_CURRENT.test(colorA)) {\n xyzA = [NONE, NONE, NONE, NONE];\n } else {\n xyzA = convertColorToXyz(colorA, {\n colorSpace,\n d50: colorSpace === 'xyz-d50',\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n xyzB = [NONE, NONE, NONE, NONE];\n } else {\n xyzB = convertColorToXyz(colorB, {\n colorSpace,\n d50: colorSpace === 'xyz-d50',\n format: VAL_MIX\n });\n }\n if (xyzA instanceof NullObject || xyzB instanceof NullObject) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n const [xxA, yyA, zzA, aaA] = xyzA;\n const [xxB, yyB, zzB, aaB] = xyzB;\n const xNone = xxA === NONE && xxB === NONE;\n const yNone = yyA === NONE && yyB === NONE;\n const zNone = zzA === NONE && zzB === NONE;\n const alphaNone = aaA === NONE && aaB === NONE;\n const [[xA, yA, zA, alphaA], [xB, yB, zB, alphaB]] =\n normalizeColorComponents(\n [xxA, yyA, zzA, aaA],\n [xxB, yyB, zzB, aaB],\n true\n );\n const factorA = alphaA * pA;\n const factorB = alphaB * pB;\n alpha = factorA + factorB;\n let x, y, z;\n if (alpha === 0) {\n x = xA * pA + xB * pB;\n y = yA * pA + yB * pB;\n z = zA * pA + zB * pB;\n } else {\n x = (xA * factorA + xB * factorB) / alpha;\n y = (yA * factorA + yB * factorB) / alpha;\n z = (zA * factorA + zB * factorB) / alpha;\n alpha = parseFloat(alpha.toFixed(3));\n }\n if (format === VAL_COMP) {\n const res: SpecifiedColorChannels = [\n colorSpace,\n xNone ? NONE : roundToPrecision(x, HEX),\n yNone ? NONE : roundToPrecision(y, HEX),\n zNone ? NONE : roundToPrecision(z, HEX),\n alphaNone ? NONE : alpha * m\n ];\n setCache(cacheKey, res);\n return res;\n }\n if (colorSpace === 'xyz-d50') {\n [r, g, b] = transformXyzD50ToRgb([x, y, z], true);\n } else {\n [r, g, b] = transformXyzToRgb([x, y, z], true);\n }\n // in hsl, hwb\n } else if (/^h(?:sl|wb)$/.test(colorSpace)) {\n let hslA, hslB;\n if (colorSpace === 'hsl') {\n if (REG_CURRENT.test(colorA)) {\n hslA = [NONE, NONE, NONE, NONE];\n } else {\n hslA = convertColorToHsl(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n hslB = [NONE, NONE, NONE, NONE];\n } else {\n hslB = convertColorToHsl(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n } else {\n if (REG_CURRENT.test(colorA)) {\n hslA = [NONE, NONE, NONE, NONE];\n } else {\n hslA = convertColorToHwb(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n hslB = [NONE, NONE, NONE, NONE];\n } else {\n hslB = convertColorToHwb(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n }\n if (hslA instanceof NullObject || hslB instanceof NullObject) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n const [hhA, ssA, llA, aaA] = hslA;\n const [hhB, ssB, llB, aaB] = hslB;\n const alphaNone = aaA === NONE && aaB === NONE;\n let [[hA, sA, lA, alphaA], [hB, sB, lB, alphaB]] = normalizeColorComponents(\n [hhA, ssA, llA, aaA],\n [hhB, ssB, llB, aaB],\n true\n );\n if (hueArc) {\n [hA, hB] = interpolateHue(hA, hB, hueArc);\n }\n const factorA = alphaA * pA;\n const factorB = alphaB * pB;\n alpha = factorA + factorB;\n const h = (hA * pA + hB * pB) % DEG;\n let s, l;\n if (alpha === 0) {\n s = sA * pA + sB * pB;\n l = lA * pA + lB * pB;\n } else {\n s = (sA * factorA + sB * factorB) / alpha;\n l = (lA * factorA + lB * factorB) / alpha;\n alpha = parseFloat(alpha.toFixed(3));\n }\n [r, g, b] = convertColorToRgb(\n `${colorSpace}(${h} ${s} ${l})`\n ) as ColorChannels;\n if (format === VAL_COMP) {\n const res: SpecifiedColorChannels = [\n 'srgb',\n roundToPrecision(r / MAX_RGB, HEX),\n roundToPrecision(g / MAX_RGB, HEX),\n roundToPrecision(b / MAX_RGB, HEX),\n alphaNone ? NONE : alpha * m\n ];\n setCache(cacheKey, res);\n return res;\n }\n // in lch, oklch\n } else if (/^(?:ok)?lch$/.test(colorSpace)) {\n let lchA, lchB;\n if (colorSpace === 'lch') {\n if (REG_CURRENT.test(colorA)) {\n lchA = [NONE, NONE, NONE, NONE];\n } else {\n lchA = convertColorToLch(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n lchB = [NONE, NONE, NONE, NONE];\n } else {\n lchB = convertColorToLch(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n } else {\n if (REG_CURRENT.test(colorA)) {\n lchA = [NONE, NONE, NONE, NONE];\n } else {\n lchA = convertColorToOklch(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n lchB = [NONE, NONE, NONE, NONE];\n } else {\n lchB = convertColorToOklch(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n }\n if (lchA instanceof NullObject || lchB instanceof NullObject) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n const [llA, ccA, hhA, aaA] = lchA;\n const [llB, ccB, hhB, aaB] = lchB;\n const lNone = llA === NONE && llB === NONE;\n const cNone = ccA === NONE && ccB === NONE;\n const hNone = hhA === NONE && hhB === NONE;\n const alphaNone = aaA === NONE && aaB === NONE;\n let [[lA, cA, hA, alphaA], [lB, cB, hB, alphaB]] = normalizeColorComponents(\n [llA, ccA, hhA, aaA],\n [llB, ccB, hhB, aaB],\n true\n );\n if (hueArc) {\n [hA, hB] = interpolateHue(hA, hB, hueArc);\n }\n const factorA = alphaA * pA;\n const factorB = alphaB * pB;\n alpha = factorA + factorB;\n const h = (hA * pA + hB * pB) % DEG;\n let l, c;\n if (alpha === 0) {\n l = lA * pA + lB * pB;\n c = cA * pA + cB * pB;\n } else {\n l = (lA * factorA + lB * factorB) / alpha;\n c = (cA * factorA + cB * factorB) / alpha;\n alpha = parseFloat(alpha.toFixed(3));\n }\n if (format === VAL_COMP) {\n const res: SpecifiedColorChannels = [\n colorSpace,\n lNone ? NONE : roundToPrecision(l, HEX),\n cNone ? NONE : roundToPrecision(c, HEX),\n hNone ? NONE : roundToPrecision(h, HEX),\n alphaNone ? NONE : alpha * m\n ];\n setCache(cacheKey, res);\n return res;\n }\n [, r, g, b] = resolveColorValue(\n `${colorSpace}(${l} ${c} ${h})`\n ) as ComputedColorChannels;\n // in lab, oklab\n } else {\n let labA, labB;\n if (colorSpace === 'lab') {\n if (REG_CURRENT.test(colorA)) {\n labA = [NONE, NONE, NONE, NONE];\n } else {\n labA = convertColorToLab(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n labB = [NONE, NONE, NONE, NONE];\n } else {\n labB = convertColorToLab(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n } else {\n if (REG_CURRENT.test(colorA)) {\n labA = [NONE, NONE, NONE, NONE];\n } else {\n labA = convertColorToOklab(colorA, {\n colorSpace,\n format: VAL_MIX\n });\n }\n if (REG_CURRENT.test(colorB)) {\n labB = [NONE, NONE, NONE, NONE];\n } else {\n labB = convertColorToOklab(colorB, {\n colorSpace,\n format: VAL_MIX\n });\n }\n }\n if (labA instanceof NullObject || labB instanceof NullObject) {\n const res = cacheInvalidColorValue(cacheKey, format, nullable);\n return res;\n }\n const [llA, aaA, bbA, alA] = labA;\n const [llB, aaB, bbB, alB] = labB;\n const lNone = llA === NONE && llB === NONE;\n const aNone = aaA === NONE && aaB === NONE;\n const bNone = bbA === NONE && bbB === NONE;\n const alphaNone = alA === NONE && alB === NONE;\n const [[lA, aA, bA, alphaA], [lB, aB, bB, alphaB]] =\n normalizeColorComponents(\n [llA, aaA, bbA, alA],\n [llB, aaB, bbB, alB],\n true\n );\n const factorA = alphaA * pA;\n const factorB = alphaB * pB;\n alpha = factorA + factorB;\n let l, aO, bO;\n if (alpha === 0) {\n l = lA * pA + lB * pB;\n aO = aA * pA + aB * pB;\n bO = bA * pA + bB * pB;\n } else {\n l = (lA * factorA + lB * factorB) / alpha;\n aO = (aA * factorA + aB * factorB) / alpha;\n bO = (bA * factorA + bB * factorB) / alpha;\n alpha = parseFloat(alpha.toFixed(3));\n }\n if (format === VAL_COMP) {\n const res: SpecifiedColorChannels = [\n colorSpace,\n lNone ? NONE : roundToPrecision(l, HEX),\n aNone ? NONE : roundToPrecision(aO, HEX),\n bNone ? NONE : roundToPrecision(bO, HEX),\n alphaNone ? NONE : alpha * m\n ];\n setCache(cacheKey, res);\n return res;\n }\n [, r, g, b] = resolveColorValue(\n `${colorSpace}(${l} ${aO} ${bO})`\n ) as ComputedColorChannels;\n }\n const res: SpecifiedColorChannels = [\n 'rgb',\n Math.round(r),\n Math.round(g),\n Math.round(b),\n parseFloat((alpha * m).toFixed(3))\n ];\n setCache(cacheKey, res);\n return res;\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/common.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/common.d.ts new file mode 100644 index 0000000..6039ef3 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/common.d.ts @@ -0,0 +1,21 @@ +/** + * common + */ +/** + * get type + * @param o - object to check + * @returns type of object + */ +export declare const getType: (o: unknown) => string; +/** + * is string + * @param o - object to check + * @returns result + */ +export declare const isString: (o: unknown) => o is string; +/** + * is string or number + * @param o - object to check + * @returns result + */ +export declare const isStringOrNumber: (o: unknown) => boolean; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/common.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/common.js new file mode 100644 index 0000000..dec91c6 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/common.js @@ -0,0 +1,17 @@ +//#region src/js/common.ts +/** +* is string +* @param o - object to check +* @returns result +*/ +var isString = (o) => typeof o === "string" || o instanceof String; +/** +* is string or number +* @param o - object to check +* @returns result +*/ +var isStringOrNumber = (o) => isString(o) || typeof o === "number"; +//#endregion +export { isString, isStringOrNumber }; + +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/common.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/common.js.map new file mode 100644 index 0000000..0a8abaa --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/common.js.map @@ -0,0 +1 @@ +{"version":3,"file":"common.js","names":[],"sources":["../../../src/js/common.ts"],"sourcesContent":["/**\n * common\n */\n\n/* numeric constants */\nconst TYPE_FROM = 8;\nconst TYPE_TO = -1;\n\n/**\n * get type\n * @param o - object to check\n * @returns type of object\n */\nexport const getType = (o: unknown): string =>\n Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO);\n\n/**\n * is string\n * @param o - object to check\n * @returns result\n */\nexport const isString = (o: unknown): o is string =>\n typeof o === 'string' || o instanceof String;\n\n/**\n * is string or number\n * @param o - object to check\n * @returns result\n */\nexport const isStringOrNumber = (o: unknown): boolean =>\n isString(o) || typeof o === 'number';\n"],"mappings":";;;;;;AAqBA,IAAa,YAAY,MACvB,OAAO,MAAM,YAAY,aAAa;;;;;;AAOxC,IAAa,oBAAoB,MAC/B,SAAS,EAAE,IAAI,OAAO,MAAM"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.d.ts new file mode 100644 index 0000000..287e617 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.d.ts @@ -0,0 +1,43 @@ +/** + * constant + */ +export declare const ANGLE = "deg|g?rad|turn"; +export declare const LENGTH = "[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)"; +export declare const NUM = "[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?"; +export declare const NUM_POSITIVE = "\\+?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?"; +export declare const NONE = "none"; +export declare const PCT = "[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%"; +export declare const SYN_FN_CALC = "^(?:calc|clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\(|(?<=[*\\/\\s\\(])(?:calc|clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\("; +export declare const SYN_FN_MATH_START = "^(?:clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\($"; +export declare const SYN_FN_VAR = "^var\\(|(?<=[*\\/\\s\\(])var\\("; +export declare const SYN_FN_VAR_START = "^(?:var|calc|clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\("; +export declare const CS_HUE = "(?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?"; +export declare const CS_HUE_CAPT = "((?:ok)?lch|hsl|hwb)(?:\\s((?:de|in)creasing|longer|shorter)\\shue)?"; +export declare const CS_LAB = "(?:ok)?lab"; +export declare const CS_LCH = "(?:ok)?lch"; +export declare const CS_SRGB = "srgb(?:-linear)?"; +export declare const CS_RGB = "(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?"; +export declare const CS_XYZ = "xyz(?:-d(?:50|65))?"; +export declare const CS_RECT = "(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?"; +export declare const CS_MIX = "(?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?|(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?"; +export declare const FN_COLOR = "color("; +export declare const FN_LIGHT_DARK = "light-dark("; +export declare const FN_MIX = "color-mix("; +export declare const FN_REL = "(?:(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+"; +export declare const FN_REL_CAPT = "((?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+"; +export declare const FN_VAR = "var("; +export declare const SYN_FN_COLOR = "(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?"; +export declare const SYN_FN_LIGHT_DARK = "^light-dark\\("; +export declare const SYN_FN_REL = "^(?:(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+|(?<=[\\s])(?:(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+"; +export declare const SYN_HSL = "(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?"; +export declare const SYN_HSL_LV3 = "[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?"; +export declare const SYN_LCH = "(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?"; +export declare const SYN_MOD = "(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?"; +export declare const SYN_RGB_LV3 = "(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?"; +export declare const SYN_COLOR_TYPE = "[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)"; +export declare const SYN_MIX_PART = "(?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?"; +export declare const SYN_MIX = "color-mix\\(\\s*in\\s+(?:(?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?|(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)\\s*,\\s*(?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?\\s*,\\s*(?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?\\s*\\)"; +export declare const SYN_MIX_CAPT = "color-mix\\(\\s*in\\s+((?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?|(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)\\s*,\\s*((?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?)\\s*,\\s*((?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?)\\s*\\)"; +export declare const VAL_COMP = "computedValue"; +export declare const VAL_MIX = "mixValue"; +export declare const VAL_SPEC = "specifiedValue"; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.js new file mode 100644 index 0000000..6fed58c --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.js @@ -0,0 +1,60 @@ +//#region src/js/constant.ts +/** +* constant +*/ +var _DIGIT = "(?:0|[1-9]\\d*)"; +var _MATH = `clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2`; +var _CALC = `calc|${_MATH}`; +var _VAR = `var|${_CALC}`; +var ANGLE = "deg|g?rad|turn"; +var LENGTH = "[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)"; +var NUM = `[+-]?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`; +var NUM_POSITIVE = `\\+?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`; +var NONE = "none"; +var PCT = `${NUM}%`; +var SYN_FN_CALC = `^(?:${_CALC})\\(|(?<=[*\\/\\s\\(])(?:${_CALC})\\(`; +var SYN_FN_MATH_START = `^(?:${_MATH})\\($`; +var SYN_FN_VAR = "^var\\(|(?<=[*\\/\\s\\(])var\\("; +var SYN_FN_VAR_START = `^(?:${_VAR})\\(`; +var _ALPHA = `(?:\\s*\\/\\s*(?:${NUM}|${PCT}|${NONE}))?`; +var _ALPHA_LV3 = `(?:\\s*,\\s*(?:${NUM}|${PCT}))?`; +var _COLOR_FUNC = "(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?"; +var _COLOR_KEY = "[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}"; +var _CS_HUE = "(?:ok)?lch|hsl|hwb"; +var _CS_HUE_ARC = "(?:de|in)creasing|longer|shorter"; +var _NUM_ANGLE = `${NUM}(?:${ANGLE})?`; +var _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`; +var _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`; +var CS_HUE = `(?:${_CS_HUE})(?:\\s(?:${_CS_HUE_ARC})\\shue)?`; +var CS_HUE_CAPT = `(${_CS_HUE})(?:\\s(${_CS_HUE_ARC})\\shue)?`; +var CS_LAB = "(?:ok)?lab"; +var CS_LCH = "(?:ok)?lch"; +var CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?`; +var CS_XYZ = "xyz(?:-d(?:50|65))?"; +var CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`; +var CS_MIX = `${CS_HUE}|${CS_RECT}`; +var FN_COLOR = "color("; +var FN_LIGHT_DARK = "light-dark("; +var FN_MIX = "color-mix("; +var FN_REL = `(?:${_COLOR_FUNC})\\(\\s*from\\s+`; +var FN_REL_CAPT = `(${_COLOR_FUNC})\\(\\s*from\\s+`; +var FN_VAR = "var("; +var SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`; +var SYN_FN_LIGHT_DARK = "^light-dark\\("; +var SYN_FN_REL = `^${FN_REL}|(?<=[\\s])${FN_REL}`; +var SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`; +var SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\s*,\\s*${PCT}){2}${_ALPHA_LV3}`; +var SYN_LCH = `(?:${_NUM_PCT_NONE}\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`; +var SYN_MOD = `${_NUM_PCT_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`; +var SYN_RGB_LV3 = `(?:${NUM}(?:\\s*,\\s*${NUM}){2}|${PCT}(?:\\s*,\\s*${PCT}){2})${_ALPHA_LV3}`; +var SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\(\\s*${SYN_HSL_LV3}\\s*\\)|rgba?\\(\\s*${SYN_RGB_LV3}\\s*\\)|(?:hsla?|hwb)\\(\\s*${SYN_HSL}\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*${SYN_MOD}\\s*\\)|(?:ok)?lch\\(\\s*${SYN_LCH}\\s*\\)|color\\(\\s*${SYN_FN_COLOR}\\s*\\)`; +var SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\s+${PCT})?`; +var SYN_MIX = `color-mix\\(\\s*in\\s+(?:${CS_MIX})\\s*,\\s*${SYN_MIX_PART}\\s*,\\s*${SYN_MIX_PART}\\s*\\)`; +var SYN_MIX_CAPT = `color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,\\s*(${SYN_MIX_PART})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)`; +var VAL_COMP = "computedValue"; +var VAL_MIX = "mixValue"; +var VAL_SPEC = "specifiedValue"; +//#endregion +export { ANGLE, CS_HUE, CS_HUE_CAPT, CS_LAB, CS_LCH, CS_MIX, CS_RECT, CS_RGB, CS_XYZ, FN_COLOR, FN_LIGHT_DARK, FN_MIX, FN_REL, FN_REL_CAPT, FN_VAR, LENGTH, NONE, NUM, NUM_POSITIVE, PCT, SYN_COLOR_TYPE, SYN_FN_CALC, SYN_FN_COLOR, SYN_FN_LIGHT_DARK, SYN_FN_MATH_START, SYN_FN_REL, SYN_FN_VAR, SYN_FN_VAR_START, SYN_HSL, SYN_HSL_LV3, SYN_LCH, SYN_MIX, SYN_MIX_CAPT, SYN_MIX_PART, SYN_MOD, SYN_RGB_LV3, VAL_COMP, VAL_MIX, VAL_SPEC }; + +//# sourceMappingURL=constant.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.js.map new file mode 100644 index 0000000..c540ed0 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/constant.js.map @@ -0,0 +1 @@ +{"version":3,"file":"constant.js","names":[],"sources":["../../../src/js/constant.ts"],"sourcesContent":["/**\n * constant\n */\n\n/* values and units */\nconst _DIGIT = '(?:0|[1-9]\\\\d*)';\nconst _COMPARE = 'clamp|max|min';\nconst _EXPO = 'exp|hypot|log|pow|sqrt';\nconst _SIGN = 'abs|sign';\nconst _STEP = 'mod|rem|round';\nconst _TRIG = 'a?(?:cos|sin|tan)|atan2';\nconst _MATH = `${_COMPARE}|${_EXPO}|${_SIGN}|${_STEP}|${_TRIG}`;\nconst _CALC = `calc|${_MATH}`;\nconst _VAR = `var|${_CALC}`;\nexport const ANGLE = 'deg|g?rad|turn';\nexport const LENGTH =\n '[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)';\nexport const NUM = `[+-]?(?:${_DIGIT}(?:\\\\.\\\\d*)?|\\\\.\\\\d+)(?:e-?${_DIGIT})?`;\nexport const NUM_POSITIVE = `\\\\+?(?:${_DIGIT}(?:\\\\.\\\\d*)?|\\\\.\\\\d+)(?:e-?${_DIGIT})?`;\nexport const NONE = 'none';\nexport const PCT = `${NUM}%`;\nexport const SYN_FN_CALC = `^(?:${_CALC})\\\\(|(?<=[*\\\\/\\\\s\\\\(])(?:${_CALC})\\\\(`;\nexport const SYN_FN_MATH_START = `^(?:${_MATH})\\\\($`;\nexport const SYN_FN_VAR = '^var\\\\(|(?<=[*\\\\/\\\\s\\\\(])var\\\\(';\nexport const SYN_FN_VAR_START = `^(?:${_VAR})\\\\(`;\n\n/* colors */\nconst _ALPHA = `(?:\\\\s*\\\\/\\\\s*(?:${NUM}|${PCT}|${NONE}))?`;\nconst _ALPHA_LV3 = `(?:\\\\s*,\\\\s*(?:${NUM}|${PCT}))?`;\nconst _COLOR_FUNC = '(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?';\nconst _COLOR_KEY = '[a-z]+|#[\\\\da-f]{3}|#[\\\\da-f]{4}|#[\\\\da-f]{6}|#[\\\\da-f]{8}';\nconst _CS_HUE = '(?:ok)?lch|hsl|hwb';\nconst _CS_HUE_ARC = '(?:de|in)creasing|longer|shorter';\nconst _NUM_ANGLE = `${NUM}(?:${ANGLE})?`;\nconst _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`;\nconst _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`;\nexport const CS_HUE = `(?:${_CS_HUE})(?:\\\\s(?:${_CS_HUE_ARC})\\\\shue)?`;\nexport const CS_HUE_CAPT = `(${_CS_HUE})(?:\\\\s(${_CS_HUE_ARC})\\\\shue)?`;\nexport const CS_LAB = '(?:ok)?lab';\nexport const CS_LCH = '(?:ok)?lch';\nexport const CS_SRGB = 'srgb(?:-linear)?';\nexport const CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|${CS_SRGB}`;\nexport const CS_XYZ = 'xyz(?:-d(?:50|65))?';\nexport const CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`;\nexport const CS_MIX = `${CS_HUE}|${CS_RECT}`;\nexport const FN_COLOR = 'color(';\nexport const FN_LIGHT_DARK = 'light-dark(';\nexport const FN_MIX = 'color-mix(';\nexport const FN_REL = `(?:${_COLOR_FUNC})\\\\(\\\\s*from\\\\s+`;\nexport const FN_REL_CAPT = `(${_COLOR_FUNC})\\\\(\\\\s*from\\\\s+`;\nexport const FN_VAR = 'var(';\nexport const SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`;\nexport const SYN_FN_LIGHT_DARK = '^light-dark\\\\(';\nexport const SYN_FN_REL = `^${FN_REL}|(?<=[\\\\s])${FN_REL}`;\nexport const SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;\nexport const SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\\\s*,\\\\s*${PCT}){2}${_ALPHA_LV3}`;\nexport const SYN_LCH = `(?:${_NUM_PCT_NONE}\\\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`;\nexport const SYN_MOD = `${_NUM_PCT_NONE}(?:\\\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;\nexport const SYN_RGB_LV3 = `(?:${NUM}(?:\\\\s*,\\\\s*${NUM}){2}|${PCT}(?:\\\\s*,\\\\s*${PCT}){2})${_ALPHA_LV3}`;\nexport const SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\\\(\\\\s*${SYN_HSL_LV3}\\\\s*\\\\)|rgba?\\\\(\\\\s*${SYN_RGB_LV3}\\\\s*\\\\)|(?:hsla?|hwb)\\\\(\\\\s*${SYN_HSL}\\\\s*\\\\)|(?:(?:ok)?lab|rgba?)\\\\(\\\\s*${SYN_MOD}\\\\s*\\\\)|(?:ok)?lch\\\\(\\\\s*${SYN_LCH}\\\\s*\\\\)|color\\\\(\\\\s*${SYN_FN_COLOR}\\\\s*\\\\)`;\nexport const SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\\\s+${PCT})?`;\nexport const SYN_MIX = `color-mix\\\\(\\\\s*in\\\\s+(?:${CS_MIX})\\\\s*,\\\\s*${SYN_MIX_PART}\\\\s*,\\\\s*${SYN_MIX_PART}\\\\s*\\\\)`;\nexport const SYN_MIX_CAPT = `color-mix\\\\(\\\\s*in\\\\s+(${CS_MIX})\\\\s*,\\\\s*(${SYN_MIX_PART})\\\\s*,\\\\s*(${SYN_MIX_PART})\\\\s*\\\\)`;\n\n/* formats */\nexport const VAL_COMP = 'computedValue';\nexport const VAL_MIX = 'mixValue';\nexport const VAL_SPEC = 'specifiedValue';\n"],"mappings":";;;;AAKA,IAAM,SAAS;AAMf,IAAM,QAAQ;AACd,IAAM,QAAQ,QAAQ;AACtB,IAAM,OAAO,OAAO;AACpB,IAAa,QAAQ;AACrB,IAAa,SACX;AACF,IAAa,MAAM,WAAW,OAAO,6BAA6B,OAAO;AACzE,IAAa,eAAe,UAAU,OAAO,6BAA6B,OAAO;AACjF,IAAa,OAAO;AACpB,IAAa,MAAM,GAAG,IAAI;AAC1B,IAAa,cAAc,OAAO,MAAM,2BAA2B,MAAM;AACzE,IAAa,oBAAoB,OAAO,MAAM;AAC9C,IAAa,aAAa;AAC1B,IAAa,mBAAmB,OAAO,KAAK;AAG5C,IAAM,SAAS,oBAAoB,IAAI,GAAG,IAAI,GAAG,KAAK;AACtD,IAAM,aAAa,kBAAkB,IAAI,GAAG,IAAI;AAChD,IAAM,cAAc;AACpB,IAAM,aAAa;AACnB,IAAM,UAAU;AAChB,IAAM,cAAc;AACpB,IAAM,aAAa,GAAG,IAAI,KAAK,MAAM;AACrC,IAAM,kBAAkB,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK;AACvD,IAAM,gBAAgB,MAAM,IAAI,GAAG,IAAI,GAAG,KAAK;AAC/C,IAAa,SAAS,MAAM,QAAQ,YAAY,YAAY;AAC5D,IAAa,cAAc,IAAI,QAAQ,UAAU,YAAY;AAC7D,IAAa,SAAS;AACtB,IAAa,SAAS;AAEtB,IAAa,SAAS;AACtB,IAAa,SAAS;AACtB,IAAa,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG;AAC9C,IAAa,SAAS,GAAG,OAAO,GAAG;AACnC,IAAa,WAAW;AACxB,IAAa,gBAAgB;AAC7B,IAAa,SAAS;AACtB,IAAa,SAAS,MAAM,YAAY;AACxC,IAAa,cAAc,IAAI,YAAY;AAC3C,IAAa,SAAS;AACtB,IAAa,eAAe,MAAM,OAAO,GAAG,OAAO,UAAU,cAAc,MAAM;AACjF,IAAa,oBAAoB;AACjC,IAAa,aAAa,IAAI,OAAO,aAAa;AAClD,IAAa,UAAU,GAAG,gBAAgB,SAAS,cAAc,MAAM;AACvE,IAAa,cAAc,GAAG,WAAW,cAAc,IAAI,MAAM;AACjE,IAAa,UAAU,MAAM,cAAc,UAAU,kBAAkB;AACvE,IAAa,UAAU,GAAG,cAAc,SAAS,cAAc,MAAM;AACrE,IAAa,cAAc,MAAM,IAAI,cAAc,IAAI,OAAO,IAAI,cAAc,IAAI,OAAO;AAC3F,IAAa,iBAAiB,GAAG,WAAW,eAAe,YAAY,sBAAsB,YAAY,8BAA8B,QAAQ,qCAAqC,QAAQ,2BAA2B,QAAQ,sBAAsB,aAAa;AAClQ,IAAa,eAAe,MAAM,eAAe,UAAU,IAAI;AAC/D,IAAa,UAAU,4BAA4B,OAAO,YAAY,aAAa,WAAW,aAAa;AAC3G,IAAa,eAAe,0BAA0B,OAAO,aAAa,aAAa,aAAa,aAAa;AAGjH,IAAa,WAAW;AACxB,IAAa,UAAU;AACvB,IAAa,WAAW"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.d.ts new file mode 100644 index 0000000..fe97f7f --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.d.ts @@ -0,0 +1,99 @@ +import { NullObject } from './cache.js'; +import { ColorChannels, Options } from './typedef.js'; +/** + * pre process + * @param value - CSS color value + * @param [opt] - options + * @returns value + */ +export declare const preProcess: (value: string, opt?: Options) => string | NullObject; +/** + * convert number to hex string + * @param value - numeric value + * @returns hex string: 00..ff + */ +export declare const numberToHex: (value: number) => string; +/** + * convert color to hex + * @param value - CSS color value + * @param [opt] - options + * @param [opt.alpha] - enable alpha channel + * @returns #rrggbb | #rrggbbaa | null + */ +export declare const colorToHex: (value: string, opt?: Options) => string | null; +/** + * convert color to hsl + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [h, s, l, alpha] + */ +export declare const colorToHsl: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to hwb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [h, w, b, alpha] + */ +export declare const colorToHwb: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to lab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, a, b, alpha] + */ +export declare const colorToLab: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to lch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, c, h, alpha] + */ +export declare const colorToLch: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to oklab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, a, b, alpha] + */ +export declare const colorToOklab: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to oklch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, c, h, alpha] + */ +export declare const colorToOklch: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to rgb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [r, g, b, alpha] + */ +export declare const colorToRgb: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to xyz + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [x, y, z, alpha] + */ +export declare const colorToXyz: (value: string, opt?: Options) => ColorChannels; +/** + * convert color to xyz-d50 + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [x, y, z, alpha] + */ +export declare const colorToXyzD50: (value: string, opt?: Options) => ColorChannels; +export declare const convert: { + colorToHex: (value: string, opt?: Options) => string | null; + colorToHsl: (value: string, opt?: Options) => ColorChannels; + colorToHwb: (value: string, opt?: Options) => ColorChannels; + colorToLab: (value: string, opt?: Options) => ColorChannels; + colorToLch: (value: string, opt?: Options) => ColorChannels; + colorToOklab: (value: string, opt?: Options) => ColorChannels; + colorToOklch: (value: string, opt?: Options) => ColorChannels; + colorToRgb: (value: string, opt?: Options) => ColorChannels; + colorToXyz: (value: string, opt?: Options) => ColorChannels; + colorToXyzD50: (value: string, opt?: Options) => ColorChannels; + numberToHex: (value: number) => string; +}; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.js new file mode 100644 index 0000000..5d90899 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.js @@ -0,0 +1,245 @@ +import { CacheItem, NullObject, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString } from "./common.js"; +import { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from "./constant.js"; +import { convertColorToHsl, convertColorToHwb, convertColorToLab, convertColorToLch, convertColorToOklab, convertColorToOklch, convertColorToRgb, numberToHexString, parseColorFunc, parseColorValue } from "./color.js"; +import { resolveRelativeColor } from "./relative-color.js"; +import { resolveColor } from "./resolve.js"; +import { resolveVar } from "./css-var.js"; +import { cssCalc } from "./css-calc.js"; +//#region src/js/convert.ts +/** +* convert +*/ +var NAMESPACE = "convert"; +var REG_FN_CALC = new RegExp(SYN_FN_CALC); +var REG_FN_REL = new RegExp(SYN_FN_REL); +var REG_FN_VAR = new RegExp(SYN_FN_VAR); +/** +* pre process +* @param value - CSS color value +* @param [opt] - options +* @returns value +*/ +var preProcess = (value, opt = {}) => { + if (!isString(value)) return new NullObject(); + value = value.trim(); + if (!value) return new NullObject(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "preProcess", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + return cachedResult.item; + } + let res = value; + if (REG_FN_VAR.test(value)) { + const resolved = resolveVar(value, opt); + if (isString(resolved)) res = resolved; + else { + setCache(cacheKey, null); + return new NullObject(); + } + } + if (isString(res)) { + if (REG_FN_REL.test(res)) { + const resolved = resolveRelativeColor(res, opt); + if (isString(resolved)) res = resolved; + else { + setCache(cacheKey, null); + return new NullObject(); + } + } else if (REG_FN_CALC.test(res)) res = cssCalc(res, opt); + } + if (isString(res)) { + if (res.startsWith("color-mix")) res = resolveColor(res, { + ...opt, + format: VAL_COMP, + nullable: true + }); + } + setCache(cacheKey, res); + return res; +}; +/** +* converter factory to reduce boilerplate +* @param name - function name for cache +* @param format - color format +* @param convertFn - conversion function +* @returns color converter function +*/ +var createColorConverter = (name, format, convertFn) => { + const colorConverterFn = (value, opt = {}) => { + if (!isString(value)) throw new TypeError(`${value} is not a string.`); + const resolved = preProcess(value, opt); + if (resolved instanceof NullObject) return [ + 0, + 0, + 0, + 0 + ]; + const val = resolved.toLowerCase(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name, + value: val + }, opt); + const cached = getCache(cacheKey); + if (cached instanceof CacheItem) return cached.item; + const result = convertFn(val, { + ...opt, + format + }); + setCache(cacheKey, result); + return result; + }; + return colorConverterFn; +}; +/** +* convert number to hex string +* @param value - numeric value +* @returns hex string: 00..ff +*/ +var numberToHex = (value) => numberToHexString(value); +/** +* convert color to hex +* @param value - CSS color value +* @param [opt] - options +* @param [opt.alpha] - enable alpha channel +* @returns #rrggbb | #rrggbbaa | null +*/ +var colorToHex = (value, opt = {}) => { + if (!isString(value)) throw new TypeError(`${value} is not a string.`); + const resolved = preProcess(value, opt); + if (resolved instanceof NullObject) return null; + const val = resolved.toLowerCase(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "colorToHex", + value: val + }, opt); + const cached = getCache(cacheKey); + if (cached instanceof CacheItem) { + if (cached.isNull) return null; + return cached.item; + } + const hex = resolveColor(val, { + ...opt, + nullable: true, + format: opt.alpha ? "hexAlpha" : "hex" + }); + if (isString(hex)) { + setCache(cacheKey, hex); + return hex; + } + setCache(cacheKey, null); + return null; +}; +/** +* convert color to hsl +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [h, s, l, alpha] +*/ +var colorToHsl = createColorConverter("colorToHsl", "hsl", convertColorToHsl); +/** +* convert color to hwb +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [h, w, b, alpha] +*/ +var colorToHwb = createColorConverter("colorToHwb", "hwb", convertColorToHwb); +/** +* convert color to lab +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [l, a, b, alpha] +*/ +var colorToLab = createColorConverter("colorToLab", "lab", convertColorToLab); +/** +* convert color to lch +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [l, c, h, alpha] +*/ +var colorToLch = createColorConverter("colorToLch", "lch", convertColorToLch); +/** +* convert color to oklab +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [l, a, b, alpha] +*/ +var colorToOklab = createColorConverter("colorToOklab", "oklab", convertColorToOklab); +/** +* convert color to oklch +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [l, c, h, alpha] +*/ +var colorToOklch = createColorConverter("colorToOklch", "oklch", convertColorToOklch); +/** +* convert color to rgb +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [r, g, b, alpha] +*/ +var colorToRgb = createColorConverter("colorToRgb", "rgb", convertColorToRgb); +/** +* convert color to xyz +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [x, y, z, alpha] +*/ +var colorToXyz = (value, opt = {}) => { + if (!isString(value)) throw new TypeError(`${value} is not a string.`); + const resolved = preProcess(value, opt); + if (resolved instanceof NullObject) return [ + 0, + 0, + 0, + 0 + ]; + const val = resolved.toLowerCase(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "colorToXyz", + value: val + }, opt); + const cached = getCache(cacheKey); + if (cached instanceof CacheItem) return cached.item; + let parsed; + if (val.startsWith("color(")) parsed = parseColorFunc(val, opt); + else parsed = parseColorValue(val, opt); + const [, ...xyz] = parsed; + setCache(cacheKey, xyz); + return xyz; +}; +/** +* convert color to xyz-d50 +* @param value - CSS color value +* @param [opt] - options +* @returns ColorChannels - [x, y, z, alpha] +*/ +var colorToXyzD50 = (value, opt = {}) => { + opt.d50 = true; + return colorToXyz(value, opt); +}; +var convert = { + colorToHex, + colorToHsl, + colorToHwb, + colorToLab, + colorToLch, + colorToOklab, + colorToOklch, + colorToRgb, + colorToXyz, + colorToXyzD50, + numberToHex +}; +//#endregion +export { convert }; + +//# sourceMappingURL=convert.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.js.map new file mode 100644 index 0000000..c13e89a --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/convert.js.map @@ -0,0 +1 @@ +{"version":3,"file":"convert.js","names":[],"sources":["../../../src/js/convert.ts"],"sourcesContent":["/**\n * convert\n */\n\nimport {\n CacheItem,\n NullObject,\n createCacheKey,\n getCache,\n setCache\n} from './cache';\nimport {\n convertColorToHsl,\n convertColorToHwb,\n convertColorToLab,\n convertColorToLch,\n convertColorToOklab,\n convertColorToOklch,\n convertColorToRgb,\n numberToHexString,\n parseColorFunc,\n parseColorValue\n} from './color';\nimport { isString } from './common';\nimport { cssCalc } from './css-calc';\nimport { resolveVar } from './css-var';\nimport { resolveRelativeColor } from './relative-color';\nimport { resolveColor } from './resolve';\nimport { ColorChannels, ComputedColorChannels, Options } from './typedef';\n\n/* constants */\nimport { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from './constant';\nconst NAMESPACE = 'convert';\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_REL = new RegExp(SYN_FN_REL);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * pre process\n * @param value - CSS color value\n * @param [opt] - options\n * @returns value\n */\nexport const preProcess = (\n value: string,\n opt: Options = {}\n): string | NullObject => {\n if (!isString(value)) {\n return new NullObject();\n }\n value = value.trim();\n if (!value) {\n return new NullObject();\n }\n const cacheKey: string = createCacheKey(\n { namespace: NAMESPACE, name: 'preProcess', value },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n return cachedResult.item as string;\n }\n let res: string | NullObject = value;\n if (REG_FN_VAR.test(value)) {\n const resolved = resolveVar(value, opt);\n if (isString(resolved)) {\n res = resolved;\n } else {\n setCache(cacheKey, null);\n return new NullObject();\n }\n }\n if (isString(res)) {\n if (REG_FN_REL.test(res)) {\n const resolved = resolveRelativeColor(res, opt);\n if (isString(resolved)) {\n res = resolved;\n } else {\n setCache(cacheKey, null);\n return new NullObject();\n }\n } else if (REG_FN_CALC.test(res)) {\n res = cssCalc(res, opt);\n }\n }\n if (isString(res)) {\n if (res.startsWith('color-mix')) {\n res = resolveColor(res, { ...opt, format: VAL_COMP, nullable: true });\n }\n }\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * converter factory to reduce boilerplate\n * @param name - function name for cache\n * @param format - color format\n * @param convertFn - conversion function\n * @returns color converter function\n */\nconst createColorConverter = (\n name: string,\n format: string,\n convertFn: Function\n) => {\n const colorConverterFn = (\n value: string,\n opt: Options = {}\n ): ColorChannels => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const resolved = preProcess(value, opt);\n if (resolved instanceof NullObject) {\n return [0, 0, 0, 0];\n }\n const val = resolved.toLowerCase();\n const cacheKey = createCacheKey(\n { namespace: NAMESPACE, name, value: val },\n opt\n );\n const cached = getCache(cacheKey);\n if (cached instanceof CacheItem) {\n return cached.item as ColorChannels;\n }\n const result = convertFn(val, { ...opt, format }) as ColorChannels;\n setCache(cacheKey, result);\n return result;\n };\n return colorConverterFn;\n};\n\n/**\n * convert number to hex string\n * @param value - numeric value\n * @returns hex string: 00..ff\n */\nexport const numberToHex = (value: number): string => numberToHexString(value);\n\n/**\n * convert color to hex\n * @param value - CSS color value\n * @param [opt] - options\n * @param [opt.alpha] - enable alpha channel\n * @returns #rrggbb | #rrggbbaa | null\n */\nexport const colorToHex = (value: string, opt: Options = {}): string | null => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const resolved = preProcess(value, opt);\n if (resolved instanceof NullObject) {\n return null;\n }\n const val = resolved.toLowerCase();\n const cacheKey = createCacheKey(\n { namespace: NAMESPACE, name: 'colorToHex', value: val },\n opt\n );\n const cached = getCache(cacheKey);\n if (cached instanceof CacheItem) {\n if (cached.isNull) {\n return null;\n }\n return cached.item as string;\n }\n const hex = resolveColor(val, {\n ...opt,\n nullable: true,\n format: opt.alpha ? 'hexAlpha' : 'hex'\n });\n if (isString(hex)) {\n setCache(cacheKey, hex);\n return hex;\n }\n setCache(cacheKey, null);\n return null;\n};\n\n/**\n * convert color to hsl\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [h, s, l, alpha]\n */\nexport const colorToHsl = createColorConverter(\n 'colorToHsl',\n 'hsl',\n convertColorToHsl\n);\n\n/**\n * convert color to hwb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [h, w, b, alpha]\n */\nexport const colorToHwb = createColorConverter(\n 'colorToHwb',\n 'hwb',\n convertColorToHwb\n);\n\n/**\n * convert color to lab\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, a, b, alpha]\n */\nexport const colorToLab = createColorConverter(\n 'colorToLab',\n 'lab',\n convertColorToLab\n);\n\n/**\n * convert color to lch\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, c, h, alpha]\n */\nexport const colorToLch = createColorConverter(\n 'colorToLch',\n 'lch',\n convertColorToLch\n);\n\n/**\n * convert color to oklab\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, a, b, alpha]\n */\nexport const colorToOklab = createColorConverter(\n 'colorToOklab',\n 'oklab',\n convertColorToOklab\n);\n\n/**\n * convert color to oklch\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, c, h, alpha]\n */\nexport const colorToOklch = createColorConverter(\n 'colorToOklch',\n 'oklch',\n convertColorToOklch\n);\n\n/**\n * convert color to rgb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [r, g, b, alpha]\n */\nexport const colorToRgb = createColorConverter(\n 'colorToRgb',\n 'rgb',\n convertColorToRgb\n);\n\n/**\n * convert color to xyz\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [x, y, z, alpha]\n */\nexport const colorToXyz = (value: string, opt: Options = {}): ColorChannels => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const resolved = preProcess(value, opt);\n if (resolved instanceof NullObject) {\n return [0, 0, 0, 0];\n }\n const val = resolved.toLowerCase();\n const cacheKey = createCacheKey(\n { namespace: NAMESPACE, name: 'colorToXyz', value: val },\n opt\n );\n const cached = getCache(cacheKey);\n if (cached instanceof CacheItem) {\n return cached.item as ColorChannels;\n }\n let parsed;\n if (val.startsWith('color(')) {\n parsed = parseColorFunc(val, opt);\n } else {\n parsed = parseColorValue(val, opt);\n }\n const [, ...xyz] = parsed as ComputedColorChannels;\n setCache(cacheKey, xyz);\n return xyz as ColorChannels;\n};\n\n/**\n * convert color to xyz-d50\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [x, y, z, alpha]\n */\nexport const colorToXyzD50 = (\n value: string,\n opt: Options = {}\n): ColorChannels => {\n opt.d50 = true;\n return colorToXyz(value, opt);\n};\n\n/* convert */\nexport const convert = {\n colorToHex,\n colorToHsl,\n colorToHwb,\n colorToLab,\n colorToLch,\n colorToOklab,\n colorToOklch,\n colorToRgb,\n colorToXyz,\n colorToXyzD50,\n numberToHex\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.d.ts new file mode 100644 index 0000000..265e284 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.d.ts @@ -0,0 +1,89 @@ +import { CSSToken } from '@csstools/css-tokenizer'; +import { NullObject } from './cache.js'; +import { Options } from './typedef.js'; +/** + * Calclator + */ +export declare class Calculator { + #private; + /** + * constructor + */ + constructor(); + get hasNum(): boolean; + set hasNum(value: boolean); + get numSum(): number[]; + get numMul(): number[]; + get hasPct(): boolean; + set hasPct(value: boolean); + get pctSum(): number[]; + get pctMul(): number[]; + get hasDim(): boolean; + set hasDim(value: boolean); + get dimSum(): string[]; + get dimSub(): string[]; + get dimMul(): string[]; + get dimDiv(): string[]; + get hasEtc(): boolean; + set hasEtc(value: boolean); + get etcSum(): string[]; + get etcSub(): string[]; + get etcMul(): string[]; + get etcDiv(): string[]; + /** + * clear values + * @returns void + */ + clear(): void; + /** + * sort values + * @param values - values + * @returns sorted values + */ + sort(values?: string[]): string[]; + /** + * multiply values + * @returns resolved value + */ + multiply(): string; + /** + * sum values + * @returns resolved value + */ + sum(): string; +} +/** + * sort calc values + * @param values - values to sort + * @param [finalize] - finalize values + * @returns sorted values + */ +export declare const sortCalcValues: (values?: (number | string)[], finalize?: boolean) => string; +/** + * serialize calc + * @param value - CSS value + * @param [opt] - options + * @returns serialized value + */ +export declare const serializeCalc: (value: string, opt?: Options) => string; +/** + * resolve dimension + * @param token - CSS token + * @param [opt] - options + * @returns resolved value + */ +export declare const resolveDimension: (token: CSSToken, opt?: Options) => string | NullObject; +/** + * parse tokens + * @param tokens - CSS tokens + * @param [opt] - options + * @returns parsed tokens + */ +export declare const parseTokens: (tokens: CSSToken[], opt?: Options) => string[]; +/** + * CSS calc() + * @param value - CSS value including calc() + * @param [opt] - options + * @returns resolved value + */ +export declare const cssCalc: (value: string, opt?: Options) => string; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.js new file mode 100644 index 0000000..1fd25a8 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.js @@ -0,0 +1,636 @@ +import { CacheItem, NullObject, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString, isStringOrNumber } from "./common.js"; +import { ANGLE, LENGTH, NUM, SYN_FN_CALC, SYN_FN_MATH_START, SYN_FN_VAR, SYN_FN_VAR_START } from "./constant.js"; +import { resolveLengthInPixels, roundToPrecision } from "./util.js"; +import { resolveVar } from "./css-var.js"; +import { calc } from "@csstools/css-calc"; +import { TokenType, tokenize } from "@csstools/css-tokenizer"; +//#region src/js/css-calc.ts +/** +* css-calc +*/ +var { CloseParen: PAREN_CLOSE, Comment: COMMENT, Dimension: DIM, EOF, Function: FUNC, OpenParen: PAREN_OPEN, Whitespace: W_SPACE } = TokenType; +var NAMESPACE = "css-calc"; +var TRIA = 3; +var HEX = 16; +var MAX_PCT = 100; +var REG_FN_CALC = new RegExp(SYN_FN_CALC); +var REG_FN_CALC_NUM = new RegExp(`^calc\\((${NUM})\\)$`); +var REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START); +var REG_FN_VAR = new RegExp(SYN_FN_VAR); +var REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START); +var REG_OPERATOR = /\s[*+/-]\s/; +var REG_PAREN_OPEN = /\($/; +var REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`); +var REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`); +var REG_TYPE_PCT = new RegExp(`^(${NUM})%$`); +/** +* Calclator +*/ +var Calculator = class { + #hasNum; + #numSum; + #numMul; + #hasPct; + #pctSum; + #pctMul; + #hasDim; + #dimSum; + #dimSub; + #dimMul; + #dimDiv; + #hasEtc; + #etcSum; + #etcSub; + #etcMul; + #etcDiv; + #calcOpts; + /** + * constructor + */ + constructor() { + this.#hasNum = false; + this.#numSum = []; + this.#numMul = []; + this.#hasPct = false; + this.#pctSum = []; + this.#pctMul = []; + this.#hasDim = false; + this.#dimSum = []; + this.#dimSub = []; + this.#dimMul = []; + this.#dimDiv = []; + this.#hasEtc = false; + this.#etcSum = []; + this.#etcSub = []; + this.#etcMul = []; + this.#etcDiv = []; + this.#calcOpts = { toCanonicalUnits: true }; + } + get hasNum() { + return this.#hasNum; + } + set hasNum(value) { + this.#hasNum = !!value; + } + get numSum() { + return this.#numSum; + } + get numMul() { + return this.#numMul; + } + get hasPct() { + return this.#hasPct; + } + set hasPct(value) { + this.#hasPct = !!value; + } + get pctSum() { + return this.#pctSum; + } + get pctMul() { + return this.#pctMul; + } + get hasDim() { + return this.#hasDim; + } + set hasDim(value) { + this.#hasDim = !!value; + } + get dimSum() { + return this.#dimSum; + } + get dimSub() { + return this.#dimSub; + } + get dimMul() { + return this.#dimMul; + } + get dimDiv() { + return this.#dimDiv; + } + get hasEtc() { + return this.#hasEtc; + } + set hasEtc(value) { + this.#hasEtc = !!value; + } + get etcSum() { + return this.#etcSum; + } + get etcSub() { + return this.#etcSub; + } + get etcMul() { + return this.#etcMul; + } + get etcDiv() { + return this.#etcDiv; + } + /** + * clear values + * @returns void + */ + clear() { + this.#hasNum = false; + this.#numSum.length = 0; + this.#numMul.length = 0; + this.#hasPct = false; + this.#pctSum.length = 0; + this.#pctMul.length = 0; + this.#hasDim = false; + this.#dimSum.length = 0; + this.#dimSub.length = 0; + this.#dimMul.length = 0; + this.#dimDiv.length = 0; + this.#hasEtc = false; + this.#etcSum.length = 0; + this.#etcSub.length = 0; + this.#etcMul.length = 0; + this.#etcDiv.length = 0; + } + /** + * sort values + * @param values - values + * @returns sorted values + */ + sort(values = []) { + const arr = [...values]; + if (arr.length > 1) arr.sort((a, b) => { + let res; + if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) { + const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT); + const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT); + if (unitA === unitB) if (Number(valA) === Number(valB)) res = 0; + else if (Number(valA) > Number(valB)) res = 1; + else res = -1; + else if (unitA > unitB) res = 1; + else res = -1; + } else if (a === b) res = 0; + else if (a > b) res = 1; + else res = -1; + return res; + }); + return arr; + } + /** + * multiply values + * @returns resolved value + */ + multiply() { + const value = []; + let num; + if (this.#hasNum) { + num = 1; + for (const i of this.#numMul) { + num *= i; + if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) break; + } + if (!this.#hasPct && !this.#hasDim && !this.hasEtc) { + if (Number.isFinite(num)) num = roundToPrecision(num, HEX); + value.push(num); + } + } + if (this.#hasPct) { + if (typeof num !== "number") num = 1; + for (const i of this.#pctMul) { + num *= i; + if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) break; + } + if (Number.isFinite(num)) num = `${roundToPrecision(num, HEX)}%`; + if (!this.#hasDim && !this.hasEtc) value.push(num); + } + if (this.#hasDim) { + let dim = ""; + let mul = ""; + let div = ""; + if (this.#dimMul.length) if (this.#dimMul.length === 1) [mul] = this.#dimMul; + else mul = `${this.sort(this.#dimMul).join(" * ")}`; + if (this.#dimDiv.length) if (this.#dimDiv.length === 1) [div] = this.#dimDiv; + else div = `${this.sort(this.#dimDiv).join(" * ")}`; + if (Number.isFinite(num)) { + if (mul) if (div) if (div.includes("*")) dim = calc(`calc(${num} * ${mul} / (${div}))`, this.#calcOpts); + else dim = calc(`calc(${num} * ${mul} / ${div})`, this.#calcOpts); + else dim = calc(`calc(${num} * ${mul})`, this.#calcOpts); + else if (div.includes("*")) dim = calc(`calc(${num} / (${div}))`, this.#calcOpts); + else dim = calc(`calc(${num} / ${div})`, this.#calcOpts); + value.push(dim.replace(/^calc/, "")); + } else { + if (!value.length && num !== void 0) value.push(num); + if (mul) { + if (div) if (div.includes("*")) dim = calc(`calc(${mul} / (${div}))`, this.#calcOpts); + else dim = calc(`calc(${mul} / ${div})`, this.#calcOpts); + else dim = calc(`calc(${mul})`, this.#calcOpts); + if (value.length) value.push("*", dim.replace(/^calc/, "")); + else value.push(dim.replace(/^calc/, "")); + } else { + dim = calc(`calc(${div})`, this.#calcOpts); + if (value.length) value.push("/", dim.replace(/^calc/, "")); + else value.push("1", "/", dim.replace(/^calc/, "")); + } + } + } + if (this.#hasEtc) { + if (this.#etcMul.length) { + if (!value.length && num !== void 0) value.push(num); + const mul = this.sort(this.#etcMul).join(" * "); + if (value.length) value.push(`* ${mul}`); + else value.push(`${mul}`); + } + if (this.#etcDiv.length) { + const div = this.sort(this.#etcDiv).join(" * "); + if (div.includes("*")) if (value.length) value.push(`/ (${div})`); + else value.push(`1 / (${div})`); + else if (value.length) value.push(`/ ${div}`); + else value.push(`1 / ${div}`); + } + } + if (value.length) return value.join(" "); + return ""; + } + /** + * sum values + * @returns resolved value + */ + sum() { + const value = []; + if (this.#hasNum) { + let num = 0; + for (const i of this.#numSum) { + num += i; + if (!Number.isFinite(num) || Number.isNaN(num)) break; + } + value.push(num); + } + if (this.#hasPct) { + let num = 0; + for (const i of this.#pctSum) { + num += i; + if (!Number.isFinite(num)) break; + } + if (Number.isFinite(num)) num = `${num}%`; + if (value.length) value.push(`+ ${num}`); + else value.push(num); + } + if (this.#hasDim) { + let dim, sum, sub; + if (this.#dimSum.length) sum = this.sort(this.#dimSum).join(" + "); + if (this.#dimSub.length) sub = this.sort(this.#dimSub).join(" + "); + if (sum) if (sub) if (sub.includes("-")) dim = calc(`calc(${sum} - (${sub}))`, this.#calcOpts); + else dim = calc(`calc(${sum} - ${sub})`, this.#calcOpts); + else dim = calc(`calc(${sum})`, this.#calcOpts); + else dim = calc(`calc(-1 * (${sub}))`, this.#calcOpts); + if (value.length) value.push("+", dim.replace(/^calc/, "")); + else value.push(dim.replace(/^calc/, "")); + } + if (this.#hasEtc) { + if (this.#etcSum.length) { + const sum = this.sort(this.#etcSum).map((item) => { + let res; + if (REG_OPERATOR.test(item) && !item.startsWith("(") && !item.endsWith(")")) res = `(${item})`; + else res = item; + return res; + }).join(" + "); + if (value.length) if (this.#etcSum.length > 1) value.push(`+ (${sum})`); + else value.push(`+ ${sum}`); + else value.push(`${sum}`); + } + if (this.#etcSub.length) { + const sub = this.sort(this.#etcSub).map((item) => { + let res; + if (REG_OPERATOR.test(item) && !item.startsWith("(") && !item.endsWith(")")) res = `(${item})`; + else res = item; + return res; + }).join(" + "); + if (value.length) if (this.#etcSub.length > 1) value.push(`- (${sub})`); + else value.push(`- ${sub}`); + else if (this.#etcSub.length > 1) value.push(`-1 * (${sub})`); + else value.push(`-1 * ${sub}`); + } + } + if (value.length) return value.join(" "); + return ""; + } +}; +/** +* sort calc values +* @param values - values to sort +* @param [finalize] - finalize values +* @returns sorted values +*/ +var sortCalcValues = (values = [], finalize = false) => { + if (values.length < TRIA) throw new Error(`Unexpected array length ${values.length}.`); + const start = values.shift(); + if (!isString(start) || !start.endsWith("(")) throw new Error(`Unexpected token ${start}.`); + const end = values.pop(); + if (end !== ")") throw new Error(`Unexpected token ${end}.`); + if (values.length === 1) { + const [value] = values; + if (!isStringOrNumber(value)) throw new Error(`Unexpected token ${value}.`); + return `${start}${value}${end}`; + } + const sortedValues = []; + const cal = new Calculator(); + let operator = ""; + const l = values.length; + let hasAddSub = false; + for (let i = 0; i < l; i++) { + const value = values[i]; + if (!isStringOrNumber(value)) throw new Error(`Unexpected token ${value}.`); + if (value === "*" || value === "/") operator = value; + else if (value === "+" || value === "-") { + const sortedValue = cal.multiply(); + if (sortedValue) sortedValues.push(sortedValue, value); + hasAddSub = true; + cal.clear(); + operator = ""; + } else { + const numValue = Number(value); + const strValue = `${value}`; + switch (operator) { + case "/": + if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numMul.push(1 / numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT); + cal.hasPct = true; + cal.pctMul.push(MAX_PCT * MAX_PCT / Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimDiv.push(strValue); + } else { + cal.hasEtc = true; + cal.etcDiv.push(strValue); + } + break; + default: if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numMul.push(numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT); + cal.hasPct = true; + cal.pctMul.push(Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimMul.push(strValue); + } else { + cal.hasEtc = true; + cal.etcMul.push(strValue); + } + } + } + if (i === l - 1) { + const sortedValue = cal.multiply(); + if (sortedValue) sortedValues.push(sortedValue); + cal.clear(); + operator = ""; + } + } + let resolvedValue = ""; + if (finalize && hasAddSub) { + const finalizedValues = []; + cal.clear(); + operator = ""; + const l = sortedValues.length; + for (let i = 0; i < l; i++) { + const value = sortedValues[i]; + if (isStringOrNumber(value)) if (value === "+" || value === "-") operator = value; + else { + const numValue = Number(value); + const strValue = `${value}`; + switch (operator) { + case "-": + if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numSum.push(-1 * numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT); + cal.hasPct = true; + cal.pctSum.push(-1 * Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimSub.push(strValue); + } else { + cal.hasEtc = true; + cal.etcSub.push(strValue); + } + break; + default: if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numSum.push(numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT); + cal.hasPct = true; + cal.pctSum.push(Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimSum.push(strValue); + } else { + cal.hasEtc = true; + cal.etcSum.push(strValue); + } + } + } + if (i === l - 1) { + const sortedValue = cal.sum(); + if (sortedValue) finalizedValues.push(sortedValue); + cal.clear(); + operator = ""; + } + } + resolvedValue = finalizedValues.join(" ").replace(/\+\s-/g, "- "); + } else resolvedValue = sortedValues.join(" ").replace(/\+\s-/g, "- "); + if (resolvedValue.startsWith("(") && resolvedValue.endsWith(")") && resolvedValue.lastIndexOf("(") === 0 && resolvedValue.indexOf(")") === resolvedValue.length - 1) resolvedValue = resolvedValue.substring(1, resolvedValue.length - 1); + return `${start}${resolvedValue}${end}`; +}; +/** +* resolve AST node +* @param node - AST node +* @param isRoot - is root node +* @returns resolved value +*/ +var resolveNode = (node, isRoot) => { + const flatItems = []; + for (const item of node) if (Array.isArray(item)) flatItems.push(resolveNode(item, false)); + else flatItems.push(item); + if (isRoot) { + if (flatItems.length >= TRIA) return sortCalcValues(flatItems, true); + const joined = flatItems.join(""); + return joined.startsWith("calc(") ? joined : `calc(${joined})`; + } + if (flatItems.length >= TRIA) { + let serialized = sortCalcValues(flatItems, false); + if (REG_FN_VAR_START.test(serialized)) serialized = calc(serialized, { toCanonicalUnits: true }); + return serialized; + } + return flatItems.join(""); +}; +/** +* serialize calc +* @param value - CSS value +* @param [opt] - options +* @returns serialized value +*/ +var serializeCalc = (value, opt = {}) => { + const { format = "" } = opt; + if (isString(value)) { + if (!REG_FN_VAR_START.test(value) || format !== "specifiedValue") return value; + value = value.toLowerCase().trim(); + } else throw new TypeError(`${value} is not a string.`); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "serializeCalc", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) return cachedResult.item; + const items = tokenize({ css: value }).map((token) => { + const [type, val] = token; + let res = ""; + if (type !== W_SPACE && type !== COMMENT) res = val; + return res; + }).filter((v) => v); + const stack = [[]]; + for (const item of items) if (REG_PAREN_OPEN.test(item)) { + const newNode = [item]; + const parent = stack[stack.length - 1]; + if (parent) parent.push(newNode); + stack.push(newNode); + } else if (item === ")") if (stack.length > 1) { + const currentLevel = stack.pop(); + if (currentLevel) currentLevel.push(item); + } else { + const root = stack[0]; + if (root) root.push(item); + } + else { + const parent = stack[stack.length - 1]; + if (parent) parent.push(item); + } + let serializedCalc = ""; + const rootItems = stack[0]; + if (rootItems) if (rootItems.length === 1 && Array.isArray(rootItems[0])) serializedCalc = resolveNode(rootItems[0], true); + else { + const flatItems = []; + for (const item of rootItems) if (Array.isArray(item)) flatItems.push(resolveNode(item, false)); + else flatItems.push(item); + if (flatItems.length >= TRIA) serializedCalc = sortCalcValues(flatItems, true); + else { + const firstItem = flatItems[0] || ""; + serializedCalc = isString(firstItem) && firstItem.startsWith("calc(") ? firstItem : `calc(${firstItem})`; + } + } + setCache(cacheKey, serializedCalc); + return serializedCalc; +}; +/** +* resolve dimension +* @param token - CSS token +* @param [opt] - options +* @returns resolved value +*/ +var resolveDimension = (token, opt = {}) => { + if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`); + const [, , , , detail = {}] = token; + const { unit, value } = detail; + if (unit === "px") return `${value}${unit}`; + const pixelValue = resolveLengthInPixels(Number(value), unit, opt); + if (Number.isFinite(pixelValue)) return `${roundToPrecision(pixelValue, HEX)}px`; + return new NullObject(); +}; +/** +* parse tokens +* @param tokens - CSS tokens +* @param [opt] - options +* @returns parsed tokens +*/ +var parseTokens = (tokens, opt = {}) => { + if (!Array.isArray(tokens)) throw new TypeError(`${tokens} is not an array.`); + const { format = "" } = opt; + const mathFunc = /* @__PURE__ */ new Set(); + let nest = 0; + const res = []; + for (const token of tokens) { + if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`); + const [type = "", value = ""] = token; + switch (type) { + case DIM: + if (format === "specifiedValue" && !mathFunc.has(nest)) res.push(value); + else { + const resolvedValue = resolveDimension(token, opt); + if (isString(resolvedValue)) res.push(resolvedValue); + else res.push(value); + } + break; + case FUNC: + case PAREN_OPEN: + res.push(value); + nest++; + if (REG_FN_MATH_START.test(value)) mathFunc.add(nest); + break; + case PAREN_CLOSE: + if (res.length) if (res[res.length - 1] === " ") res.splice(-1, 1, value); + else res.push(value); + else res.push(value); + if (mathFunc.has(nest)) mathFunc.delete(nest); + nest--; + break; + case W_SPACE: + if (res.length) { + const lastValue = res[res.length - 1]; + if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") res.push(value); + } + break; + default: if (type !== COMMENT && type !== EOF) res.push(value); + } + } + return res; +}; +/** +* CSS calc() +* @param value - CSS value including calc() +* @param [opt] - options +* @returns resolved value +*/ +var cssCalc = (value, opt = {}) => { + const { format = "" } = opt; + if (isString(value)) { + if (REG_FN_VAR.test(value)) if (format === "specifiedValue") return value; + else { + const resolvedValue = resolveVar(value, opt); + if (isString(resolvedValue)) return resolvedValue; + else return ""; + } + else if (!REG_FN_CALC.test(value)) return value; + value = value.toLowerCase().trim(); + } else throw new TypeError(`${value} is not a string.`); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "cssCalc", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) return cachedResult.item; + let resolvedValue = calc(parseTokens(tokenize({ css: value }), opt).join(""), { toCanonicalUnits: true }); + if (REG_FN_VAR_START.test(value)) { + if (REG_TYPE_DIM_PCT.test(resolvedValue)) { + const [, val, unit] = resolvedValue.match(REG_TYPE_DIM_PCT); + resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`; + } + if (resolvedValue && !REG_FN_VAR_START.test(resolvedValue) && format === "specifiedValue") resolvedValue = `calc(${resolvedValue})`; + } + if (format === "specifiedValue") { + if (/\s[-+*/]\s/.test(resolvedValue) && !resolvedValue.includes("NaN")) resolvedValue = serializeCalc(resolvedValue, opt); + else if (REG_FN_CALC_NUM.test(resolvedValue)) { + const [, val] = resolvedValue.match(REG_FN_CALC_NUM); + resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`; + } + } + setCache(cacheKey, resolvedValue); + return resolvedValue; +}; +//#endregion +export { cssCalc, resolveDimension, serializeCalc }; + +//# sourceMappingURL=css-calc.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.js.map new file mode 100644 index 0000000..c0877aa --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-calc.js.map @@ -0,0 +1 @@ +{"version":3,"file":"css-calc.js","names":["#hasNum","#numSum","#numMul","#hasPct","#pctSum","#pctMul","#hasDim","#dimSum","#dimSub","#dimMul","#dimDiv","#hasEtc","#etcSum","#etcSub","#etcMul","#etcDiv","#calcOpts"],"sources":["../../../src/js/css-calc.ts"],"sourcesContent":["/**\n * css-calc\n */\n\nimport { calc, conversionOptions as CalcOptions } from '@csstools/css-calc';\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport {\n CacheItem,\n NullObject,\n createCacheKey,\n getCache,\n setCache\n} from './cache';\nimport { isString, isStringOrNumber } from './common';\nimport { resolveVar } from './css-var';\nimport { resolveLengthInPixels, roundToPrecision } from './util';\nimport { MatchedRegExp, Options } from './typedef';\n\n/* constants */\nimport {\n ANGLE,\n LENGTH,\n NUM,\n SYN_FN_CALC,\n SYN_FN_MATH_START,\n SYN_FN_VAR,\n SYN_FN_VAR_START,\n VAL_SPEC\n} from './constant';\nconst {\n CloseParen: PAREN_CLOSE,\n Comment: COMMENT,\n Dimension: DIM,\n EOF,\n Function: FUNC,\n OpenParen: PAREN_OPEN,\n Whitespace: W_SPACE\n} = TokenType;\nconst NAMESPACE = 'css-calc';\n\n/* numeric constants */\nconst TRIA = 3;\nconst HEX = 16;\nconst MAX_PCT = 100;\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_CALC_NUM = new RegExp(`^calc\\\\((${NUM})\\\\)$`);\nconst REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\nconst REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START);\nconst REG_OPERATOR = /\\s[*+/-]\\s/;\nconst REG_PAREN_OPEN = /\\($/;\nconst REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`);\nconst REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`);\nconst REG_TYPE_PCT = new RegExp(`^(${NUM})%$`);\n\n/**\n * Calclator\n */\nexport class Calculator {\n /* private */\n // number\n #hasNum: boolean;\n #numSum: number[];\n #numMul: number[];\n // percentage\n #hasPct: boolean;\n #pctSum: number[];\n #pctMul: number[];\n // dimension\n #hasDim: boolean;\n #dimSum: string[];\n #dimSub: string[];\n #dimMul: string[];\n #dimDiv: string[];\n // et cetra\n #hasEtc: boolean;\n #etcSum: string[];\n #etcSub: string[];\n #etcMul: string[];\n #etcDiv: string[];\n // calc options\n #calcOpts: CalcOptions;\n\n /**\n * constructor\n */\n constructor() {\n // number\n this.#hasNum = false;\n this.#numSum = [];\n this.#numMul = [];\n // percentage\n this.#hasPct = false;\n this.#pctSum = [];\n this.#pctMul = [];\n // dimension\n this.#hasDim = false;\n this.#dimSum = [];\n this.#dimSub = [];\n this.#dimMul = [];\n this.#dimDiv = [];\n // et cetra\n this.#hasEtc = false;\n this.#etcSum = [];\n this.#etcSub = [];\n this.#etcMul = [];\n this.#etcDiv = [];\n // calc options\n this.#calcOpts = {\n toCanonicalUnits: true\n };\n }\n\n get hasNum() {\n return this.#hasNum;\n }\n\n set hasNum(value: boolean) {\n this.#hasNum = !!value;\n }\n\n get numSum() {\n return this.#numSum;\n }\n\n get numMul() {\n return this.#numMul;\n }\n\n get hasPct() {\n return this.#hasPct;\n }\n\n set hasPct(value: boolean) {\n this.#hasPct = !!value;\n }\n\n get pctSum() {\n return this.#pctSum;\n }\n\n get pctMul() {\n return this.#pctMul;\n }\n\n get hasDim() {\n return this.#hasDim;\n }\n\n set hasDim(value: boolean) {\n this.#hasDim = !!value;\n }\n\n get dimSum() {\n return this.#dimSum;\n }\n\n get dimSub() {\n return this.#dimSub;\n }\n\n get dimMul() {\n return this.#dimMul;\n }\n\n get dimDiv() {\n return this.#dimDiv;\n }\n\n get hasEtc() {\n return this.#hasEtc;\n }\n\n set hasEtc(value: boolean) {\n this.#hasEtc = !!value;\n }\n\n get etcSum() {\n return this.#etcSum;\n }\n\n get etcSub() {\n return this.#etcSub;\n }\n\n get etcMul() {\n return this.#etcMul;\n }\n\n get etcDiv() {\n return this.#etcDiv;\n }\n\n /**\n * clear values\n * @returns void\n */\n clear() {\n // number\n this.#hasNum = false;\n this.#numSum.length = 0;\n this.#numMul.length = 0;\n // percentage\n this.#hasPct = false;\n this.#pctSum.length = 0;\n this.#pctMul.length = 0;\n // dimension\n this.#hasDim = false;\n this.#dimSum.length = 0;\n this.#dimSub.length = 0;\n this.#dimMul.length = 0;\n this.#dimDiv.length = 0;\n // et cetra\n this.#hasEtc = false;\n this.#etcSum.length = 0;\n this.#etcSub.length = 0;\n this.#etcMul.length = 0;\n this.#etcDiv.length = 0;\n }\n\n /**\n * sort values\n * @param values - values\n * @returns sorted values\n */\n sort(values: string[] = []): string[] {\n const arr = [...values];\n if (arr.length > 1) {\n arr.sort((a, b) => {\n let res;\n if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) {\n const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT) as MatchedRegExp;\n const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT) as MatchedRegExp;\n if (unitA === unitB) {\n if (Number(valA) === Number(valB)) {\n res = 0;\n } else if (Number(valA) > Number(valB)) {\n res = 1;\n } else {\n res = -1;\n }\n } else if (unitA > unitB) {\n res = 1;\n } else {\n res = -1;\n }\n } else {\n if (a === b) {\n res = 0;\n } else if (a > b) {\n res = 1;\n } else {\n res = -1;\n }\n }\n return res;\n });\n }\n return arr;\n }\n\n /**\n * multiply values\n * @returns resolved value\n */\n multiply(): string {\n const value = [];\n let num;\n if (this.#hasNum) {\n num = 1;\n for (const i of this.#numMul) {\n num *= i;\n if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {\n break;\n }\n }\n if (!this.#hasPct && !this.#hasDim && !this.hasEtc) {\n if (Number.isFinite(num)) {\n num = roundToPrecision(num, HEX);\n }\n value.push(num);\n }\n }\n if (this.#hasPct) {\n if (typeof num !== 'number') {\n num = 1;\n }\n for (const i of this.#pctMul) {\n num *= i;\n if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {\n break;\n }\n }\n if (Number.isFinite(num)) {\n num = `${roundToPrecision(num, HEX)}%`;\n }\n if (!this.#hasDim && !this.hasEtc) {\n value.push(num);\n }\n }\n if (this.#hasDim) {\n let dim = '';\n let mul = '';\n let div = '';\n if (this.#dimMul.length) {\n if (this.#dimMul.length === 1) {\n [mul] = this.#dimMul as [string];\n } else {\n mul = `${this.sort(this.#dimMul).join(' * ')}`;\n }\n }\n if (this.#dimDiv.length) {\n if (this.#dimDiv.length === 1) {\n [div] = this.#dimDiv as [string];\n } else {\n div = `${this.sort(this.#dimDiv).join(' * ')}`;\n }\n }\n if (Number.isFinite(num)) {\n if (mul) {\n if (div) {\n if (div.includes('*')) {\n dim = calc(`calc(${num} * ${mul} / (${div}))`, this.#calcOpts);\n } else {\n dim = calc(`calc(${num} * ${mul} / ${div})`, this.#calcOpts);\n }\n } else {\n dim = calc(`calc(${num} * ${mul})`, this.#calcOpts);\n }\n } else if (div.includes('*')) {\n dim = calc(`calc(${num} / (${div}))`, this.#calcOpts);\n } else {\n dim = calc(`calc(${num} / ${div})`, this.#calcOpts);\n }\n value.push(dim.replace(/^calc/, ''));\n } else {\n if (!value.length && num !== undefined) {\n value.push(num);\n }\n if (mul) {\n if (div) {\n if (div.includes('*')) {\n dim = calc(`calc(${mul} / (${div}))`, this.#calcOpts);\n } else {\n dim = calc(`calc(${mul} / ${div})`, this.#calcOpts);\n }\n } else {\n dim = calc(`calc(${mul})`, this.#calcOpts);\n }\n if (value.length) {\n value.push('*', dim.replace(/^calc/, ''));\n } else {\n value.push(dim.replace(/^calc/, ''));\n }\n } else {\n dim = calc(`calc(${div})`, this.#calcOpts);\n if (value.length) {\n value.push('/', dim.replace(/^calc/, ''));\n } else {\n value.push('1', '/', dim.replace(/^calc/, ''));\n }\n }\n }\n }\n if (this.#hasEtc) {\n if (this.#etcMul.length) {\n if (!value.length && num !== undefined) {\n value.push(num);\n }\n const mul = this.sort(this.#etcMul).join(' * ');\n if (value.length) {\n value.push(`* ${mul}`);\n } else {\n value.push(`${mul}`);\n }\n }\n if (this.#etcDiv.length) {\n const div = this.sort(this.#etcDiv).join(' * ');\n if (div.includes('*')) {\n if (value.length) {\n value.push(`/ (${div})`);\n } else {\n value.push(`1 / (${div})`);\n }\n } else if (value.length) {\n value.push(`/ ${div}`);\n } else {\n value.push(`1 / ${div}`);\n }\n }\n }\n if (value.length) {\n return value.join(' ');\n }\n return '';\n }\n\n /**\n * sum values\n * @returns resolved value\n */\n sum(): string {\n const value = [];\n if (this.#hasNum) {\n let num = 0;\n for (const i of this.#numSum) {\n num += i;\n if (!Number.isFinite(num) || Number.isNaN(num)) {\n break;\n }\n }\n value.push(num);\n }\n if (this.#hasPct) {\n let num: number | string = 0;\n for (const i of this.#pctSum) {\n num += i;\n if (!Number.isFinite(num)) {\n break;\n }\n }\n if (Number.isFinite(num)) {\n num = `${num}%`;\n }\n if (value.length) {\n value.push(`+ ${num}`);\n } else {\n value.push(num);\n }\n }\n if (this.#hasDim) {\n let dim, sum, sub;\n if (this.#dimSum.length) {\n sum = this.sort(this.#dimSum).join(' + ');\n }\n if (this.#dimSub.length) {\n sub = this.sort(this.#dimSub).join(' + ');\n }\n if (sum) {\n if (sub) {\n if (sub.includes('-')) {\n dim = calc(`calc(${sum} - (${sub}))`, this.#calcOpts);\n } else {\n dim = calc(`calc(${sum} - ${sub})`, this.#calcOpts);\n }\n } else {\n dim = calc(`calc(${sum})`, this.#calcOpts);\n }\n } else {\n dim = calc(`calc(-1 * (${sub}))`, this.#calcOpts);\n }\n if (value.length) {\n value.push('+', dim.replace(/^calc/, ''));\n } else {\n value.push(dim.replace(/^calc/, ''));\n }\n }\n if (this.#hasEtc) {\n if (this.#etcSum.length) {\n const sum = this.sort(this.#etcSum)\n .map(item => {\n let res;\n if (\n REG_OPERATOR.test(item) &&\n !item.startsWith('(') &&\n !item.endsWith(')')\n ) {\n res = `(${item})`;\n } else {\n res = item;\n }\n return res;\n })\n .join(' + ');\n if (value.length) {\n if (this.#etcSum.length > 1) {\n value.push(`+ (${sum})`);\n } else {\n value.push(`+ ${sum}`);\n }\n } else {\n value.push(`${sum}`);\n }\n }\n if (this.#etcSub.length) {\n const sub = this.sort(this.#etcSub)\n .map(item => {\n let res;\n if (\n REG_OPERATOR.test(item) &&\n !item.startsWith('(') &&\n !item.endsWith(')')\n ) {\n res = `(${item})`;\n } else {\n res = item;\n }\n return res;\n })\n .join(' + ');\n if (value.length) {\n if (this.#etcSub.length > 1) {\n value.push(`- (${sub})`);\n } else {\n value.push(`- ${sub}`);\n }\n } else if (this.#etcSub.length > 1) {\n value.push(`-1 * (${sub})`);\n } else {\n value.push(`-1 * ${sub}`);\n }\n }\n }\n if (value.length) {\n return value.join(' ');\n }\n return '';\n }\n}\n\n/**\n * sort calc values\n * @param values - values to sort\n * @param [finalize] - finalize values\n * @returns sorted values\n */\nexport const sortCalcValues = (\n values: (number | string)[] = [],\n finalize: boolean = false\n): string => {\n if (values.length < TRIA) {\n throw new Error(`Unexpected array length ${values.length}.`);\n }\n const start = values.shift();\n if (!isString(start) || !start.endsWith('(')) {\n throw new Error(`Unexpected token ${start}.`);\n }\n const end = values.pop();\n if (end !== ')') {\n throw new Error(`Unexpected token ${end}.`);\n }\n if (values.length === 1) {\n const [value] = values;\n if (!isStringOrNumber(value)) {\n throw new Error(`Unexpected token ${value}.`);\n }\n return `${start}${value}${end}`;\n }\n const sortedValues = [];\n const cal = new Calculator();\n let operator: string = '';\n const l = values.length;\n // Array traversal optimization for operator check\n let hasAddSub = false;\n for (let i = 0; i < l; i++) {\n const value = values[i];\n if (!isStringOrNumber(value)) {\n throw new Error(`Unexpected token ${value}.`);\n }\n if (value === '*' || value === '/') {\n operator = value;\n } else if (value === '+' || value === '-') {\n const sortedValue = cal.multiply();\n if (sortedValue) {\n sortedValues.push(sortedValue, value);\n }\n // Mark presence of + or -\n hasAddSub = true;\n cal.clear();\n operator = '';\n } else {\n const numValue = Number(value);\n const strValue = `${value}`;\n switch (operator) {\n case '/': {\n if (Number.isFinite(numValue)) {\n cal.hasNum = true;\n cal.numMul.push(1 / numValue);\n } else if (REG_TYPE_PCT.test(strValue)) {\n const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n cal.hasPct = true;\n cal.pctMul.push((MAX_PCT * MAX_PCT) / Number(val));\n } else if (REG_TYPE_DIM.test(strValue)) {\n cal.hasDim = true;\n cal.dimDiv.push(strValue);\n } else {\n cal.hasEtc = true;\n cal.etcDiv.push(strValue);\n }\n break;\n }\n case '*':\n default: {\n if (Number.isFinite(numValue)) {\n cal.hasNum = true;\n cal.numMul.push(numValue);\n } else if (REG_TYPE_PCT.test(strValue)) {\n const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n cal.hasPct = true;\n cal.pctMul.push(Number(val));\n } else if (REG_TYPE_DIM.test(strValue)) {\n cal.hasDim = true;\n cal.dimMul.push(strValue);\n } else {\n cal.hasEtc = true;\n cal.etcMul.push(strValue);\n }\n }\n }\n }\n if (i === l - 1) {\n const sortedValue = cal.multiply();\n if (sortedValue) {\n sortedValues.push(sortedValue);\n }\n cal.clear();\n operator = '';\n }\n }\n let resolvedValue = '';\n if (finalize && hasAddSub) {\n const finalizedValues = [];\n cal.clear();\n operator = '';\n const l = sortedValues.length;\n for (let i = 0; i < l; i++) {\n const value = sortedValues[i];\n if (isStringOrNumber(value)) {\n if (value === '+' || value === '-') {\n operator = value;\n } else {\n const numValue = Number(value);\n const strValue = `${value}`;\n switch (operator) {\n case '-': {\n if (Number.isFinite(numValue)) {\n cal.hasNum = true;\n cal.numSum.push(-1 * numValue);\n } else if (REG_TYPE_PCT.test(strValue)) {\n const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n cal.hasPct = true;\n cal.pctSum.push(-1 * Number(val));\n } else if (REG_TYPE_DIM.test(strValue)) {\n cal.hasDim = true;\n cal.dimSub.push(strValue);\n } else {\n cal.hasEtc = true;\n cal.etcSub.push(strValue);\n }\n break;\n }\n case '+':\n default: {\n if (Number.isFinite(numValue)) {\n cal.hasNum = true;\n cal.numSum.push(numValue);\n } else if (REG_TYPE_PCT.test(strValue)) {\n const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n cal.hasPct = true;\n cal.pctSum.push(Number(val));\n } else if (REG_TYPE_DIM.test(strValue)) {\n cal.hasDim = true;\n cal.dimSum.push(strValue);\n } else {\n cal.hasEtc = true;\n cal.etcSum.push(strValue);\n }\n }\n }\n }\n }\n if (i === l - 1) {\n const sortedValue = cal.sum();\n if (sortedValue) {\n finalizedValues.push(sortedValue);\n }\n cal.clear();\n operator = '';\n }\n }\n resolvedValue = finalizedValues.join(' ').replace(/\\+\\s-/g, '- ');\n } else {\n resolvedValue = sortedValues.join(' ').replace(/\\+\\s-/g, '- ');\n }\n if (\n resolvedValue.startsWith('(') &&\n resolvedValue.endsWith(')') &&\n resolvedValue.lastIndexOf('(') === 0 &&\n resolvedValue.indexOf(')') === resolvedValue.length - 1\n ) {\n resolvedValue = resolvedValue.substring(1, resolvedValue.length - 1);\n }\n return `${start}${resolvedValue}${end}`;\n};\n\n/**\n * resolve AST node\n * @param node - AST node\n * @param isRoot - is root node\n * @returns resolved value\n */\nconst resolveNode = (node: any[], isRoot: boolean): string => {\n const flatItems: string[] = [];\n for (const item of node) {\n if (Array.isArray(item)) {\n flatItems.push(resolveNode(item, false));\n } else {\n flatItems.push(item as string);\n }\n }\n if (isRoot) {\n if (flatItems.length >= TRIA) {\n return sortCalcValues(flatItems, true);\n }\n const joined = flatItems.join('');\n return joined.startsWith('calc(') ? joined : `calc(${joined})`;\n }\n if (flatItems.length >= TRIA) {\n let serialized = sortCalcValues(flatItems, false);\n if (REG_FN_VAR_START.test(serialized)) {\n serialized = calc(serialized, { toCanonicalUnits: true });\n }\n return serialized;\n }\n return flatItems.join('');\n};\n\n/**\n * serialize calc\n * @param value - CSS value\n * @param [opt] - options\n * @returns serialized value\n */\nexport const serializeCalc = (value: string, opt: Options = {}): string => {\n const { format = '' } = opt;\n if (isString(value)) {\n if (!REG_FN_VAR_START.test(value) || format !== VAL_SPEC) {\n return value;\n }\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'serializeCalc',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n return cachedResult.item as string;\n }\n const items: string[] = tokenize({ css: value })\n .map((token: CSSToken): string => {\n const [type, val] = token as [TokenType, string];\n let res = '';\n if (type !== W_SPACE && type !== COMMENT) {\n res = val;\n }\n return res;\n })\n .filter(v => v);\n const stack: any[][] = [[]];\n for (const item of items) {\n if (REG_PAREN_OPEN.test(item)) {\n const newNode = [item];\n const parent = stack[stack.length - 1];\n if (parent) {\n parent.push(newNode);\n }\n stack.push(newNode);\n } else if (item === ')') {\n if (stack.length > 1) {\n const currentLevel = stack.pop();\n if (currentLevel) {\n currentLevel.push(item);\n }\n } else {\n const root = stack[0];\n if (root) {\n root.push(item);\n }\n }\n } else {\n const parent = stack[stack.length - 1];\n if (parent) {\n parent.push(item);\n }\n }\n }\n let serializedCalc = '';\n const rootItems = stack[0];\n if (rootItems) {\n if (rootItems.length === 1 && Array.isArray(rootItems[0])) {\n serializedCalc = resolveNode(rootItems[0], true);\n } else {\n const flatItems: string[] = [];\n for (const item of rootItems) {\n if (Array.isArray(item)) {\n flatItems.push(resolveNode(item, false));\n } else {\n flatItems.push(item as string);\n }\n }\n if (flatItems.length >= TRIA) {\n serializedCalc = sortCalcValues(flatItems, true);\n } else {\n const firstItem = flatItems[0] || '';\n serializedCalc =\n isString(firstItem) && firstItem.startsWith('calc(')\n ? firstItem\n : `calc(${firstItem})`;\n }\n }\n }\n setCache(cacheKey, serializedCalc);\n return serializedCalc;\n};\n\n/**\n * resolve dimension\n * @param token - CSS token\n * @param [opt] - options\n * @returns resolved value\n */\nexport const resolveDimension = (\n token: CSSToken,\n opt: Options = {}\n): string | NullObject => {\n if (!Array.isArray(token)) {\n throw new TypeError(`${token} is not an array.`);\n }\n const [, , , , detail = {}] = token;\n const { unit, value } = detail as {\n unit: string;\n value: number;\n };\n if (unit === 'px') {\n return `${value}${unit}`;\n }\n const pixelValue = resolveLengthInPixels(Number(value), unit, opt);\n if (Number.isFinite(pixelValue)) {\n return `${roundToPrecision(pixelValue, HEX)}px`;\n }\n return new NullObject();\n};\n\n/**\n * parse tokens\n * @param tokens - CSS tokens\n * @param [opt] - options\n * @returns parsed tokens\n */\nexport const parseTokens = (\n tokens: CSSToken[],\n opt: Options = {}\n): string[] => {\n if (!Array.isArray(tokens)) {\n throw new TypeError(`${tokens} is not an array.`);\n }\n const { format = '' } = opt;\n const mathFunc = new Set();\n let nest = 0;\n const res: string[] = [];\n for (const token of tokens) {\n if (!Array.isArray(token)) {\n throw new TypeError(`${token} is not an array.`);\n }\n const [type = '', value = ''] = token as [TokenType, string];\n switch (type) {\n case DIM: {\n if (format === VAL_SPEC && !mathFunc.has(nest)) {\n res.push(value);\n } else {\n const resolvedValue = resolveDimension(token, opt);\n if (isString(resolvedValue)) {\n res.push(resolvedValue);\n } else {\n res.push(value);\n }\n }\n break;\n }\n case FUNC:\n case PAREN_OPEN: {\n res.push(value);\n nest++;\n if (REG_FN_MATH_START.test(value)) {\n mathFunc.add(nest);\n }\n break;\n }\n case PAREN_CLOSE: {\n if (res.length) {\n const lastValue = res[res.length - 1];\n if (lastValue === ' ') {\n res.splice(-1, 1, value);\n } else {\n res.push(value);\n }\n } else {\n res.push(value);\n }\n if (mathFunc.has(nest)) {\n mathFunc.delete(nest);\n }\n nest--;\n break;\n }\n case W_SPACE: {\n if (res.length) {\n const lastValue = res[res.length - 1];\n if (\n isString(lastValue) &&\n !lastValue.endsWith('(') &&\n lastValue !== ' '\n ) {\n res.push(value);\n }\n }\n break;\n }\n default: {\n if (type !== COMMENT && type !== EOF) {\n res.push(value);\n }\n }\n }\n }\n return res;\n};\n\n/**\n * CSS calc()\n * @param value - CSS value including calc()\n * @param [opt] - options\n * @returns resolved value\n */\nexport const cssCalc = (value: string, opt: Options = {}): string => {\n const { format = '' } = opt;\n if (isString(value)) {\n if (REG_FN_VAR.test(value)) {\n if (format === VAL_SPEC) {\n return value;\n } else {\n const resolvedValue = resolveVar(value, opt);\n if (isString(resolvedValue)) {\n return resolvedValue;\n } else {\n return '';\n }\n }\n } else if (!REG_FN_CALC.test(value)) {\n return value;\n }\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'cssCalc',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n return cachedResult.item as string;\n }\n const tokens = tokenize({ css: value });\n const values = parseTokens(tokens, opt);\n let resolvedValue: string = calc(values.join(''), {\n toCanonicalUnits: true\n });\n if (REG_FN_VAR_START.test(value)) {\n if (REG_TYPE_DIM_PCT.test(resolvedValue)) {\n const [, val, unit] = resolvedValue.match(\n REG_TYPE_DIM_PCT\n ) as MatchedRegExp;\n resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`;\n }\n // wrap with `calc()`\n if (\n resolvedValue &&\n !REG_FN_VAR_START.test(resolvedValue) &&\n format === VAL_SPEC\n ) {\n resolvedValue = `calc(${resolvedValue})`;\n }\n }\n if (format === VAL_SPEC) {\n if (/\\s[-+*/]\\s/.test(resolvedValue) && !resolvedValue.includes('NaN')) {\n resolvedValue = serializeCalc(resolvedValue, opt);\n } else if (REG_FN_CALC_NUM.test(resolvedValue)) {\n const [, val] = resolvedValue.match(REG_FN_CALC_NUM) as MatchedRegExp;\n resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`;\n }\n }\n setCache(cacheKey, resolvedValue);\n return resolvedValue;\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.d.ts new file mode 100644 index 0000000..cf0b891 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.d.ts @@ -0,0 +1,79 @@ +import { Options } from './typedef.js'; +/** + * @type ColorStopList - list of color stops + */ +type ColorStopList = [string, string, ...string[]]; +/** + * @typedef ValidateGradientLine - validate gradient line + * @property line - gradient line + * @property valid - result + */ +interface ValidateGradientLine { + line: string; + valid: boolean; +} +/** + * @typedef ValidateColorStops - validate color stops + * @property colorStops - list of color stops + * @property valid - result + */ +interface ValidateColorStops { + colorStops: string[]; + valid: boolean; +} +/** + * @typedef Gradient - parsed CSS gradient + * @property value - input value + * @property type - gradient type + * @property [gradientLine] - gradient line + * @property colorStopList - list of color stops + */ +interface Gradient { + value: string; + type: string; + gradientLine?: string; + colorStopList: ColorStopList; +} +/** + * get gradient type + * @param value - gradient value + * @returns gradient type + */ +export declare const getGradientType: (value: string) => string; +/** + * validate gradient line + * @param value - gradient line value + * @param type - gradient type + * @returns result + */ +export declare const validateGradientLine: (value: string, type: string) => ValidateGradientLine; +/** + * validate color stop list + * @param list + * @param type + * @param [opt] + * @returns result + */ +export declare const validateColorStopList: (list: string[], type: string, opt?: Options) => ValidateColorStops; +/** + * parse CSS gradient + * @param value - gradient value + * @param [opt] - options + * @returns parsed result + */ +export declare const parseGradient: (value: string, opt?: Options) => Gradient | null; +/** + * resolve CSS gradient + * @param value - CSS value + * @param [opt] - options + * @returns result + */ +export declare const resolveGradient: (value: string, opt?: Options) => string; +/** + * is CSS gradient + * @param value - CSS value + * @param [opt] - options + * @returns result + */ +export declare const isGradient: (value: string, opt?: Options) => boolean; +export {}; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.js new file mode 100644 index 0000000..6067ff5 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.js @@ -0,0 +1,291 @@ +import { CacheItem, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString } from "./common.js"; +import { ANGLE, CS_HUE, CS_RECT, LENGTH, NUM, NUM_POSITIVE, PCT, VAL_COMP } from "./constant.js"; +import { resolveColor } from "./resolve.js"; +import { isColor, splitValue } from "./util.js"; +//#region src/js/css-gradient.ts +/** +* css-gradient +*/ +var NAMESPACE = "css-gradient"; +var DIM_ANGLE = `${NUM}(?:${ANGLE})`; +var DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`; +var DIM_LEN_PCT = `${`${NUM}(?:${LENGTH})|0`}|${PCT}`; +var DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`; +var DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`; +var CTR = "center"; +var L_R = "left|right"; +var T_B = "top|bottom"; +var S_E = "start|end"; +var AXIS_X = `${L_R}|x-(?:${S_E})`; +var AXIS_Y = `${T_B}|y-(?:${S_E})`; +var BLOCK = `block-(?:${S_E})`; +var INLINE = `inline-(?:${S_E})`; +var POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`; +var POS_2 = [ + `(?:${CTR}|${AXIS_X})\\s+(?:${CTR}|${AXIS_Y})`, + `(?:${CTR}|${AXIS_Y})\\s+(?:${CTR}|${AXIS_X})`, + `(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`, + `(?:${CTR}|${BLOCK})\\s+(?:${CTR}|${INLINE})`, + `(?:${CTR}|${INLINE})\\s+(?:${CTR}|${BLOCK})`, + `(?:${CTR}|${S_E})\\s+(?:${CTR}|${S_E})` +].join("|"); +var POS_4 = [ + `(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})`, + `(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})`, + `(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})\\s+(?:${INLINE})\\s+(?:${DIM_LEN_PCT})`, + `(?:${INLINE})\\s+(?:${DIM_LEN_PCT})\\s+(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})`, + `(?:${S_E})\\s+(?:${DIM_LEN_PCT})\\s+(?:${S_E})\\s+(?:${DIM_LEN_PCT})` +].join("|"); +var RAD_EXTENT = "(?:clos|farth)est-(?:corner|side)"; +var RAD_SIZE = [ + `${RAD_EXTENT}(?:\\s+${RAD_EXTENT})?`, + `${DIM_LEN_POSI}`, + `(?:${DIM_LEN_PCT_POSI})\\s+(?:${DIM_LEN_PCT_POSI})` +].join("|"); +var RAD_SHAPE = "circle|ellipse"; +var FROM_ANGLE = `from\\s+${DIM_ANGLE}`; +var AT_POSITION = `at\\s+(?:${POS_1}|${POS_2}|${POS_4})`; +var TO_SIDE_CORNER = `to\\s+(?:(?:${L_R})(?:\\s(?:${T_B}))?|(?:${T_B})(?:\\s(?:${L_R}))?)`; +var IN_COLOR_SPACE = `in\\s+(?:${CS_RECT}|${CS_HUE})`; +var LINE_SYNTAX_LINEAR = [`(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\s+${IN_COLOR_SPACE})?`, `${IN_COLOR_SPACE}(?:\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?`].join("|"); +var LINE_SYNTAX_RADIAL = [ + `(?:${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`, + `(?:${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`, + `${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`, + `${IN_COLOR_SPACE}(?:\\s+${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?`, + `${IN_COLOR_SPACE}(?:\\s+${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?`, + `${IN_COLOR_SPACE}(?:\\s+${AT_POSITION})?` +].join("|"); +var LINE_SYNTAX_CONIC = [ + `${FROM_ANGLE}(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`, + `${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`, + `${IN_COLOR_SPACE}(?:\\s+${FROM_ANGLE})?(?:\\s+${AT_POSITION})?` +].join("|"); +var DEFAULT_LINEAR = [/to\s+bottom/]; +var DEFAULT_RADIAL = [ + /ellipse/, + /farthest-corner/, + /at\s+center/ +]; +var DEFAULT_CONIC = [/at\s+center/]; +var IS_CONIC = /^(?:repeating-)?conic-gradient$/; +var IS_LINEAR = /^(?:repeating-)?linear-gradient$/; +var IS_RADIAL = /^(?:repeating-)?radial-gradient$/; +var REG_COLOR_HINT_CONIC = new RegExp(`^(?:${DIM_ANGLE_PCT})$`); +var REG_COLOR_HINT_NON_CONIC = new RegExp(`^(?:${DIM_LEN_PCT})$`); +var REG_DIM_CONIC = new RegExp(`(?:\\s+(?:${DIM_ANGLE_PCT})){1,2}$`); +var REG_DIM_NON_CONIC = new RegExp(`(?:\\s+(?:${DIM_LEN_PCT})){1,2}$`); +var REG_GRAD = /^(?:repeating-)?(?:conic|linear|radial)-gradient\(/; +var REG_GRAD_CAPT = /^((?:repeating-)?(?:conic|linear|radial)-gradient)\(/; +var REG_LINE_CONIC = new RegExp(`^(?:${LINE_SYNTAX_CONIC})$`); +var REG_LINE_LINEAR = new RegExp(`^(?:${LINE_SYNTAX_LINEAR})$`); +var REG_LINE_RADIAL = new RegExp(`^(?:${LINE_SYNTAX_RADIAL})$`); +/** +* get gradient type +* @param value - gradient value +* @returns gradient type +*/ +var getGradientType = (value) => { + if (isString(value)) { + value = value.trim(); + if (REG_GRAD.test(value)) { + const [, type] = value.match(REG_GRAD_CAPT); + return type; + } + } + return ""; +}; +/** +* validate gradient line +* @param value - gradient line value +* @param type - gradient type +* @returns result +*/ +var validateGradientLine = (value, type) => { + if (isString(value) && isString(type)) { + value = value.trim(); + type = type.trim(); + let reg = null; + let defaultValues = []; + if (IS_LINEAR.test(type)) { + reg = REG_LINE_LINEAR; + defaultValues = DEFAULT_LINEAR; + } else if (IS_RADIAL.test(type)) { + reg = REG_LINE_RADIAL; + defaultValues = DEFAULT_RADIAL; + } else if (IS_CONIC.test(type)) { + reg = REG_LINE_CONIC; + defaultValues = DEFAULT_CONIC; + } + if (reg) { + const valid = reg.test(value); + if (valid) { + let line = value; + for (const defaultValue of defaultValues) line = line.replace(defaultValue, ""); + line = line.replace(/\s{2,}/g, " ").trim(); + return { + line, + valid + }; + } + return { + valid, + line: value + }; + } + } + return { + line: value, + valid: false + }; +}; +/** +* validate color stop list +* @param list +* @param type +* @param [opt] +* @returns result +*/ +var validateColorStopList = (list, type, opt = {}) => { + if (Array.isArray(list) && list.length > 1) { + const isConic = IS_CONIC.test(type); + const regColorHint = isConic ? REG_COLOR_HINT_CONIC : REG_COLOR_HINT_NON_CONIC; + const regDimension = isConic ? REG_DIM_CONIC : REG_DIM_NON_CONIC; + const valueList = []; + let prevType = ""; + for (let i = 0; i < list.length; i++) { + const item = list[i]; + if (isString(item)) if (regColorHint.test(item)) { + if (i === 0 || prevType === "hint") return { + colorStops: list, + valid: false + }; + prevType = "hint"; + valueList.push(item); + } else { + const itemColor = item.replace(regDimension, ""); + if (isColor(itemColor, { format: "specifiedValue" })) { + const resolvedColor = resolveColor(itemColor, opt); + prevType = "color"; + valueList.push(item.replace(itemColor, resolvedColor)); + } else return { + colorStops: list, + valid: false + }; + } + else return { + colorStops: list, + valid: false + }; + } + if (prevType !== "color") return { + colorStops: list, + valid: false + }; + return { + valid: true, + colorStops: valueList + }; + } + return { + colorStops: list, + valid: false + }; +}; +/** +* parse CSS gradient +* @param value - gradient value +* @param [opt] - options +* @returns parsed result +*/ +var parseGradient = (value, opt = {}) => { + if (isString(value)) { + value = value.trim(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "parseGradient", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return null; + return cachedResult.item; + } + const type = getGradientType(value); + const gradValue = value.replace(REG_GRAD, "").replace(/\)$/, ""); + if (type && gradValue) { + const [lineOrColorStop = "", ...itemList] = splitValue(gradValue, { delimiter: "," }); + const regDimension = IS_CONIC.test(type) ? REG_DIM_CONIC : REG_DIM_NON_CONIC; + let colorStop = ""; + if (regDimension.test(lineOrColorStop)) { + const itemColor = lineOrColorStop.replace(regDimension, ""); + if (isColor(itemColor, { format: "specifiedValue" })) { + const resolvedColor = resolveColor(itemColor, opt); + colorStop = lineOrColorStop.replace(itemColor, resolvedColor); + } + } else if (isColor(lineOrColorStop, { format: "specifiedValue" })) colorStop = resolveColor(lineOrColorStop, opt); + if (colorStop) { + itemList.unshift(colorStop); + const { colorStops, valid } = validateColorStopList(itemList, type, opt); + if (valid) { + const res = { + value, + type, + colorStopList: colorStops + }; + setCache(cacheKey, res); + return res; + } + } else if (itemList.length > 1) { + const { line: gradientLine, valid: validLine } = validateGradientLine(lineOrColorStop, type); + const { colorStops, valid: validColorStops } = validateColorStopList(itemList, type, opt); + if (validLine && validColorStops) { + const res = { + value, + type, + gradientLine, + colorStopList: colorStops + }; + setCache(cacheKey, res); + return res; + } + } + } + setCache(cacheKey, null); + return null; + } + return null; +}; +/** +* resolve CSS gradient +* @param value - CSS value +* @param [opt] - options +* @returns result +*/ +var resolveGradient = (value, opt = {}) => { + const { format = VAL_COMP } = opt; + const gradient = parseGradient(value, opt); + if (gradient) { + const { type = "", gradientLine = "", colorStopList = [] } = gradient; + if (type && Array.isArray(colorStopList) && colorStopList.length > 1) { + if (gradientLine) return `${type}(${gradientLine}, ${colorStopList.join(", ")})`; + return `${type}(${colorStopList.join(", ")})`; + } + } + if (format === "specifiedValue") return ""; + return "none"; +}; +/** +* is CSS gradient +* @param value - CSS value +* @param [opt] - options +* @returns result +*/ +var isGradient = (value, opt = {}) => { + return parseGradient(value, opt) !== null; +}; +//#endregion +export { isGradient, resolveGradient }; + +//# sourceMappingURL=css-gradient.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.js.map new file mode 100644 index 0000000..6d30cce --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-gradient.js.map @@ -0,0 +1 @@ +{"version":3,"file":"css-gradient.js","names":[],"sources":["../../../src/js/css-gradient.ts"],"sourcesContent":["/**\n * css-gradient\n */\n\nimport { CacheItem, createCacheKey, getCache, setCache } from './cache';\nimport { resolveColor } from './resolve';\nimport { isString } from './common';\nimport { MatchedRegExp, Options } from './typedef';\nimport { isColor, splitValue } from './util';\n\n/* constants */\nimport {\n ANGLE,\n CS_HUE,\n CS_RECT,\n LENGTH,\n NUM,\n NUM_POSITIVE,\n PCT,\n VAL_COMP,\n VAL_SPEC\n} from './constant';\nconst NAMESPACE = 'css-gradient';\nconst DIM_ANGLE = `${NUM}(?:${ANGLE})`;\nconst DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`;\nconst DIM_LEN = `${NUM}(?:${LENGTH})|0`;\nconst DIM_LEN_PCT = `${DIM_LEN}|${PCT}`;\nconst DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`;\nconst DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`;\nconst CTR = 'center';\nconst L_R = 'left|right';\nconst T_B = 'top|bottom';\nconst S_E = 'start|end';\nconst AXIS_X = `${L_R}|x-(?:${S_E})`;\nconst AXIS_Y = `${T_B}|y-(?:${S_E})`;\nconst BLOCK = `block-(?:${S_E})`;\nconst INLINE = `inline-(?:${S_E})`;\nconst POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`;\nconst POS_2 = [\n `(?:${CTR}|${AXIS_X})\\\\s+(?:${CTR}|${AXIS_Y})`,\n `(?:${CTR}|${AXIS_Y})\\\\s+(?:${CTR}|${AXIS_X})`,\n `(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`,\n `(?:${CTR}|${BLOCK})\\\\s+(?:${CTR}|${INLINE})`,\n `(?:${CTR}|${INLINE})\\\\s+(?:${CTR}|${BLOCK})`,\n `(?:${CTR}|${S_E})\\\\s+(?:${CTR}|${S_E})`\n].join('|');\nconst POS_4 = [\n `(?:${AXIS_X})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${AXIS_Y})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${AXIS_Y})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${AXIS_X})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${BLOCK})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${INLINE})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${INLINE})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${BLOCK})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${S_E})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${S_E})\\\\s+(?:${DIM_LEN_PCT})`\n].join('|');\nconst RAD_EXTENT = '(?:clos|farth)est-(?:corner|side)';\nconst RAD_SIZE = [\n `${RAD_EXTENT}(?:\\\\s+${RAD_EXTENT})?`,\n `${DIM_LEN_POSI}`,\n `(?:${DIM_LEN_PCT_POSI})\\\\s+(?:${DIM_LEN_PCT_POSI})`\n].join('|');\nconst RAD_SHAPE = 'circle|ellipse';\nconst FROM_ANGLE = `from\\\\s+${DIM_ANGLE}`;\nconst AT_POSITION = `at\\\\s+(?:${POS_1}|${POS_2}|${POS_4})`;\nconst TO_SIDE_CORNER = `to\\\\s+(?:(?:${L_R})(?:\\\\s(?:${T_B}))?|(?:${T_B})(?:\\\\s(?:${L_R}))?)`;\nconst IN_COLOR_SPACE = `in\\\\s+(?:${CS_RECT}|${CS_HUE})`;\nconst LINE_SYNTAX_LINEAR = [\n `(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?`\n].join('|');\nconst LINE_SYNTAX_RADIAL = [\n `(?:${RAD_SHAPE})(?:\\\\s+(?:${RAD_SIZE}))?(?:\\\\s+${AT_POSITION})?(?:\\\\s+${IN_COLOR_SPACE})?`,\n `(?:${RAD_SIZE})(?:\\\\s+(?:${RAD_SHAPE}))?(?:\\\\s+${AT_POSITION})?(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${AT_POSITION}(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${RAD_SHAPE})(?:\\\\s+(?:${RAD_SIZE}))?(?:\\\\s+${AT_POSITION})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${RAD_SIZE})(?:\\\\s+(?:${RAD_SHAPE}))?(?:\\\\s+${AT_POSITION})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${AT_POSITION})?`\n].join('|');\nconst LINE_SYNTAX_CONIC = [\n `${FROM_ANGLE}(?:\\\\s+${AT_POSITION})?(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${AT_POSITION}(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${FROM_ANGLE})?(?:\\\\s+${AT_POSITION})?`\n].join('|');\nconst DEFAULT_LINEAR = [/to\\s+bottom/];\nconst DEFAULT_RADIAL = [/ellipse/, /farthest-corner/, /at\\s+center/];\nconst DEFAULT_CONIC = [/at\\s+center/];\n\n/* type definitions */\n/**\n * @type ColorStopList - list of color stops\n */\ntype ColorStopList = [string, string, ...string[]];\n\n/**\n * @typedef ValidateGradientLine - validate gradient line\n * @property line - gradient line\n * @property valid - result\n */\ninterface ValidateGradientLine {\n line: string;\n valid: boolean;\n}\n\n/**\n * @typedef ValidateColorStops - validate color stops\n * @property colorStops - list of color stops\n * @property valid - result\n */\ninterface ValidateColorStops {\n colorStops: string[];\n valid: boolean;\n}\n\n/**\n * @typedef Gradient - parsed CSS gradient\n * @property value - input value\n * @property type - gradient type\n * @property [gradientLine] - gradient line\n * @property colorStopList - list of color stops\n */\ninterface Gradient {\n value: string;\n type: string;\n gradientLine?: string;\n colorStopList: ColorStopList;\n}\n\n/* regexp */\nconst IS_CONIC = /^(?:repeating-)?conic-gradient$/;\nconst IS_LINEAR = /^(?:repeating-)?linear-gradient$/;\nconst IS_RADIAL = /^(?:repeating-)?radial-gradient$/;\nconst REG_COLOR_HINT_CONIC = new RegExp(`^(?:${DIM_ANGLE_PCT})$`);\nconst REG_COLOR_HINT_NON_CONIC = new RegExp(`^(?:${DIM_LEN_PCT})$`);\nconst REG_DIM_CONIC = new RegExp(`(?:\\\\s+(?:${DIM_ANGLE_PCT})){1,2}$`);\nconst REG_DIM_NON_CONIC = new RegExp(`(?:\\\\s+(?:${DIM_LEN_PCT})){1,2}$`);\nconst REG_GRAD = /^(?:repeating-)?(?:conic|linear|radial)-gradient\\(/;\nconst REG_GRAD_CAPT = /^((?:repeating-)?(?:conic|linear|radial)-gradient)\\(/;\nconst REG_LINE_CONIC = new RegExp(`^(?:${LINE_SYNTAX_CONIC})$`);\nconst REG_LINE_LINEAR = new RegExp(`^(?:${LINE_SYNTAX_LINEAR})$`);\nconst REG_LINE_RADIAL = new RegExp(`^(?:${LINE_SYNTAX_RADIAL})$`);\n\n/**\n * get gradient type\n * @param value - gradient value\n * @returns gradient type\n */\nexport const getGradientType = (value: string): string => {\n if (isString(value)) {\n value = value.trim();\n if (REG_GRAD.test(value)) {\n const [, type] = value.match(REG_GRAD_CAPT) as MatchedRegExp;\n return type;\n }\n }\n return '';\n};\n\n/**\n * validate gradient line\n * @param value - gradient line value\n * @param type - gradient type\n * @returns result\n */\nexport const validateGradientLine = (\n value: string,\n type: string\n): ValidateGradientLine => {\n if (isString(value) && isString(type)) {\n value = value.trim();\n type = type.trim();\n let reg: RegExp | null = null;\n let defaultValues: RegExp[] = [];\n\n if (IS_LINEAR.test(type)) {\n reg = REG_LINE_LINEAR;\n defaultValues = DEFAULT_LINEAR;\n } else if (IS_RADIAL.test(type)) {\n reg = REG_LINE_RADIAL;\n defaultValues = DEFAULT_RADIAL;\n } else if (IS_CONIC.test(type)) {\n reg = REG_LINE_CONIC;\n defaultValues = DEFAULT_CONIC;\n }\n if (reg) {\n const valid = reg.test(value);\n if (valid) {\n let line = value;\n for (const defaultValue of defaultValues) {\n line = line.replace(defaultValue, '');\n }\n line = line.replace(/\\s{2,}/g, ' ').trim();\n return { line, valid };\n }\n return { valid, line: value };\n }\n }\n return { line: value, valid: false };\n};\n\n/**\n * validate color stop list\n * @param list\n * @param type\n * @param [opt]\n * @returns result\n */\nexport const validateColorStopList = (\n list: string[],\n type: string,\n opt: Options = {}\n): ValidateColorStops => {\n if (Array.isArray(list) && list.length > 1) {\n const isConic = IS_CONIC.test(type);\n const regColorHint = isConic\n ? REG_COLOR_HINT_CONIC\n : REG_COLOR_HINT_NON_CONIC;\n const regDimension = isConic ? REG_DIM_CONIC : REG_DIM_NON_CONIC;\n const valueList: string[] = [];\n // State tracker: 'color' or 'hint'\n let prevType = '';\n for (let i = 0; i < list.length; i++) {\n const item = list[i];\n if (isString(item)) {\n if (regColorHint.test(item)) {\n // Hints cannot be the first item, and two hints cannot be adjacent\n if (i === 0 || prevType === 'hint') {\n return { colorStops: list, valid: false };\n }\n prevType = 'hint';\n valueList.push(item);\n } else {\n const itemColor = item.replace(regDimension, '');\n if (isColor(itemColor, { format: VAL_SPEC })) {\n const resolvedColor = resolveColor(itemColor, opt) as string;\n prevType = 'color';\n valueList.push(item.replace(itemColor, resolvedColor));\n } else {\n return { colorStops: list, valid: false };\n }\n }\n } else {\n return { colorStops: list, valid: false };\n }\n }\n // The last item must be a color, not a hint\n if (prevType !== 'color') {\n return { colorStops: list, valid: false };\n }\n return { valid: true, colorStops: valueList };\n }\n return { colorStops: list, valid: false };\n};\n\n/**\n * parse CSS gradient\n * @param value - gradient value\n * @param [opt] - options\n * @returns parsed result\n */\nexport const parseGradient = (\n value: string,\n opt: Options = {}\n): Gradient | null => {\n if (isString(value)) {\n value = value.trim();\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'parseGradient',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return null;\n }\n return cachedResult.item as Gradient;\n }\n const type = getGradientType(value);\n const gradValue = value.replace(REG_GRAD, '').replace(/\\)$/, '');\n if (type && gradValue) {\n const [lineOrColorStop = '', ...itemList] = splitValue(gradValue, {\n delimiter: ','\n });\n const isConic = IS_CONIC.test(type);\n const regDimension = isConic ? REG_DIM_CONIC : REG_DIM_NON_CONIC;\n let colorStop = '';\n if (regDimension.test(lineOrColorStop)) {\n const itemColor = lineOrColorStop.replace(regDimension, '');\n if (isColor(itemColor, { format: VAL_SPEC })) {\n const resolvedColor = resolveColor(itemColor, opt) as string;\n colorStop = lineOrColorStop.replace(itemColor, resolvedColor);\n }\n } else if (isColor(lineOrColorStop, { format: VAL_SPEC })) {\n colorStop = resolveColor(lineOrColorStop, opt) as string;\n }\n if (colorStop) {\n itemList.unshift(colorStop);\n const { colorStops, valid } = validateColorStopList(\n itemList,\n type,\n opt\n );\n if (valid) {\n const res: Gradient = {\n value,\n type,\n colorStopList: colorStops as ColorStopList\n };\n setCache(cacheKey, res);\n return res;\n }\n } else if (itemList.length > 1) {\n const { line: gradientLine, valid: validLine } = validateGradientLine(\n lineOrColorStop,\n type\n );\n const { colorStops, valid: validColorStops } = validateColorStopList(\n itemList,\n type,\n opt\n );\n if (validLine && validColorStops) {\n const res: Gradient = {\n value,\n type,\n gradientLine,\n colorStopList: colorStops as ColorStopList\n };\n setCache(cacheKey, res);\n return res;\n }\n }\n }\n setCache(cacheKey, null);\n return null;\n }\n return null;\n};\n\n/**\n * resolve CSS gradient\n * @param value - CSS value\n * @param [opt] - options\n * @returns result\n */\nexport const resolveGradient = (value: string, opt: Options = {}): string => {\n const { format = VAL_COMP } = opt;\n const gradient = parseGradient(value, opt);\n if (gradient) {\n const { type = '', gradientLine = '', colorStopList = [] } = gradient;\n if (type && Array.isArray(colorStopList) && colorStopList.length > 1) {\n if (gradientLine) {\n return `${type}(${gradientLine}, ${colorStopList.join(', ')})`;\n }\n return `${type}(${colorStopList.join(', ')})`;\n }\n }\n if (format === VAL_SPEC) {\n return '';\n }\n return 'none';\n};\n\n/**\n * is CSS gradient\n * @param value - CSS value\n * @param [opt] - options\n * @returns result\n */\nexport const isGradient = (value: string, opt: Options = {}): boolean => {\n const gradient = parseGradient(value, opt);\n return gradient !== null;\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.d.ts new file mode 100644 index 0000000..9072353 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.d.ts @@ -0,0 +1,31 @@ +import { CSSToken } from '@csstools/css-tokenizer'; +import { NullObject } from './cache.js'; +import { Options } from './typedef.js'; +/** + * resolve custom property + * @param tokens - CSS tokens + * @param [opt] - options + * @returns result - [tokens, resolvedValue] + */ +export declare function resolveCustomProperty(tokens: CSSToken[], opt?: Options): [CSSToken[], string]; +/** + * parse tokens + * @param tokens - CSS tokens + * @param [opt] - options + * @returns parsed tokens + */ +export declare function parseTokens(tokens: CSSToken[], opt?: Options): string[] | NullObject; +/** + * resolve CSS var() + * @param value - CSS value including var() + * @param [opt] - options + * @returns resolved value + */ +export declare function resolveVar(value: string, opt?: Options): string | NullObject; +/** + * CSS var() + * @param value - CSS value including var() + * @param [opt] - options + * @returns resolved value + */ +export declare const cssVar: (value: string, opt?: Options) => string; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.js new file mode 100644 index 0000000..b61c9f9 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.js @@ -0,0 +1,144 @@ +import { CacheItem, NullObject, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString } from "./common.js"; +import { SYN_FN_CALC, SYN_FN_VAR } from "./constant.js"; +import { isColor } from "./util.js"; +import { cssCalc } from "./css-calc.js"; +import { TokenType, tokenize } from "@csstools/css-tokenizer"; +//#region src/js/css-var.ts +/** +* css-var +*/ +var { CloseParen: PAREN_CLOSE, Comment: COMMENT, EOF, Ident: IDENT, Whitespace: W_SPACE } = TokenType; +var NAMESPACE = "css-var"; +var REG_FN_CALC = new RegExp(SYN_FN_CALC); +var REG_FN_VAR = new RegExp(SYN_FN_VAR); +var REG_CSS_WIDE_KEYWORD = /^(?:inherit|initial|revert(?:-layer)?|unset)$/; +/** +* resolve custom property +* @param tokens - CSS tokens +* @param [opt] - options +* @returns result - [tokens, resolvedValue] +*/ +function resolveCustomProperty(tokens, opt = {}) { + if (!Array.isArray(tokens)) throw new TypeError(`${tokens} is not an array.`); + const { customProperty = {} } = opt; + const items = []; + while (tokens.length) { + const token = tokens.shift(); + if (!token) break; + if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`); + const [type, value] = token; + if (type === PAREN_CLOSE) break; + if (value === "var(") { + const [, item] = resolveCustomProperty(tokens, opt); + if (item) items.push(item); + } else if (type === IDENT) { + if (value.startsWith("--")) { + let item; + if (Object.hasOwn(customProperty, value)) item = customProperty[value]; + else if (typeof customProperty.callback === "function") item = customProperty.callback(value); + if (item) items.push(item); + } else if (value) items.push(value); + } + } + let resolveAsColor = false; + if (items.length > 1) resolveAsColor = isColor(items[items.length - 1]); + let resolvedValue = ""; + for (let item of items) { + item = item.trim(); + if (REG_FN_VAR.test(item)) { + const resolvedItem = resolveVar(item, opt); + if (isString(resolvedItem)) { + if (!resolveAsColor || isColor(resolvedItem)) resolvedValue = resolvedItem; + } + } else if (REG_FN_CALC.test(item)) { + item = cssCalc(item, opt); + if (!resolveAsColor || isColor(item)) resolvedValue = item; + } else if (item && !REG_CSS_WIDE_KEYWORD.test(item)) { + if (!resolveAsColor || isColor(item)) resolvedValue = item; + } + if (resolvedValue) break; + } + return [tokens, resolvedValue]; +} +/** +* parse tokens +* @param tokens - CSS tokens +* @param [opt] - options +* @returns parsed tokens +*/ +function parseTokens(tokens, opt = {}) { + const res = []; + while (tokens.length) { + const token = tokens.shift(); + if (!token) break; + const [type = "", value = ""] = token; + if (value === "var(") { + const [, resolvedValue] = resolveCustomProperty(tokens, opt); + if (!resolvedValue) return new NullObject(); + res.push(resolvedValue); + } else switch (type) { + case PAREN_CLOSE: + if (res.length) if (res[res.length - 1] === " ") res[res.length - 1] = value; + else res.push(value); + else res.push(value); + break; + case W_SPACE: + if (res.length) { + const lastValue = res[res.length - 1]; + if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") res.push(value); + } + break; + default: if (type !== COMMENT && type !== EOF) res.push(value); + } + } + return res; +} +/** +* resolve CSS var() +* @param value - CSS value including var() +* @param [opt] - options +* @returns resolved value +*/ +function resolveVar(value, opt = {}) { + const { format = "" } = opt; + if (isString(value)) { + if (!REG_FN_VAR.test(value) || format === "specifiedValue") return value; + value = value.trim(); + } else throw new TypeError(`${value} is not a string.`); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "resolveVar", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + return cachedResult.item; + } + const values = parseTokens(tokenize({ css: value }), opt); + if (Array.isArray(values)) { + let color = values.join(""); + if (REG_FN_CALC.test(color)) color = cssCalc(color, opt); + setCache(cacheKey, color); + return color; + } else { + setCache(cacheKey, null); + return new NullObject(); + } +} +/** +* CSS var() +* @param value - CSS value including var() +* @param [opt] - options +* @returns resolved value +*/ +var cssVar = (value, opt = {}) => { + const resolvedValue = resolveVar(value, opt); + if (isString(resolvedValue)) return resolvedValue; + return ""; +}; +//#endregion +export { cssVar, resolveVar }; + +//# sourceMappingURL=css-var.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.js.map new file mode 100644 index 0000000..c03de04 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/css-var.js.map @@ -0,0 +1 @@ +{"version":3,"file":"css-var.js","names":[],"sources":["../../../src/js/css-var.ts"],"sourcesContent":["/**\n * css-var\n */\n\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport {\n CacheItem,\n NullObject,\n createCacheKey,\n getCache,\n setCache\n} from './cache';\nimport { isString } from './common';\nimport { cssCalc } from './css-calc';\nimport { isColor } from './util';\nimport { Options } from './typedef';\n\n/* constants */\nimport { FN_VAR, SYN_FN_CALC, SYN_FN_VAR, VAL_SPEC } from './constant';\nconst {\n CloseParen: PAREN_CLOSE,\n Comment: COMMENT,\n EOF,\n Ident: IDENT,\n Whitespace: W_SPACE\n} = TokenType;\nconst NAMESPACE = 'css-var';\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\nconst REG_CSS_WIDE_KEYWORD = /^(?:inherit|initial|revert(?:-layer)?|unset)$/;\n\n/**\n * resolve custom property\n * @param tokens - CSS tokens\n * @param [opt] - options\n * @returns result - [tokens, resolvedValue]\n */\nexport function resolveCustomProperty(\n tokens: CSSToken[],\n opt: Options = {}\n): [CSSToken[], string] {\n if (!Array.isArray(tokens)) {\n throw new TypeError(`${tokens} is not an array.`);\n }\n const { customProperty = {} } = opt;\n const items: string[] = [];\n while (tokens.length) {\n const token = tokens.shift();\n if (!token) {\n break;\n }\n if (!Array.isArray(token)) {\n throw new TypeError(`${token} is not an array.`);\n }\n const [type, value] = token as [TokenType, string];\n // end of var()\n if (type === PAREN_CLOSE) {\n break;\n }\n // nested var()\n if (value === FN_VAR) {\n const [, item] = resolveCustomProperty(tokens, opt);\n if (item) {\n items.push(item);\n }\n } else if (type === IDENT) {\n if (value.startsWith('--')) {\n let item;\n if (Object.hasOwn(customProperty, value)) {\n item = customProperty[value] as string;\n } else if (typeof customProperty.callback === 'function') {\n item = customProperty.callback(value);\n }\n if (item) {\n items.push(item);\n }\n } else if (value) {\n items.push(value);\n }\n }\n }\n let resolveAsColor = false;\n if (items.length > 1) {\n resolveAsColor = isColor(items[items.length - 1]);\n }\n let resolvedValue = '';\n for (let item of items) {\n item = item.trim();\n if (REG_FN_VAR.test(item)) {\n // recurse resolveVar()\n const resolvedItem = resolveVar(item, opt);\n if (isString(resolvedItem)) {\n if (!resolveAsColor || isColor(resolvedItem)) {\n resolvedValue = resolvedItem;\n }\n }\n } else if (REG_FN_CALC.test(item)) {\n item = cssCalc(item, opt);\n if (!resolveAsColor || isColor(item)) {\n resolvedValue = item;\n }\n } else if (item && !REG_CSS_WIDE_KEYWORD.test(item)) {\n if (!resolveAsColor || isColor(item)) {\n resolvedValue = item;\n }\n }\n if (resolvedValue) {\n break;\n }\n }\n return [tokens, resolvedValue];\n}\n\n/**\n * parse tokens\n * @param tokens - CSS tokens\n * @param [opt] - options\n * @returns parsed tokens\n */\nexport function parseTokens(\n tokens: CSSToken[],\n opt: Options = {}\n): string[] | NullObject {\n const res: string[] = [];\n while (tokens.length) {\n const token = tokens.shift();\n if (!token) break;\n const [type = '', value = ''] = token as [TokenType, string];\n if (value === FN_VAR) {\n const [, resolvedValue] = resolveCustomProperty(tokens, opt);\n if (!resolvedValue) {\n return new NullObject();\n }\n res.push(resolvedValue);\n } else {\n switch (type) {\n case PAREN_CLOSE: {\n if (res.length) {\n if (res[res.length - 1] === ' ') {\n res[res.length - 1] = value;\n } else {\n res.push(value);\n }\n } else {\n res.push(value);\n }\n break;\n }\n case W_SPACE: {\n if (res.length) {\n const lastValue = res[res.length - 1];\n if (\n isString(lastValue) &&\n !lastValue.endsWith('(') &&\n lastValue !== ' '\n ) {\n res.push(value);\n }\n }\n break;\n }\n default: {\n if (type !== COMMENT && type !== EOF) {\n res.push(value);\n }\n }\n }\n }\n }\n return res;\n}\n\n/**\n * resolve CSS var()\n * @param value - CSS value including var()\n * @param [opt] - options\n * @returns resolved value\n */\nexport function resolveVar(\n value: string,\n opt: Options = {}\n): string | NullObject {\n const { format = '' } = opt;\n if (isString(value)) {\n if (!REG_FN_VAR.test(value) || format === VAL_SPEC) {\n return value;\n }\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'resolveVar',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n return cachedResult.item as string;\n }\n const tokens = tokenize({ css: value });\n const values = parseTokens(tokens, opt);\n if (Array.isArray(values)) {\n let color = values.join('');\n if (REG_FN_CALC.test(color)) {\n color = cssCalc(color, opt);\n }\n setCache(cacheKey, color);\n return color;\n } else {\n setCache(cacheKey, null);\n return new NullObject();\n }\n}\n\n/**\n * CSS var()\n * @param value - CSS value including var()\n * @param [opt] - options\n * @returns resolved value\n */\nexport const cssVar = (value: string, opt: Options = {}): string => {\n const resolvedValue = resolveVar(value, opt);\n if (isString(resolvedValue)) {\n return resolvedValue;\n }\n return '';\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.d.ts new file mode 100644 index 0000000..ca8a089 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.d.ts @@ -0,0 +1,65 @@ +import { CSSToken } from '@csstools/css-tokenizer'; +import { NullObject } from './cache.js'; +import { ColorChannels, Options, StringColorChannels } from './typedef.js'; +/** + * @type NumberOrStringColorChannels - color channel + */ +type NumberOrStringColorChannels = ColorChannels & StringColorChannels; +/** + * resolve relative color channels + * @param value + * - CSS color value + * - system colors are not supported + * @param [opt] - options + * @param [opt.currentColor] + * - color to use for `currentcolor` keyword + * - if omitted, it will be treated as a missing color + * i.e. `rgb(none none none / none)` + * @param [opt.customProperty] + * - custom properties + * - pair of `--` prefixed property name and value, + * e.g. `customProperty: { '--some-color': '#0000ff' }` + * - and/or `callback` function to get the value of the custom property, + * e.g. `customProperty: { callback: someDeclaration.getPropertyValue }` + * @param [opt.dimension] + * - dimension, convert relative length to pixels + * - pair of unit and it's value as a number in pixels, + * e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }` + * - and/or `callback` function to get the value as a number in pixels, + * e.g. `dimension: { callback: convertUnitToPixel }` + * @param [opt.format] + * - output format, one of below + * - `computedValue` (default), [computed value][139] of the color + * - `specifiedValue`, [specified value][140] of the color + * - `hex`, hex color notation, i.e. `rrggbb` + * - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa` + * @returns + * - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)', + * color(color-space r g b / alpha), color(color-space x y z / alpha), + * lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha), + * oklch(l c h / alpha), null + * - in `computedValue`, values are numbers, however `rgb()` values are + * integers + * - in `specifiedValue`, returns `empty string` for unknown and/or invalid + * color + * - in `hex`, returns `null` for `transparent`, and also returns `null` if + * any of `r`, `g`, `b`, `alpha` is not a number + * - in `hexAlpha`, returns `#00000000` for `transparent`, + * however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number + */ +export declare function resolveColorChannels(tokens: CSSToken[], opt?: Options): NumberOrStringColorChannels | NullObject; +/** + * extract origin color + * @param value - CSS color value + * @param [opt] - options + * @returns origin color value + */ +export declare function extractOriginColor(value: string, opt?: Options): string | NullObject; +/** + * resolve relative color + * @param value - CSS relative color value + * @param [opt] - options + * @returns resolved value + */ +export declare function resolveRelativeColor(value: string, opt?: Options): string | NullObject; +export {}; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.js new file mode 100644 index 0000000..68db1ec --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.js @@ -0,0 +1,451 @@ +import { CacheItem, NullObject, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString, isStringOrNumber } from "./common.js"; +import { CS_LAB, CS_LCH, FN_REL, FN_REL_CAPT, FN_VAR, NONE, SYN_COLOR_TYPE, SYN_FN_MATH_START, SYN_FN_VAR, SYN_MIX, VAL_SPEC } from "./constant.js"; +import { NAMED_COLORS, convertColorToRgb } from "./color.js"; +import { resolveColor } from "./resolve.js"; +import { roundToPrecision, splitValue } from "./util.js"; +import { resolveDimension, serializeCalc } from "./css-calc.js"; +import { TokenType, tokenize } from "@csstools/css-tokenizer"; +import { SyntaxFlag, color } from "@csstools/css-color-parser"; +import { parseComponentValue } from "@csstools/css-parser-algorithms"; +//#region src/js/relative-color.ts +/** +* relative-color +*/ +var { CloseParen: PAREN_CLOSE, Comment: COMMENT, Delim: DELIM, Dimension: DIM, EOF, Function: FUNC, Ident: IDENT, Number: NUM, OpenParen: PAREN_OPEN, Percentage: PCT, Whitespace: W_SPACE } = TokenType; +var { HasNoneKeywords: KEY_NONE } = SyntaxFlag; +var NAMESPACE = "relative-color"; +var OCT = 8; +var DEC = 10; +var HEX = 16; +var MAX_PCT = 100; +var MAX_RGB = 255; +var COLOR_CHANNELS = new Map([ + ["color", [ + "r", + "g", + "b", + "alpha" + ]], + ["hsl", [ + "h", + "s", + "l", + "alpha" + ]], + ["hsla", [ + "h", + "s", + "l", + "alpha" + ]], + ["hwb", [ + "h", + "w", + "b", + "alpha" + ]], + ["lab", [ + "l", + "a", + "b", + "alpha" + ]], + ["lch", [ + "l", + "c", + "h", + "alpha" + ]], + ["oklab", [ + "l", + "a", + "b", + "alpha" + ]], + ["oklch", [ + "l", + "c", + "h", + "alpha" + ]], + ["rgb", [ + "r", + "g", + "b", + "alpha" + ]], + ["rgba", [ + "r", + "g", + "b", + "alpha" + ]] +]); +var REG_COLOR_CAPT = new RegExp(`^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\s+`); +var REG_CS_HSL = /(?:hsla?|hwb)$/; +var REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`); +var REG_FN_CALC_SUM = /^(?:abs|sig?n|cos|tan)\(/; +var REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START); +var REG_FN_REL = new RegExp(FN_REL); +var REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`); +var REG_FN_REL_START = new RegExp(`^${FN_REL}`); +var REG_FN_VAR = new RegExp(SYN_FN_VAR); +/** +* resolve relative color channels +* @param value +* - CSS color value +* - system colors are not supported +* @param [opt] - options +* @param [opt.currentColor] +* - color to use for `currentcolor` keyword +* - if omitted, it will be treated as a missing color +* i.e. `rgb(none none none / none)` +* @param [opt.customProperty] +* - custom properties +* - pair of `--` prefixed property name and value, +* e.g. `customProperty: { '--some-color': '#0000ff' }` +* - and/or `callback` function to get the value of the custom property, +* e.g. `customProperty: { callback: someDeclaration.getPropertyValue }` +* @param [opt.dimension] +* - dimension, convert relative length to pixels +* - pair of unit and it's value as a number in pixels, +* e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }` +* - and/or `callback` function to get the value as a number in pixels, +* e.g. `dimension: { callback: convertUnitToPixel }` +* @param [opt.format] +* - output format, one of below +* - `computedValue` (default), [computed value][139] of the color +* - `specifiedValue`, [specified value][140] of the color +* - `hex`, hex color notation, i.e. `rrggbb` +* - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa` +* @returns +* - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)', +* color(color-space r g b / alpha), color(color-space x y z / alpha), +* lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha), +* oklch(l c h / alpha), null +* - in `computedValue`, values are numbers, however `rgb()` values are +* integers +* - in `specifiedValue`, returns `empty string` for unknown and/or invalid +* color +* - in `hex`, returns `null` for `transparent`, and also returns `null` if +* any of `r`, `g`, `b`, `alpha` is not a number +* - in `hexAlpha`, returns `#00000000` for `transparent`, +* however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number +*/ +function resolveColorChannels(tokens, opt = {}) { + if (!Array.isArray(tokens)) throw new TypeError(`${tokens} is not an array.`); + const { colorSpace = "", format = "" } = opt; + const colorChannel = COLOR_CHANNELS.get(colorSpace); + if (!colorChannel) return new NullObject(); + const mathFunc = /* @__PURE__ */ new Set(); + const channels = [ + [], + [], + [], + [] + ]; + let i = 0; + let nest = 0; + let func = ""; + let precededPct = false; + for (const token of tokens) { + if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`); + const [type, value, , , detail] = token; + const channel = channels[i]; + if (Array.isArray(channel)) switch (type) { + case DELIM: + if (func) { + if ((value === "+" || value === "-") && precededPct && !REG_FN_CALC_SUM.test(func)) return new NullObject(); + precededPct = false; + channel.push(value); + } + break; + case DIM: { + if (!func || !REG_FN_CALC_SUM.test(func)) return new NullObject(); + const resolvedValue = resolveDimension(token, opt); + if (isString(resolvedValue)) channel.push(resolvedValue); + else channel.push(value); + break; + } + case FUNC: + channel.push(value); + func = value; + nest++; + if (REG_FN_MATH_START.test(value)) mathFunc.add(nest); + break; + case IDENT: + if (!colorChannel.includes(value)) return new NullObject(); + channel.push(value); + if (!func) i++; + break; + case NUM: + channel.push(Number(detail?.value)); + if (!func) i++; + break; + case PAREN_OPEN: + channel.push(value); + nest++; + break; + case PAREN_CLOSE: + if (func) { + if (channel[channel.length - 1] === " ") channel[channel.length - 1] = value; + else channel.push(value); + if (mathFunc.has(nest)) mathFunc.delete(nest); + nest--; + if (nest === 0) { + func = ""; + i++; + } + } + break; + case PCT: + if (!func) return new NullObject(); + else if (!REG_FN_CALC_SUM.test(func)) { + let lastValue; + for (let j = channel.length - 1; j >= 0; j--) if (channel[j] !== " ") { + lastValue = channel[j]; + break; + } + if (lastValue === "+" || lastValue === "-") return new NullObject(); + else if (lastValue === "*" || lastValue === "/") precededPct = false; + else precededPct = true; + } + channel.push(Number(detail?.value) / MAX_PCT); + break; + case W_SPACE: + if (channel.length && func) { + const lastValue = channel[channel.length - 1]; + if (typeof lastValue === "number") channel.push(value); + else if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") channel.push(value); + } + break; + default: if (type !== COMMENT && type !== EOF && func) channel.push(value); + } + } + const channelValues = []; + for (const channel of channels) if (channel.length === 1) { + const [resolvedValue] = channel; + if (isStringOrNumber(resolvedValue)) channelValues.push(resolvedValue); + } else if (channel.length) { + const resolvedValue = serializeCalc(channel.join(""), { format }); + channelValues.push(resolvedValue); + } + return channelValues; +} +/** +* extract origin color +* @param value - CSS color value +* @param [opt] - options +* @returns origin color value +*/ +function extractOriginColor(value, opt = {}) { + const { colorScheme = "normal", currentColor = "", format = "" } = opt; + if (isString(value)) { + value = value.toLowerCase().trim(); + if (!value) return new NullObject(); + if (!REG_FN_REL_START.test(value)) return value; + } else return new NullObject(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "extractOriginColor", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + return cachedResult.item; + } + if (/currentcolor/.test(value)) if (currentColor) value = value.replace(/currentcolor/g, currentColor); + else { + setCache(cacheKey, null); + return new NullObject(); + } + let colorSpace = ""; + if (REG_FN_REL_CAPT.test(value)) [, colorSpace] = value.match(REG_FN_REL_CAPT); + opt.colorSpace = colorSpace; + if (value.includes("light-dark(")) { + const [, originColor = ""] = splitValue(value.replace(new RegExp(`^${colorSpace}\\(`), "").replace(/\)$/, "")); + const specifiedOriginColor = resolveColor(originColor, { + colorScheme, + format: VAL_SPEC + }); + if (specifiedOriginColor === "") { + setCache(cacheKey, null); + return new NullObject(); + } + if (format === "specifiedValue") value = value.replace(originColor, specifiedOriginColor); + else { + const resolvedOriginColor = resolveColor(specifiedOriginColor, opt); + if (isString(resolvedOriginColor)) value = value.replace(originColor, resolvedOriginColor); + } + } + if (REG_COLOR_CAPT.test(value)) { + const [, originColor] = value.match(REG_COLOR_CAPT); + const [, restValue] = value.split(originColor); + if (/^[a-z]+$/.test(originColor)) { + if (!/^transparent$/.test(originColor) && !Object.hasOwn(NAMED_COLORS, originColor)) { + setCache(cacheKey, null); + return new NullObject(); + } + } else if (format === "specifiedValue") { + const resolvedOriginColor = resolveColor(originColor, opt); + if (isString(resolvedOriginColor)) value = value.replace(originColor, resolvedOriginColor); + } + if (format === "specifiedValue") { + const channelValues = resolveColorChannels(tokenize({ css: restValue }), opt); + if (channelValues instanceof NullObject) { + setCache(cacheKey, null); + return channelValues; + } + const [v1, v2, v3, v4] = channelValues; + let channelValue = ""; + if (isStringOrNumber(v4)) channelValue = ` ${v1} ${v2} ${v3} / ${v4})`; + else channelValue = ` ${channelValues.join(" ")})`; + if (restValue !== channelValue) value = value.replace(restValue, channelValue); + } + } else { + const [, restValue] = value.split(REG_FN_REL_START); + const tokens = tokenize({ css: restValue }); + const originColor = []; + let nest = 0; + let tokenIndex = 0; + for (const [type, tokenValue] of tokens) { + tokenIndex++; + switch (type) { + case FUNC: + case PAREN_OPEN: + originColor.push(tokenValue); + nest++; + break; + case PAREN_CLOSE: { + const lastValue = originColor[originColor.length - 1]; + if (lastValue === " ") originColor[originColor.length - 1] = tokenValue; + else if (isString(lastValue)) originColor.push(tokenValue); + nest--; + break; + } + case W_SPACE: { + const lastValue = originColor[originColor.length - 1]; + if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") originColor.push(tokenValue); + break; + } + default: if (type !== COMMENT && type !== EOF) originColor.push(tokenValue); + } + if (nest === 0) break; + } + const resolvedOriginColor = resolveRelativeColor(originColor.join("").trim(), opt); + if (resolvedOriginColor instanceof NullObject) { + setCache(cacheKey, null); + return resolvedOriginColor; + } + const channelValues = resolveColorChannels(tokens.slice(tokenIndex), opt); + if (channelValues instanceof NullObject) { + setCache(cacheKey, null); + return channelValues; + } + const [v1, v2, v3, v4] = channelValues; + let channelValue = ""; + if (isStringOrNumber(v4)) channelValue = ` ${v1} ${v2} ${v3} / ${v4})`; + else channelValue = ` ${channelValues.join(" ")})`; + value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`); + } + setCache(cacheKey, value); + return value; +} +/** +* resolve relative color +* @param value - CSS relative color value +* @param [opt] - options +* @returns resolved value +*/ +function resolveRelativeColor(value, opt = {}) { + const { format = "" } = opt; + if (isString(value)) { + if (REG_FN_VAR.test(value)) { + if (format !== "specifiedValue") throw new SyntaxError(`Unexpected token ${FN_VAR} found.`); + return value; + } else if (!REG_FN_REL.test(value)) return value; + value = value.toLowerCase().trim(); + } else throw new TypeError(`${value} is not a string.`); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "resolveRelativeColor", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + return cachedResult.item; + } + const originColor = extractOriginColor(value, opt); + if (originColor instanceof NullObject) { + setCache(cacheKey, null); + return originColor; + } + value = originColor; + if (format === "specifiedValue") { + if (value.startsWith("rgba(")) value = value.replace("rgba(", "rgb("); + else if (value.startsWith("hsla(")) value = value.replace("hsla(", "hsl("); + return value; + } + const parsedComponents = color(parseComponentValue(tokenize({ css: value }))); + if (!parsedComponents) { + setCache(cacheKey, null); + return new NullObject(); + } + const { alpha: alphaComponent, channels: channelsComponent, colorNotation, syntaxFlags } = parsedComponents; + let alpha; + if (Number.isNaN(Number(alphaComponent))) if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) alpha = NONE; + else alpha = 0; + else alpha = roundToPrecision(Number(alphaComponent), OCT); + let v1; + let v2; + let v3; + [v1, v2, v3] = channelsComponent; + let resolvedValue; + if (REG_CS_CIE.test(colorNotation)) { + const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE); + if (Number.isNaN(v1)) if (hasNone) v1 = NONE; + else v1 = 0; + else v1 = roundToPrecision(v1, HEX); + if (Number.isNaN(v2)) if (hasNone) v2 = NONE; + else v2 = 0; + else v2 = roundToPrecision(v2, HEX); + if (Number.isNaN(v3)) if (hasNone) v3 = NONE; + else v3 = 0; + else v3 = roundToPrecision(v3, HEX); + if (alpha === 1) resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`; + else resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`; + } else if (REG_CS_HSL.test(colorNotation)) { + if (Number.isNaN(v1)) v1 = 0; + if (Number.isNaN(v2)) v2 = 0; + if (Number.isNaN(v3)) v3 = 0; + let [r, g, b] = convertColorToRgb(`${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`); + r = roundToPrecision(r / MAX_RGB, DEC); + g = roundToPrecision(g / MAX_RGB, DEC); + b = roundToPrecision(b / MAX_RGB, DEC); + if (alpha === 1) resolvedValue = `color(srgb ${r} ${g} ${b})`; + else resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`; + } else { + const cs = colorNotation === "rgb" ? "srgb" : colorNotation; + const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE); + if (Number.isNaN(v1)) if (hasNone) v1 = NONE; + else v1 = 0; + else v1 = roundToPrecision(v1, DEC); + if (Number.isNaN(v2)) if (hasNone) v2 = NONE; + else v2 = 0; + else v2 = roundToPrecision(v2, DEC); + if (Number.isNaN(v3)) if (hasNone) v3 = NONE; + else v3 = 0; + else v3 = roundToPrecision(v3, DEC); + if (alpha === 1) resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`; + else resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`; + } + setCache(cacheKey, resolvedValue); + return resolvedValue; +} +//#endregion +export { resolveRelativeColor }; + +//# sourceMappingURL=relative-color.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.js.map new file mode 100644 index 0000000..e838fdf --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/relative-color.js.map @@ -0,0 +1 @@ +{"version":3,"file":"relative-color.js","names":[],"sources":["../../../src/js/relative-color.ts"],"sourcesContent":["/**\n * relative-color\n */\n\nimport { SyntaxFlag, color as colorParser } from '@csstools/css-color-parser';\nimport {\n ComponentValue,\n parseComponentValue\n} from '@csstools/css-parser-algorithms';\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport {\n CacheItem,\n NullObject,\n createCacheKey,\n getCache,\n setCache\n} from './cache';\nimport { NAMED_COLORS, convertColorToRgb } from './color';\nimport { isString, isStringOrNumber } from './common';\nimport { resolveDimension, serializeCalc } from './css-calc';\nimport { resolveColor } from './resolve';\nimport { roundToPrecision, splitValue } from './util';\nimport {\n ColorChannels,\n MatchedRegExp,\n Options,\n StringColorChannels\n} from './typedef';\n\n/* constants */\nimport {\n CS_LAB,\n CS_LCH,\n FN_LIGHT_DARK,\n FN_REL,\n FN_REL_CAPT,\n FN_VAR,\n NONE,\n SYN_COLOR_TYPE,\n SYN_FN_MATH_START,\n SYN_FN_VAR,\n SYN_MIX,\n VAL_SPEC\n} from './constant';\nconst {\n CloseParen: PAREN_CLOSE,\n Comment: COMMENT,\n Delim: DELIM,\n Dimension: DIM,\n EOF,\n Function: FUNC,\n Ident: IDENT,\n Number: NUM,\n OpenParen: PAREN_OPEN,\n Percentage: PCT,\n Whitespace: W_SPACE\n} = TokenType;\nconst { HasNoneKeywords: KEY_NONE } = SyntaxFlag;\nconst NAMESPACE = 'relative-color';\n\n/* constants */\nconst OCT = 8;\nconst DEC = 10;\nconst HEX = 16;\nconst MAX_PCT = 100;\nconst MAX_RGB = 255;\nconst COLOR_CHANNELS = new Map([\n ['color', ['r', 'g', 'b', 'alpha']],\n ['hsl', ['h', 's', 'l', 'alpha']],\n ['hsla', ['h', 's', 'l', 'alpha']],\n ['hwb', ['h', 'w', 'b', 'alpha']],\n ['lab', ['l', 'a', 'b', 'alpha']],\n ['lch', ['l', 'c', 'h', 'alpha']],\n ['oklab', ['l', 'a', 'b', 'alpha']],\n ['oklch', ['l', 'c', 'h', 'alpha']],\n ['rgb', ['r', 'g', 'b', 'alpha']],\n ['rgba', ['r', 'g', 'b', 'alpha']]\n]);\n\n/* type definitions */\n/**\n * @type NumberOrStringColorChannels - color channel\n */\ntype NumberOrStringColorChannels = ColorChannels & StringColorChannels;\n\n/* regexp */\nconst REG_COLOR_CAPT = new RegExp(\n `^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\\\s+`\n);\nconst REG_CS_HSL = /(?:hsla?|hwb)$/;\nconst REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`);\nconst REG_FN_CALC_SUM = /^(?:abs|sig?n|cos|tan)\\(/;\nconst REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);\nconst REG_FN_REL = new RegExp(FN_REL);\nconst REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`);\nconst REG_FN_REL_START = new RegExp(`^${FN_REL}`);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * resolve relative color channels\n * @param value\n * - CSS color value\n * - system colors are not supported\n * @param [opt] - options\n * @param [opt.currentColor]\n * - color to use for `currentcolor` keyword\n * - if omitted, it will be treated as a missing color\n * i.e. `rgb(none none none / none)`\n * @param [opt.customProperty]\n * - custom properties\n * - pair of `--` prefixed property name and value,\n * e.g. `customProperty: { '--some-color': '#0000ff' }`\n * - and/or `callback` function to get the value of the custom property,\n * e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`\n * @param [opt.dimension]\n * - dimension, convert relative length to pixels\n * - pair of unit and it's value as a number in pixels,\n * e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`\n * - and/or `callback` function to get the value as a number in pixels,\n * e.g. `dimension: { callback: convertUnitToPixel }`\n * @param [opt.format]\n * - output format, one of below\n * - `computedValue` (default), [computed value][139] of the color\n * - `specifiedValue`, [specified value][140] of the color\n * - `hex`, hex color notation, i.e. `rrggbb`\n * - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`\n * @returns\n * - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',\n * color(color-space r g b / alpha), color(color-space x y z / alpha),\n * lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),\n * oklch(l c h / alpha), null\n * - in `computedValue`, values are numbers, however `rgb()` values are\n * integers\n * - in `specifiedValue`, returns `empty string` for unknown and/or invalid\n * color\n * - in `hex`, returns `null` for `transparent`, and also returns `null` if\n * any of `r`, `g`, `b`, `alpha` is not a number\n * - in `hexAlpha`, returns `#00000000` for `transparent`,\n * however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number\n */\nexport function resolveColorChannels(\n tokens: CSSToken[],\n opt: Options = {}\n): NumberOrStringColorChannels | NullObject {\n if (!Array.isArray(tokens)) {\n throw new TypeError(`${tokens} is not an array.`);\n }\n const { colorSpace = '', format = '' } = opt;\n const colorChannel = COLOR_CHANNELS.get(colorSpace);\n // invalid color channel\n if (!colorChannel) {\n return new NullObject();\n }\n const mathFunc = new Set();\n const channels: [\n (number | string)[],\n (number | string)[],\n (number | string)[],\n (number | string)[]\n ] = [[], [], [], []];\n let i = 0;\n let nest = 0;\n let func = '';\n let precededPct = false;\n for (const token of tokens) {\n if (!Array.isArray(token)) {\n throw new TypeError(`${token} is not an array.`);\n }\n const [type, value, , , detail] = token as [\n TokenType,\n string,\n number,\n number,\n { value: string | number } | undefined\n ];\n const channel = channels[i];\n if (Array.isArray(channel)) {\n switch (type) {\n case DELIM: {\n if (func) {\n if (\n (value === '+' || value === '-') &&\n precededPct &&\n !REG_FN_CALC_SUM.test(func)\n ) {\n return new NullObject();\n }\n precededPct = false;\n channel.push(value);\n }\n break;\n }\n case DIM: {\n if (!func || !REG_FN_CALC_SUM.test(func)) {\n return new NullObject();\n }\n const resolvedValue = resolveDimension(token, opt);\n if (isString(resolvedValue)) {\n channel.push(resolvedValue);\n } else {\n channel.push(value);\n }\n break;\n }\n case FUNC: {\n channel.push(value);\n func = value;\n nest++;\n if (REG_FN_MATH_START.test(value)) {\n mathFunc.add(nest);\n }\n break;\n }\n case IDENT: {\n // invalid channel key\n if (!colorChannel.includes(value)) {\n return new NullObject();\n }\n channel.push(value);\n if (!func) {\n i++;\n }\n break;\n }\n case NUM: {\n channel.push(Number(detail?.value));\n if (!func) {\n i++;\n }\n break;\n }\n case PAREN_OPEN: {\n channel.push(value);\n nest++;\n break;\n }\n case PAREN_CLOSE: {\n if (func) {\n const lastValue = channel[channel.length - 1];\n if (lastValue === ' ') {\n channel[channel.length - 1] = value;\n } else {\n channel.push(value);\n }\n if (mathFunc.has(nest)) {\n mathFunc.delete(nest);\n }\n nest--;\n if (nest === 0) {\n func = '';\n i++;\n }\n }\n break;\n }\n case PCT: {\n if (!func) {\n return new NullObject();\n } else if (!REG_FN_CALC_SUM.test(func)) {\n let lastValue: string | number | undefined;\n for (let j = channel.length - 1; j >= 0; j--) {\n if (channel[j] !== ' ') {\n lastValue = channel[j];\n break;\n }\n }\n if (lastValue === '+' || lastValue === '-') {\n return new NullObject();\n } else if (lastValue === '*' || lastValue === '/') {\n precededPct = false;\n } else {\n precededPct = true;\n }\n }\n channel.push(Number(detail?.value) / MAX_PCT);\n break;\n }\n case W_SPACE: {\n if (channel.length && func) {\n const lastValue = channel[channel.length - 1];\n if (typeof lastValue === 'number') {\n channel.push(value);\n } else if (\n isString(lastValue) &&\n !lastValue.endsWith('(') &&\n lastValue !== ' '\n ) {\n channel.push(value);\n }\n }\n break;\n }\n default: {\n if (type !== COMMENT && type !== EOF && func) {\n channel.push(value);\n }\n }\n }\n }\n }\n const channelValues = [];\n for (const channel of channels) {\n if (channel.length === 1) {\n const [resolvedValue] = channel;\n if (isStringOrNumber(resolvedValue)) {\n channelValues.push(resolvedValue);\n }\n } else if (channel.length) {\n const resolvedValue = serializeCalc(channel.join(''), {\n format\n });\n channelValues.push(resolvedValue);\n }\n }\n return channelValues as NumberOrStringColorChannels;\n}\n\n/**\n * extract origin color\n * @param value - CSS color value\n * @param [opt] - options\n * @returns origin color value\n */\nexport function extractOriginColor(\n value: string,\n opt: Options = {}\n): string | NullObject {\n const { colorScheme = 'normal', currentColor = '', format = '' } = opt;\n if (isString(value)) {\n value = value.toLowerCase().trim();\n if (!value) {\n return new NullObject();\n }\n if (!REG_FN_REL_START.test(value)) {\n return value;\n }\n } else {\n return new NullObject();\n }\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'extractOriginColor',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n return cachedResult.item as string;\n }\n if (/currentcolor/.test(value)) {\n if (currentColor) {\n value = value.replace(/currentcolor/g, currentColor);\n } else {\n setCache(cacheKey, null);\n return new NullObject();\n }\n }\n let colorSpace = '';\n if (REG_FN_REL_CAPT.test(value)) {\n [, colorSpace] = value.match(REG_FN_REL_CAPT) as MatchedRegExp;\n }\n opt.colorSpace = colorSpace;\n if (value.includes(FN_LIGHT_DARK)) {\n const colorParts = value\n .replace(new RegExp(`^${colorSpace}\\\\(`), '')\n .replace(/\\)$/, '');\n const [, originColor = ''] = splitValue(colorParts);\n const specifiedOriginColor = resolveColor(originColor, {\n colorScheme,\n format: VAL_SPEC\n }) as string;\n if (specifiedOriginColor === '') {\n setCache(cacheKey, null);\n return new NullObject();\n }\n if (format === VAL_SPEC) {\n value = value.replace(originColor, specifiedOriginColor);\n } else {\n const resolvedOriginColor = resolveColor(specifiedOriginColor, opt);\n if (isString(resolvedOriginColor)) {\n value = value.replace(originColor, resolvedOriginColor);\n }\n }\n }\n if (REG_COLOR_CAPT.test(value)) {\n const [, originColor] = value.match(REG_COLOR_CAPT) as MatchedRegExp;\n const [, restValue] = value.split(originColor) as MatchedRegExp;\n if (/^[a-z]+$/.test(originColor)) {\n if (\n !/^transparent$/.test(originColor) &&\n !Object.hasOwn(NAMED_COLORS, originColor)\n ) {\n setCache(cacheKey, null);\n return new NullObject();\n }\n } else if (format === VAL_SPEC) {\n const resolvedOriginColor = resolveColor(originColor, opt);\n if (isString(resolvedOriginColor)) {\n value = value.replace(originColor, resolvedOriginColor);\n }\n }\n if (format === VAL_SPEC) {\n const tokens = tokenize({ css: restValue });\n const channelValues = resolveColorChannels(tokens, opt);\n if (channelValues instanceof NullObject) {\n setCache(cacheKey, null);\n return channelValues;\n }\n const [v1, v2, v3, v4] = channelValues;\n let channelValue = '';\n if (isStringOrNumber(v4)) {\n channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;\n } else {\n channelValue = ` ${channelValues.join(' ')})`;\n }\n if (restValue !== channelValue) {\n value = value.replace(restValue, channelValue);\n }\n }\n } else {\n // nested relative color\n const [, restValue] = value.split(REG_FN_REL_START) as MatchedRegExp;\n const tokens = tokenize({ css: restValue });\n const originColor: string[] = [];\n let nest = 0;\n let tokenIndex = 0;\n for (const [type, tokenValue] of tokens) {\n tokenIndex++;\n switch (type) {\n case FUNC:\n case PAREN_OPEN: {\n originColor.push(tokenValue);\n nest++;\n break;\n }\n case PAREN_CLOSE: {\n const lastValue = originColor[originColor.length - 1];\n if (lastValue === ' ') {\n originColor[originColor.length - 1] = tokenValue;\n } else if (isString(lastValue)) {\n originColor.push(tokenValue);\n }\n nest--;\n break;\n }\n case W_SPACE: {\n const lastValue = originColor[originColor.length - 1];\n if (\n isString(lastValue) &&\n !lastValue.endsWith('(') &&\n lastValue !== ' '\n ) {\n originColor.push(tokenValue);\n }\n break;\n }\n default: {\n if (type !== COMMENT && type !== EOF) {\n originColor.push(tokenValue);\n }\n }\n }\n if (nest === 0) {\n break;\n }\n }\n const resolvedOriginColor = resolveRelativeColor(\n originColor.join('').trim(),\n opt\n );\n if (resolvedOriginColor instanceof NullObject) {\n setCache(cacheKey, null);\n return resolvedOriginColor;\n }\n const channelValues = resolveColorChannels(tokens.slice(tokenIndex), opt);\n if (channelValues instanceof NullObject) {\n setCache(cacheKey, null);\n return channelValues;\n }\n const [v1, v2, v3, v4] = channelValues;\n let channelValue = '';\n if (isStringOrNumber(v4)) {\n channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;\n } else {\n channelValue = ` ${channelValues.join(' ')})`;\n }\n value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`);\n }\n setCache(cacheKey, value);\n return value;\n}\n\n/**\n * resolve relative color\n * @param value - CSS relative color value\n * @param [opt] - options\n * @returns resolved value\n */\nexport function resolveRelativeColor(\n value: string,\n opt: Options = {}\n): string | NullObject {\n const { format = '' } = opt;\n if (isString(value)) {\n if (REG_FN_VAR.test(value)) {\n // var() must be resolved before resolveRelativeColor()\n if (format !== VAL_SPEC) {\n throw new SyntaxError(`Unexpected token ${FN_VAR} found.`);\n }\n return value;\n } else if (!REG_FN_REL.test(value)) {\n return value;\n }\n value = value.toLowerCase().trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'resolveRelativeColor',\n value\n },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n return cachedResult.item as string;\n }\n const originColor = extractOriginColor(value, opt);\n if (originColor instanceof NullObject) {\n setCache(cacheKey, null);\n return originColor;\n }\n value = originColor;\n if (format === VAL_SPEC) {\n if (value.startsWith('rgba(')) {\n value = value.replace('rgba(', 'rgb(');\n } else if (value.startsWith('hsla(')) {\n value = value.replace('hsla(', 'hsl(');\n }\n return value;\n }\n const tokens = tokenize({ css: value });\n const components = parseComponentValue(tokens) as ComponentValue;\n const parsedComponents = colorParser(components);\n if (!parsedComponents) {\n setCache(cacheKey, null);\n return new NullObject();\n }\n const {\n alpha: alphaComponent,\n channels: channelsComponent,\n colorNotation,\n syntaxFlags\n } = parsedComponents;\n let alpha: number | string;\n if (Number.isNaN(Number(alphaComponent))) {\n if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) {\n alpha = NONE;\n } else {\n alpha = 0;\n }\n } else {\n alpha = roundToPrecision(Number(alphaComponent), OCT);\n }\n let v1: number | string;\n let v2: number | string;\n let v3: number | string;\n [v1, v2, v3] = channelsComponent;\n let resolvedValue;\n if (REG_CS_CIE.test(colorNotation)) {\n const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);\n if (Number.isNaN(v1)) {\n if (hasNone) {\n v1 = NONE;\n } else {\n v1 = 0;\n }\n } else {\n v1 = roundToPrecision(v1, HEX);\n }\n if (Number.isNaN(v2)) {\n if (hasNone) {\n v2 = NONE;\n } else {\n v2 = 0;\n }\n } else {\n v2 = roundToPrecision(v2, HEX);\n }\n if (Number.isNaN(v3)) {\n if (hasNone) {\n v3 = NONE;\n } else {\n v3 = 0;\n }\n } else {\n v3 = roundToPrecision(v3, HEX);\n }\n if (alpha === 1) {\n resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`;\n } else {\n resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`;\n }\n } else if (REG_CS_HSL.test(colorNotation)) {\n if (Number.isNaN(v1)) {\n v1 = 0;\n }\n if (Number.isNaN(v2)) {\n v2 = 0;\n }\n if (Number.isNaN(v3)) {\n v3 = 0;\n }\n let [r, g, b] = convertColorToRgb(\n `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`\n ) as ColorChannels;\n r = roundToPrecision(r / MAX_RGB, DEC);\n g = roundToPrecision(g / MAX_RGB, DEC);\n b = roundToPrecision(b / MAX_RGB, DEC);\n if (alpha === 1) {\n resolvedValue = `color(srgb ${r} ${g} ${b})`;\n } else {\n resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`;\n }\n } else {\n const cs = colorNotation === 'rgb' ? 'srgb' : colorNotation;\n const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);\n if (Number.isNaN(v1)) {\n if (hasNone) {\n v1 = NONE;\n } else {\n v1 = 0;\n }\n } else {\n v1 = roundToPrecision(v1, DEC);\n }\n if (Number.isNaN(v2)) {\n if (hasNone) {\n v2 = NONE;\n } else {\n v2 = 0;\n }\n } else {\n v2 = roundToPrecision(v2, DEC);\n }\n if (Number.isNaN(v3)) {\n if (hasNone) {\n v3 = NONE;\n } else {\n v3 = 0;\n }\n } else {\n v3 = roundToPrecision(v3, DEC);\n }\n if (alpha === 1) {\n resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`;\n } else {\n resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`;\n }\n }\n setCache(cacheKey, resolvedValue);\n return resolvedValue;\n}\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.d.ts new file mode 100644 index 0000000..429627d --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.d.ts @@ -0,0 +1,15 @@ +import { NullObject } from './cache.js'; +import { Options } from './typedef.js'; +/** + * resolve color + * @param value - CSS color value + * @param [opt] - options + * @returns resolved color + */ +export declare const resolveColor: (value: string, opt?: Options) => string | NullObject; +/** + * resolve CSS color + * @param value - CSS color value. system colors are not supported + * @param [opt] - options + */ +export declare const resolve: (value: string, opt?: Options) => string | null; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.js new file mode 100644 index 0000000..f28636a --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.js @@ -0,0 +1,210 @@ +import { CacheItem, NullObject, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString } from "./common.js"; +import { SYN_FN_CALC, SYN_FN_LIGHT_DARK, SYN_FN_REL, SYN_FN_VAR, VAL_COMP, VAL_SPEC } from "./constant.js"; +import { convertRgbToHex, resolveColorFunc, resolveColorMix, resolveColorValue } from "./color.js"; +import { resolveRelativeColor } from "./relative-color.js"; +import { splitValue } from "./util.js"; +import { resolveVar } from "./css-var.js"; +import { cssCalc } from "./css-calc.js"; +//#region src/js/resolve.ts +/** +* resolve +*/ +var NAMESPACE = "resolve"; +var RGB_TRANSPARENT = "rgba(0, 0, 0, 0)"; +var REG_FN_CALC = new RegExp(SYN_FN_CALC); +var REG_FN_LIGHT_DARK = new RegExp(SYN_FN_LIGHT_DARK); +var REG_FN_REL = new RegExp(SYN_FN_REL); +var REG_FN_VAR = new RegExp(SYN_FN_VAR); +/** +* resolve color +* @param value - CSS color value +* @param [opt] - options +* @returns resolved color +*/ +var resolveColor = (value, opt = {}) => { + if (!isString(value)) throw new TypeError(`${value} is not a string.`); + value = value.trim(); + const { colorScheme = "normal", currentColor = "", format = VAL_COMP, nullable = false } = opt; + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "resolve", + value + }, opt); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) return cachedResult; + return cachedResult.item; + } + if (REG_FN_VAR.test(value)) { + if (format === "specifiedValue") { + setCache(cacheKey, value); + return value; + } + const resolvedVar = resolveVar(value, opt); + if (resolvedVar instanceof NullObject) { + const res = format === "hex" || format === "hexAlpha" || nullable ? resolvedVar : RGB_TRANSPARENT; + setCache(cacheKey, res); + return res; + } + value = resolvedVar; + } + if (opt.format !== format) opt.format = format; + value = value.toLowerCase(); + if (REG_FN_LIGHT_DARK.test(value) && value.endsWith(")")) { + const [light = "", dark = ""] = splitValue(value.replace(REG_FN_LIGHT_DARK, "").replace(/\)$/, ""), { delimiter: "," }); + if (light && dark) { + if (format === "specifiedValue") { + const lightColor = resolveColor(light, opt); + const darkColor = resolveColor(dark, opt); + const res = lightColor && darkColor ? `light-dark(${lightColor}, ${darkColor})` : ""; + setCache(cacheKey, res); + return res; + } + const resolved = resolveColor(colorScheme === "dark" ? dark : light, opt); + const res = resolved instanceof NullObject && !nullable ? RGB_TRANSPARENT : resolved; + setCache(cacheKey, res); + return res; + } + const invalidRes = format === "specifiedValue" ? "" : format === "hex" || format === "hexAlpha" ? new NullObject() : RGB_TRANSPARENT; + setCache(cacheKey, invalidRes); + return invalidRes; + } + if (REG_FN_REL.test(value)) { + const resolvedRel = resolveRelativeColor(value, opt); + if (format === "computedValue") { + const res = resolvedRel instanceof NullObject && !nullable ? RGB_TRANSPARENT : resolvedRel; + setCache(cacheKey, res); + return res; + } + if (format === "specifiedValue") { + const res = resolvedRel instanceof NullObject ? "" : resolvedRel; + setCache(cacheKey, res); + return res; + } + value = resolvedRel instanceof NullObject ? "" : resolvedRel; + } + if (REG_FN_CALC.test(value)) value = cssCalc(value, opt); + let cs = ""; + let r = NaN; + let g = NaN; + let b = NaN; + let alpha = NaN; + if (value === "transparent") { + let res; + switch (format) { + case VAL_SPEC: + res = value; + break; + case "hex": + res = new NullObject(); + break; + case "hexAlpha": + res = "#00000000"; + break; + default: res = RGB_TRANSPARENT; + } + setCache(cacheKey, res); + return res; + } + if (value === "currentcolor") { + if (format === "specifiedValue") { + setCache(cacheKey, value); + return value; + } + if (currentColor) { + let resolvedCurrent; + if (currentColor.startsWith("color-mix(")) resolvedCurrent = resolveColorMix(currentColor, opt); + else if (currentColor.startsWith("color(")) resolvedCurrent = resolveColorFunc(currentColor, opt); + else resolvedCurrent = resolveColorValue(currentColor, opt); + if (resolvedCurrent instanceof NullObject) { + setCache(cacheKey, resolvedCurrent); + return resolvedCurrent; + } + [cs, r, g, b, alpha] = resolvedCurrent; + } else { + const res = format === "computedValue" ? RGB_TRANSPARENT : value; + if (format === "computedValue") { + setCache(cacheKey, res); + return res; + } + } + } else if (format === "specifiedValue") { + let res = ""; + if (value.startsWith("color-mix(")) res = resolveColorMix(value, opt); + else if (value.startsWith("color(")) { + const [scs, rr, gg, bb, aa] = resolveColorFunc(value, opt); + res = aa === 1 ? `color(${scs} ${rr} ${gg} ${bb})` : `color(${scs} ${rr} ${gg} ${bb} / ${aa})`; + } else { + const rgb = resolveColorValue(value, opt); + if (isString(rgb)) res = rgb; + else { + const [scs, rr, gg, bb, aa] = rgb; + if (scs === "rgb") res = aa === 1 ? `${scs}(${rr}, ${gg}, ${bb})` : `${scs}a(${rr}, ${gg}, ${bb}, ${aa})`; + else res = aa === 1 ? `${scs}(${rr} ${gg} ${bb})` : `${scs}(${rr} ${gg} ${bb} / ${aa})`; + } + } + setCache(cacheKey, res); + return res; + } else if (value.startsWith("color-mix(")) { + if (currentColor) value = value.replace(/currentcolor/g, currentColor); + value = value.replace(/transparent/g, RGB_TRANSPARENT); + const resolvedMix = resolveColorMix(value, opt); + if (resolvedMix instanceof NullObject) { + setCache(cacheKey, resolvedMix); + return resolvedMix; + } + [cs, r, g, b, alpha] = resolvedMix; + } else if (value.startsWith("color(")) { + const resolvedFunc = resolveColorFunc(value, opt); + if (resolvedFunc instanceof NullObject) { + setCache(cacheKey, resolvedFunc); + return resolvedFunc; + } + [cs, r, g, b, alpha] = resolvedFunc; + } else if (value) { + const resolvedVal = resolveColorValue(value, opt); + if (resolvedVal instanceof NullObject) { + setCache(cacheKey, resolvedVal); + return resolvedVal; + } + [cs, r, g, b, alpha] = resolvedVal; + } + let finalRes = ""; + switch (format) { + case "hex": + case "hexAlpha": + if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) || Number.isNaN(alpha) || format === "hex" && alpha === 0) finalRes = new NullObject(); + else finalRes = convertRgbToHex([ + r, + g, + b, + format === "hex" ? 1 : alpha + ]); + break; + default: if (cs === "rgb") finalRes = alpha === 1 ? `${cs}(${r}, ${g}, ${b})` : `${cs}a(${r}, ${g}, ${b}, ${alpha})`; + else if ([ + "lab", + "lch", + "oklab", + "oklch" + ].includes(cs)) finalRes = alpha === 1 ? `${cs}(${r} ${g} ${b})` : `${cs}(${r} ${g} ${b} / ${alpha})`; + else finalRes = alpha === 1 ? `color(${cs} ${r} ${g} ${b})` : `color(${cs} ${r} ${g} ${b} / ${alpha})`; + } + setCache(cacheKey, finalRes); + return finalRes; +}; +/** +* resolve CSS color +* @param value - CSS color value. system colors are not supported +* @param [opt] - options +*/ +var resolve = (value, opt = {}) => { + opt.nullable = false; + const resolvedValue = resolveColor(value, opt); + return resolvedValue instanceof NullObject ? null : resolvedValue; +}; +//#endregion +export { resolve, resolveColor }; + +//# sourceMappingURL=resolve.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.js.map new file mode 100644 index 0000000..a2cb6a7 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/resolve.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve.js","names":[],"sources":["../../../src/js/resolve.ts"],"sourcesContent":["/**\n * resolve\n */\n\nimport {\n CacheItem,\n NullObject,\n createCacheKey,\n getCache,\n setCache\n} from './cache';\nimport {\n convertRgbToHex,\n resolveColorFunc,\n resolveColorMix,\n resolveColorValue\n} from './color';\nimport { isString } from './common';\nimport { cssCalc } from './css-calc';\nimport { resolveVar } from './css-var';\nimport { resolveRelativeColor } from './relative-color';\nimport { splitValue } from './util';\nimport {\n ComputedColorChannels,\n Options,\n SpecifiedColorChannels\n} from './typedef';\n\n/* constants */\nimport {\n FN_COLOR,\n FN_MIX,\n SYN_FN_CALC,\n SYN_FN_LIGHT_DARK,\n SYN_FN_REL,\n SYN_FN_VAR,\n VAL_COMP,\n VAL_SPEC\n} from './constant';\nconst NAMESPACE = 'resolve';\nconst RGB_TRANSPARENT = 'rgba(0, 0, 0, 0)';\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_LIGHT_DARK = new RegExp(SYN_FN_LIGHT_DARK);\nconst REG_FN_REL = new RegExp(SYN_FN_REL);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * resolve color\n * @param value - CSS color value\n * @param [opt] - options\n * @returns resolved color\n */\nexport const resolveColor = (\n value: string,\n opt: Options = {}\n): string | NullObject => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n value = value.trim();\n const {\n colorScheme = 'normal',\n currentColor = '',\n format = VAL_COMP,\n nullable = false\n } = opt;\n const cacheKey: string = createCacheKey(\n { namespace: NAMESPACE, name: 'resolve', value },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n if (cachedResult.isNull) {\n return cachedResult as NullObject;\n }\n return cachedResult.item as string;\n }\n // 1. var() resolution\n if (REG_FN_VAR.test(value)) {\n if (format === VAL_SPEC) {\n setCache(cacheKey, value);\n return value;\n }\n const resolvedVar = resolveVar(value, opt);\n if (resolvedVar instanceof NullObject) {\n const res =\n format === 'hex' || format === 'hexAlpha' || nullable\n ? resolvedVar\n : RGB_TRANSPARENT;\n setCache(cacheKey, res);\n return res;\n }\n value = resolvedVar;\n }\n if (opt.format !== format) {\n opt.format = format;\n }\n value = value.toLowerCase();\n // 2. light-dark() resolution\n if (REG_FN_LIGHT_DARK.test(value) && value.endsWith(')')) {\n const colorParts = value.replace(REG_FN_LIGHT_DARK, '').replace(/\\)$/, '');\n const [light = '', dark = ''] = splitValue(colorParts, { delimiter: ',' });\n if (light && dark) {\n if (format === VAL_SPEC) {\n const lightColor = resolveColor(light, opt);\n const darkColor = resolveColor(dark, opt);\n const res =\n lightColor && darkColor\n ? `light-dark(${lightColor}, ${darkColor})`\n : '';\n setCache(cacheKey, res);\n return res;\n }\n const chosen = colorScheme === 'dark' ? dark : light;\n const resolved = resolveColor(chosen, opt);\n const res =\n resolved instanceof NullObject && !nullable\n ? RGB_TRANSPARENT\n : resolved;\n setCache(cacheKey, res);\n return res;\n }\n // fallback for invalid light-dark\n const invalidRes =\n format === VAL_SPEC\n ? ''\n : format === 'hex' || format === 'hexAlpha'\n ? new NullObject()\n : RGB_TRANSPARENT;\n setCache(cacheKey, invalidRes);\n return invalidRes;\n }\n // 3. Relative Color resolution\n if (REG_FN_REL.test(value)) {\n const resolvedRel = resolveRelativeColor(value, opt);\n if (format === VAL_COMP) {\n const res =\n resolvedRel instanceof NullObject && !nullable\n ? RGB_TRANSPARENT\n : resolvedRel;\n setCache(cacheKey, res);\n return res;\n }\n if (format === VAL_SPEC) {\n const res = resolvedRel instanceof NullObject ? '' : resolvedRel;\n setCache(cacheKey, res);\n return res;\n }\n value = resolvedRel instanceof NullObject ? '' : resolvedRel;\n }\n // 4. calc() resolution\n if (REG_FN_CALC.test(value)) {\n value = cssCalc(value, opt);\n }\n // 5. Keyword & Color-space resolution\n let cs = '';\n let r = NaN;\n let g = NaN;\n let b = NaN;\n let alpha = NaN;\n if (value === 'transparent') {\n let res: string | NullObject;\n switch (format) {\n case VAL_SPEC: {\n res = value;\n break;\n }\n case 'hex': {\n res = new NullObject();\n break;\n }\n case 'hexAlpha': {\n res = '#00000000';\n break;\n }\n default: {\n res = RGB_TRANSPARENT;\n }\n }\n setCache(cacheKey, res);\n return res;\n }\n if (value === 'currentcolor') {\n if (format === VAL_SPEC) {\n setCache(cacheKey, value);\n return value;\n }\n if (currentColor) {\n let resolvedCurrent;\n if (currentColor.startsWith(FN_MIX)) {\n resolvedCurrent = resolveColorMix(currentColor, opt);\n } else if (currentColor.startsWith(FN_COLOR)) {\n resolvedCurrent = resolveColorFunc(currentColor, opt);\n } else {\n resolvedCurrent = resolveColorValue(currentColor, opt);\n }\n if (resolvedCurrent instanceof NullObject) {\n setCache(cacheKey, resolvedCurrent);\n return resolvedCurrent;\n }\n [cs, r, g, b, alpha] = resolvedCurrent as ComputedColorChannels;\n } else {\n // value is handled below if not VAL_COMP\n const res = format === VAL_COMP ? RGB_TRANSPARENT : value;\n if (format === VAL_COMP) {\n setCache(cacheKey, res);\n return res;\n }\n }\n } else if (format === VAL_SPEC) {\n let res = '';\n if (value.startsWith(FN_MIX)) {\n res = resolveColorMix(value, opt) as string;\n } else if (value.startsWith(FN_COLOR)) {\n const [scs, rr, gg, bb, aa] = resolveColorFunc(\n value,\n opt\n ) as SpecifiedColorChannels;\n res =\n aa === 1\n ? `color(${scs} ${rr} ${gg} ${bb})`\n : `color(${scs} ${rr} ${gg} ${bb} / ${aa})`;\n } else {\n const rgb = resolveColorValue(value, opt);\n if (isString(rgb)) {\n res = rgb;\n } else {\n const [scs, rr, gg, bb, aa] = rgb as SpecifiedColorChannels;\n if (scs === 'rgb') {\n res =\n aa === 1\n ? `${scs}(${rr}, ${gg}, ${bb})`\n : `${scs}a(${rr}, ${gg}, ${bb}, ${aa})`;\n } else {\n res =\n aa === 1\n ? `${scs}(${rr} ${gg} ${bb})`\n : `${scs}(${rr} ${gg} ${bb} / ${aa})`;\n }\n }\n }\n setCache(cacheKey, res);\n return res;\n } else if (value.startsWith(FN_MIX)) {\n if (currentColor) {\n value = value.replace(/currentcolor/g, currentColor);\n }\n value = value.replace(/transparent/g, RGB_TRANSPARENT);\n const resolvedMix = resolveColorMix(value, opt);\n if (resolvedMix instanceof NullObject) {\n setCache(cacheKey, resolvedMix);\n return resolvedMix;\n }\n [cs, r, g, b, alpha] = resolvedMix as ComputedColorChannels;\n } else if (value.startsWith(FN_COLOR)) {\n const resolvedFunc = resolveColorFunc(value, opt);\n if (resolvedFunc instanceof NullObject) {\n setCache(cacheKey, resolvedFunc);\n return resolvedFunc;\n }\n [cs, r, g, b, alpha] = resolvedFunc as ComputedColorChannels;\n } else if (value) {\n const resolvedVal = resolveColorValue(value, opt);\n if (resolvedVal instanceof NullObject) {\n setCache(cacheKey, resolvedVal);\n return resolvedVal;\n }\n [cs, r, g, b, alpha] = resolvedVal as ComputedColorChannels;\n }\n // 6. Format Finalization\n let finalRes: string | NullObject = '';\n switch (format) {\n case 'hex':\n case 'hexAlpha': {\n if (\n Number.isNaN(r) ||\n Number.isNaN(g) ||\n Number.isNaN(b) ||\n Number.isNaN(alpha) ||\n (format === 'hex' && alpha === 0)\n ) {\n finalRes = new NullObject();\n } else {\n finalRes = convertRgbToHex([r, g, b, format === 'hex' ? 1 : alpha]);\n }\n break;\n }\n default: {\n if (cs === 'rgb') {\n finalRes =\n alpha === 1\n ? `${cs}(${r}, ${g}, ${b})`\n : `${cs}a(${r}, ${g}, ${b}, ${alpha})`;\n } else if (['lab', 'lch', 'oklab', 'oklch'].includes(cs)) {\n finalRes =\n alpha === 1\n ? `${cs}(${r} ${g} ${b})`\n : `${cs}(${r} ${g} ${b} / ${alpha})`;\n } else {\n finalRes =\n alpha === 1\n ? `color(${cs} ${r} ${g} ${b})`\n : `color(${cs} ${r} ${g} ${b} / ${alpha})`;\n }\n }\n }\n setCache(cacheKey, finalRes);\n return finalRes;\n};\n\n/**\n * resolve CSS color\n * @param value - CSS color value. system colors are not supported\n * @param [opt] - options\n */\nexport const resolve = (value: string, opt: Options = {}): string | null => {\n opt.nullable = false;\n const resolvedValue = resolveColor(value, opt);\n return resolvedValue instanceof NullObject ? null : (resolvedValue as string);\n};\n"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/typedef.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/typedef.d.ts new file mode 100644 index 0000000..5130377 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/typedef.d.ts @@ -0,0 +1,80 @@ +/** + * typedef + */ +/** + * @typedef Options - options + * @property [alpha] - enable alpha + * @property [colorSpace] - color space + * @property [currentColor] - color for currentcolor + * @property [customProperty] - custom properties + * @property [d50] - white point in d50 + * @property [dimension] - dimension + * @property [format] - output format + * @property [key] - key + */ +export interface Options { + alpha?: boolean; + colorScheme?: string; + colorSpace?: string; + currentColor?: string; + customProperty?: Record string)>; + d50?: boolean; + delimiter?: string | string[]; + dimension?: Record number)>; + format?: string; + nullable?: boolean; + preserveComment?: boolean; +} +/** + * @type ColorChannels - color channels + */ +export type ColorChannels = [x: number, y: number, z: number, alpha: number]; +/** + * @type StringColorChannels - color channels + */ +export type StringColorChannels = [ + x: string, + y: string, + z: string, + alpha: string | undefined +]; +/** + * @type StringColorSpacedChannels - specified value + */ +export type StringColorSpacedChannels = [ + cs: string, + x: string, + y: string, + z: string, + alpha: string | undefined +]; +/** + * @type ComputedColorChannels - computed value + */ +export type ComputedColorChannels = [ + cs: string, + x: number, + y: number, + z: number, + alpha: number +]; +/** + * @type SpecifiedColorChannels - specified value + */ +export type SpecifiedColorChannels = [ + cs: string, + x: number | string, + y: number | string, + z: number | string, + alpha: number | string +]; +/** + * @type MatchedRegExp - matched regexp array + */ +export type MatchedRegExp = [ + match: string, + gr1: string, + gr2: string, + gr3: string, + gr4: string +]; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/util.d.ts b/node_modules/@asamuzakjp/css-color/dist/esm/js/util.d.ts new file mode 100644 index 0000000..3c095db --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/util.d.ts @@ -0,0 +1,59 @@ +import { Options } from './typedef.js'; +/** + * split value + * NOTE: comments are stripped, it can be preserved if, in the options param, + * `delimiter` is either ',' or '/' and with `preserveComment` set to `true` + * @param value - CSS value + * @param [opt] - options + * @returns array of values + */ +export declare const splitValue: (value: string, opt?: Options) => string[]; +/** + * extract dashed-ident tokens + * @param value - CSS value + * @returns array of dashed-ident tokens + */ +export declare const extractDashedIdent: (value: string) => string[]; +/** + * is color + * @param value - CSS value + * @param [opt] - options + * @returns result + */ +export declare const isColor: (value: unknown, opt?: Options) => boolean; +/** + * round to specified precision + * @param value - numeric value + * @param bit - minimum bits + * @returns rounded value + */ +export declare const roundToPrecision: (value: number, bit?: number) => number; +/** + * interpolate hue + * @param hueA - hue value + * @param hueB - hue value + * @param arc - shorter | longer | increasing | decreasing + * @returns result - [hueA, hueB] + */ +export declare const interpolateHue: (hueA: number, hueB: number, arc?: string) => [number, number]; +/** + * resolve length in pixels + * @param value - value + * @param unit - unit + * @param [opt] - options + * @returns pixelated value + */ +export declare const resolveLengthInPixels: (value: number | string, unit: string | undefined, opt?: Options) => number; +/** + * is absolute size or length + * @param value - value + * @param unit - unit + * @returns result + */ +export declare const isAbsoluteSizeOrLength: (value: number | string, unit: string | undefined) => boolean; +/** + * is absolute font size + * @param css - css + * @returns result + */ +export declare const isAbsoluteFontSize: (css: unknown) => boolean; diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/util.js b/node_modules/@asamuzakjp/css-color/dist/esm/js/util.js new file mode 100644 index 0000000..be90d9f --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/util.js @@ -0,0 +1,274 @@ +import { CacheItem, createCacheKey, getCache, setCache } from "./cache.js"; +import { isString } from "./common.js"; +import { SYN_COLOR_TYPE, SYN_MIX, VAL_SPEC } from "./constant.js"; +import { NAMED_COLORS } from "./color.js"; +import { resolveColor } from "./resolve.js"; +import { TokenType, tokenize } from "@csstools/css-tokenizer"; +//#region src/js/util.ts +/** +* util +*/ +var { CloseParen: PAREN_CLOSE, Comma: COMMA, Comment: COMMENT, Delim: DELIM, EOF, Function: FUNC, OpenParen: PAREN_OPEN, Whitespace: W_SPACE } = TokenType; +var NAMESPACE = "util"; +var DEC = 10; +var HEX = 16; +var DEG = 360; +var DEG_HALF = 180; +var REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`); +var REG_DIMENSION = /^([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)([a-z]*)$/i; +var REG_FN_COLOR = /^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\(/; +var REG_MIX = new RegExp(SYN_MIX); +var REG_DASHED_IDENT = /--[\w-]+/g; +var REG_COMMA = /^,$/; +var REG_SLASH = /^\/$/; +var REG_WHITESPACE = /^\s+$/; +/** +* split value +* NOTE: comments are stripped, it can be preserved if, in the options param, +* `delimiter` is either ',' or '/' and with `preserveComment` set to `true` +* @param value - CSS value +* @param [opt] - options +* @returns array of values +*/ +var splitValue = (value, opt = {}) => { + if (!isString(value)) throw new TypeError(`${value} is not a string.`); + const strValue = value.trim(); + const { delimiter = " ", preserveComment = false } = opt; + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "splitValue", + value: strValue + }, { + delimiter, + preserveComment + }); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) return cachedResult.item; + let regDelimiter; + switch (delimiter) { + case ",": + regDelimiter = REG_COMMA; + break; + case "/": + regDelimiter = REG_SLASH; + break; + default: regDelimiter = REG_WHITESPACE; + } + const tokens = tokenize({ css: strValue }); + let nest = 0; + let currentStr = ""; + const res = []; + for (const [type, val] of tokens) switch (type) { + case COMMA: + case DELIM: + if (nest === 0 && regDelimiter.test(val)) { + res.push(currentStr.trim()); + currentStr = ""; + } else currentStr += val; + break; + case COMMENT: + if (preserveComment && (delimiter === "," || delimiter === "/")) currentStr += val; + break; + case FUNC: + case PAREN_OPEN: + currentStr += val; + nest++; + break; + case PAREN_CLOSE: + currentStr += val; + nest--; + break; + case W_SPACE: + if (regDelimiter.test(val)) if (nest === 0) { + if (currentStr) { + res.push(currentStr.trim()); + currentStr = ""; + } + } else currentStr += " "; + else if (!currentStr.endsWith(" ")) currentStr += " "; + break; + default: if (type === EOF) { + res.push(currentStr.trim()); + currentStr = ""; + } else currentStr += val; + } + setCache(cacheKey, res); + return res; +}; +/** +* extract dashed-ident tokens +* @param value - CSS value +* @returns array of dashed-ident tokens +*/ +var extractDashedIdent = (value) => { + if (!isString(value)) throw new TypeError(`${value} is not a string.`); + const strValue = value.trim(); + const cacheKey = createCacheKey({ + namespace: NAMESPACE, + name: "extractDashedIdent", + value: strValue + }); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) return cachedResult.item; + const matches = strValue.match(REG_DASHED_IDENT); + const res = matches ? [...new Set(matches)] : []; + setCache(cacheKey, res); + return res; +}; +/** +* is color +* @param value - CSS value +* @param [opt] - options +* @returns result +*/ +var isColor = (value, opt = {}) => { + if (!isString(value)) return false; + const str = value.toLowerCase().trim(); + if (!str) return false; + if (/^[a-z]+$/.test(str)) return str === "currentcolor" || str === "transparent" || Object.hasOwn(NAMED_COLORS, str); + if (REG_COLOR.test(str) || REG_MIX.test(str)) return true; + if (REG_FN_COLOR.test(str)) { + const colorOpt = { + ...opt, + nullable: true + }; + if (!colorOpt.format) colorOpt.format = VAL_SPEC; + return !!resolveColor(str, colorOpt); + } + return false; +}; +/** +* round to specified precision +* @param value - numeric value +* @param bit - minimum bits +* @returns rounded value +*/ +var roundToPrecision = (value, bit = 0) => { + if (!Number.isFinite(value)) throw new TypeError(`${value} is not a finite number.`); + if (!Number.isFinite(bit)) throw new TypeError(`${bit} is not a finite number.`); + if (bit < 0 || bit > HEX) throw new RangeError(`${bit} is not between 0 and ${HEX}.`); + if (bit === 0) return Math.round(value); + const precision = bit === HEX ? 6 : bit < DEC ? 4 : 5; + return parseFloat(value.toPrecision(precision)); +}; +/** +* interpolate hue +* @param hueA - hue value +* @param hueB - hue value +* @param arc - shorter | longer | increasing | decreasing +* @returns result - [hueA, hueB] +*/ +var interpolateHue = (hueA, hueB, arc = "shorter") => { + if (!Number.isFinite(hueA)) throw new TypeError(`${hueA} is not a finite number.`); + if (!Number.isFinite(hueB)) throw new TypeError(`${hueB} is not a finite number.`); + let a = hueA; + let b = hueB; + switch (arc) { + case "decreasing": + if (b > a) a += DEG; + break; + case "increasing": + if (b < a) b += DEG; + break; + case "longer": + if (b > a && b < a + DEG_HALF) a += DEG; + else if (b > a - DEG_HALF && b <= a) b += DEG; + break; + default: if (b > a + DEG_HALF) a += DEG; + else if (b < a - DEG_HALF) b += DEG; + } + return [a, b]; +}; +var absoluteFontSize = new Map([ + ["xx-small", 9 / 16], + ["x-small", 5 / 8], + ["small", 13 / 16], + ["medium", 1], + ["large", 9 / 8], + ["x-large", 3 / 2], + ["xx-large", 2], + ["xxx-large", 3] +]); +var relativeFontSize = new Map([["smaller", 1 / 1.2], ["larger", 1.2]]); +var absoluteLength = new Map([ + ["cm", 96 / 2.54], + ["mm", 96 / 25.4], + ["q", 96 / 101.6], + ["in", 96], + ["pc", 16], + ["pt", 96 / 72], + ["px", 1] +]); +var relativeLength = new Map([ + ["rcap", 1], + ["rch", .5], + ["rem", 1], + ["rex", .5], + ["ric", 1], + ["rlh", 1.2] +]); +/** +* resolve length in pixels +* @param value - value +* @param unit - unit +* @param [opt] - options +* @returns pixelated value +*/ +var resolveLengthInPixels = (value, unit, opt = {}) => { + const { dimension = {} } = opt; + const { callback, em, rem, vh, vw } = dimension; + if (isString(value)) { + const str = value.toLowerCase().trim(); + const ratio = absoluteFontSize.get(str); + if (ratio !== void 0) return ratio * rem; + const relRatio = relativeFontSize.get(str); + if (relRatio !== void 0) return relRatio * em; + return NaN; + } + if (Number.isFinite(value) && unit) { + const u = unit.toLowerCase(); + if (Object.hasOwn(dimension, u)) return value * Number(dimension[u]); + if (typeof callback === "function") return value * (callback(u) ?? NaN); + const absRatio = absoluteLength.get(u); + if (absRatio !== void 0) return value * absRatio; + const relRatio = relativeLength.get(u); + if (relRatio !== void 0) return value * relRatio * rem; + const rUnitRatio = relativeLength.get(`r${u}`); + if (rUnitRatio !== void 0) return value * rUnitRatio * em; + switch (u) { + case "vb": + case "vi": return value * vw; + case "vmax": return value * Math.max(vh, vw); + case "vmin": return value * Math.min(vh, vw); + default: + } + } + return NaN; +}; +/** +* is absolute size or length +* @param value - value +* @param unit - unit +* @returns result +*/ +var isAbsoluteSizeOrLength = (value, unit) => { + if (isString(value)) return absoluteFontSize.has(value.toLowerCase().trim()); + if (isString(unit)) return absoluteLength.has(unit.toLowerCase().trim()); + return value === 0; +}; +/** +* is absolute font size +* @param css - css +* @returns result +*/ +var isAbsoluteFontSize = (css) => { + if (!isString(css)) return false; + const str = css.trim(); + if (isAbsoluteSizeOrLength(str, void 0)) return true; + const match = str.match(REG_DIMENSION); + return match ? isAbsoluteSizeOrLength(Number(match[1]), match[2] || void 0) : false; +}; +//#endregion +export { extractDashedIdent, interpolateHue, isAbsoluteFontSize, isAbsoluteSizeOrLength, isColor, resolveLengthInPixels, roundToPrecision, splitValue }; + +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/dist/esm/js/util.js.map b/node_modules/@asamuzakjp/css-color/dist/esm/js/util.js.map new file mode 100644 index 0000000..03ef78f --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/dist/esm/js/util.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.js","names":[],"sources":["../../../src/js/util.ts"],"sourcesContent":["/**\n * util\n */\n\nimport { TokenType, tokenize } from '@csstools/css-tokenizer';\nimport { CacheItem, createCacheKey, getCache, setCache } from './cache';\nimport { isString } from './common';\nimport { resolveColor } from './resolve';\nimport { Options } from './typedef';\n\n/* constants */\nimport { NAMED_COLORS } from './color';\nimport { SYN_COLOR_TYPE, SYN_MIX, VAL_SPEC } from './constant';\nconst {\n CloseParen: PAREN_CLOSE,\n Comma: COMMA,\n Comment: COMMENT,\n Delim: DELIM,\n EOF,\n Function: FUNC,\n OpenParen: PAREN_OPEN,\n Whitespace: W_SPACE\n} = TokenType;\nconst NAMESPACE = 'util';\n\n/* numeric constants */\nconst DEC = 10;\nconst HEX = 16;\nconst DEG = 360;\nconst DEG_HALF = 180;\n\n/* regexp */\nconst REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`);\nconst REG_DIMENSION = /^([+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:e[+-]?\\d+)?)([a-z]*)$/i;\nconst REG_FN_COLOR =\n /^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\\(/;\nconst REG_MIX = new RegExp(SYN_MIX);\nconst REG_DASHED_IDENT = /--[\\w-]+/g;\nconst REG_COMMA = /^,$/;\nconst REG_SLASH = /^\\/$/;\nconst REG_WHITESPACE = /^\\s+$/;\n\n/**\n * split value\n * NOTE: comments are stripped, it can be preserved if, in the options param,\n * `delimiter` is either ',' or '/' and with `preserveComment` set to `true`\n * @param value - CSS value\n * @param [opt] - options\n * @returns array of values\n */\nexport const splitValue = (value: string, opt: Options = {}): string[] => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const strValue = value.trim();\n const { delimiter = ' ', preserveComment = false } = opt;\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'splitValue',\n value: strValue\n },\n { delimiter, preserveComment }\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n return cachedResult.item as string[];\n }\n let regDelimiter;\n switch (delimiter) {\n case ',': {\n regDelimiter = REG_COMMA;\n break;\n }\n case '/': {\n regDelimiter = REG_SLASH;\n break;\n }\n default: {\n regDelimiter = REG_WHITESPACE;\n }\n }\n const tokens = tokenize({ css: strValue });\n let nest = 0;\n let currentStr = '';\n const res: string[] = [];\n for (const [type, val] of tokens) {\n switch (type) {\n case COMMA:\n case DELIM: {\n if (nest === 0 && regDelimiter.test(val)) {\n res.push(currentStr.trim());\n currentStr = '';\n } else {\n currentStr += val;\n }\n break;\n }\n case COMMENT: {\n if (preserveComment && (delimiter === ',' || delimiter === '/')) {\n currentStr += val;\n }\n break;\n }\n case FUNC:\n case PAREN_OPEN: {\n currentStr += val;\n nest++;\n break;\n }\n case PAREN_CLOSE: {\n currentStr += val;\n nest--;\n break;\n }\n case W_SPACE: {\n if (regDelimiter.test(val)) {\n if (nest === 0) {\n if (currentStr) {\n res.push(currentStr.trim());\n currentStr = '';\n }\n } else {\n currentStr += ' ';\n }\n } else if (!currentStr.endsWith(' ')) {\n currentStr += ' ';\n }\n break;\n }\n default: {\n if (type === EOF) {\n res.push(currentStr.trim());\n currentStr = '';\n } else {\n currentStr += val;\n }\n }\n }\n }\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * extract dashed-ident tokens\n * @param value - CSS value\n * @returns array of dashed-ident tokens\n */\nexport const extractDashedIdent = (value: string): string[] => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const strValue = value.trim();\n const cacheKey: string = createCacheKey({\n namespace: NAMESPACE,\n name: 'extractDashedIdent',\n value: strValue\n });\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n return cachedResult.item as string[];\n }\n const matches = strValue.match(REG_DASHED_IDENT);\n const res = matches ? [...new Set(matches)] : [];\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * is color\n * @param value - CSS value\n * @param [opt] - options\n * @returns result\n */\nexport const isColor = (value: unknown, opt: Options = {}): boolean => {\n if (!isString(value)) {\n return false;\n }\n const str = value.toLowerCase().trim();\n if (!str) {\n return false;\n }\n if (/^[a-z]+$/.test(str)) {\n return (\n str === 'currentcolor' ||\n str === 'transparent' ||\n Object.hasOwn(NAMED_COLORS, str)\n );\n }\n if (REG_COLOR.test(str) || REG_MIX.test(str)) {\n return true;\n }\n if (REG_FN_COLOR.test(str)) {\n const colorOpt = { ...opt, nullable: true };\n if (!colorOpt.format) colorOpt.format = VAL_SPEC;\n return !!resolveColor(str, colorOpt);\n }\n return false;\n};\n\n/**\n * round to specified precision\n * @param value - numeric value\n * @param bit - minimum bits\n * @returns rounded value\n */\nexport const roundToPrecision = (value: number, bit: number = 0): number => {\n if (!Number.isFinite(value)) {\n throw new TypeError(`${value} is not a finite number.`);\n }\n if (!Number.isFinite(bit)) {\n throw new TypeError(`${bit} is not a finite number.`);\n }\n if (bit < 0 || bit > HEX) {\n throw new RangeError(`${bit} is not between 0 and ${HEX}.`);\n }\n if (bit === 0) {\n return Math.round(value);\n }\n const precision = bit === HEX ? 6 : bit < DEC ? 4 : 5;\n return parseFloat(value.toPrecision(precision));\n};\n\n/**\n * interpolate hue\n * @param hueA - hue value\n * @param hueB - hue value\n * @param arc - shorter | longer | increasing | decreasing\n * @returns result - [hueA, hueB]\n */\nexport const interpolateHue = (\n hueA: number,\n hueB: number,\n arc: string = 'shorter'\n): [number, number] => {\n if (!Number.isFinite(hueA)) {\n throw new TypeError(`${hueA} is not a finite number.`);\n }\n if (!Number.isFinite(hueB)) {\n throw new TypeError(`${hueB} is not a finite number.`);\n }\n let a = hueA;\n let b = hueB;\n switch (arc) {\n case 'decreasing': {\n if (b > a) {\n a += DEG;\n }\n break;\n }\n case 'increasing': {\n if (b < a) {\n b += DEG;\n }\n break;\n }\n case 'longer': {\n if (b > a && b < a + DEG_HALF) {\n a += DEG;\n } else if (b > a - DEG_HALF && b <= a) {\n b += DEG;\n }\n break;\n }\n case 'shorter':\n default: {\n if (b > a + DEG_HALF) {\n a += DEG;\n } else if (b < a - DEG_HALF) {\n b += DEG;\n }\n }\n }\n return [a, b];\n};\n\n/* absolute font size to pixel ratio */\nconst absoluteFontSize = new Map([\n ['xx-small', 9 / 16],\n ['x-small', 5 / 8],\n ['small', 13 / 16],\n ['medium', 1],\n ['large', 9 / 8],\n ['x-large', 3 / 2],\n ['xx-large', 2],\n ['xxx-large', 3]\n]);\n\n/* relative font size to pixel ratio */\nconst relativeFontSize = new Map([\n ['smaller', 1 / 1.2],\n ['larger', 1.2]\n]);\n\n/* absolute length to pixel ratio */\nconst absoluteLength = new Map([\n ['cm', 96 / 2.54],\n ['mm', 96 / 25.4],\n ['q', 96 / 101.6],\n ['in', 96],\n ['pc', 16],\n ['pt', 96 / 72],\n ['px', 1]\n]);\n\n/* relative length to pixel ratio */\nconst relativeLength = new Map([\n ['rcap', 1],\n ['rch', 0.5],\n ['rem', 1],\n ['rex', 0.5],\n ['ric', 1],\n ['rlh', 1.2]\n]);\n\n/**\n * resolve length in pixels\n * @param value - value\n * @param unit - unit\n * @param [opt] - options\n * @returns pixelated value\n */\nexport const resolveLengthInPixels = (\n value: number | string,\n unit: string | undefined,\n opt: Options = {}\n): number => {\n const { dimension = {} } = opt;\n const { callback, em, rem, vh, vw } = dimension as {\n callback: (K: string) => number;\n em: number;\n rem: number;\n vh: number;\n vw: number;\n };\n if (isString(value)) {\n const str = value.toLowerCase().trim();\n const ratio = absoluteFontSize.get(str);\n if (ratio !== undefined) {\n return ratio * rem;\n }\n const relRatio = relativeFontSize.get(str);\n if (relRatio !== undefined) {\n return relRatio * em;\n }\n return Number.NaN;\n }\n if (Number.isFinite(value) && unit) {\n const u = unit.toLowerCase();\n if (Object.hasOwn(dimension, u)) {\n return value * Number(dimension[u]);\n }\n if (typeof callback === 'function') {\n return value * (callback(u) ?? Number.NaN);\n }\n const absRatio = absoluteLength.get(u);\n if (absRatio !== undefined) {\n return value * absRatio;\n }\n const relRatio = relativeLength.get(u);\n if (relRatio !== undefined) {\n return value * relRatio * rem;\n }\n const rUnitRatio = relativeLength.get(`r${u}`);\n if (rUnitRatio !== undefined) {\n return value * rUnitRatio * em;\n }\n switch (u) {\n case 'vb':\n case 'vi': {\n return value * vw;\n }\n case 'vmax': {\n return value * Math.max(vh, vw);\n }\n case 'vmin': {\n return value * Math.min(vh, vw);\n }\n default:\n }\n }\n // unsupported or invalid value\n return Number.NaN;\n};\n\n/**\n * is absolute size or length\n * @param value - value\n * @param unit - unit\n * @returns result\n */\nexport const isAbsoluteSizeOrLength = (\n value: number | string,\n unit: string | undefined\n): boolean => {\n if (isString(value)) {\n return absoluteFontSize.has(value.toLowerCase().trim());\n }\n if (isString(unit)) {\n return absoluteLength.has(unit.toLowerCase().trim());\n }\n return value === 0;\n};\n\n/**\n * is absolute font size\n * @param css - css\n * @returns result\n */\nexport const isAbsoluteFontSize = (css: unknown): boolean => {\n if (!isString(css)) {\n return false;\n }\n const str = css.trim();\n if (isAbsoluteSizeOrLength(str, undefined)) {\n return true;\n }\n const match = str.match(REG_DIMENSION);\n return match\n ? isAbsoluteSizeOrLength(Number(match[1]), match[2] || undefined)\n : false;\n};\n"],"mappings":";;;;;;;;;;AAaA,IAAM,EACJ,YAAY,aACZ,OAAO,OACP,SAAS,SACT,OAAO,OACP,KACA,UAAU,MACV,WAAW,YACX,YAAY,YACV;AACJ,IAAM,YAAY;AAGlB,IAAM,MAAM;AACZ,IAAM,MAAM;AACZ,IAAM,MAAM;AACZ,IAAM,WAAW;AAGjB,IAAM,YAAY,IAAI,OAAO,OAAO,eAAe,IAAI;AACvD,IAAM,gBAAgB;AACtB,IAAM,eACJ;AACF,IAAM,UAAU,IAAI,OAAO,QAAQ;AACnC,IAAM,mBAAmB;AACzB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,iBAAiB;;;;;;;;;AAUvB,IAAa,cAAc,OAAe,MAAe,EAAE,KAAe;AACxE,KAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,UAAU,GAAG,MAAM,mBAAmB;CAElD,MAAM,WAAW,MAAM,MAAM;CAC7B,MAAM,EAAE,YAAY,KAAK,kBAAkB,UAAU;CACrD,MAAM,WAAmB,eACvB;EACE,WAAW;EACX,MAAM;EACN,OAAO;EACR,EACD;EAAE;EAAW;EAAiB,CAC/B;CACD,MAAM,eAAe,SAAS,SAAS;AACvC,KAAI,wBAAwB,UAC1B,QAAO,aAAa;CAEtB,IAAI;AACJ,SAAQ,WAAR;EACE,KAAK;AACH,kBAAe;AACf;EAEF,KAAK;AACH,kBAAe;AACf;EAEF,QACE,gBAAe;;CAGnB,MAAM,SAAS,SAAS,EAAE,KAAK,UAAU,CAAC;CAC1C,IAAI,OAAO;CACX,IAAI,aAAa;CACjB,MAAM,MAAgB,EAAE;AACxB,MAAK,MAAM,CAAC,MAAM,QAAQ,OACxB,SAAQ,MAAR;EACE,KAAK;EACL,KAAK;AACH,OAAI,SAAS,KAAK,aAAa,KAAK,IAAI,EAAE;AACxC,QAAI,KAAK,WAAW,MAAM,CAAC;AAC3B,iBAAa;SAEb,eAAc;AAEhB;EAEF,KAAK;AACH,OAAI,oBAAoB,cAAc,OAAO,cAAc,KACzD,eAAc;AAEhB;EAEF,KAAK;EACL,KAAK;AACH,iBAAc;AACd;AACA;EAEF,KAAK;AACH,iBAAc;AACd;AACA;EAEF,KAAK;AACH,OAAI,aAAa,KAAK,IAAI,CACxB,KAAI,SAAS;QACP,YAAY;AACd,SAAI,KAAK,WAAW,MAAM,CAAC;AAC3B,kBAAa;;SAGf,eAAc;YAEP,CAAC,WAAW,SAAS,IAAI,CAClC,eAAc;AAEhB;EAEF,QACE,KAAI,SAAS,KAAK;AAChB,OAAI,KAAK,WAAW,MAAM,CAAC;AAC3B,gBAAa;QAEb,eAAc;;AAKtB,UAAS,UAAU,IAAI;AACvB,QAAO;;;;;;;AAQT,IAAa,sBAAsB,UAA4B;AAC7D,KAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,UAAU,GAAG,MAAM,mBAAmB;CAElD,MAAM,WAAW,MAAM,MAAM;CAC7B,MAAM,WAAmB,eAAe;EACtC,WAAW;EACX,MAAM;EACN,OAAO;EACR,CAAC;CACF,MAAM,eAAe,SAAS,SAAS;AACvC,KAAI,wBAAwB,UAC1B,QAAO,aAAa;CAEtB,MAAM,UAAU,SAAS,MAAM,iBAAiB;CAChD,MAAM,MAAM,UAAU,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,GAAG,EAAE;AAChD,UAAS,UAAU,IAAI;AACvB,QAAO;;;;;;;;AAST,IAAa,WAAW,OAAgB,MAAe,EAAE,KAAc;AACrE,KAAI,CAAC,SAAS,MAAM,CAClB,QAAO;CAET,MAAM,MAAM,MAAM,aAAa,CAAC,MAAM;AACtC,KAAI,CAAC,IACH,QAAO;AAET,KAAI,WAAW,KAAK,IAAI,CACtB,QACE,QAAQ,kBACR,QAAQ,iBACR,OAAO,OAAO,cAAc,IAAI;AAGpC,KAAI,UAAU,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,CAC1C,QAAO;AAET,KAAI,aAAa,KAAK,IAAI,EAAE;EAC1B,MAAM,WAAW;GAAE,GAAG;GAAK,UAAU;GAAM;AAC3C,MAAI,CAAC,SAAS,OAAQ,UAAS,SAAS;AACxC,SAAO,CAAC,CAAC,aAAa,KAAK,SAAS;;AAEtC,QAAO;;;;;;;;AAST,IAAa,oBAAoB,OAAe,MAAc,MAAc;AAC1E,KAAI,CAAC,OAAO,SAAS,MAAM,CACzB,OAAM,IAAI,UAAU,GAAG,MAAM,0BAA0B;AAEzD,KAAI,CAAC,OAAO,SAAS,IAAI,CACvB,OAAM,IAAI,UAAU,GAAG,IAAI,0BAA0B;AAEvD,KAAI,MAAM,KAAK,MAAM,IACnB,OAAM,IAAI,WAAW,GAAG,IAAI,wBAAwB,IAAI,GAAG;AAE7D,KAAI,QAAQ,EACV,QAAO,KAAK,MAAM,MAAM;CAE1B,MAAM,YAAY,QAAQ,MAAM,IAAI,MAAM,MAAM,IAAI;AACpD,QAAO,WAAW,MAAM,YAAY,UAAU,CAAC;;;;;;;;;AAUjD,IAAa,kBACX,MACA,MACA,MAAc,cACO;AACrB,KAAI,CAAC,OAAO,SAAS,KAAK,CACxB,OAAM,IAAI,UAAU,GAAG,KAAK,0BAA0B;AAExD,KAAI,CAAC,OAAO,SAAS,KAAK,CACxB,OAAM,IAAI,UAAU,GAAG,KAAK,0BAA0B;CAExD,IAAI,IAAI;CACR,IAAI,IAAI;AACR,SAAQ,KAAR;EACE,KAAK;AACH,OAAI,IAAI,EACN,MAAK;AAEP;EAEF,KAAK;AACH,OAAI,IAAI,EACN,MAAK;AAEP;EAEF,KAAK;AACH,OAAI,IAAI,KAAK,IAAI,IAAI,SACnB,MAAK;YACI,IAAI,IAAI,YAAY,KAAK,EAClC,MAAK;AAEP;EAGF,QACE,KAAI,IAAI,IAAI,SACV,MAAK;WACI,IAAI,IAAI,SACjB,MAAK;;AAIX,QAAO,CAAC,GAAG,EAAE;;AAIf,IAAM,mBAAmB,IAAI,IAAI;CAC/B,CAAC,YAAY,IAAI,GAAG;CACpB,CAAC,WAAW,IAAI,EAAE;CAClB,CAAC,SAAS,KAAK,GAAG;CAClB,CAAC,UAAU,EAAE;CACb,CAAC,SAAS,IAAI,EAAE;CAChB,CAAC,WAAW,IAAI,EAAE;CAClB,CAAC,YAAY,EAAE;CACf,CAAC,aAAa,EAAE;CACjB,CAAC;AAGF,IAAM,mBAAmB,IAAI,IAAI,CAC/B,CAAC,WAAW,IAAI,IAAI,EACpB,CAAC,UAAU,IAAI,CAChB,CAAC;AAGF,IAAM,iBAAiB,IAAI,IAAI;CAC7B,CAAC,MAAM,KAAK,KAAK;CACjB,CAAC,MAAM,KAAK,KAAK;CACjB,CAAC,KAAK,KAAK,MAAM;CACjB,CAAC,MAAM,GAAG;CACV,CAAC,MAAM,GAAG;CACV,CAAC,MAAM,KAAK,GAAG;CACf,CAAC,MAAM,EAAE;CACV,CAAC;AAGF,IAAM,iBAAiB,IAAI,IAAI;CAC7B,CAAC,QAAQ,EAAE;CACX,CAAC,OAAO,GAAI;CACZ,CAAC,OAAO,EAAE;CACV,CAAC,OAAO,GAAI;CACZ,CAAC,OAAO,EAAE;CACV,CAAC,OAAO,IAAI;CACb,CAAC;;;;;;;;AASF,IAAa,yBACX,OACA,MACA,MAAe,EAAE,KACN;CACX,MAAM,EAAE,YAAY,EAAE,KAAK;CAC3B,MAAM,EAAE,UAAU,IAAI,KAAK,IAAI,OAAO;AAOtC,KAAI,SAAS,MAAM,EAAE;EACnB,MAAM,MAAM,MAAM,aAAa,CAAC,MAAM;EACtC,MAAM,QAAQ,iBAAiB,IAAI,IAAI;AACvC,MAAI,UAAU,KAAA,EACZ,QAAO,QAAQ;EAEjB,MAAM,WAAW,iBAAiB,IAAI,IAAI;AAC1C,MAAI,aAAa,KAAA,EACf,QAAO,WAAW;AAEpB,SAAO;;AAET,KAAI,OAAO,SAAS,MAAM,IAAI,MAAM;EAClC,MAAM,IAAI,KAAK,aAAa;AAC5B,MAAI,OAAO,OAAO,WAAW,EAAE,CAC7B,QAAO,QAAQ,OAAO,UAAU,GAAG;AAErC,MAAI,OAAO,aAAa,WACtB,QAAO,SAAS,SAAS,EAAE,IAAI;EAEjC,MAAM,WAAW,eAAe,IAAI,EAAE;AACtC,MAAI,aAAa,KAAA,EACf,QAAO,QAAQ;EAEjB,MAAM,WAAW,eAAe,IAAI,EAAE;AACtC,MAAI,aAAa,KAAA,EACf,QAAO,QAAQ,WAAW;EAE5B,MAAM,aAAa,eAAe,IAAI,IAAI,IAAI;AAC9C,MAAI,eAAe,KAAA,EACjB,QAAO,QAAQ,aAAa;AAE9B,UAAQ,GAAR;GACE,KAAK;GACL,KAAK,KACH,QAAO,QAAQ;GAEjB,KAAK,OACH,QAAO,QAAQ,KAAK,IAAI,IAAI,GAAG;GAEjC,KAAK,OACH,QAAO,QAAQ,KAAK,IAAI,IAAI,GAAG;GAEjC;;;AAIJ,QAAO;;;;;;;;AAST,IAAa,0BACX,OACA,SACY;AACZ,KAAI,SAAS,MAAM,CACjB,QAAO,iBAAiB,IAAI,MAAM,aAAa,CAAC,MAAM,CAAC;AAEzD,KAAI,SAAS,KAAK,CAChB,QAAO,eAAe,IAAI,KAAK,aAAa,CAAC,MAAM,CAAC;AAEtD,QAAO,UAAU;;;;;;;AAQnB,IAAa,sBAAsB,QAA0B;AAC3D,KAAI,CAAC,SAAS,IAAI,CAChB,QAAO;CAET,MAAM,MAAM,IAAI,MAAM;AACtB,KAAI,uBAAuB,KAAK,KAAA,EAAU,CACxC,QAAO;CAET,MAAM,QAAQ,IAAI,MAAM,cAAc;AACtC,QAAO,QACH,uBAAuB,OAAO,MAAM,GAAG,EAAE,MAAM,MAAM,KAAA,EAAU,GAC/D"} \ No newline at end of file diff --git a/node_modules/@asamuzakjp/css-color/package.json b/node_modules/@asamuzakjp/css-color/package.json new file mode 100644 index 0000000..714492f --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/package.json @@ -0,0 +1,84 @@ +{ + "name": "@asamuzakjp/css-color", + "description": "CSS color - Resolve and convert CSS colors.", + "author": "asamuzaK", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/asamuzaK/cssColor.git" + }, + "homepage": "https://github.com/asamuzaK/cssColor#readme", + "bugs": { + "url": "https://github.com/asamuzaK/cssColor/issues" + }, + "files": [ + "dist", + "src" + ], + "type": "module", + "exports": { + ".": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "./package.json": "./package.json" + }, + "dependencies": { + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "devDependencies": { + "@tanstack/vite-config": "^0.5.2", + "@vitest/coverage-istanbul": "^4.1.4", + "esbuild": "^0.27.7", + "eslint": "^9.39.4", + "eslint-plugin-regexp": "^3.1.0", + "globals": "^17.4.0", + "knip": "^6.4.0", + "neostandard": "^0.13.0", + "prettier": "^3.8.2", + "publint": "^0.3.18", + "rimraf": "^6.1.3", + "typescript": "^5.9.3", + "vite": "^8.0.8", + "vitest": "^4.1.4" + }, + "packageManager": "pnpm@10.33.0", + "pnpm": { + "onlyBuiltDependencies": [ + "esbuild", + "oxc-resolver", + "unrs-resolver" + ], + "overrides": { + "ajv": "^8.18.0", + "@eslint/eslintrc>ajv": "^6.14.0", + "eslint>ajv": "^6.14.0", + "brace-expansion": "^5.0.4", + "minimatch": "^3.1.5", + "@typescript-eslint/typescript-estree>minimatch": "^9.0.9", + "@vue/language-core>minimatch": "^9.0.9", + "eslint-plugin-import-x>minimatch": "^10.2.4", + "glob>minimatch": "^10.2.4", + "lodash@>=4.0.0 <=4.17.23": ">=4.18.0", + "lodash@<=4.17.23": ">=4.18.0" + } + }, + "scripts": { + "build": "pnpm run clean && pnpm run test && pnpm run knip && vite build && pnpm run publint", + "clean": "rimraf ./coverage ./dist", + "knip": "knip", + "prettier": "prettier . --ignore-unknown --write", + "publint": "publint --strict", + "test": "pnpm run prettier && pnpm run --stream \"/^test:.*/\"", + "test:eslint": "eslint ./src ./test --fix", + "test:types": "tsc", + "test:unit": "vitest" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "version": "5.1.10" +} diff --git a/node_modules/@asamuzakjp/css-color/src/index.ts b/node_modules/@asamuzakjp/css-color/src/index.ts new file mode 100644 index 0000000..ff2ab2d --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/index.ts @@ -0,0 +1,34 @@ +/*! + * CSS color - Resolve, parse, convert CSS color. + * @license MIT + * @copyright asamuzaK (Kazz) + * @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE} + */ + +import { cssCalc } from './js/css-calc'; +import { isGradient, resolveGradient } from './js/css-gradient'; +import { cssVar } from './js/css-var'; +import { + extractDashedIdent, + isAbsoluteFontSize, + isAbsoluteSizeOrLength, + isColor, + resolveLengthInPixels, + splitValue +} from './js/util'; + +export { convert } from './js/convert'; +export { resolve } from './js/resolve'; +/* utils */ +export const utils = { + cssCalc, + cssVar, + extractDashedIdent, + isAbsoluteFontSize, + isAbsoluteSizeOrLength, + isColor, + isGradient, + resolveGradient, + resolveLengthInPixels, + splitValue +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/cache.ts b/node_modules/@asamuzakjp/css-color/src/js/cache.ts new file mode 100644 index 0000000..2d84db9 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/cache.ts @@ -0,0 +1,213 @@ +/** + * cache + */ + +import { Options } from './typedef'; + +/* constants */ +const MAX_CACHE = 1024; + +/** + * CacheItem + */ +export class CacheItem { + /* private */ + #isNull: boolean; + #item: unknown; + + constructor(item: unknown, isNull: boolean = false) { + this.#item = item; + this.#isNull = !!isNull; + } + + get item() { + return this.#item; + } + + get isNull() { + return this.#isNull; + } +} + +/** + * NullObject + */ +export class NullObject extends CacheItem { + constructor() { + super(Symbol('null'), true); + } +} + +/** + * Generational Cache implementation + */ +export class GenerationalCache { + #max: number; + #boundary: number; + #current: Map; + #old: Map; + + constructor(max: number) { + this.#current = new Map(); + this.#old = new Map(); + if (Number.isFinite(max) && max > 4) { + this.#max = max; + this.#boundary = Math.ceil(max / 2); + } else { + this.#max = 4; + this.#boundary = 2; + } + } + + get size(): number { + return this.#current.size + this.#old.size; + } + + get max(): number { + return this.#max; + } + + set max(value: number) { + if (Number.isFinite(value) && value > 4) { + this.#max = value; + this.#boundary = Math.ceil(value / 2); + } else { + this.#max = 4; + this.#boundary = 2; + } + this.#current.clear(); + this.#old.clear(); + } + + get(key: K): V | undefined { + let value = this.#current.get(key); + if (value !== undefined) { + return value; + } + value = this.#old.get(key); + if (value !== undefined) { + this.set(key, value); + return value; + } + return undefined; + } + + set(key: K, value: V): void { + this.#current.set(key, value); + if (this.#current.size >= this.#boundary) { + this.#old = this.#current; + this.#current = new Map(); + } + } + + has(key: K): boolean { + return this.#current.has(key) || this.#old.has(key); + } + + delete(key: K): void { + this.#current.delete(key); + this.#old.delete(key); + } + + clear(): void { + this.#current.clear(); + this.#old.clear(); + } +} + +/* + * generational cache instance + */ +export const genCache = new GenerationalCache(MAX_CACHE); + +/** + * shared null object + */ +const sharedNullObject = new NullObject(); + +/** + * set cache + * @param key - cache key + * @param value - value to cache + * @returns void + */ +export const setCache = (key: string, value: unknown): void => { + if (!key) { + return; + } + if (value === null) { + genCache.set(key, sharedNullObject); + } else if (value instanceof CacheItem) { + genCache.set(key, value); + } else { + genCache.set(key, new CacheItem(value)); + } +}; + +/** + * get cache + * @param key - cache key + * @returns cached item or false otherwise + */ +export const getCache = (key: string): CacheItem | false => { + if (!key) { + return false; + } + const item = genCache.get(key); + if (item !== undefined) { + return item as CacheItem; + } + return false; +}; + +/** + * helper function to sort object keys alphabetically + * @param obj - Object + * @returns stringified JSON + */ +const stringifySorted = (obj: Record): string => { + const keys = Object.keys(obj); + if (keys.length === 0) { + return ''; + } + keys.sort(); + let result = ''; + for (const key of keys) { + result += `${key}:${JSON.stringify(obj[key])};`; + } + return result; +}; + +/** + * create cache key + * @param keyData - key data + * @param [opt] - options + * @returns cache key + */ +export const createCacheKey = ( + keyData: Record, + opt: Options = {} +): string => { + if ( + !keyData || + (opt.customProperty && typeof opt.customProperty.callback === 'function') || + (opt.dimension && typeof opt.dimension.callback === 'function') + ) { + return ''; + } + const namespace = keyData.namespace || ''; + const name = keyData.name || ''; + const value = keyData.value || ''; + if (!namespace && !name && !value) { + return ''; + } + const baseKey = `${namespace}:${name}:${value}`; + const optStr = `${opt.format || ''}|${opt.colorSpace || ''}|${opt.colorScheme || ''}|${opt.currentColor || ''}|${opt.d50 ? '1' : '0'}|${opt.nullable ? '1' : '0'}|${opt.preserveComment ? '1' : '0'}|${opt.delimiter || ''}`; + const customPropStr = opt.customProperty + ? stringifySorted(opt.customProperty as Record) + : ''; + const dimStr = opt.dimension + ? stringifySorted(opt.dimension as Record) + : ''; + return `${baseKey}::${optStr}::${customPropStr}::${dimStr}`; +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/color.ts b/node_modules/@asamuzakjp/css-color/src/js/color.ts new file mode 100644 index 0000000..d935eb2 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/color.ts @@ -0,0 +1,3496 @@ +/** + * color + * + * Ref: CSS Color Module Level 4 + * Sample code for Color Conversions + * https://w3c.github.io/csswg-drafts/css-color-4/#color-conversion-code + */ + +import { + CacheItem, + NullObject, + createCacheKey, + getCache, + setCache +} from './cache'; +import { isString } from './common'; +import { resolveColor } from './resolve'; +import { interpolateHue, roundToPrecision, splitValue } from './util'; +import { + ColorChannels, + ComputedColorChannels, + Options, + MatchedRegExp, + SpecifiedColorChannels, + StringColorChannels, + StringColorSpacedChannels +} from './typedef'; + +/* constants */ +import { + ANGLE, + CS_HUE_CAPT, + CS_MIX, + CS_RGB, + CS_XYZ, + FN_COLOR, + FN_LIGHT_DARK, + FN_MIX, + NONE, + NUM, + PCT, + SYN_COLOR_TYPE, + SYN_FN_COLOR, + SYN_HSL, + SYN_HSL_LV3, + SYN_LCH, + SYN_MIX, + SYN_MIX_CAPT, + SYN_MIX_PART, + SYN_MOD, + SYN_RGB_LV3, + VAL_COMP, + VAL_MIX, + VAL_SPEC +} from './constant'; +const NAMESPACE = 'color'; + +/* numeric constants */ +const PPTH = 0.001; +const HALF = 0.5; +const DUO = 2; +const TRIA = 3; +const QUAD = 4; +const OCT = 8; +const DEC = 10; +const DOZ = 12; +const HEX = 16; +const SEXA = 60; +const DEG_HALF = 180; +const DEG = 360; +const MAX_PCT = 100; +const MAX_RGB = 255; +const POW_SQR = 2; +const POW_CUBE = 3; +const POW_LINEAR = 2.4; +const LINEAR_COEF = 12.92; +const LINEAR_OFFSET = 0.055; +const LAB_L = 116; +const LAB_A = 500; +const LAB_B = 200; +const LAB_EPSILON = 216 / 24389; +const LAB_KAPPA = 24389 / 27; + +/* type definitions */ +/** + * @type NumStrColorChannels - string or numeric color channels + */ +type NumStrColorChannels = [ + x: number | string, + y: number | string, + z: number | string, + alpha: number | string +]; + +/** + * @type TriColorChannels - color channels without alpha + */ +type TriColorChannels = [x: number, y: number, z: number]; + +/** + * @type ColorMatrix - color matrix + */ +type ColorMatrix = [ + r1: TriColorChannels, + r2: TriColorChannels, + r3: TriColorChannels +]; + +/* white point */ +const D50: TriColorChannels = [ + 0.3457 / 0.3585, + 1.0, + (1.0 - 0.3457 - 0.3585) / 0.3585 +]; +const MATRIX_D50_TO_D65: ColorMatrix = [ + [0.955473421488075, -0.02309845494876471, 0.06325924320057072], + [-0.0283697093338637, 1.0099953980813041, 0.021041441191917323], + [0.012314014864481998, -0.020507649298898964, 1.330365926242124] +]; +const MATRIX_D65_TO_D50: ColorMatrix = [ + [1.0479297925449969, 0.022946870601609652, -0.05019226628920524], + [0.02962780877005599, 0.9904344267538799, -0.017073799063418826], + [-0.009243040646204504, 0.015055191490298152, 0.7518742814281371] +]; + +/* color space */ +const MATRIX_L_RGB_TO_XYZ: ColorMatrix = [ + [506752 / 1228815, 87881 / 245763, 12673 / 70218], + [87098 / 409605, 175762 / 245763, 12673 / 175545], + [7918 / 409605, 87881 / 737289, 1001167 / 1053270] +]; +const MATRIX_XYZ_TO_L_RGB: ColorMatrix = [ + [12831 / 3959, -329 / 214, -1974 / 3959], + [-851781 / 878810, 1648619 / 878810, 36519 / 878810], + [705 / 12673, -2585 / 12673, 705 / 667] +]; +const MATRIX_XYZ_TO_LMS: ColorMatrix = [ + [0.819022437996703, 0.3619062600528904, -0.1288737815209879], + [0.0329836539323885, 0.9292868615863434, 0.0361446663506424], + [0.0481771893596242, 0.2642395317527308, 0.6335478284694309] +]; +const MATRIX_LMS_TO_XYZ: ColorMatrix = [ + [1.2268798758459243, -0.5578149944602171, 0.2813910456659647], + [-0.0405757452148008, 1.112286803280317, -0.0717110580655164], + [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816] +]; +const MATRIX_OKLAB_TO_LMS: ColorMatrix = [ + [1.0, 0.3963377773761749, 0.2158037573099136], + [1.0, -0.1055613458156586, -0.0638541728258133], + [1.0, -0.0894841775298119, -1.2914855480194092] +]; +const MATRIX_LMS_TO_OKLAB: ColorMatrix = [ + [0.210454268309314, 0.7936177747023054, -0.0040720430116193], + [1.9779985324311684, -2.4285922420485799, 0.450593709617411], + [0.0259040424655478, 0.7827717124575296, -0.8086757549230774] +]; +const MATRIX_P3_TO_XYZ: ColorMatrix = [ + [608311 / 1250200, 189793 / 714400, 198249 / 1000160], + [35783 / 156275, 247089 / 357200, 198249 / 2500400], + [0 / 1, 32229 / 714400, 5220557 / 5000800] +]; +const MATRIX_REC2020_TO_XYZ: ColorMatrix = [ + [63426534 / 99577255, 20160776 / 139408157, 47086771 / 278816314], + [26158966 / 99577255, 472592308 / 697040785, 8267143 / 139408157], + [0 / 1, 19567812 / 697040785, 295819943 / 278816314] +]; +const MATRIX_A98_TO_XYZ: ColorMatrix = [ + [573536 / 994567, 263643 / 1420810, 187206 / 994567], + [591459 / 1989134, 6239551 / 9945670, 374412 / 4972835], + [53769 / 1989134, 351524 / 4972835, 4929758 / 4972835] +]; +const MATRIX_PROPHOTO_TO_XYZ_D50: ColorMatrix = [ + [0.7977666449006423, 0.13518129740053308, 0.0313477341283922], + [0.2880748288194013, 0.711835234241873, 0.00008993693872564], + [0.0, 0.0, 0.8251046025104602] +]; + +/* regexp */ +const REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`); +const REG_CS_HUE = new RegExp(`^${CS_HUE_CAPT}$`); +const REG_CS_XYZ = /^xyz(?:-d(?:50|65))?$/; +const REG_CURRENT = /^currentColor$/i; +const REG_FN_COLOR = new RegExp(`^color\\(\\s*(${SYN_FN_COLOR})\\s*\\)$`); +const REG_HSL = new RegExp(`^hsla?\\(\\s*(${SYN_HSL}|${SYN_HSL_LV3})\\s*\\)$`); +const REG_HWB = new RegExp(`^hwb\\(\\s*(${SYN_HSL})\\s*\\)$`); +const REG_LAB = new RegExp(`^lab\\(\\s*(${SYN_MOD})\\s*\\)$`); +const REG_LCH = new RegExp(`^lch\\(\\s*(${SYN_LCH})\\s*\\)$`); +const REG_MIX = new RegExp(`^${SYN_MIX}$`); +const REG_MIX_CAPT = new RegExp(`^${SYN_MIX_CAPT}$`); +const REG_MIX_NEST = new RegExp(`${SYN_MIX}`, 'g'); +const REG_OKLAB = new RegExp(`^oklab\\(\\s*(${SYN_MOD})\\s*\\)$`); +const REG_OKLCH = new RegExp(`^oklch\\(\\s*(${SYN_LCH})\\s*\\)$`); +const REG_SPEC = /^(?:specifi|comput)edValue$/; +const REG_ANGLE_TO_DEG = new RegExp(`^(${NUM})(${ANGLE})?$`); +const REG_PARSE_RGB = new RegExp( + `^rgba?\\(\\s*(${SYN_MOD}|${SYN_RGB_LV3})\\s*\\)$` +); +const REG_MIX_CS_RGB_XYZ = new RegExp(`^(?:${CS_RGB}|${CS_XYZ})$`); +const REG_MIX_IN_CS = new RegExp(`in\\s+(${CS_MIX})`); +const REG_MIX_START = new RegExp(`^color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,`); +const REG_MIX_COLOR_PART = new RegExp(`^(${SYN_COLOR_TYPE})(?:\\s+(${PCT}))?$`); + +/** + * named colors + */ +export const NAMED_COLORS = { + aliceblue: [0xf0, 0xf8, 0xff], + antiquewhite: [0xfa, 0xeb, 0xd7], + aqua: [0x00, 0xff, 0xff], + aquamarine: [0x7f, 0xff, 0xd4], + azure: [0xf0, 0xff, 0xff], + beige: [0xf5, 0xf5, 0xdc], + bisque: [0xff, 0xe4, 0xc4], + black: [0x00, 0x00, 0x00], + blanchedalmond: [0xff, 0xeb, 0xcd], + blue: [0x00, 0x00, 0xff], + blueviolet: [0x8a, 0x2b, 0xe2], + brown: [0xa5, 0x2a, 0x2a], + burlywood: [0xde, 0xb8, 0x87], + cadetblue: [0x5f, 0x9e, 0xa0], + chartreuse: [0x7f, 0xff, 0x00], + chocolate: [0xd2, 0x69, 0x1e], + coral: [0xff, 0x7f, 0x50], + cornflowerblue: [0x64, 0x95, 0xed], + cornsilk: [0xff, 0xf8, 0xdc], + crimson: [0xdc, 0x14, 0x3c], + cyan: [0x00, 0xff, 0xff], + darkblue: [0x00, 0x00, 0x8b], + darkcyan: [0x00, 0x8b, 0x8b], + darkgoldenrod: [0xb8, 0x86, 0x0b], + darkgray: [0xa9, 0xa9, 0xa9], + darkgreen: [0x00, 0x64, 0x00], + darkgrey: [0xa9, 0xa9, 0xa9], + darkkhaki: [0xbd, 0xb7, 0x6b], + darkmagenta: [0x8b, 0x00, 0x8b], + darkolivegreen: [0x55, 0x6b, 0x2f], + darkorange: [0xff, 0x8c, 0x00], + darkorchid: [0x99, 0x32, 0xcc], + darkred: [0x8b, 0x00, 0x00], + darksalmon: [0xe9, 0x96, 0x7a], + darkseagreen: [0x8f, 0xbc, 0x8f], + darkslateblue: [0x48, 0x3d, 0x8b], + darkslategray: [0x2f, 0x4f, 0x4f], + darkslategrey: [0x2f, 0x4f, 0x4f], + darkturquoise: [0x00, 0xce, 0xd1], + darkviolet: [0x94, 0x00, 0xd3], + deeppink: [0xff, 0x14, 0x93], + deepskyblue: [0x00, 0xbf, 0xff], + dimgray: [0x69, 0x69, 0x69], + dimgrey: [0x69, 0x69, 0x69], + dodgerblue: [0x1e, 0x90, 0xff], + firebrick: [0xb2, 0x22, 0x22], + floralwhite: [0xff, 0xfa, 0xf0], + forestgreen: [0x22, 0x8b, 0x22], + fuchsia: [0xff, 0x00, 0xff], + gainsboro: [0xdc, 0xdc, 0xdc], + ghostwhite: [0xf8, 0xf8, 0xff], + gold: [0xff, 0xd7, 0x00], + goldenrod: [0xda, 0xa5, 0x20], + gray: [0x80, 0x80, 0x80], + green: [0x00, 0x80, 0x00], + greenyellow: [0xad, 0xff, 0x2f], + grey: [0x80, 0x80, 0x80], + honeydew: [0xf0, 0xff, 0xf0], + hotpink: [0xff, 0x69, 0xb4], + indianred: [0xcd, 0x5c, 0x5c], + indigo: [0x4b, 0x00, 0x82], + ivory: [0xff, 0xff, 0xf0], + khaki: [0xf0, 0xe6, 0x8c], + lavender: [0xe6, 0xe6, 0xfa], + lavenderblush: [0xff, 0xf0, 0xf5], + lawngreen: [0x7c, 0xfc, 0x00], + lemonchiffon: [0xff, 0xfa, 0xcd], + lightblue: [0xad, 0xd8, 0xe6], + lightcoral: [0xf0, 0x80, 0x80], + lightcyan: [0xe0, 0xff, 0xff], + lightgoldenrodyellow: [0xfa, 0xfa, 0xd2], + lightgray: [0xd3, 0xd3, 0xd3], + lightgreen: [0x90, 0xee, 0x90], + lightgrey: [0xd3, 0xd3, 0xd3], + lightpink: [0xff, 0xb6, 0xc1], + lightsalmon: [0xff, 0xa0, 0x7a], + lightseagreen: [0x20, 0xb2, 0xaa], + lightskyblue: [0x87, 0xce, 0xfa], + lightslategray: [0x77, 0x88, 0x99], + lightslategrey: [0x77, 0x88, 0x99], + lightsteelblue: [0xb0, 0xc4, 0xde], + lightyellow: [0xff, 0xff, 0xe0], + lime: [0x00, 0xff, 0x00], + limegreen: [0x32, 0xcd, 0x32], + linen: [0xfa, 0xf0, 0xe6], + magenta: [0xff, 0x00, 0xff], + maroon: [0x80, 0x00, 0x00], + mediumaquamarine: [0x66, 0xcd, 0xaa], + mediumblue: [0x00, 0x00, 0xcd], + mediumorchid: [0xba, 0x55, 0xd3], + mediumpurple: [0x93, 0x70, 0xdb], + mediumseagreen: [0x3c, 0xb3, 0x71], + mediumslateblue: [0x7b, 0x68, 0xee], + mediumspringgreen: [0x00, 0xfa, 0x9a], + mediumturquoise: [0x48, 0xd1, 0xcc], + mediumvioletred: [0xc7, 0x15, 0x85], + midnightblue: [0x19, 0x19, 0x70], + mintcream: [0xf5, 0xff, 0xfa], + mistyrose: [0xff, 0xe4, 0xe1], + moccasin: [0xff, 0xe4, 0xb5], + navajowhite: [0xff, 0xde, 0xad], + navy: [0x00, 0x00, 0x80], + oldlace: [0xfd, 0xf5, 0xe6], + olive: [0x80, 0x80, 0x00], + olivedrab: [0x6b, 0x8e, 0x23], + orange: [0xff, 0xa5, 0x00], + orangered: [0xff, 0x45, 0x00], + orchid: [0xda, 0x70, 0xd6], + palegoldenrod: [0xee, 0xe8, 0xaa], + palegreen: [0x98, 0xfb, 0x98], + paleturquoise: [0xaf, 0xee, 0xee], + palevioletred: [0xdb, 0x70, 0x93], + papayawhip: [0xff, 0xef, 0xd5], + peachpuff: [0xff, 0xda, 0xb9], + peru: [0xcd, 0x85, 0x3f], + pink: [0xff, 0xc0, 0xcb], + plum: [0xdd, 0xa0, 0xdd], + powderblue: [0xb0, 0xe0, 0xe6], + purple: [0x80, 0x00, 0x80], + rebeccapurple: [0x66, 0x33, 0x99], + red: [0xff, 0x00, 0x00], + rosybrown: [0xbc, 0x8f, 0x8f], + royalblue: [0x41, 0x69, 0xe1], + saddlebrown: [0x8b, 0x45, 0x13], + salmon: [0xfa, 0x80, 0x72], + sandybrown: [0xf4, 0xa4, 0x60], + seagreen: [0x2e, 0x8b, 0x57], + seashell: [0xff, 0xf5, 0xee], + sienna: [0xa0, 0x52, 0x2d], + silver: [0xc0, 0xc0, 0xc0], + skyblue: [0x87, 0xce, 0xeb], + slateblue: [0x6a, 0x5a, 0xcd], + slategray: [0x70, 0x80, 0x90], + slategrey: [0x70, 0x80, 0x90], + snow: [0xff, 0xfa, 0xfa], + springgreen: [0x00, 0xff, 0x7f], + steelblue: [0x46, 0x82, 0xb4], + tan: [0xd2, 0xb4, 0x8c], + teal: [0x00, 0x80, 0x80], + thistle: [0xd8, 0xbf, 0xd8], + tomato: [0xff, 0x63, 0x47], + turquoise: [0x40, 0xe0, 0xd0], + violet: [0xee, 0x82, 0xee], + wheat: [0xf5, 0xde, 0xb3], + white: [0xff, 0xff, 0xff], + whitesmoke: [0xf5, 0xf5, 0xf5], + yellow: [0xff, 0xff, 0x00], + yellowgreen: [0x9a, 0xcd, 0x32] +} as const satisfies { + [key: string]: TriColorChannels; +}; + +/** + * cache invalid color value + * @param key - cache key + * @param nullable - is nullable + * @returns cached value + */ +export const cacheInvalidColorValue = ( + cacheKey: string, + format: string, + nullable: boolean = false +): SpecifiedColorChannels | string | NullObject => { + if (format === VAL_SPEC) { + const res = ''; + setCache(cacheKey, res); + return res; + } + if (nullable) { + setCache(cacheKey, null); + return new NullObject(); + } + const res: SpecifiedColorChannels = ['rgb', 0, 0, 0, 0]; + setCache(cacheKey, res); + return res; +}; + +/** + * resolve invalid color value + * @param format - output format + * @param nullable - is nullable + * @returns resolved value + */ +export const resolveInvalidColorValue = ( + format: string, + nullable: boolean = false +): SpecifiedColorChannels | string | NullObject => { + switch (format) { + case 'hsl': + case 'hwb': + case VAL_MIX: { + return new NullObject(); + } + case VAL_SPEC: { + return ''; + } + default: { + if (nullable) { + return new NullObject(); + } + return ['rgb', 0, 0, 0, 0] as SpecifiedColorChannels; + } + } +}; + +/** + * validate color components + * @param arr - color components + * @param [opt] - options + * @param [opt.alpha] - alpha channel + * @param [opt.minLength] - min length + * @param [opt.maxLength] - max length + * @param [opt.minRange] - min range + * @param [opt.maxRange] - max range + * @param [opt.validateRange] - validate range + * @returns result - validated color components + */ +export const validateColorComponents = ( + arr: ColorChannels | TriColorChannels, + opt: { + alpha?: boolean; + minLength?: number; + maxLength?: number; + minRange?: number; + maxRange?: number; + validateRange?: boolean; + } = {} +): ColorChannels | TriColorChannels => { + if (!Array.isArray(arr)) { + throw new TypeError(`${arr} is not an array.`); + } + const { + alpha = false, + minLength = TRIA, + maxLength = QUAD, + minRange = 0, + maxRange = 1, + validateRange = true + } = opt; + if (!Number.isFinite(minLength)) { + throw new TypeError(`${minLength} is not a number.`); + } + if (!Number.isFinite(maxLength)) { + throw new TypeError(`${maxLength} is not a number.`); + } + if (!Number.isFinite(minRange)) { + throw new TypeError(`${minRange} is not a number.`); + } + if (!Number.isFinite(maxRange)) { + throw new TypeError(`${maxRange} is not a number.`); + } + const l = arr.length; + if (l < minLength || l > maxLength) { + throw new Error(`Unexpected array length ${l}.`); + } + let i = 0; + while (i < l) { + const v = arr[i] as number; + if (!Number.isFinite(v)) { + throw new TypeError(`${v} is not a number.`); + } else if (i < TRIA && validateRange && (v < minRange || v > maxRange)) { + throw new RangeError(`${v} is not between ${minRange} and ${maxRange}.`); + } else if (i === TRIA && (v < 0 || v > 1)) { + throw new RangeError(`${v} is not between 0 and 1.`); + } + i++; + } + if (alpha && l === TRIA) { + arr.push(1); + } + return arr; +}; + +/** + * transform matrix + * @param mtx - 3 * 3 matrix + * @param vct - vector + * @param [skip] - skip validate + * @returns TriColorChannels - [p1, p2, p3] + */ +export const transformMatrix = ( + mtx: ColorMatrix, + vct: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + if (!Array.isArray(mtx)) { + throw new TypeError(`${mtx} is not an array.`); + } else if (mtx.length !== TRIA) { + throw new Error(`Unexpected array length ${mtx.length}.`); + } else if (!skip) { + for (let i of mtx) { + i = validateColorComponents(i as TriColorChannels, { + maxLength: TRIA, + validateRange: false + }) as TriColorChannels; + } + } + const [[r1c1, r1c2, r1c3], [r2c1, r2c2, r2c3], [r3c1, r3c2, r3c3]] = mtx; + let v1, v2, v3; + if (skip) { + [v1, v2, v3] = vct; + } else { + [v1, v2, v3] = validateColorComponents(vct, { + maxLength: TRIA, + validateRange: false + }); + } + const p1 = r1c1 * v1 + r1c2 * v2 + r1c3 * v3; + const p2 = r2c1 * v1 + r2c2 * v2 + r2c3 * v3; + const p3 = r3c1 * v1 + r3c2 * v2 + r3c3 * v3; + return [p1, p2, p3]; +}; + +/** + * normalize color components + * @param colorA - color components [v1, v2, v3, v4] + * @param colorB - color components [v1, v2, v3, v4] + * @param [skip] - skip validate + * @returns result - [colorA, colorB] + */ +export const normalizeColorComponents = ( + colorA: [number | string, number | string, number | string, number | string], + colorB: [number | string, number | string, number | string, number | string], + skip: boolean = false +): [ColorChannels, ColorChannels] => { + if (!Array.isArray(colorA)) { + throw new TypeError(`${colorA} is not an array.`); + } else if (colorA.length !== QUAD) { + throw new Error(`Unexpected array length ${colorA.length}.`); + } + if (!Array.isArray(colorB)) { + throw new TypeError(`${colorB} is not an array.`); + } else if (colorB.length !== QUAD) { + throw new Error(`Unexpected array length ${colorB.length}.`); + } + let i = 0; + while (i < QUAD) { + if (colorA[i] === NONE && colorB[i] === NONE) { + colorA[i] = 0; + colorB[i] = 0; + } else if (colorA[i] === NONE) { + colorA[i] = colorB[i] as number; + } else if (colorB[i] === NONE) { + colorB[i] = colorA[i] as number; + } + i++; + } + if (skip) { + return [colorA as ColorChannels, colorB as ColorChannels]; + } + const validatedColorA = validateColorComponents(colorA as ColorChannels, { + minLength: QUAD, + validateRange: false + }); + const validatedColorB = validateColorComponents(colorB as ColorChannels, { + minLength: QUAD, + validateRange: false + }); + return [validatedColorA as ColorChannels, validatedColorB as ColorChannels]; +}; + +/** + * number to hex string + * @param value - numeric value + * @returns hex string + */ +export const numberToHexString = (value: number): string => { + if (!Number.isFinite(value)) { + throw new TypeError(`${value} is not a number.`); + } else { + value = Math.round(value); + if (value < 0 || value > MAX_RGB) { + throw new RangeError(`${value} is not between 0 and ${MAX_RGB}.`); + } + } + let hex = value.toString(HEX); + if (hex.length === 1) { + hex = `0${hex}`; + } + return hex; +}; + +/** + * angle to deg + * @param angle + * @returns deg: 0..360 + */ +export const angleToDeg = (angle: string): number => { + if (isString(angle)) { + angle = angle.trim(); + } else { + throw new TypeError(`${angle} is not a string.`); + } + const GRAD = DEG / 400; + const RAD = DEG / (Math.PI * DUO); + if (!REG_ANGLE_TO_DEG.test(angle)) { + throw new SyntaxError(`Invalid property value: ${angle}`); + } + const [, value, unit] = angle.match(REG_ANGLE_TO_DEG) as MatchedRegExp; + let deg; + switch (unit) { + case 'grad': + deg = parseFloat(value) * GRAD; + break; + case 'rad': + deg = parseFloat(value) * RAD; + break; + case 'turn': + deg = parseFloat(value) * DEG; + break; + default: + deg = parseFloat(value); + } + deg %= DEG; + if (deg < 0) { + deg += DEG; + } else if (Object.is(deg, -0)) { + deg = 0; + } + return deg; +}; + +/** + * parse alpha + * @param [alpha] - alpha value + * @returns alpha: 0..1 + */ +export const parseAlpha = (alpha: string = ''): number => { + if (isString(alpha)) { + alpha = alpha.trim(); + if (!alpha) { + alpha = '1'; + } else if (alpha === NONE) { + alpha = '0'; + } else { + let a; + if (alpha.endsWith('%')) { + a = parseFloat(alpha) / MAX_PCT; + } else { + a = parseFloat(alpha); + } + if (!Number.isFinite(a)) { + throw new TypeError(`${a} is not a finite number.`); + } + if (a < PPTH) { + alpha = '0'; + } else if (a > 1) { + alpha = '1'; + } else { + alpha = a.toFixed(TRIA); + } + } + } else { + alpha = '1'; + } + return parseFloat(alpha); +}; + +/** + * parse hex alpha + * @param value - alpha value in hex string + * @returns alpha: 0..1 + */ +export const parseHexAlpha = (value: string): number => { + if (isString(value)) { + if (value === '') { + throw new SyntaxError('Invalid property value: (empty string)'); + } + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + let alpha = parseInt(value, HEX); + if (alpha <= 0) { + return 0; + } + if (alpha >= MAX_RGB) { + return 1; + } + const alphaMap = new Map(); + for (let i = 1; i < MAX_PCT; i++) { + alphaMap.set(Math.round((i * MAX_RGB) / MAX_PCT), i); + } + if (alphaMap.has(alpha)) { + alpha = alphaMap.get(alpha) / MAX_PCT; + } else { + alpha = Math.round(alpha / MAX_RGB / PPTH) * PPTH; + } + return parseFloat(alpha.toFixed(TRIA)); +}; + +/** + * transform rgb to linear rgb + * @param rgb - [r, g, b] r|g|b: 0..255 + * @param [skip] - skip validate + * @returns TriColorChannels - [r, g, b] r|g|b: 0..1 + */ +export const transformRgbToLinearRgb = ( + rgb: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + let rr, gg, bb; + if (skip) { + [rr, gg, bb] = rgb; + } else { + [rr, gg, bb] = validateColorComponents(rgb, { + maxLength: TRIA, + maxRange: MAX_RGB + }); + } + let r = rr / MAX_RGB; + let g = gg / MAX_RGB; + let b = bb / MAX_RGB; + const COND_POW = 0.04045; + if (r > COND_POW) { + r = Math.pow((r + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR); + } else { + r /= LINEAR_COEF; + } + if (g > COND_POW) { + g = Math.pow((g + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR); + } else { + g /= LINEAR_COEF; + } + if (b > COND_POW) { + b = Math.pow((b + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR); + } else { + b /= LINEAR_COEF; + } + return [r, g, b]; +}; + +/** + * transform rgb to xyz + * @param rgb - [r, g, b] r|g|b: 0..255 + * @param [skip] - skip validate + * @returns TriColorChannels - [x, y, z] + */ +export const transformRgbToXyz = ( + rgb: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + if (!skip) { + rgb = validateColorComponents(rgb, { + maxLength: TRIA, + maxRange: MAX_RGB + }) as TriColorChannels; + } + rgb = transformRgbToLinearRgb(rgb, true); + const xyz = transformMatrix(MATRIX_L_RGB_TO_XYZ, rgb, true); + return xyz; +}; + +/** + * transform rgb to xyz-d50 + * @param rgb - [r, g, b] r|g|b: 0..255 alpha: 0..1 + * @returns TriColorChannels - [x, y, z] + */ +export const transformRgbToXyzD50 = ( + rgb: TriColorChannels +): TriColorChannels => { + let xyz = transformRgbToXyz(rgb); + xyz = transformMatrix(MATRIX_D65_TO_D50, xyz, true); + return xyz; +}; + +/** + * transform linear rgb to rgb + * @param rgb - [r, g, b] r|g|b: 0..1 + * @param [round] - round result + * @returns TriColorChannels - [r, g, b] r|g|b: 0..255 + */ +export const transformLinearRgbToRgb = ( + rgb: TriColorChannels, + round: boolean = false +): TriColorChannels => { + let [r, g, b] = validateColorComponents(rgb, { + maxLength: TRIA + }); + const COND_POW = 809 / 258400; + if (r > COND_POW) { + r = Math.pow(r, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET; + } else { + r *= LINEAR_COEF; + } + r *= MAX_RGB; + if (g > COND_POW) { + g = Math.pow(g, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET; + } else { + g *= LINEAR_COEF; + } + g *= MAX_RGB; + if (b > COND_POW) { + b = Math.pow(b, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET; + } else { + b *= LINEAR_COEF; + } + b *= MAX_RGB; + return [ + round ? Math.round(r) : r, + round ? Math.round(g) : g, + round ? Math.round(b) : b + ]; +}; + +/** + * transform xyz to rgb + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [r, g, b] r|g|b: 0..255 + */ +export const transformXyzToRgb = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + if (!skip) { + xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }) as TriColorChannels; + } + let [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, xyz, true); + [r, g, b] = transformLinearRgbToRgb( + [ + Math.min(Math.max(r, 0), 1), + Math.min(Math.max(g, 0), 1), + Math.min(Math.max(b, 0), 1) + ], + true + ); + return [r, g, b]; +}; + +/** + * transform xyz to xyz-d50 + * @param xyz - [x, y, z] + * @returns TriColorChannels - [x, y, z] + */ +export const transformXyzToXyzD50 = ( + xyz: TriColorChannels +): TriColorChannels => { + xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }) as TriColorChannels; + xyz = transformMatrix(MATRIX_D65_TO_D50, xyz, true); + return xyz; +}; + +/** + * transform xyz to hsl + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [h, s, l] + */ +export const transformXyzToHsl = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + const [rr, gg, bb] = transformXyzToRgb(xyz, skip); + const r = rr / MAX_RGB; + const g = gg / MAX_RGB; + const b = bb / MAX_RGB; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const d = max - min; + const l = (max + min) * HALF * MAX_PCT; + let h, s; + if (Math.round(l) === 0 || Math.round(l) === MAX_PCT) { + h = 0; + s = 0; + } else { + s = (d / (1 - Math.abs(max + min - 1))) * MAX_PCT; + if (s === 0) { + h = 0; + } else { + switch (max) { + case r: + h = (g - b) / d; + break; + case g: + h = (b - r) / d + DUO; + break; + case b: + default: + h = (r - g) / d + QUAD; + break; + } + h = (h * SEXA) % DEG; + if (h < 0) { + h += DEG; + } + } + } + return [h, s, l]; +}; + +/** + * transform xyz to hwb + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [h, w, b] + */ +export const transformXyzToHwb = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + const [r, g, b] = transformXyzToRgb(xyz, skip); + const wh = Math.min(r, g, b) / MAX_RGB; + const bk = 1 - Math.max(r, g, b) / MAX_RGB; + let h; + if (wh + bk === 1) { + h = 0; + } else { + [h] = transformXyzToHsl(xyz); + } + return [h, wh * MAX_PCT, bk * MAX_PCT]; +}; + +/** + * transform xyz to oklab + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, a, b] + */ +export const transformXyzToOklab = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + if (!skip) { + xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }) as TriColorChannels; + } + const lms = transformMatrix(MATRIX_XYZ_TO_LMS, xyz, true); + const xyzLms = lms.map(c => Math.cbrt(c)) as TriColorChannels; + let [l, a, b] = transformMatrix(MATRIX_LMS_TO_OKLAB, xyzLms, true); + l = Math.min(Math.max(l, 0), 1); + const lPct = Math.round(parseFloat(l.toFixed(QUAD)) * MAX_PCT); + if (lPct === 0 || lPct === MAX_PCT) { + a = 0; + b = 0; + } + return [l, a, b]; +}; + +/** + * transform xyz to oklch + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, c, h] + */ +export const transformXyzToOklch = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + const [l, a, b] = transformXyzToOklab(xyz, skip); + let c, h; + const lPct = Math.round(parseFloat(l.toFixed(QUAD)) * MAX_PCT); + if (lPct === 0 || lPct === MAX_PCT) { + c = 0; + h = 0; + } else { + c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0); + if (parseFloat(c.toFixed(QUAD)) === 0) { + h = 0; + } else { + h = (Math.atan2(b, a) * DEG_HALF) / Math.PI; + if (h < 0) { + h += DEG; + } + } + } + return [l, c, h]; +}; + +/** + * transform xyz D50 to rgb + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [r, g, b] r|g|b: 0..255 + */ +export const transformXyzD50ToRgb = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + if (!skip) { + xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }) as TriColorChannels; + } + const xyzD65 = transformMatrix(MATRIX_D50_TO_D65, xyz, true); + const rgb = transformXyzToRgb(xyzD65, true); + return rgb; +}; + +/** + * transform xyz-d50 to lab + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, a, b] + */ +export const transformXyzD50ToLab = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + if (!skip) { + xyz = validateColorComponents(xyz, { + maxLength: TRIA, + validateRange: false + }) as TriColorChannels; + } + const xyzD50 = xyz.map((val, i) => val / (D50[i] as number)); + const [f0, f1, f2] = xyzD50.map(val => + val > LAB_EPSILON ? Math.cbrt(val) : (val * LAB_KAPPA + HEX) / LAB_L + ) as TriColorChannels; + const l = Math.min(Math.max(LAB_L * f1 - HEX, 0), MAX_PCT); + let a, b; + if (l === 0 || l === MAX_PCT) { + a = 0; + b = 0; + } else { + a = (f0 - f1) * LAB_A; + b = (f1 - f2) * LAB_B; + } + return [l, a, b]; +}; + +/** + * transform xyz-d50 to lch + * @param xyz - [x, y, z] + * @param [skip] - skip validate + * @returns TriColorChannels - [l, c, h] + */ +export const transformXyzD50ToLch = ( + xyz: TriColorChannels, + skip: boolean = false +): TriColorChannels => { + const [l, a, b] = transformXyzD50ToLab(xyz, skip); + let c, h; + if (l === 0 || l === MAX_PCT) { + c = 0; + h = 0; + } else { + c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0); + h = (Math.atan2(b, a) * DEG_HALF) / Math.PI; + if (h < 0) { + h += DEG; + } + } + return [l, c, h]; +}; + +/** + * convert rgb to hex color + * @param rgb - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 + * @returns hex color + */ +export const convertRgbToHex = (rgb: ColorChannels): string => { + const [r, g, b, alpha] = validateColorComponents(rgb, { + alpha: true, + maxRange: MAX_RGB + }) as ColorChannels; + const rr = numberToHexString(r); + const gg = numberToHexString(g); + const bb = numberToHexString(b); + const aa = numberToHexString(alpha * MAX_RGB); + let hex; + if (aa === 'ff') { + hex = `#${rr}${gg}${bb}`; + } else { + hex = `#${rr}${gg}${bb}${aa}`; + } + return hex; +}; + +/** + * convert linear rgb to hex color + * @param rgb - [r, g, b, alpha] r|g|b|alpha: 0..1 + * @param [skip] - skip validate + * @returns hex color + */ +export const convertLinearRgbToHex = ( + rgb: ColorChannels, + skip: boolean = false +): string => { + let r, g, b, alpha; + if (skip) { + [r, g, b, alpha] = rgb; + } else { + [r, g, b, alpha] = validateColorComponents(rgb, { + minLength: QUAD + }) as ColorChannels; + } + [r, g, b] = transformLinearRgbToRgb([r, g, b], true); + const rr = numberToHexString(r); + const gg = numberToHexString(g); + const bb = numberToHexString(b); + const aa = numberToHexString(alpha * MAX_RGB); + let hex; + if (aa === 'ff') { + hex = `#${rr}${gg}${bb}`; + } else { + hex = `#${rr}${gg}${bb}${aa}`; + } + return hex; +}; + +/** + * convert xyz to hex color + * @param xyz - [x, y, z, alpha] + * @returns hex color + */ +export const convertXyzToHex = (xyz: ColorChannels): string => { + const [x, y, z, alpha] = validateColorComponents(xyz, { + minLength: QUAD, + validateRange: false + }) as ColorChannels; + const [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true); + const hex = convertLinearRgbToHex( + [ + Math.min(Math.max(r, 0), 1), + Math.min(Math.max(g, 0), 1), + Math.min(Math.max(b, 0), 1), + alpha + ], + true + ); + return hex; +}; + +/** + * convert xyz D50 to hex color + * @param xyz - [x, y, z, alpha] + * @returns hex color + */ +export const convertXyzD50ToHex = (xyz: ColorChannels): string => { + const [x, y, z, alpha] = validateColorComponents(xyz, { + minLength: QUAD, + validateRange: false + }) as ColorChannels; + const xyzD65 = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true); + const [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, xyzD65, true); + const hex = convertLinearRgbToHex([ + Math.min(Math.max(r, 0), 1), + Math.min(Math.max(g, 0), 1), + Math.min(Math.max(b, 0), 1), + alpha + ]); + return hex; +}; + +/** + * convert hex color to rgb + * @param value - hex color value + * @returns ColorChannels - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 + */ +export const convertHexToRgb = (value: string): ColorChannels => { + if (isString(value)) { + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + if ( + !( + /^#[\da-f]{6}$/.test(value) || + /^#[\da-f]{3}$/.test(value) || + /^#[\da-f]{8}$/.test(value) || + /^#[\da-f]{4}$/.test(value) + ) + ) { + throw new SyntaxError(`Invalid property value: ${value}`); + } + const arr: number[] = []; + if (/^#[\da-f]{3}$/.test(value)) { + const [, r, g, b] = value.match( + /^#([\da-f])([\da-f])([\da-f])$/ + ) as MatchedRegExp; + arr.push( + parseInt(`${r}${r}`, HEX), + parseInt(`${g}${g}`, HEX), + parseInt(`${b}${b}`, HEX), + 1 + ); + } else if (/^#[\da-f]{4}$/.test(value)) { + const [, r, g, b, alpha] = value.match( + /^#([\da-f])([\da-f])([\da-f])([\da-f])$/ + ) as MatchedRegExp; + arr.push( + parseInt(`${r}${r}`, HEX), + parseInt(`${g}${g}`, HEX), + parseInt(`${b}${b}`, HEX), + parseHexAlpha(`${alpha}${alpha}`) + ); + } else if (/^#[\da-f]{8}$/.test(value)) { + const [, r, g, b, alpha] = value.match( + /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})$/ + ) as MatchedRegExp; + arr.push( + parseInt(r, HEX), + parseInt(g, HEX), + parseInt(b, HEX), + parseHexAlpha(alpha) + ); + } else { + const [, r, g, b] = value.match( + /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/ + ) as MatchedRegExp; + arr.push(parseInt(r, HEX), parseInt(g, HEX), parseInt(b, HEX), 1); + } + return arr as ColorChannels; +}; + +/** + * convert hex color to linear rgb + * @param value - hex color value + * @returns ColorChannels - [r, g, b, alpha] r|g|b|alpha: 0..1 + */ +export const convertHexToLinearRgb = (value: string): ColorChannels => { + const [rr, gg, bb, alpha] = convertHexToRgb(value); + const [r, g, b] = transformRgbToLinearRgb([rr, gg, bb], true); + return [r, g, b, alpha]; +}; + +/** + * convert hex color to xyz + * @param value - hex color value + * @returns ColorChannels - [x, y, z, alpha] + */ +export const convertHexToXyz = (value: string): ColorChannels => { + const [r, g, b, alpha] = convertHexToLinearRgb(value); + const [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [r, g, b], true); + return [x, y, z, alpha]; +}; + +/** + * parse rgb() + * @param value - rgb color value + * @param [opt] - options + * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject + */ +export const parseRgb = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_PARSE_RGB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const [, val] = value.match(REG_PARSE_RGB) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let r, g, b; + if (v1 === NONE) { + r = 0; + } else { + if (v1.endsWith('%')) { + r = (parseFloat(v1) * MAX_RGB) / MAX_PCT; + } else { + r = parseFloat(v1); + } + r = Math.min(Math.max(roundToPrecision(r, OCT), 0), MAX_RGB); + } + if (v2 === NONE) { + g = 0; + } else { + if (v2.endsWith('%')) { + g = (parseFloat(v2) * MAX_RGB) / MAX_PCT; + } else { + g = parseFloat(v2); + } + g = Math.min(Math.max(roundToPrecision(g, OCT), 0), MAX_RGB); + } + if (v3 === NONE) { + b = 0; + } else { + if (v3.endsWith('%')) { + b = (parseFloat(v3) * MAX_RGB) / MAX_PCT; + } else { + b = parseFloat(v3); + } + b = Math.min(Math.max(roundToPrecision(b, OCT), 0), MAX_RGB); + } + const alpha = parseAlpha(v4); + return ['rgb', r, g, b, format === VAL_MIX && v4 === NONE ? NONE : alpha]; +}; + +/** + * parse hsl() + * @param value - hsl color value + * @param [opt] - options + * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject + */ +export const parseHsl = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_HSL.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const [, val] = value.match(REG_HSL) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let h, s, l; + if (v1 === NONE) { + h = 0; + } else { + h = angleToDeg(v1); + } + if (v2 === NONE) { + s = 0; + } else { + s = Math.min(Math.max(parseFloat(v2), 0), MAX_PCT); + } + if (v3 === NONE) { + l = 0; + } else { + l = Math.min(Math.max(parseFloat(v3), 0), MAX_PCT); + } + const alpha = parseAlpha(v4); + if (format === 'hsl') { + return [ + format, + v1 === NONE ? v1 : h, + v2 === NONE ? v2 : s, + v3 === NONE ? v3 : l, + v4 === NONE ? v4 : alpha + ]; + } + h = (h / DEG) * DOZ; + l /= MAX_PCT; + const sa = (s / MAX_PCT) * Math.min(l, 1 - l); + const rk = h % DOZ; + const gk = (8 + h) % DOZ; + const bk = (4 + h) % DOZ; + const r = l - sa * Math.max(-1, Math.min(rk - TRIA, TRIA ** POW_SQR - rk, 1)); + const g = l - sa * Math.max(-1, Math.min(gk - TRIA, TRIA ** POW_SQR - gk, 1)); + const b = l - sa * Math.max(-1, Math.min(bk - TRIA, TRIA ** POW_SQR - bk, 1)); + return [ + 'rgb', + Math.min(Math.max(roundToPrecision(r * MAX_RGB, OCT), 0), MAX_RGB), + Math.min(Math.max(roundToPrecision(g * MAX_RGB, OCT), 0), MAX_RGB), + Math.min(Math.max(roundToPrecision(b * MAX_RGB, OCT), 0), MAX_RGB), + alpha + ]; +}; + +/** + * parse hwb() + * @param value - hwb color value + * @param [opt] - options + * @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject + */ +export const parseHwb = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_HWB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const [, val] = value.match(REG_HWB) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let h, wh, bk; + if (v1 === NONE) { + h = 0; + } else { + h = angleToDeg(v1); + } + if (v2 === NONE) { + wh = 0; + } else { + wh = Math.min(Math.max(parseFloat(v2), 0), MAX_PCT) / MAX_PCT; + } + if (v3 === NONE) { + bk = 0; + } else { + bk = Math.min(Math.max(parseFloat(v3), 0), MAX_PCT) / MAX_PCT; + } + const alpha = parseAlpha(v4); + if (format === 'hwb') { + return [ + format, + v1 === NONE ? v1 : h, + v2 === NONE ? v2 : wh * MAX_PCT, + v3 === NONE ? v3 : bk * MAX_PCT, + v4 === NONE ? v4 : alpha + ]; + } + if (wh + bk >= 1) { + const v = roundToPrecision((wh / (wh + bk)) * MAX_RGB, OCT); + return ['rgb', v, v, v, alpha]; + } + const factor = (1 - wh - bk) / MAX_RGB; + let [, r, g, b] = parseHsl(`hsl(${h} 100 50)`) as ComputedColorChannels; + r = roundToPrecision((r * factor + wh) * MAX_RGB, OCT); + g = roundToPrecision((g * factor + wh) * MAX_RGB, OCT); + b = roundToPrecision((b * factor + wh) * MAX_RGB, OCT); + return [ + 'rgb', + Math.min(Math.max(r, 0), MAX_RGB), + Math.min(Math.max(g, 0), MAX_RGB), + Math.min(Math.max(b, 0), MAX_RGB), + alpha + ]; +}; + +/** + * parse lab() + * @param value - lab color value + * @param [opt] - options + * @returns parsed color + * - [xyz-d50, x, y, z, alpha], ['lab', l, a, b, alpha], '(empty)', NullObject + */ +export const parseLab = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_LAB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const COEF_PCT = 1.25; + const COND_POW = 8; + const [, val] = value.match(REG_LAB) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let l, a, b; + if (v1 === NONE) { + l = 0; + } else { + if (v1.endsWith('%')) { + l = parseFloat(v1); + if (l > MAX_PCT) { + l = MAX_PCT; + } + } else { + l = parseFloat(v1); + } + if (l < 0) { + l = 0; + } + } + if (v2 === NONE) { + a = 0; + } else { + a = v2.endsWith('%') ? parseFloat(v2) * COEF_PCT : parseFloat(v2); + } + if (v3 === NONE) { + b = 0; + } else { + b = v3.endsWith('%') ? parseFloat(v3) * COEF_PCT : parseFloat(v3); + } + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) { + return [ + 'lab', + v1 === NONE ? v1 : roundToPrecision(l, HEX), + v2 === NONE ? v2 : roundToPrecision(a, HEX), + v3 === NONE ? v3 : roundToPrecision(b, HEX), + v4 === NONE ? v4 : alpha + ]; + } + const fl = (l + HEX) / LAB_L; + const fa = a / LAB_A + fl; + const fb = fl - b / LAB_B; + const powFl = Math.pow(fl, POW_CUBE); + const powFa = Math.pow(fa, POW_CUBE); + const powFb = Math.pow(fb, POW_CUBE); + const xyz = [ + powFa > LAB_EPSILON ? powFa : (fa * LAB_L - HEX) / LAB_KAPPA, + l > COND_POW ? powFl : l / LAB_KAPPA, + powFb > LAB_EPSILON ? powFb : (fb * LAB_L - HEX) / LAB_KAPPA + ]; + const [x, y, z] = xyz.map( + (val, i) => val * (D50[i] as number) + ) as TriColorChannels; + return [ + 'xyz-d50', + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; + +/** + * parse lch() + * @param value - lch color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-d50', x, y, z, alpha], ['lch', l, c, h, alpha] + * - '(empty)', NullObject + */ +export const parseLch = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_LCH.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const COEF_PCT = 1.5; + const [, val] = value.match(REG_LCH) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let l, c, h; + if (v1 === NONE) { + l = 0; + } else { + l = parseFloat(v1); + if (l < 0) { + l = 0; + } + } + if (v2 === NONE) { + c = 0; + } else { + c = v2.endsWith('%') ? parseFloat(v2) * COEF_PCT : parseFloat(v2); + } + if (v3 === NONE) { + h = 0; + } else { + h = angleToDeg(v3); + } + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) { + return [ + 'lch', + v1 === NONE ? v1 : roundToPrecision(l, HEX), + v2 === NONE ? v2 : roundToPrecision(c, HEX), + v3 === NONE ? v3 : roundToPrecision(h, HEX), + v4 === NONE ? v4 : alpha + ]; + } + const a = c * Math.cos((h * Math.PI) / DEG_HALF); + const b = c * Math.sin((h * Math.PI) / DEG_HALF); + const [, x, y, z] = parseLab(`lab(${l} ${a} ${b})`) as ComputedColorChannels; + return [ + 'xyz-d50', + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha as number + ]; +}; + +/** + * parse oklab() + * @param value - oklab color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-d65', x, y, z, alpha], ['oklab', l, a, b, alpha] + * - '(empty)', NullObject + */ +export const parseOklab = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_OKLAB.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const COEF_PCT = 0.4; + const [, val] = value.match(REG_OKLAB) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let l, a, b; + if (v1 === NONE) { + l = 0; + } else { + l = v1.endsWith('%') ? parseFloat(v1) / MAX_PCT : parseFloat(v1); + if (l < 0) { + l = 0; + } + } + if (v2 === NONE) { + a = 0; + } else if (v2.endsWith('%')) { + a = (parseFloat(v2) * COEF_PCT) / MAX_PCT; + } else { + a = parseFloat(v2); + } + if (v3 === NONE) { + b = 0; + } else if (v3.endsWith('%')) { + b = (parseFloat(v3) * COEF_PCT) / MAX_PCT; + } else { + b = parseFloat(v3); + } + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) { + return [ + 'oklab', + v1 === NONE ? v1 : roundToPrecision(l, HEX), + v2 === NONE ? v2 : roundToPrecision(a, HEX), + v3 === NONE ? v3 : roundToPrecision(b, HEX), + v4 === NONE ? v4 : alpha + ]; + } + const lms = transformMatrix(MATRIX_OKLAB_TO_LMS, [l, a, b]); + const xyzLms = lms.map(c => Math.pow(c, POW_CUBE)) as TriColorChannels; + const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, xyzLms, true); + return [ + 'xyz-d65', + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha as number + ]; +}; + +/** + * parse oklch() + * @param value - oklch color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-d65', x, y, z, alpha], ['oklch', l, c, h, alpha] + * - '(empty)', NullObject + */ +export const parseOklch = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + if (!REG_OKLCH.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const COEF_PCT = 0.4; + const [, val] = value.match(REG_OKLCH) as MatchedRegExp; + const [v1, v2, v3, v4 = ''] = val.match(/[^\s,/]+/g) as StringColorChannels; + let l, c, h; + if (v1 === NONE) { + l = 0; + } else { + l = v1.endsWith('%') ? parseFloat(v1) / MAX_PCT : parseFloat(v1); + if (l < 0) { + l = 0; + } + } + if (v2 === NONE) { + c = 0; + } else { + if (v2.endsWith('%')) { + c = (parseFloat(v2) * COEF_PCT) / MAX_PCT; + } else { + c = parseFloat(v2); + } + if (c < 0) { + c = 0; + } + } + if (v3 === NONE) { + h = 0; + } else { + h = angleToDeg(v3); + } + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format)) { + return [ + 'oklch', + v1 === NONE ? v1 : roundToPrecision(l, HEX), + v2 === NONE ? v2 : roundToPrecision(c, HEX), + v3 === NONE ? v3 : roundToPrecision(h, HEX), + v4 === NONE ? v4 : alpha + ]; + } + const a = c * Math.cos((h * Math.PI) / DEG_HALF); + const b = c * Math.sin((h * Math.PI) / DEG_HALF); + const lms = transformMatrix(MATRIX_OKLAB_TO_LMS, [l, a, b]); + const xyzLms = lms.map(cc => Math.pow(cc, POW_CUBE)) as TriColorChannels; + const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, xyzLms, true); + return [ + 'xyz-d65', + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; + +/** + * parse color() + * @param value - color function value + * @param [opt] - options + * @returns parsed color + * - ['xyz-(d50|d65)', x, y, z, alpha], [cs, r, g, b, alpha] + * - '(empty)', NullObject + */ +export const parseColorFunc = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { colorSpace = '', d50 = false, format = '', nullable = false } = opt; + if (!REG_FN_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp; + let [cs, v1, v2, v3, v4 = ''] = val.match( + /[^\s,/]+/g + ) as StringColorSpacedChannels; + let r, g, b; + if (cs === 'xyz') { + cs = 'xyz-d65'; + } + if (v1 === NONE) { + r = 0; + } else { + r = v1.endsWith('%') ? parseFloat(v1) / MAX_PCT : parseFloat(v1); + } + if (v2 === NONE) { + g = 0; + } else { + g = v2.endsWith('%') ? parseFloat(v2) / MAX_PCT : parseFloat(v2); + } + if (v3 === NONE) { + b = 0; + } else { + b = v3.endsWith('%') ? parseFloat(v3) / MAX_PCT : parseFloat(v3); + } + const alpha = parseAlpha(v4); + if (REG_SPEC.test(format) || (format === VAL_MIX && cs === colorSpace)) { + return [ + cs, + v1 === NONE ? v1 : roundToPrecision(r, DEC), + v2 === NONE ? v2 : roundToPrecision(g, DEC), + v3 === NONE ? v3 : roundToPrecision(b, DEC), + v4 === NONE ? v4 : alpha + ]; + } + let x = 0; + let y = 0; + let z = 0; + // srgb-linear + if (cs === 'srgb-linear') { + [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [r, g, b]); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // display-p3 + } else if (cs === 'display-p3') { + const linearRgb = transformRgbToLinearRgb([ + r * MAX_RGB, + g * MAX_RGB, + b * MAX_RGB + ]); + [x, y, z] = transformMatrix(MATRIX_P3_TO_XYZ, linearRgb); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // rec2020 + } else if (cs === 'rec2020') { + const ALPHA = 1.09929682680944; + const BETA = 0.018053968510807; + const REC_COEF = 0.45; + const rgb = [r, g, b].map(c => { + let cl; + if (c < BETA * REC_COEF * DEC) { + cl = c / (REC_COEF * DEC); + } else { + cl = Math.pow((c + ALPHA - 1) / ALPHA, 1 / REC_COEF); + } + return cl; + }) as TriColorChannels; + [x, y, z] = transformMatrix(MATRIX_REC2020_TO_XYZ, rgb); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // a98-rgb + } else if (cs === 'a98-rgb') { + const POW_A98 = 563 / 256; + const rgb = [r, g, b].map(c => { + const cl = Math.pow(c, POW_A98); + return cl; + }) as TriColorChannels; + [x, y, z] = transformMatrix(MATRIX_A98_TO_XYZ, rgb); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // prophoto-rgb + } else if (cs === 'prophoto-rgb') { + const POW_PROPHOTO = 1.8; + const rgb = [r, g, b].map(c => { + let cl; + if (c > 1 / (HEX * DUO)) { + cl = Math.pow(c, POW_PROPHOTO); + } else { + cl = c / HEX; + } + return cl; + }) as TriColorChannels; + [x, y, z] = transformMatrix(MATRIX_PROPHOTO_TO_XYZ_D50, rgb); + if (!d50) { + [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true); + } + // xyz, xyz-d50, xyz-d65 + } else if (/^xyz(?:-d(?:50|65))?$/.test(cs)) { + [x, y, z] = [r, g, b]; + if (cs === 'xyz-d50') { + if (!d50) { + [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z]); + } + } else if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // srgb + } else { + [x, y, z] = transformRgbToXyz([r * MAX_RGB, g * MAX_RGB, b * MAX_RGB]); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + } + return [ + d50 ? 'xyz-d50' : 'xyz-d65', + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + format === VAL_MIX && v4 === NONE ? v4 : alpha + ]; +}; + +/** + * parse color value + * @param value - CSS color value + * @param [opt] - options + * @returns parsed color + * - ['xyz-(d50|d65)', x, y, z, alpha], ['rgb', r, g, b, alpha] + * - value, '(empty)', NullObject + */ +export const parseColorValue = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { d50 = false, format = '', nullable = false } = opt; + if (!REG_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + return res; + } + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + let x = 0; + let y = 0; + let z = 0; + let alpha = 0; + // complement currentcolor as a missing color + if (REG_CURRENT.test(value)) { + if (format === VAL_COMP) { + return ['rgb', 0, 0, 0, 0]; + } + if (format === VAL_SPEC) { + return value; + } + // named-color + } else if (/^[a-z]+$/.test(value)) { + if (Object.hasOwn(NAMED_COLORS, value)) { + if (format === VAL_SPEC) { + return value; + } + const [r, g, b] = NAMED_COLORS[ + value as keyof typeof NAMED_COLORS + ] as TriColorChannels; + alpha = 1; + if (format === VAL_COMP) { + return ['rgb', r, g, b, alpha]; + } + [x, y, z] = transformRgbToXyz([r, g, b], true); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + } else { + switch (format) { + case VAL_COMP: { + if (nullable && value !== 'transparent') { + return new NullObject(); + } + return ['rgb', 0, 0, 0, 0]; + } + case VAL_SPEC: { + if (value === 'transparent') { + return value; + } + return ''; + } + case VAL_MIX: { + if (value === 'transparent') { + return ['rgb', 0, 0, 0, 0]; + } + return new NullObject(); + } + default: + } + } + // hex-color + } else if (value[0] === '#') { + if (REG_SPEC.test(format)) { + const rgb = convertHexToRgb(value); + return ['rgb', ...rgb]; + } + [x, y, z, alpha] = convertHexToXyz(value); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // lab() + } else if (value.startsWith('lab')) { + if (REG_SPEC.test(format)) { + return parseLab(value, opt); + } + [, x, y, z, alpha] = parseLab(value) as ComputedColorChannels; + if (!d50) { + [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true); + } + // lch() + } else if (value.startsWith('lch')) { + if (REG_SPEC.test(format)) { + return parseLch(value, opt); + } + [, x, y, z, alpha] = parseLch(value) as ComputedColorChannels; + if (!d50) { + [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true); + } + // oklab() + } else if (value.startsWith('oklab')) { + if (REG_SPEC.test(format)) { + return parseOklab(value, opt); + } + [, x, y, z, alpha] = parseOklab(value) as ComputedColorChannels; + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + // oklch() + } else if (value.startsWith('oklch')) { + if (REG_SPEC.test(format)) { + return parseOklch(value, opt); + } + [, x, y, z, alpha] = parseOklch(value) as ComputedColorChannels; + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + } else { + let r, g, b; + // hsl() + if (value.startsWith('hsl')) { + [, r, g, b, alpha] = parseHsl(value) as ComputedColorChannels; + // hwb() + } else if (value.startsWith('hwb')) { + [, r, g, b, alpha] = parseHwb(value) as ComputedColorChannels; + // rgb() + } else { + [, r, g, b, alpha] = parseRgb(value, opt) as ComputedColorChannels; + } + if (REG_SPEC.test(format)) { + return ['rgb', Math.round(r), Math.round(g), Math.round(b), alpha]; + } + [x, y, z] = transformRgbToXyz([r, g, b]); + if (d50) { + [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true); + } + } + return [ + d50 ? 'xyz-d50' : 'xyz-d65', + roundToPrecision(x, HEX), + roundToPrecision(y, HEX), + roundToPrecision(z, HEX), + alpha + ]; +}; + +/** + * resolve color value + * @param value - CSS color value + * @param [opt] - options + * @returns resolved color + * - [cs, v1, v2, v3, alpha], value, '(empty)', NullObject + */ +export const resolveColorValue = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { colorSpace = '', format = '', nullable = false } = opt; + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'resolveColorValue', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + const cachedItem = cachedResult.item; + if (isString(cachedItem)) { + return cachedItem as string; + } + return cachedItem as SpecifiedColorChannels; + } + if (!REG_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + setCache(cacheKey, null); + return res; + } + setCache(cacheKey, res); + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + let cs = ''; + let r = 0; + let g = 0; + let b = 0; + let alpha = 0; + // complement currentcolor as a missing color + if (REG_CURRENT.test(value)) { + if (format === VAL_SPEC) { + setCache(cacheKey, value); + return value; + } + // named-color + } else if (/^[a-z]+$/.test(value)) { + if (Object.hasOwn(NAMED_COLORS, value)) { + if (format === VAL_SPEC) { + setCache(cacheKey, value); + return value; + } + [r, g, b] = NAMED_COLORS[ + value as keyof typeof NAMED_COLORS + ] as TriColorChannels; + alpha = 1; + } else { + switch (format) { + case VAL_SPEC: { + if (value === 'transparent') { + setCache(cacheKey, value); + return value; + } + const res = ''; + setCache(cacheKey, res); + return res; + } + case VAL_MIX: { + if (value === 'transparent') { + const res: SpecifiedColorChannels = ['rgb', 0, 0, 0, 0]; + setCache(cacheKey, res); + return res; + } + setCache(cacheKey, null); + return new NullObject(); + } + case VAL_COMP: + default: { + if (nullable && value !== 'transparent') { + setCache(cacheKey, null); + return new NullObject(); + } + const res: SpecifiedColorChannels = ['rgb', 0, 0, 0, 0]; + setCache(cacheKey, res); + return res; + } + } + } + // hex-color + } else if (value[0] === '#') { + [r, g, b, alpha] = convertHexToRgb(value); + // hsl() + } else if (value.startsWith('hsl')) { + [, r, g, b, alpha] = parseHsl(value, opt) as ComputedColorChannels; + // hwb() + } else if (value.startsWith('hwb')) { + [, r, g, b, alpha] = parseHwb(value, opt) as ComputedColorChannels; + // lab(), lch() + } else if (/^l(?:ab|ch)/.test(value)) { + let x, y, z; + if (value.startsWith('lab')) { + [cs, x, y, z, alpha] = parseLab(value, opt) as ComputedColorChannels; + } else { + [cs, x, y, z, alpha] = parseLch(value, opt) as ComputedColorChannels; + } + if (REG_SPEC.test(format)) { + const res: SpecifiedColorChannels = [cs, x, y, z, alpha]; + setCache(cacheKey, res); + return res; + } + [r, g, b] = transformXyzD50ToRgb([x, y, z]); + // oklab(), oklch() + } else if (/^okl(?:ab|ch)/.test(value)) { + let x, y, z; + if (value.startsWith('oklab')) { + [cs, x, y, z, alpha] = parseOklab(value, opt) as ComputedColorChannels; + } else { + [cs, x, y, z, alpha] = parseOklch(value, opt) as ComputedColorChannels; + } + if (REG_SPEC.test(format)) { + const res: SpecifiedColorChannels = [cs, x, y, z, alpha]; + setCache(cacheKey, res); + return res; + } + [r, g, b] = transformXyzToRgb([x, y, z]); + // rgb() + } else { + [, r, g, b, alpha] = parseRgb(value, opt) as ComputedColorChannels; + } + if (format === VAL_MIX && colorSpace === 'srgb') { + const res: SpecifiedColorChannels = [ + 'srgb', + r / MAX_RGB, + g / MAX_RGB, + b / MAX_RGB, + alpha + ]; + setCache(cacheKey, res); + return res; + } + const res: SpecifiedColorChannels = [ + 'rgb', + Math.round(r), + Math.round(g), + Math.round(b), + alpha + ]; + setCache(cacheKey, res); + return res; +}; + +/** + * resolve color() + * @param value - color function value + * @param [opt] - options + * @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', NullObject + */ +export const resolveColorFunc = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { colorSpace = '', format = '', nullable = false } = opt; + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'resolveColorFunc', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + const cachedItem = cachedResult.item; + if (isString(cachedItem)) { + return cachedItem as string; + } + return cachedItem as SpecifiedColorChannels; + } + if (!REG_FN_COLOR.test(value)) { + const res = resolveInvalidColorValue(format, nullable); + if (res instanceof NullObject) { + setCache(cacheKey, null); + return res; + } + setCache(cacheKey, res); + if (isString(res)) { + return res as string; + } + return res as SpecifiedColorChannels; + } + const [cs, v1, v2, v3, v4] = parseColorFunc( + value, + opt + ) as SpecifiedColorChannels; + if (REG_SPEC.test(format) || (format === VAL_MIX && cs === colorSpace)) { + const res: SpecifiedColorChannels = [cs, v1, v2, v3, v4]; + setCache(cacheKey, res); + return res; + } + const x = parseFloat(`${v1}`); + const y = parseFloat(`${v2}`); + const z = parseFloat(`${v3}`); + const alpha = parseAlpha(`${v4}`); + const [r, g, b] = transformXyzToRgb([x, y, z], true); + const res: SpecifiedColorChannels = ['rgb', r, g, b, alpha]; + setCache(cacheKey, res); + return res; +}; + +/** + * convert color value to linear rgb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [r, g, b, alpha] r|g|b|alpha: 0..1 + */ +export const convertColorToLinearRgb = ( + value: string, + opt: { + colorSpace?: string; + format?: string; + } = {} +): ColorChannels | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { colorSpace = '', format = '' } = opt; + let cs = ''; + let r, g, b, alpha, x, y, z; + if (format === VAL_MIX) { + let xyz; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [cs, x, y, z, alpha] = xyz as ComputedColorChannels; + if (cs === colorSpace) { + return [x, y, z, alpha]; + } + [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true); + } else if (value.startsWith(FN_COLOR)) { + const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp; + const [cs] = val.match(/[^\s,/]+/g) as StringColorSpacedChannels; + if (cs === 'srgb-linear') { + [, r, g, b, alpha] = resolveColorFunc(value, { + format: VAL_COMP + }) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels; + [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true); + } + } else { + [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels; + [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true); + } + return [ + Math.min(Math.max(r, 0), 1), + Math.min(Math.max(g, 0), 1), + Math.min(Math.max(b, 0), 1), + alpha + ]; +}; + +/** + * convert color value to rgb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject + * - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1 + */ +export const convertColorToRgb = ( + value: string, + opt: Options = {} +): ColorChannels | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let r, g, b, alpha; + if (format === VAL_MIX) { + let rgb; + if (value.startsWith(FN_COLOR)) { + rgb = resolveColorFunc(value, opt); + } else { + rgb = resolveColorValue(value, opt); + } + if (rgb instanceof NullObject) { + return rgb; + } + [, r, g, b, alpha] = rgb as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp; + const [cs] = val.match(/[^\s,/]+/g) as StringColorSpacedChannels; + if (cs === 'srgb') { + [, r, g, b, alpha] = resolveColorFunc(value, { + format: VAL_COMP + }) as ComputedColorChannels; + r *= MAX_RGB; + g *= MAX_RGB; + b *= MAX_RGB; + } else { + [, r, g, b, alpha] = resolveColorFunc(value) as ComputedColorChannels; + } + } else if (/^(?:ok)?l(?:ab|ch)/.test(value)) { + [r, g, b, alpha] = convertColorToLinearRgb(value) as ColorChannels; + [r, g, b] = transformLinearRgbToRgb([r, g, b]); + } else { + [, r, g, b, alpha] = resolveColorValue(value, { + format: VAL_COMP + }) as ComputedColorChannels; + } + return [r, g, b, alpha]; +}; + +/** + * convert color value to xyz + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [x, y, z, alpha] + */ +export const convertColorToXyz = ( + value: string, + opt: Options = {} +): ColorChannels | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { d50 = false, format = '' } = opt; + let x, y, z, alpha; + if (format === VAL_MIX) { + let xyz; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + const [, val] = value.match(REG_FN_COLOR) as MatchedRegExp; + const [cs] = val.match(/[^\s,/]+/g) as StringColorSpacedChannels; + if (d50) { + if (cs === 'xyz-d50') { + [, x, y, z, alpha] = resolveColorFunc(value, { + format: VAL_COMP + }) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorFunc( + value, + opt + ) as ComputedColorChannels; + } + } else if (/^xyz(?:-d65)?$/.test(cs)) { + [, x, y, z, alpha] = resolveColorFunc(value, { + format: VAL_COMP + }) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels; + } + } else { + [, x, y, z, alpha] = parseColorValue(value, opt) as ComputedColorChannels; + } + return [x, y, z, alpha]; +}; + +/** + * convert color value to hsl + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [h, s, l, alpha], hue may be powerless + */ +export const convertColorToHsl = ( + value: string, + opt: Options = {} +): ColorChannels | [number | string, number, number, number] | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let h, s, l, alpha; + if (REG_HSL.test(value)) { + [, h, s, l, alpha] = parseHsl(value, { + format: 'hsl' + }) as ComputedColorChannels; + if (format === 'hsl') { + return [Math.round(h), Math.round(s), Math.round(l), alpha]; + } + return [h, s, l, alpha]; + } + let x, y, z; + if (format === VAL_MIX) { + let xyz; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels; + } + [h, s, l] = transformXyzToHsl([x, y, z], true) as TriColorChannels; + if (format === 'hsl') { + return [Math.round(h), Math.round(s), Math.round(l), alpha]; + } + return [format === VAL_MIX && s === 0 ? NONE : h, s, l, alpha]; +}; + +/** + * convert color value to hwb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [h, w, b, alpha], hue may be powerless + */ +export const convertColorToHwb = ( + value: string, + opt: Options = {} +): ColorChannels | [number | string, number, number, number] | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let h, w, b, alpha; + if (REG_HWB.test(value)) { + [, h, w, b, alpha] = parseHwb(value, { + format: 'hwb' + }) as ComputedColorChannels; + if (format === 'hwb') { + return [Math.round(h), Math.round(w), Math.round(b), alpha]; + } + return [h, w, b, alpha]; + } + let x, y, z; + if (format === VAL_MIX) { + let xyz; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels; + } + [h, w, b] = transformXyzToHwb([x, y, z], true) as TriColorChannels; + if (format === 'hwb') { + return [Math.round(h), Math.round(w), Math.round(b), alpha]; + } + return [format === VAL_MIX && w + b >= 100 ? NONE : h, w, b, alpha]; +}; + +/** + * convert color value to lab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, a, b, alpha] + */ +export const convertColorToLab = ( + value: string, + opt: Options = {} +): ColorChannels | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let l, a, b, alpha; + if (REG_LAB.test(value)) { + [, l, a, b, alpha] = parseLab(value, { + format: VAL_COMP + }) as ComputedColorChannels; + return [l, a, b, alpha]; + } + let x, y, z; + if (format === VAL_MIX) { + let xyz; + opt.d50 = true; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + [, x, y, z, alpha] = parseColorFunc(value, { + d50: true + }) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorValue(value, { + d50: true + }) as ComputedColorChannels; + } + [l, a, b] = transformXyzD50ToLab([x, y, z], true); + return [l, a, b, alpha]; +}; + +/** + * convert color value to lch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless + */ +export const convertColorToLch = ( + value: string, + opt: Options = {} +): ColorChannels | [number, number, number | string, number] | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let l, c, h, alpha; + if (REG_LCH.test(value)) { + [, l, c, h, alpha] = parseLch(value, { + format: VAL_COMP + }) as ComputedColorChannels; + return [l, c, h, alpha]; + } + let x, y, z; + if (format === VAL_MIX) { + let xyz; + opt.d50 = true; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + [, x, y, z, alpha] = parseColorFunc(value, { + d50: true + }) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorValue(value, { + d50: true + }) as ComputedColorChannels; + } + [l, c, h] = transformXyzD50ToLch([x, y, z], true); + return [l, c, format === VAL_MIX && c === 0 ? NONE : h, alpha]; +}; + +/** + * convert color value to oklab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, a, b, alpha] + */ +export const convertColorToOklab = ( + value: string, + opt: Options = {} +): ColorChannels | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let l, a, b, alpha; + if (REG_OKLAB.test(value)) { + [, l, a, b, alpha] = parseOklab(value, { + format: VAL_COMP + }) as ComputedColorChannels; + return [l, a, b, alpha]; + } + let x, y, z; + if (format === VAL_MIX) { + let xyz; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels; + } + [l, a, b] = transformXyzToOklab([x, y, z], true); + return [l, a, b, alpha]; +}; + +/** + * convert color value to oklch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless + */ +export const convertColorToOklch = ( + value: string, + opt: Options = {} +): ColorChannels | [number, number, number | string, number] | NullObject => { + if (isString(value)) { + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '' } = opt; + let l, c, h, alpha; + if (REG_OKLCH.test(value)) { + [, l, c, h, alpha] = parseOklch(value, { + format: VAL_COMP + }) as ComputedColorChannels; + return [l, c, h, alpha]; + } + let x, y, z; + if (format === VAL_MIX) { + let xyz; + if (value.startsWith(FN_COLOR)) { + xyz = parseColorFunc(value, opt); + } else { + xyz = parseColorValue(value, opt); + } + if (xyz instanceof NullObject) { + return xyz; + } + [, x, y, z, alpha] = xyz as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + [, x, y, z, alpha] = parseColorFunc(value) as ComputedColorChannels; + } else { + [, x, y, z, alpha] = parseColorValue(value) as ComputedColorChannels; + } + [l, c, h] = transformXyzToOklch([x, y, z], true) as TriColorChannels; + return [l, c, format === VAL_MIX && c === 0 ? NONE : h, alpha]; +}; + +/** + * resolve color-mix() + * @param value - color-mix color value + * @param [opt] - options + * @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)' + */ +export const resolveColorMix = ( + value: string, + opt: Options = {} +): SpecifiedColorChannels | string | NullObject => { + if (isString(value)) { + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const { format = '', nullable = false } = opt; + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'resolveColorMix', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + const cachedItem = cachedResult.item; + if (isString(cachedItem)) { + return cachedItem as string; + } + return cachedItem as SpecifiedColorChannels; + } + const nestedItems = []; + let colorSpace = ''; + let hueArc = ''; + let colorA = ''; + let pctA = ''; + let colorB = ''; + let pctB = ''; + let parsed = false; + if (!REG_MIX.test(value)) { + // nested color-mix() + if (value.startsWith(FN_MIX) && REG_MIX_NEST.test(value)) { + const items = value.match(REG_MIX_NEST) as RegExpMatchArray; + for (const item of items) { + if (item) { + let val = resolveColorMix(item, { + format: format === VAL_SPEC ? format : VAL_COMP + }) as ComputedColorChannels | string; + // computed value + if (Array.isArray(val)) { + const [cs, v1, v2, v3, v4] = val as ComputedColorChannels; + if (v1 === 0 && v2 === 0 && v3 === 0 && v4 === 0) { + value = ''; + break; + } + if (REG_MIX_CS_RGB_XYZ.test(cs)) { + if (v4 === 1) { + val = `color(${cs} ${v1} ${v2} ${v3})`; + } else { + val = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`; + } + } else if (v4 === 1) { + val = `${cs}(${v1} ${v2} ${v3})`; + } else { + val = `${cs}(${v1} ${v2} ${v3} / ${v4})`; + } + } else if (!REG_MIX.test(val)) { + value = ''; + break; + } + nestedItems.push(val); + value = value.replace(item, val); + } + } + if (!value) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + // contains light-dark() + } else if ( + value.startsWith(FN_MIX) && + value.endsWith(')') && + value.includes(FN_LIGHT_DARK) + ) { + const colorParts = value.replace(FN_MIX, '').replace(/\)$/, ''); + const [csPart = '', partA = '', partB = ''] = splitValue(colorParts, { + delimiter: ',' + }); + const [colorPartA = '', pctPartA = ''] = splitValue(partA); + const [colorPartB = '', pctPartB = ''] = splitValue(partB); + const specifiedColorA = resolveColor(colorPartA, { + format: VAL_SPEC + }) as string; + const specifiedColorB = resolveColor(colorPartB, { + format: VAL_SPEC + }) as string; + if (REG_MIX_IN_CS.test(csPart) && specifiedColorA && specifiedColorB) { + if (format === VAL_SPEC) { + const [, cs] = csPart.match(REG_MIX_IN_CS) as MatchedRegExp; + if (REG_CS_HUE.test(cs)) { + [, colorSpace, hueArc] = cs.match(REG_CS_HUE) as MatchedRegExp; + } else { + colorSpace = cs; + } + colorA = specifiedColorA; + if (pctPartA) { + pctA = pctPartA; + } + colorB = specifiedColorB; + if (pctPartB) { + pctB = pctPartB; + } + value = value + .replace(colorPartA, specifiedColorA) + .replace(colorPartB, specifiedColorB); + parsed = true; + } else { + const resolvedColorA = resolveColor(colorPartA, opt); + const resolvedColorB = resolveColor(colorPartB, opt); + if (isString(resolvedColorA) && isString(resolvedColorB)) { + value = value + .replace(colorPartA, resolvedColorA) + .replace(colorPartB, resolvedColorB); + } + } + } else { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + } else { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + } + if (nestedItems.length && format === VAL_SPEC) { + const [, cs] = value.match(REG_MIX_START) as MatchedRegExp; + if (REG_CS_HUE.test(cs)) { + [, colorSpace, hueArc] = cs.match(REG_CS_HUE) as MatchedRegExp; + } else { + colorSpace = cs; + } + if (nestedItems.length === 2) { + let [itemA, itemB] = nestedItems as [string, string]; + itemA = itemA.replace(/(?=[()])/g, '\\'); + itemB = itemB.replace(/(?=[()])/g, '\\'); + const regA = new RegExp(`(${itemA})(?:\\s+(${PCT}))?`); + const regB = new RegExp(`(${itemB})(?:\\s+(${PCT}))?`); + [, colorA, pctA] = value.match(regA) as MatchedRegExp; + [, colorB, pctB] = value.match(regB) as MatchedRegExp; + } else { + let [item] = nestedItems as [string]; + item = item.replace(/(?=[()])/g, '\\'); + const itemPart = `${item}(?:\\s+${PCT})?`; + const itemPartCapt = `(${item})(?:\\s+(${PCT}))?`; + const regItemPart = new RegExp(`^${itemPartCapt}$`); + const regLastItem = new RegExp(`${itemPartCapt}\\s*\\)$`); + // item is at the end + if (regLastItem.test(value)) { + const reg = new RegExp( + `(${SYN_MIX_PART})\\s*,\\s*(${itemPart})\\s*\\)$` + ); + const [, colorPartA, colorPartB] = value.match(reg) as MatchedRegExp; + [, colorA, pctA] = colorPartA.match( + REG_MIX_COLOR_PART + ) as MatchedRegExp; + [, colorB, pctB] = colorPartB.match(regItemPart) as MatchedRegExp; + } else { + const reg = new RegExp( + `(${itemPart})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)$` + ); + const [, colorPartA, colorPartB] = value.match(reg) as MatchedRegExp; + [, colorA, pctA] = colorPartA.match(regItemPart) as MatchedRegExp; + [, colorB, pctB] = colorPartB.match( + REG_MIX_COLOR_PART + ) as MatchedRegExp; + } + } + } else if (!parsed) { + const [, cs, colorPartA, colorPartB] = value.match( + REG_MIX_CAPT + ) as MatchedRegExp; + [, colorA, pctA] = colorPartA.match(REG_MIX_COLOR_PART) as MatchedRegExp; + [, colorB, pctB] = colorPartB.match(REG_MIX_COLOR_PART) as MatchedRegExp; + if (REG_CS_HUE.test(cs)) { + [, colorSpace, hueArc] = cs.match(REG_CS_HUE) as MatchedRegExp; + } else { + colorSpace = cs; + } + } + // normalize percentages and set multipler + let pA, pB, m; + if (pctA && pctB) { + const p1 = parseFloat(pctA) / MAX_PCT; + const p2 = parseFloat(pctB) / MAX_PCT; + if (p1 < 0 || p1 > 1 || p2 < 0 || p2 > 1 || (p1 === 0 && p2 === 0)) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + const factor = p1 + p2; + pA = p1 / factor; + pB = p2 / factor; + m = factor < 1 ? factor : 1; + } else { + if (pctA) { + pA = parseFloat(pctA) / MAX_PCT; + if (pA < 0 || pA > 1) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + pB = 1 - pA; + } else if (pctB) { + pB = parseFloat(pctB) / MAX_PCT; + if (pB < 0 || pB > 1) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + pA = 1 - pB; + } else { + pA = HALF; + pB = HALF; + } + m = 1; + } + if (colorSpace === 'xyz') { + colorSpace = 'xyz-d65'; + } + // specified value + if (format === VAL_SPEC) { + let valueA = ''; + let valueB = ''; + if (colorA.startsWith(FN_MIX) || colorA.startsWith(FN_LIGHT_DARK)) { + valueA = colorA; + } else if (colorA.startsWith(FN_COLOR)) { + const [cs, v1, v2, v3, v4] = parseColorFunc( + colorA, + opt + ) as SpecifiedColorChannels; + if (v4 === 1) { + valueA = `color(${cs} ${v1} ${v2} ${v3})`; + } else { + valueA = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`; + } + } else { + const val = parseColorValue(colorA, opt); + if (Array.isArray(val)) { + const [cs, v1, v2, v3, v4] = val; + if (v4 === 1) { + if (cs === 'rgb') { + valueA = `${cs}(${v1}, ${v2}, ${v3})`; + } else { + valueA = `${cs}(${v1} ${v2} ${v3})`; + } + } else if (cs === 'rgb') { + valueA = `${cs}a(${v1}, ${v2}, ${v3}, ${v4})`; + } else { + valueA = `${cs}(${v1} ${v2} ${v3} / ${v4})`; + } + } else { + if (!isString(val) || !val) { + setCache(cacheKey, ''); + return ''; + } + valueA = val; + } + } + if (colorB.startsWith(FN_MIX) || colorB.startsWith(FN_LIGHT_DARK)) { + valueB = colorB; + } else if (colorB.startsWith(FN_COLOR)) { + const [cs, v1, v2, v3, v4] = parseColorFunc( + colorB, + opt + ) as SpecifiedColorChannels; + if (v4 === 1) { + valueB = `color(${cs} ${v1} ${v2} ${v3})`; + } else { + valueB = `color(${cs} ${v1} ${v2} ${v3} / ${v4})`; + } + } else { + const val = parseColorValue(colorB, opt); + if (Array.isArray(val)) { + const [cs, v1, v2, v3, v4] = val; + if (v4 === 1) { + if (cs === 'rgb') { + valueB = `${cs}(${v1}, ${v2}, ${v3})`; + } else { + valueB = `${cs}(${v1} ${v2} ${v3})`; + } + } else if (cs === 'rgb') { + valueB = `${cs}a(${v1}, ${v2}, ${v3}, ${v4})`; + } else { + valueB = `${cs}(${v1} ${v2} ${v3} / ${v4})`; + } + } else { + if (!isString(val) || !val) { + setCache(cacheKey, ''); + return ''; + } + valueB = val; + } + } + if (pctA && pctB) { + valueA += ` ${parseFloat(pctA)}%`; + valueB += ` ${parseFloat(pctB)}%`; + } else if (pctA) { + const pA = parseFloat(pctA); + if (pA !== MAX_PCT * HALF) { + valueA += ` ${pA}%`; + } + } else if (pctB) { + const pA = MAX_PCT - parseFloat(pctB); + if (pA !== MAX_PCT * HALF) { + valueA += ` ${pA}%`; + } + } + if (hueArc) { + const res = `color-mix(in ${colorSpace} ${hueArc} hue, ${valueA}, ${valueB})`; + setCache(cacheKey, res); + return res; + } else { + const res = `color-mix(in ${colorSpace}, ${valueA}, ${valueB})`; + setCache(cacheKey, res); + return res; + } + } + let r = 0; + let g = 0; + let b = 0; + let alpha = 0; + // in srgb, srgb-linear + if (/^srgb(?:-linear)?$/.test(colorSpace)) { + let rgbA, rgbB; + if (colorSpace === 'srgb') { + if (REG_CURRENT.test(colorA)) { + rgbA = [NONE, NONE, NONE, NONE]; + } else { + rgbA = convertColorToRgb(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + rgbB = [NONE, NONE, NONE, NONE]; + } else { + rgbB = convertColorToRgb(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } else { + if (REG_CURRENT.test(colorA)) { + rgbA = [NONE, NONE, NONE, NONE]; + } else { + rgbA = convertColorToLinearRgb(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + rgbB = [NONE, NONE, NONE, NONE]; + } else { + rgbB = convertColorToLinearRgb(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } + if (rgbA instanceof NullObject || rgbB instanceof NullObject) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + const [rrA, ggA, bbA, aaA] = rgbA as NumStrColorChannels; + const [rrB, ggB, bbB, aaB] = rgbB as NumStrColorChannels; + const rNone = rrA === NONE && rrB === NONE; + const gNone = ggA === NONE && ggB === NONE; + const bNone = bbA === NONE && bbB === NONE; + const alphaNone = aaA === NONE && aaB === NONE; + const [[rA, gA, bA, alphaA], [rB, gB, bB, alphaB]] = + normalizeColorComponents( + [rrA, ggA, bbA, aaA], + [rrB, ggB, bbB, aaB], + true + ); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + if (alpha === 0) { + r = rA * pA + rB * pB; + g = gA * pA + gB * pB; + b = bA * pA + bB * pB; + } else { + r = (rA * factorA + rB * factorB) / alpha; + g = (gA * factorA + gB * factorB) / alpha; + b = (bA * factorA + bB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === VAL_COMP) { + const res: SpecifiedColorChannels = [ + colorSpace, + rNone ? NONE : roundToPrecision(r, HEX), + gNone ? NONE : roundToPrecision(g, HEX), + bNone ? NONE : roundToPrecision(b, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + r *= MAX_RGB; + g *= MAX_RGB; + b *= MAX_RGB; + // in xyz, xyz-d65, xyz-d50 + } else if (REG_CS_XYZ.test(colorSpace)) { + let xyzA, xyzB; + if (REG_CURRENT.test(colorA)) { + xyzA = [NONE, NONE, NONE, NONE]; + } else { + xyzA = convertColorToXyz(colorA, { + colorSpace, + d50: colorSpace === 'xyz-d50', + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + xyzB = [NONE, NONE, NONE, NONE]; + } else { + xyzB = convertColorToXyz(colorB, { + colorSpace, + d50: colorSpace === 'xyz-d50', + format: VAL_MIX + }); + } + if (xyzA instanceof NullObject || xyzB instanceof NullObject) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + const [xxA, yyA, zzA, aaA] = xyzA; + const [xxB, yyB, zzB, aaB] = xyzB; + const xNone = xxA === NONE && xxB === NONE; + const yNone = yyA === NONE && yyB === NONE; + const zNone = zzA === NONE && zzB === NONE; + const alphaNone = aaA === NONE && aaB === NONE; + const [[xA, yA, zA, alphaA], [xB, yB, zB, alphaB]] = + normalizeColorComponents( + [xxA, yyA, zzA, aaA], + [xxB, yyB, zzB, aaB], + true + ); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + let x, y, z; + if (alpha === 0) { + x = xA * pA + xB * pB; + y = yA * pA + yB * pB; + z = zA * pA + zB * pB; + } else { + x = (xA * factorA + xB * factorB) / alpha; + y = (yA * factorA + yB * factorB) / alpha; + z = (zA * factorA + zB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === VAL_COMP) { + const res: SpecifiedColorChannels = [ + colorSpace, + xNone ? NONE : roundToPrecision(x, HEX), + yNone ? NONE : roundToPrecision(y, HEX), + zNone ? NONE : roundToPrecision(z, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + if (colorSpace === 'xyz-d50') { + [r, g, b] = transformXyzD50ToRgb([x, y, z], true); + } else { + [r, g, b] = transformXyzToRgb([x, y, z], true); + } + // in hsl, hwb + } else if (/^h(?:sl|wb)$/.test(colorSpace)) { + let hslA, hslB; + if (colorSpace === 'hsl') { + if (REG_CURRENT.test(colorA)) { + hslA = [NONE, NONE, NONE, NONE]; + } else { + hslA = convertColorToHsl(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + hslB = [NONE, NONE, NONE, NONE]; + } else { + hslB = convertColorToHsl(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } else { + if (REG_CURRENT.test(colorA)) { + hslA = [NONE, NONE, NONE, NONE]; + } else { + hslA = convertColorToHwb(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + hslB = [NONE, NONE, NONE, NONE]; + } else { + hslB = convertColorToHwb(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } + if (hslA instanceof NullObject || hslB instanceof NullObject) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + const [hhA, ssA, llA, aaA] = hslA; + const [hhB, ssB, llB, aaB] = hslB; + const alphaNone = aaA === NONE && aaB === NONE; + let [[hA, sA, lA, alphaA], [hB, sB, lB, alphaB]] = normalizeColorComponents( + [hhA, ssA, llA, aaA], + [hhB, ssB, llB, aaB], + true + ); + if (hueArc) { + [hA, hB] = interpolateHue(hA, hB, hueArc); + } + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + const h = (hA * pA + hB * pB) % DEG; + let s, l; + if (alpha === 0) { + s = sA * pA + sB * pB; + l = lA * pA + lB * pB; + } else { + s = (sA * factorA + sB * factorB) / alpha; + l = (lA * factorA + lB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + [r, g, b] = convertColorToRgb( + `${colorSpace}(${h} ${s} ${l})` + ) as ColorChannels; + if (format === VAL_COMP) { + const res: SpecifiedColorChannels = [ + 'srgb', + roundToPrecision(r / MAX_RGB, HEX), + roundToPrecision(g / MAX_RGB, HEX), + roundToPrecision(b / MAX_RGB, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + // in lch, oklch + } else if (/^(?:ok)?lch$/.test(colorSpace)) { + let lchA, lchB; + if (colorSpace === 'lch') { + if (REG_CURRENT.test(colorA)) { + lchA = [NONE, NONE, NONE, NONE]; + } else { + lchA = convertColorToLch(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + lchB = [NONE, NONE, NONE, NONE]; + } else { + lchB = convertColorToLch(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } else { + if (REG_CURRENT.test(colorA)) { + lchA = [NONE, NONE, NONE, NONE]; + } else { + lchA = convertColorToOklch(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + lchB = [NONE, NONE, NONE, NONE]; + } else { + lchB = convertColorToOklch(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } + if (lchA instanceof NullObject || lchB instanceof NullObject) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + const [llA, ccA, hhA, aaA] = lchA; + const [llB, ccB, hhB, aaB] = lchB; + const lNone = llA === NONE && llB === NONE; + const cNone = ccA === NONE && ccB === NONE; + const hNone = hhA === NONE && hhB === NONE; + const alphaNone = aaA === NONE && aaB === NONE; + let [[lA, cA, hA, alphaA], [lB, cB, hB, alphaB]] = normalizeColorComponents( + [llA, ccA, hhA, aaA], + [llB, ccB, hhB, aaB], + true + ); + if (hueArc) { + [hA, hB] = interpolateHue(hA, hB, hueArc); + } + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + const h = (hA * pA + hB * pB) % DEG; + let l, c; + if (alpha === 0) { + l = lA * pA + lB * pB; + c = cA * pA + cB * pB; + } else { + l = (lA * factorA + lB * factorB) / alpha; + c = (cA * factorA + cB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === VAL_COMP) { + const res: SpecifiedColorChannels = [ + colorSpace, + lNone ? NONE : roundToPrecision(l, HEX), + cNone ? NONE : roundToPrecision(c, HEX), + hNone ? NONE : roundToPrecision(h, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + [, r, g, b] = resolveColorValue( + `${colorSpace}(${l} ${c} ${h})` + ) as ComputedColorChannels; + // in lab, oklab + } else { + let labA, labB; + if (colorSpace === 'lab') { + if (REG_CURRENT.test(colorA)) { + labA = [NONE, NONE, NONE, NONE]; + } else { + labA = convertColorToLab(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + labB = [NONE, NONE, NONE, NONE]; + } else { + labB = convertColorToLab(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } else { + if (REG_CURRENT.test(colorA)) { + labA = [NONE, NONE, NONE, NONE]; + } else { + labA = convertColorToOklab(colorA, { + colorSpace, + format: VAL_MIX + }); + } + if (REG_CURRENT.test(colorB)) { + labB = [NONE, NONE, NONE, NONE]; + } else { + labB = convertColorToOklab(colorB, { + colorSpace, + format: VAL_MIX + }); + } + } + if (labA instanceof NullObject || labB instanceof NullObject) { + const res = cacheInvalidColorValue(cacheKey, format, nullable); + return res; + } + const [llA, aaA, bbA, alA] = labA; + const [llB, aaB, bbB, alB] = labB; + const lNone = llA === NONE && llB === NONE; + const aNone = aaA === NONE && aaB === NONE; + const bNone = bbA === NONE && bbB === NONE; + const alphaNone = alA === NONE && alB === NONE; + const [[lA, aA, bA, alphaA], [lB, aB, bB, alphaB]] = + normalizeColorComponents( + [llA, aaA, bbA, alA], + [llB, aaB, bbB, alB], + true + ); + const factorA = alphaA * pA; + const factorB = alphaB * pB; + alpha = factorA + factorB; + let l, aO, bO; + if (alpha === 0) { + l = lA * pA + lB * pB; + aO = aA * pA + aB * pB; + bO = bA * pA + bB * pB; + } else { + l = (lA * factorA + lB * factorB) / alpha; + aO = (aA * factorA + aB * factorB) / alpha; + bO = (bA * factorA + bB * factorB) / alpha; + alpha = parseFloat(alpha.toFixed(3)); + } + if (format === VAL_COMP) { + const res: SpecifiedColorChannels = [ + colorSpace, + lNone ? NONE : roundToPrecision(l, HEX), + aNone ? NONE : roundToPrecision(aO, HEX), + bNone ? NONE : roundToPrecision(bO, HEX), + alphaNone ? NONE : alpha * m + ]; + setCache(cacheKey, res); + return res; + } + [, r, g, b] = resolveColorValue( + `${colorSpace}(${l} ${aO} ${bO})` + ) as ComputedColorChannels; + } + const res: SpecifiedColorChannels = [ + 'rgb', + Math.round(r), + Math.round(g), + Math.round(b), + parseFloat((alpha * m).toFixed(3)) + ]; + setCache(cacheKey, res); + return res; +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/common.ts b/node_modules/@asamuzakjp/css-color/src/js/common.ts new file mode 100644 index 0000000..32bf8bd --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/common.ts @@ -0,0 +1,31 @@ +/** + * common + */ + +/* numeric constants */ +const TYPE_FROM = 8; +const TYPE_TO = -1; + +/** + * get type + * @param o - object to check + * @returns type of object + */ +export const getType = (o: unknown): string => + Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO); + +/** + * is string + * @param o - object to check + * @returns result + */ +export const isString = (o: unknown): o is string => + typeof o === 'string' || o instanceof String; + +/** + * is string or number + * @param o - object to check + * @returns result + */ +export const isStringOrNumber = (o: unknown): boolean => + isString(o) || typeof o === 'number'; diff --git a/node_modules/@asamuzakjp/css-color/src/js/constant.ts b/node_modules/@asamuzakjp/css-color/src/js/constant.ts new file mode 100644 index 0000000..b331181 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/constant.ts @@ -0,0 +1,68 @@ +/** + * constant + */ + +/* values and units */ +const _DIGIT = '(?:0|[1-9]\\d*)'; +const _COMPARE = 'clamp|max|min'; +const _EXPO = 'exp|hypot|log|pow|sqrt'; +const _SIGN = 'abs|sign'; +const _STEP = 'mod|rem|round'; +const _TRIG = 'a?(?:cos|sin|tan)|atan2'; +const _MATH = `${_COMPARE}|${_EXPO}|${_SIGN}|${_STEP}|${_TRIG}`; +const _CALC = `calc|${_MATH}`; +const _VAR = `var|${_CALC}`; +export const ANGLE = 'deg|g?rad|turn'; +export const LENGTH = + '[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)'; +export const NUM = `[+-]?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`; +export const NUM_POSITIVE = `\\+?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`; +export const NONE = 'none'; +export const PCT = `${NUM}%`; +export const SYN_FN_CALC = `^(?:${_CALC})\\(|(?<=[*\\/\\s\\(])(?:${_CALC})\\(`; +export const SYN_FN_MATH_START = `^(?:${_MATH})\\($`; +export const SYN_FN_VAR = '^var\\(|(?<=[*\\/\\s\\(])var\\('; +export const SYN_FN_VAR_START = `^(?:${_VAR})\\(`; + +/* colors */ +const _ALPHA = `(?:\\s*\\/\\s*(?:${NUM}|${PCT}|${NONE}))?`; +const _ALPHA_LV3 = `(?:\\s*,\\s*(?:${NUM}|${PCT}))?`; +const _COLOR_FUNC = '(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?'; +const _COLOR_KEY = '[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}'; +const _CS_HUE = '(?:ok)?lch|hsl|hwb'; +const _CS_HUE_ARC = '(?:de|in)creasing|longer|shorter'; +const _NUM_ANGLE = `${NUM}(?:${ANGLE})?`; +const _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`; +const _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`; +export const CS_HUE = `(?:${_CS_HUE})(?:\\s(?:${_CS_HUE_ARC})\\shue)?`; +export const CS_HUE_CAPT = `(${_CS_HUE})(?:\\s(${_CS_HUE_ARC})\\shue)?`; +export const CS_LAB = '(?:ok)?lab'; +export const CS_LCH = '(?:ok)?lch'; +export const CS_SRGB = 'srgb(?:-linear)?'; +export const CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|${CS_SRGB}`; +export const CS_XYZ = 'xyz(?:-d(?:50|65))?'; +export const CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`; +export const CS_MIX = `${CS_HUE}|${CS_RECT}`; +export const FN_COLOR = 'color('; +export const FN_LIGHT_DARK = 'light-dark('; +export const FN_MIX = 'color-mix('; +export const FN_REL = `(?:${_COLOR_FUNC})\\(\\s*from\\s+`; +export const FN_REL_CAPT = `(${_COLOR_FUNC})\\(\\s*from\\s+`; +export const FN_VAR = 'var('; +export const SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`; +export const SYN_FN_LIGHT_DARK = '^light-dark\\('; +export const SYN_FN_REL = `^${FN_REL}|(?<=[\\s])${FN_REL}`; +export const SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`; +export const SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\s*,\\s*${PCT}){2}${_ALPHA_LV3}`; +export const SYN_LCH = `(?:${_NUM_PCT_NONE}\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`; +export const SYN_MOD = `${_NUM_PCT_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`; +export const SYN_RGB_LV3 = `(?:${NUM}(?:\\s*,\\s*${NUM}){2}|${PCT}(?:\\s*,\\s*${PCT}){2})${_ALPHA_LV3}`; +export const SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\(\\s*${SYN_HSL_LV3}\\s*\\)|rgba?\\(\\s*${SYN_RGB_LV3}\\s*\\)|(?:hsla?|hwb)\\(\\s*${SYN_HSL}\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*${SYN_MOD}\\s*\\)|(?:ok)?lch\\(\\s*${SYN_LCH}\\s*\\)|color\\(\\s*${SYN_FN_COLOR}\\s*\\)`; +export const SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\s+${PCT})?`; +export const SYN_MIX = `color-mix\\(\\s*in\\s+(?:${CS_MIX})\\s*,\\s*${SYN_MIX_PART}\\s*,\\s*${SYN_MIX_PART}\\s*\\)`; +export const SYN_MIX_CAPT = `color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,\\s*(${SYN_MIX_PART})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)`; + +/* formats */ +export const VAL_COMP = 'computedValue'; +export const VAL_MIX = 'mixValue'; +export const VAL_SPEC = 'specifiedValue'; diff --git a/node_modules/@asamuzakjp/css-color/src/js/convert.ts b/node_modules/@asamuzakjp/css-color/src/js/convert.ts new file mode 100644 index 0000000..104bf96 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/convert.ts @@ -0,0 +1,331 @@ +/** + * convert + */ + +import { + CacheItem, + NullObject, + createCacheKey, + getCache, + setCache +} from './cache'; +import { + convertColorToHsl, + convertColorToHwb, + convertColorToLab, + convertColorToLch, + convertColorToOklab, + convertColorToOklch, + convertColorToRgb, + numberToHexString, + parseColorFunc, + parseColorValue +} from './color'; +import { isString } from './common'; +import { cssCalc } from './css-calc'; +import { resolveVar } from './css-var'; +import { resolveRelativeColor } from './relative-color'; +import { resolveColor } from './resolve'; +import { ColorChannels, ComputedColorChannels, Options } from './typedef'; + +/* constants */ +import { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from './constant'; +const NAMESPACE = 'convert'; + +/* regexp */ +const REG_FN_CALC = new RegExp(SYN_FN_CALC); +const REG_FN_REL = new RegExp(SYN_FN_REL); +const REG_FN_VAR = new RegExp(SYN_FN_VAR); + +/** + * pre process + * @param value - CSS color value + * @param [opt] - options + * @returns value + */ +export const preProcess = ( + value: string, + opt: Options = {} +): string | NullObject => { + if (!isString(value)) { + return new NullObject(); + } + value = value.trim(); + if (!value) { + return new NullObject(); + } + const cacheKey: string = createCacheKey( + { namespace: NAMESPACE, name: 'preProcess', value }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + return cachedResult.item as string; + } + let res: string | NullObject = value; + if (REG_FN_VAR.test(value)) { + const resolved = resolveVar(value, opt); + if (isString(resolved)) { + res = resolved; + } else { + setCache(cacheKey, null); + return new NullObject(); + } + } + if (isString(res)) { + if (REG_FN_REL.test(res)) { + const resolved = resolveRelativeColor(res, opt); + if (isString(resolved)) { + res = resolved; + } else { + setCache(cacheKey, null); + return new NullObject(); + } + } else if (REG_FN_CALC.test(res)) { + res = cssCalc(res, opt); + } + } + if (isString(res)) { + if (res.startsWith('color-mix')) { + res = resolveColor(res, { ...opt, format: VAL_COMP, nullable: true }); + } + } + setCache(cacheKey, res); + return res; +}; + +/** + * converter factory to reduce boilerplate + * @param name - function name for cache + * @param format - color format + * @param convertFn - conversion function + * @returns color converter function + */ +const createColorConverter = ( + name: string, + format: string, + convertFn: Function +) => { + const colorConverterFn = ( + value: string, + opt: Options = {} + ): ColorChannels => { + if (!isString(value)) { + throw new TypeError(`${value} is not a string.`); + } + const resolved = preProcess(value, opt); + if (resolved instanceof NullObject) { + return [0, 0, 0, 0]; + } + const val = resolved.toLowerCase(); + const cacheKey = createCacheKey( + { namespace: NAMESPACE, name, value: val }, + opt + ); + const cached = getCache(cacheKey); + if (cached instanceof CacheItem) { + return cached.item as ColorChannels; + } + const result = convertFn(val, { ...opt, format }) as ColorChannels; + setCache(cacheKey, result); + return result; + }; + return colorConverterFn; +}; + +/** + * convert number to hex string + * @param value - numeric value + * @returns hex string: 00..ff + */ +export const numberToHex = (value: number): string => numberToHexString(value); + +/** + * convert color to hex + * @param value - CSS color value + * @param [opt] - options + * @param [opt.alpha] - enable alpha channel + * @returns #rrggbb | #rrggbbaa | null + */ +export const colorToHex = (value: string, opt: Options = {}): string | null => { + if (!isString(value)) { + throw new TypeError(`${value} is not a string.`); + } + const resolved = preProcess(value, opt); + if (resolved instanceof NullObject) { + return null; + } + const val = resolved.toLowerCase(); + const cacheKey = createCacheKey( + { namespace: NAMESPACE, name: 'colorToHex', value: val }, + opt + ); + const cached = getCache(cacheKey); + if (cached instanceof CacheItem) { + if (cached.isNull) { + return null; + } + return cached.item as string; + } + const hex = resolveColor(val, { + ...opt, + nullable: true, + format: opt.alpha ? 'hexAlpha' : 'hex' + }); + if (isString(hex)) { + setCache(cacheKey, hex); + return hex; + } + setCache(cacheKey, null); + return null; +}; + +/** + * convert color to hsl + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [h, s, l, alpha] + */ +export const colorToHsl = createColorConverter( + 'colorToHsl', + 'hsl', + convertColorToHsl +); + +/** + * convert color to hwb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [h, w, b, alpha] + */ +export const colorToHwb = createColorConverter( + 'colorToHwb', + 'hwb', + convertColorToHwb +); + +/** + * convert color to lab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, a, b, alpha] + */ +export const colorToLab = createColorConverter( + 'colorToLab', + 'lab', + convertColorToLab +); + +/** + * convert color to lch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, c, h, alpha] + */ +export const colorToLch = createColorConverter( + 'colorToLch', + 'lch', + convertColorToLch +); + +/** + * convert color to oklab + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, a, b, alpha] + */ +export const colorToOklab = createColorConverter( + 'colorToOklab', + 'oklab', + convertColorToOklab +); + +/** + * convert color to oklch + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [l, c, h, alpha] + */ +export const colorToOklch = createColorConverter( + 'colorToOklch', + 'oklch', + convertColorToOklch +); + +/** + * convert color to rgb + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [r, g, b, alpha] + */ +export const colorToRgb = createColorConverter( + 'colorToRgb', + 'rgb', + convertColorToRgb +); + +/** + * convert color to xyz + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [x, y, z, alpha] + */ +export const colorToXyz = (value: string, opt: Options = {}): ColorChannels => { + if (!isString(value)) { + throw new TypeError(`${value} is not a string.`); + } + const resolved = preProcess(value, opt); + if (resolved instanceof NullObject) { + return [0, 0, 0, 0]; + } + const val = resolved.toLowerCase(); + const cacheKey = createCacheKey( + { namespace: NAMESPACE, name: 'colorToXyz', value: val }, + opt + ); + const cached = getCache(cacheKey); + if (cached instanceof CacheItem) { + return cached.item as ColorChannels; + } + let parsed; + if (val.startsWith('color(')) { + parsed = parseColorFunc(val, opt); + } else { + parsed = parseColorValue(val, opt); + } + const [, ...xyz] = parsed as ComputedColorChannels; + setCache(cacheKey, xyz); + return xyz as ColorChannels; +}; + +/** + * convert color to xyz-d50 + * @param value - CSS color value + * @param [opt] - options + * @returns ColorChannels - [x, y, z, alpha] + */ +export const colorToXyzD50 = ( + value: string, + opt: Options = {} +): ColorChannels => { + opt.d50 = true; + return colorToXyz(value, opt); +}; + +/* convert */ +export const convert = { + colorToHex, + colorToHsl, + colorToHwb, + colorToLab, + colorToLch, + colorToOklab, + colorToOklch, + colorToRgb, + colorToXyz, + colorToXyzD50, + numberToHex +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/css-calc.ts b/node_modules/@asamuzakjp/css-color/src/js/css-calc.ts new file mode 100644 index 0000000..62e9a23 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/css-calc.ts @@ -0,0 +1,1008 @@ +/** + * css-calc + */ + +import { calc, conversionOptions as CalcOptions } from '@csstools/css-calc'; +import { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer'; +import { + CacheItem, + NullObject, + createCacheKey, + getCache, + setCache +} from './cache'; +import { isString, isStringOrNumber } from './common'; +import { resolveVar } from './css-var'; +import { resolveLengthInPixels, roundToPrecision } from './util'; +import { MatchedRegExp, Options } from './typedef'; + +/* constants */ +import { + ANGLE, + LENGTH, + NUM, + SYN_FN_CALC, + SYN_FN_MATH_START, + SYN_FN_VAR, + SYN_FN_VAR_START, + VAL_SPEC +} from './constant'; +const { + CloseParen: PAREN_CLOSE, + Comment: COMMENT, + Dimension: DIM, + EOF, + Function: FUNC, + OpenParen: PAREN_OPEN, + Whitespace: W_SPACE +} = TokenType; +const NAMESPACE = 'css-calc'; + +/* numeric constants */ +const TRIA = 3; +const HEX = 16; +const MAX_PCT = 100; + +/* regexp */ +const REG_FN_CALC = new RegExp(SYN_FN_CALC); +const REG_FN_CALC_NUM = new RegExp(`^calc\\((${NUM})\\)$`); +const REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START); +const REG_FN_VAR = new RegExp(SYN_FN_VAR); +const REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START); +const REG_OPERATOR = /\s[*+/-]\s/; +const REG_PAREN_OPEN = /\($/; +const REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`); +const REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`); +const REG_TYPE_PCT = new RegExp(`^(${NUM})%$`); + +/** + * Calclator + */ +export class Calculator { + /* private */ + // number + #hasNum: boolean; + #numSum: number[]; + #numMul: number[]; + // percentage + #hasPct: boolean; + #pctSum: number[]; + #pctMul: number[]; + // dimension + #hasDim: boolean; + #dimSum: string[]; + #dimSub: string[]; + #dimMul: string[]; + #dimDiv: string[]; + // et cetra + #hasEtc: boolean; + #etcSum: string[]; + #etcSub: string[]; + #etcMul: string[]; + #etcDiv: string[]; + // calc options + #calcOpts: CalcOptions; + + /** + * constructor + */ + constructor() { + // number + this.#hasNum = false; + this.#numSum = []; + this.#numMul = []; + // percentage + this.#hasPct = false; + this.#pctSum = []; + this.#pctMul = []; + // dimension + this.#hasDim = false; + this.#dimSum = []; + this.#dimSub = []; + this.#dimMul = []; + this.#dimDiv = []; + // et cetra + this.#hasEtc = false; + this.#etcSum = []; + this.#etcSub = []; + this.#etcMul = []; + this.#etcDiv = []; + // calc options + this.#calcOpts = { + toCanonicalUnits: true + }; + } + + get hasNum() { + return this.#hasNum; + } + + set hasNum(value: boolean) { + this.#hasNum = !!value; + } + + get numSum() { + return this.#numSum; + } + + get numMul() { + return this.#numMul; + } + + get hasPct() { + return this.#hasPct; + } + + set hasPct(value: boolean) { + this.#hasPct = !!value; + } + + get pctSum() { + return this.#pctSum; + } + + get pctMul() { + return this.#pctMul; + } + + get hasDim() { + return this.#hasDim; + } + + set hasDim(value: boolean) { + this.#hasDim = !!value; + } + + get dimSum() { + return this.#dimSum; + } + + get dimSub() { + return this.#dimSub; + } + + get dimMul() { + return this.#dimMul; + } + + get dimDiv() { + return this.#dimDiv; + } + + get hasEtc() { + return this.#hasEtc; + } + + set hasEtc(value: boolean) { + this.#hasEtc = !!value; + } + + get etcSum() { + return this.#etcSum; + } + + get etcSub() { + return this.#etcSub; + } + + get etcMul() { + return this.#etcMul; + } + + get etcDiv() { + return this.#etcDiv; + } + + /** + * clear values + * @returns void + */ + clear() { + // number + this.#hasNum = false; + this.#numSum.length = 0; + this.#numMul.length = 0; + // percentage + this.#hasPct = false; + this.#pctSum.length = 0; + this.#pctMul.length = 0; + // dimension + this.#hasDim = false; + this.#dimSum.length = 0; + this.#dimSub.length = 0; + this.#dimMul.length = 0; + this.#dimDiv.length = 0; + // et cetra + this.#hasEtc = false; + this.#etcSum.length = 0; + this.#etcSub.length = 0; + this.#etcMul.length = 0; + this.#etcDiv.length = 0; + } + + /** + * sort values + * @param values - values + * @returns sorted values + */ + sort(values: string[] = []): string[] { + const arr = [...values]; + if (arr.length > 1) { + arr.sort((a, b) => { + let res; + if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) { + const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT) as MatchedRegExp; + const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT) as MatchedRegExp; + if (unitA === unitB) { + if (Number(valA) === Number(valB)) { + res = 0; + } else if (Number(valA) > Number(valB)) { + res = 1; + } else { + res = -1; + } + } else if (unitA > unitB) { + res = 1; + } else { + res = -1; + } + } else { + if (a === b) { + res = 0; + } else if (a > b) { + res = 1; + } else { + res = -1; + } + } + return res; + }); + } + return arr; + } + + /** + * multiply values + * @returns resolved value + */ + multiply(): string { + const value = []; + let num; + if (this.#hasNum) { + num = 1; + for (const i of this.#numMul) { + num *= i; + if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) { + break; + } + } + if (!this.#hasPct && !this.#hasDim && !this.hasEtc) { + if (Number.isFinite(num)) { + num = roundToPrecision(num, HEX); + } + value.push(num); + } + } + if (this.#hasPct) { + if (typeof num !== 'number') { + num = 1; + } + for (const i of this.#pctMul) { + num *= i; + if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) { + break; + } + } + if (Number.isFinite(num)) { + num = `${roundToPrecision(num, HEX)}%`; + } + if (!this.#hasDim && !this.hasEtc) { + value.push(num); + } + } + if (this.#hasDim) { + let dim = ''; + let mul = ''; + let div = ''; + if (this.#dimMul.length) { + if (this.#dimMul.length === 1) { + [mul] = this.#dimMul as [string]; + } else { + mul = `${this.sort(this.#dimMul).join(' * ')}`; + } + } + if (this.#dimDiv.length) { + if (this.#dimDiv.length === 1) { + [div] = this.#dimDiv as [string]; + } else { + div = `${this.sort(this.#dimDiv).join(' * ')}`; + } + } + if (Number.isFinite(num)) { + if (mul) { + if (div) { + if (div.includes('*')) { + dim = calc(`calc(${num} * ${mul} / (${div}))`, this.#calcOpts); + } else { + dim = calc(`calc(${num} * ${mul} / ${div})`, this.#calcOpts); + } + } else { + dim = calc(`calc(${num} * ${mul})`, this.#calcOpts); + } + } else if (div.includes('*')) { + dim = calc(`calc(${num} / (${div}))`, this.#calcOpts); + } else { + dim = calc(`calc(${num} / ${div})`, this.#calcOpts); + } + value.push(dim.replace(/^calc/, '')); + } else { + if (!value.length && num !== undefined) { + value.push(num); + } + if (mul) { + if (div) { + if (div.includes('*')) { + dim = calc(`calc(${mul} / (${div}))`, this.#calcOpts); + } else { + dim = calc(`calc(${mul} / ${div})`, this.#calcOpts); + } + } else { + dim = calc(`calc(${mul})`, this.#calcOpts); + } + if (value.length) { + value.push('*', dim.replace(/^calc/, '')); + } else { + value.push(dim.replace(/^calc/, '')); + } + } else { + dim = calc(`calc(${div})`, this.#calcOpts); + if (value.length) { + value.push('/', dim.replace(/^calc/, '')); + } else { + value.push('1', '/', dim.replace(/^calc/, '')); + } + } + } + } + if (this.#hasEtc) { + if (this.#etcMul.length) { + if (!value.length && num !== undefined) { + value.push(num); + } + const mul = this.sort(this.#etcMul).join(' * '); + if (value.length) { + value.push(`* ${mul}`); + } else { + value.push(`${mul}`); + } + } + if (this.#etcDiv.length) { + const div = this.sort(this.#etcDiv).join(' * '); + if (div.includes('*')) { + if (value.length) { + value.push(`/ (${div})`); + } else { + value.push(`1 / (${div})`); + } + } else if (value.length) { + value.push(`/ ${div}`); + } else { + value.push(`1 / ${div}`); + } + } + } + if (value.length) { + return value.join(' '); + } + return ''; + } + + /** + * sum values + * @returns resolved value + */ + sum(): string { + const value = []; + if (this.#hasNum) { + let num = 0; + for (const i of this.#numSum) { + num += i; + if (!Number.isFinite(num) || Number.isNaN(num)) { + break; + } + } + value.push(num); + } + if (this.#hasPct) { + let num: number | string = 0; + for (const i of this.#pctSum) { + num += i; + if (!Number.isFinite(num)) { + break; + } + } + if (Number.isFinite(num)) { + num = `${num}%`; + } + if (value.length) { + value.push(`+ ${num}`); + } else { + value.push(num); + } + } + if (this.#hasDim) { + let dim, sum, sub; + if (this.#dimSum.length) { + sum = this.sort(this.#dimSum).join(' + '); + } + if (this.#dimSub.length) { + sub = this.sort(this.#dimSub).join(' + '); + } + if (sum) { + if (sub) { + if (sub.includes('-')) { + dim = calc(`calc(${sum} - (${sub}))`, this.#calcOpts); + } else { + dim = calc(`calc(${sum} - ${sub})`, this.#calcOpts); + } + } else { + dim = calc(`calc(${sum})`, this.#calcOpts); + } + } else { + dim = calc(`calc(-1 * (${sub}))`, this.#calcOpts); + } + if (value.length) { + value.push('+', dim.replace(/^calc/, '')); + } else { + value.push(dim.replace(/^calc/, '')); + } + } + if (this.#hasEtc) { + if (this.#etcSum.length) { + const sum = this.sort(this.#etcSum) + .map(item => { + let res; + if ( + REG_OPERATOR.test(item) && + !item.startsWith('(') && + !item.endsWith(')') + ) { + res = `(${item})`; + } else { + res = item; + } + return res; + }) + .join(' + '); + if (value.length) { + if (this.#etcSum.length > 1) { + value.push(`+ (${sum})`); + } else { + value.push(`+ ${sum}`); + } + } else { + value.push(`${sum}`); + } + } + if (this.#etcSub.length) { + const sub = this.sort(this.#etcSub) + .map(item => { + let res; + if ( + REG_OPERATOR.test(item) && + !item.startsWith('(') && + !item.endsWith(')') + ) { + res = `(${item})`; + } else { + res = item; + } + return res; + }) + .join(' + '); + if (value.length) { + if (this.#etcSub.length > 1) { + value.push(`- (${sub})`); + } else { + value.push(`- ${sub}`); + } + } else if (this.#etcSub.length > 1) { + value.push(`-1 * (${sub})`); + } else { + value.push(`-1 * ${sub}`); + } + } + } + if (value.length) { + return value.join(' '); + } + return ''; + } +} + +/** + * sort calc values + * @param values - values to sort + * @param [finalize] - finalize values + * @returns sorted values + */ +export const sortCalcValues = ( + values: (number | string)[] = [], + finalize: boolean = false +): string => { + if (values.length < TRIA) { + throw new Error(`Unexpected array length ${values.length}.`); + } + const start = values.shift(); + if (!isString(start) || !start.endsWith('(')) { + throw new Error(`Unexpected token ${start}.`); + } + const end = values.pop(); + if (end !== ')') { + throw new Error(`Unexpected token ${end}.`); + } + if (values.length === 1) { + const [value] = values; + if (!isStringOrNumber(value)) { + throw new Error(`Unexpected token ${value}.`); + } + return `${start}${value}${end}`; + } + const sortedValues = []; + const cal = new Calculator(); + let operator: string = ''; + const l = values.length; + // Array traversal optimization for operator check + let hasAddSub = false; + for (let i = 0; i < l; i++) { + const value = values[i]; + if (!isStringOrNumber(value)) { + throw new Error(`Unexpected token ${value}.`); + } + if (value === '*' || value === '/') { + operator = value; + } else if (value === '+' || value === '-') { + const sortedValue = cal.multiply(); + if (sortedValue) { + sortedValues.push(sortedValue, value); + } + // Mark presence of + or - + hasAddSub = true; + cal.clear(); + operator = ''; + } else { + const numValue = Number(value); + const strValue = `${value}`; + switch (operator) { + case '/': { + if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numMul.push(1 / numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp; + cal.hasPct = true; + cal.pctMul.push((MAX_PCT * MAX_PCT) / Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimDiv.push(strValue); + } else { + cal.hasEtc = true; + cal.etcDiv.push(strValue); + } + break; + } + case '*': + default: { + if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numMul.push(numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp; + cal.hasPct = true; + cal.pctMul.push(Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimMul.push(strValue); + } else { + cal.hasEtc = true; + cal.etcMul.push(strValue); + } + } + } + } + if (i === l - 1) { + const sortedValue = cal.multiply(); + if (sortedValue) { + sortedValues.push(sortedValue); + } + cal.clear(); + operator = ''; + } + } + let resolvedValue = ''; + if (finalize && hasAddSub) { + const finalizedValues = []; + cal.clear(); + operator = ''; + const l = sortedValues.length; + for (let i = 0; i < l; i++) { + const value = sortedValues[i]; + if (isStringOrNumber(value)) { + if (value === '+' || value === '-') { + operator = value; + } else { + const numValue = Number(value); + const strValue = `${value}`; + switch (operator) { + case '-': { + if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numSum.push(-1 * numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp; + cal.hasPct = true; + cal.pctSum.push(-1 * Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimSub.push(strValue); + } else { + cal.hasEtc = true; + cal.etcSub.push(strValue); + } + break; + } + case '+': + default: { + if (Number.isFinite(numValue)) { + cal.hasNum = true; + cal.numSum.push(numValue); + } else if (REG_TYPE_PCT.test(strValue)) { + const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp; + cal.hasPct = true; + cal.pctSum.push(Number(val)); + } else if (REG_TYPE_DIM.test(strValue)) { + cal.hasDim = true; + cal.dimSum.push(strValue); + } else { + cal.hasEtc = true; + cal.etcSum.push(strValue); + } + } + } + } + } + if (i === l - 1) { + const sortedValue = cal.sum(); + if (sortedValue) { + finalizedValues.push(sortedValue); + } + cal.clear(); + operator = ''; + } + } + resolvedValue = finalizedValues.join(' ').replace(/\+\s-/g, '- '); + } else { + resolvedValue = sortedValues.join(' ').replace(/\+\s-/g, '- '); + } + if ( + resolvedValue.startsWith('(') && + resolvedValue.endsWith(')') && + resolvedValue.lastIndexOf('(') === 0 && + resolvedValue.indexOf(')') === resolvedValue.length - 1 + ) { + resolvedValue = resolvedValue.substring(1, resolvedValue.length - 1); + } + return `${start}${resolvedValue}${end}`; +}; + +/** + * resolve AST node + * @param node - AST node + * @param isRoot - is root node + * @returns resolved value + */ +const resolveNode = (node: any[], isRoot: boolean): string => { + const flatItems: string[] = []; + for (const item of node) { + if (Array.isArray(item)) { + flatItems.push(resolveNode(item, false)); + } else { + flatItems.push(item as string); + } + } + if (isRoot) { + if (flatItems.length >= TRIA) { + return sortCalcValues(flatItems, true); + } + const joined = flatItems.join(''); + return joined.startsWith('calc(') ? joined : `calc(${joined})`; + } + if (flatItems.length >= TRIA) { + let serialized = sortCalcValues(flatItems, false); + if (REG_FN_VAR_START.test(serialized)) { + serialized = calc(serialized, { toCanonicalUnits: true }); + } + return serialized; + } + return flatItems.join(''); +}; + +/** + * serialize calc + * @param value - CSS value + * @param [opt] - options + * @returns serialized value + */ +export const serializeCalc = (value: string, opt: Options = {}): string => { + const { format = '' } = opt; + if (isString(value)) { + if (!REG_FN_VAR_START.test(value) || format !== VAL_SPEC) { + return value; + } + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'serializeCalc', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + return cachedResult.item as string; + } + const items: string[] = tokenize({ css: value }) + .map((token: CSSToken): string => { + const [type, val] = token as [TokenType, string]; + let res = ''; + if (type !== W_SPACE && type !== COMMENT) { + res = val; + } + return res; + }) + .filter(v => v); + const stack: any[][] = [[]]; + for (const item of items) { + if (REG_PAREN_OPEN.test(item)) { + const newNode = [item]; + const parent = stack[stack.length - 1]; + if (parent) { + parent.push(newNode); + } + stack.push(newNode); + } else if (item === ')') { + if (stack.length > 1) { + const currentLevel = stack.pop(); + if (currentLevel) { + currentLevel.push(item); + } + } else { + const root = stack[0]; + if (root) { + root.push(item); + } + } + } else { + const parent = stack[stack.length - 1]; + if (parent) { + parent.push(item); + } + } + } + let serializedCalc = ''; + const rootItems = stack[0]; + if (rootItems) { + if (rootItems.length === 1 && Array.isArray(rootItems[0])) { + serializedCalc = resolveNode(rootItems[0], true); + } else { + const flatItems: string[] = []; + for (const item of rootItems) { + if (Array.isArray(item)) { + flatItems.push(resolveNode(item, false)); + } else { + flatItems.push(item as string); + } + } + if (flatItems.length >= TRIA) { + serializedCalc = sortCalcValues(flatItems, true); + } else { + const firstItem = flatItems[0] || ''; + serializedCalc = + isString(firstItem) && firstItem.startsWith('calc(') + ? firstItem + : `calc(${firstItem})`; + } + } + } + setCache(cacheKey, serializedCalc); + return serializedCalc; +}; + +/** + * resolve dimension + * @param token - CSS token + * @param [opt] - options + * @returns resolved value + */ +export const resolveDimension = ( + token: CSSToken, + opt: Options = {} +): string | NullObject => { + if (!Array.isArray(token)) { + throw new TypeError(`${token} is not an array.`); + } + const [, , , , detail = {}] = token; + const { unit, value } = detail as { + unit: string; + value: number; + }; + if (unit === 'px') { + return `${value}${unit}`; + } + const pixelValue = resolveLengthInPixels(Number(value), unit, opt); + if (Number.isFinite(pixelValue)) { + return `${roundToPrecision(pixelValue, HEX)}px`; + } + return new NullObject(); +}; + +/** + * parse tokens + * @param tokens - CSS tokens + * @param [opt] - options + * @returns parsed tokens + */ +export const parseTokens = ( + tokens: CSSToken[], + opt: Options = {} +): string[] => { + if (!Array.isArray(tokens)) { + throw new TypeError(`${tokens} is not an array.`); + } + const { format = '' } = opt; + const mathFunc = new Set(); + let nest = 0; + const res: string[] = []; + for (const token of tokens) { + if (!Array.isArray(token)) { + throw new TypeError(`${token} is not an array.`); + } + const [type = '', value = ''] = token as [TokenType, string]; + switch (type) { + case DIM: { + if (format === VAL_SPEC && !mathFunc.has(nest)) { + res.push(value); + } else { + const resolvedValue = resolveDimension(token, opt); + if (isString(resolvedValue)) { + res.push(resolvedValue); + } else { + res.push(value); + } + } + break; + } + case FUNC: + case PAREN_OPEN: { + res.push(value); + nest++; + if (REG_FN_MATH_START.test(value)) { + mathFunc.add(nest); + } + break; + } + case PAREN_CLOSE: { + if (res.length) { + const lastValue = res[res.length - 1]; + if (lastValue === ' ') { + res.splice(-1, 1, value); + } else { + res.push(value); + } + } else { + res.push(value); + } + if (mathFunc.has(nest)) { + mathFunc.delete(nest); + } + nest--; + break; + } + case W_SPACE: { + if (res.length) { + const lastValue = res[res.length - 1]; + if ( + isString(lastValue) && + !lastValue.endsWith('(') && + lastValue !== ' ' + ) { + res.push(value); + } + } + break; + } + default: { + if (type !== COMMENT && type !== EOF) { + res.push(value); + } + } + } + } + return res; +}; + +/** + * CSS calc() + * @param value - CSS value including calc() + * @param [opt] - options + * @returns resolved value + */ +export const cssCalc = (value: string, opt: Options = {}): string => { + const { format = '' } = opt; + if (isString(value)) { + if (REG_FN_VAR.test(value)) { + if (format === VAL_SPEC) { + return value; + } else { + const resolvedValue = resolveVar(value, opt); + if (isString(resolvedValue)) { + return resolvedValue; + } else { + return ''; + } + } + } else if (!REG_FN_CALC.test(value)) { + return value; + } + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'cssCalc', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + return cachedResult.item as string; + } + const tokens = tokenize({ css: value }); + const values = parseTokens(tokens, opt); + let resolvedValue: string = calc(values.join(''), { + toCanonicalUnits: true + }); + if (REG_FN_VAR_START.test(value)) { + if (REG_TYPE_DIM_PCT.test(resolvedValue)) { + const [, val, unit] = resolvedValue.match( + REG_TYPE_DIM_PCT + ) as MatchedRegExp; + resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`; + } + // wrap with `calc()` + if ( + resolvedValue && + !REG_FN_VAR_START.test(resolvedValue) && + format === VAL_SPEC + ) { + resolvedValue = `calc(${resolvedValue})`; + } + } + if (format === VAL_SPEC) { + if (/\s[-+*/]\s/.test(resolvedValue) && !resolvedValue.includes('NaN')) { + resolvedValue = serializeCalc(resolvedValue, opt); + } else if (REG_FN_CALC_NUM.test(resolvedValue)) { + const [, val] = resolvedValue.match(REG_FN_CALC_NUM) as MatchedRegExp; + resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`; + } + } + setCache(cacheKey, resolvedValue); + return resolvedValue; +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/css-gradient.ts b/node_modules/@asamuzakjp/css-color/src/js/css-gradient.ts new file mode 100644 index 0000000..76be172 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/css-gradient.ts @@ -0,0 +1,374 @@ +/** + * css-gradient + */ + +import { CacheItem, createCacheKey, getCache, setCache } from './cache'; +import { resolveColor } from './resolve'; +import { isString } from './common'; +import { MatchedRegExp, Options } from './typedef'; +import { isColor, splitValue } from './util'; + +/* constants */ +import { + ANGLE, + CS_HUE, + CS_RECT, + LENGTH, + NUM, + NUM_POSITIVE, + PCT, + VAL_COMP, + VAL_SPEC +} from './constant'; +const NAMESPACE = 'css-gradient'; +const DIM_ANGLE = `${NUM}(?:${ANGLE})`; +const DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`; +const DIM_LEN = `${NUM}(?:${LENGTH})|0`; +const DIM_LEN_PCT = `${DIM_LEN}|${PCT}`; +const DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`; +const DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`; +const CTR = 'center'; +const L_R = 'left|right'; +const T_B = 'top|bottom'; +const S_E = 'start|end'; +const AXIS_X = `${L_R}|x-(?:${S_E})`; +const AXIS_Y = `${T_B}|y-(?:${S_E})`; +const BLOCK = `block-(?:${S_E})`; +const INLINE = `inline-(?:${S_E})`; +const POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`; +const POS_2 = [ + `(?:${CTR}|${AXIS_X})\\s+(?:${CTR}|${AXIS_Y})`, + `(?:${CTR}|${AXIS_Y})\\s+(?:${CTR}|${AXIS_X})`, + `(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`, + `(?:${CTR}|${BLOCK})\\s+(?:${CTR}|${INLINE})`, + `(?:${CTR}|${INLINE})\\s+(?:${CTR}|${BLOCK})`, + `(?:${CTR}|${S_E})\\s+(?:${CTR}|${S_E})` +].join('|'); +const POS_4 = [ + `(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})`, + `(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})`, + `(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})\\s+(?:${INLINE})\\s+(?:${DIM_LEN_PCT})`, + `(?:${INLINE})\\s+(?:${DIM_LEN_PCT})\\s+(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})`, + `(?:${S_E})\\s+(?:${DIM_LEN_PCT})\\s+(?:${S_E})\\s+(?:${DIM_LEN_PCT})` +].join('|'); +const RAD_EXTENT = '(?:clos|farth)est-(?:corner|side)'; +const RAD_SIZE = [ + `${RAD_EXTENT}(?:\\s+${RAD_EXTENT})?`, + `${DIM_LEN_POSI}`, + `(?:${DIM_LEN_PCT_POSI})\\s+(?:${DIM_LEN_PCT_POSI})` +].join('|'); +const RAD_SHAPE = 'circle|ellipse'; +const FROM_ANGLE = `from\\s+${DIM_ANGLE}`; +const AT_POSITION = `at\\s+(?:${POS_1}|${POS_2}|${POS_4})`; +const TO_SIDE_CORNER = `to\\s+(?:(?:${L_R})(?:\\s(?:${T_B}))?|(?:${T_B})(?:\\s(?:${L_R}))?)`; +const IN_COLOR_SPACE = `in\\s+(?:${CS_RECT}|${CS_HUE})`; +const LINE_SYNTAX_LINEAR = [ + `(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\s+${IN_COLOR_SPACE})?`, + `${IN_COLOR_SPACE}(?:\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?` +].join('|'); +const LINE_SYNTAX_RADIAL = [ + `(?:${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`, + `(?:${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`, + `${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`, + `${IN_COLOR_SPACE}(?:\\s+${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?`, + `${IN_COLOR_SPACE}(?:\\s+${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?`, + `${IN_COLOR_SPACE}(?:\\s+${AT_POSITION})?` +].join('|'); +const LINE_SYNTAX_CONIC = [ + `${FROM_ANGLE}(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`, + `${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`, + `${IN_COLOR_SPACE}(?:\\s+${FROM_ANGLE})?(?:\\s+${AT_POSITION})?` +].join('|'); +const DEFAULT_LINEAR = [/to\s+bottom/]; +const DEFAULT_RADIAL = [/ellipse/, /farthest-corner/, /at\s+center/]; +const DEFAULT_CONIC = [/at\s+center/]; + +/* type definitions */ +/** + * @type ColorStopList - list of color stops + */ +type ColorStopList = [string, string, ...string[]]; + +/** + * @typedef ValidateGradientLine - validate gradient line + * @property line - gradient line + * @property valid - result + */ +interface ValidateGradientLine { + line: string; + valid: boolean; +} + +/** + * @typedef ValidateColorStops - validate color stops + * @property colorStops - list of color stops + * @property valid - result + */ +interface ValidateColorStops { + colorStops: string[]; + valid: boolean; +} + +/** + * @typedef Gradient - parsed CSS gradient + * @property value - input value + * @property type - gradient type + * @property [gradientLine] - gradient line + * @property colorStopList - list of color stops + */ +interface Gradient { + value: string; + type: string; + gradientLine?: string; + colorStopList: ColorStopList; +} + +/* regexp */ +const IS_CONIC = /^(?:repeating-)?conic-gradient$/; +const IS_LINEAR = /^(?:repeating-)?linear-gradient$/; +const IS_RADIAL = /^(?:repeating-)?radial-gradient$/; +const REG_COLOR_HINT_CONIC = new RegExp(`^(?:${DIM_ANGLE_PCT})$`); +const REG_COLOR_HINT_NON_CONIC = new RegExp(`^(?:${DIM_LEN_PCT})$`); +const REG_DIM_CONIC = new RegExp(`(?:\\s+(?:${DIM_ANGLE_PCT})){1,2}$`); +const REG_DIM_NON_CONIC = new RegExp(`(?:\\s+(?:${DIM_LEN_PCT})){1,2}$`); +const REG_GRAD = /^(?:repeating-)?(?:conic|linear|radial)-gradient\(/; +const REG_GRAD_CAPT = /^((?:repeating-)?(?:conic|linear|radial)-gradient)\(/; +const REG_LINE_CONIC = new RegExp(`^(?:${LINE_SYNTAX_CONIC})$`); +const REG_LINE_LINEAR = new RegExp(`^(?:${LINE_SYNTAX_LINEAR})$`); +const REG_LINE_RADIAL = new RegExp(`^(?:${LINE_SYNTAX_RADIAL})$`); + +/** + * get gradient type + * @param value - gradient value + * @returns gradient type + */ +export const getGradientType = (value: string): string => { + if (isString(value)) { + value = value.trim(); + if (REG_GRAD.test(value)) { + const [, type] = value.match(REG_GRAD_CAPT) as MatchedRegExp; + return type; + } + } + return ''; +}; + +/** + * validate gradient line + * @param value - gradient line value + * @param type - gradient type + * @returns result + */ +export const validateGradientLine = ( + value: string, + type: string +): ValidateGradientLine => { + if (isString(value) && isString(type)) { + value = value.trim(); + type = type.trim(); + let reg: RegExp | null = null; + let defaultValues: RegExp[] = []; + + if (IS_LINEAR.test(type)) { + reg = REG_LINE_LINEAR; + defaultValues = DEFAULT_LINEAR; + } else if (IS_RADIAL.test(type)) { + reg = REG_LINE_RADIAL; + defaultValues = DEFAULT_RADIAL; + } else if (IS_CONIC.test(type)) { + reg = REG_LINE_CONIC; + defaultValues = DEFAULT_CONIC; + } + if (reg) { + const valid = reg.test(value); + if (valid) { + let line = value; + for (const defaultValue of defaultValues) { + line = line.replace(defaultValue, ''); + } + line = line.replace(/\s{2,}/g, ' ').trim(); + return { line, valid }; + } + return { valid, line: value }; + } + } + return { line: value, valid: false }; +}; + +/** + * validate color stop list + * @param list + * @param type + * @param [opt] + * @returns result + */ +export const validateColorStopList = ( + list: string[], + type: string, + opt: Options = {} +): ValidateColorStops => { + if (Array.isArray(list) && list.length > 1) { + const isConic = IS_CONIC.test(type); + const regColorHint = isConic + ? REG_COLOR_HINT_CONIC + : REG_COLOR_HINT_NON_CONIC; + const regDimension = isConic ? REG_DIM_CONIC : REG_DIM_NON_CONIC; + const valueList: string[] = []; + // State tracker: 'color' or 'hint' + let prevType = ''; + for (let i = 0; i < list.length; i++) { + const item = list[i]; + if (isString(item)) { + if (regColorHint.test(item)) { + // Hints cannot be the first item, and two hints cannot be adjacent + if (i === 0 || prevType === 'hint') { + return { colorStops: list, valid: false }; + } + prevType = 'hint'; + valueList.push(item); + } else { + const itemColor = item.replace(regDimension, ''); + if (isColor(itemColor, { format: VAL_SPEC })) { + const resolvedColor = resolveColor(itemColor, opt) as string; + prevType = 'color'; + valueList.push(item.replace(itemColor, resolvedColor)); + } else { + return { colorStops: list, valid: false }; + } + } + } else { + return { colorStops: list, valid: false }; + } + } + // The last item must be a color, not a hint + if (prevType !== 'color') { + return { colorStops: list, valid: false }; + } + return { valid: true, colorStops: valueList }; + } + return { colorStops: list, valid: false }; +}; + +/** + * parse CSS gradient + * @param value - gradient value + * @param [opt] - options + * @returns parsed result + */ +export const parseGradient = ( + value: string, + opt: Options = {} +): Gradient | null => { + if (isString(value)) { + value = value.trim(); + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'parseGradient', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return null; + } + return cachedResult.item as Gradient; + } + const type = getGradientType(value); + const gradValue = value.replace(REG_GRAD, '').replace(/\)$/, ''); + if (type && gradValue) { + const [lineOrColorStop = '', ...itemList] = splitValue(gradValue, { + delimiter: ',' + }); + const isConic = IS_CONIC.test(type); + const regDimension = isConic ? REG_DIM_CONIC : REG_DIM_NON_CONIC; + let colorStop = ''; + if (regDimension.test(lineOrColorStop)) { + const itemColor = lineOrColorStop.replace(regDimension, ''); + if (isColor(itemColor, { format: VAL_SPEC })) { + const resolvedColor = resolveColor(itemColor, opt) as string; + colorStop = lineOrColorStop.replace(itemColor, resolvedColor); + } + } else if (isColor(lineOrColorStop, { format: VAL_SPEC })) { + colorStop = resolveColor(lineOrColorStop, opt) as string; + } + if (colorStop) { + itemList.unshift(colorStop); + const { colorStops, valid } = validateColorStopList( + itemList, + type, + opt + ); + if (valid) { + const res: Gradient = { + value, + type, + colorStopList: colorStops as ColorStopList + }; + setCache(cacheKey, res); + return res; + } + } else if (itemList.length > 1) { + const { line: gradientLine, valid: validLine } = validateGradientLine( + lineOrColorStop, + type + ); + const { colorStops, valid: validColorStops } = validateColorStopList( + itemList, + type, + opt + ); + if (validLine && validColorStops) { + const res: Gradient = { + value, + type, + gradientLine, + colorStopList: colorStops as ColorStopList + }; + setCache(cacheKey, res); + return res; + } + } + } + setCache(cacheKey, null); + return null; + } + return null; +}; + +/** + * resolve CSS gradient + * @param value - CSS value + * @param [opt] - options + * @returns result + */ +export const resolveGradient = (value: string, opt: Options = {}): string => { + const { format = VAL_COMP } = opt; + const gradient = parseGradient(value, opt); + if (gradient) { + const { type = '', gradientLine = '', colorStopList = [] } = gradient; + if (type && Array.isArray(colorStopList) && colorStopList.length > 1) { + if (gradientLine) { + return `${type}(${gradientLine}, ${colorStopList.join(', ')})`; + } + return `${type}(${colorStopList.join(', ')})`; + } + } + if (format === VAL_SPEC) { + return ''; + } + return 'none'; +}; + +/** + * is CSS gradient + * @param value - CSS value + * @param [opt] - options + * @returns result + */ +export const isGradient = (value: string, opt: Options = {}): boolean => { + const gradient = parseGradient(value, opt); + return gradient !== null; +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/css-var.ts b/node_modules/@asamuzakjp/css-color/src/js/css-var.ts new file mode 100644 index 0000000..a488edd --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/css-var.ts @@ -0,0 +1,236 @@ +/** + * css-var + */ + +import { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer'; +import { + CacheItem, + NullObject, + createCacheKey, + getCache, + setCache +} from './cache'; +import { isString } from './common'; +import { cssCalc } from './css-calc'; +import { isColor } from './util'; +import { Options } from './typedef'; + +/* constants */ +import { FN_VAR, SYN_FN_CALC, SYN_FN_VAR, VAL_SPEC } from './constant'; +const { + CloseParen: PAREN_CLOSE, + Comment: COMMENT, + EOF, + Ident: IDENT, + Whitespace: W_SPACE +} = TokenType; +const NAMESPACE = 'css-var'; + +/* regexp */ +const REG_FN_CALC = new RegExp(SYN_FN_CALC); +const REG_FN_VAR = new RegExp(SYN_FN_VAR); +const REG_CSS_WIDE_KEYWORD = /^(?:inherit|initial|revert(?:-layer)?|unset)$/; + +/** + * resolve custom property + * @param tokens - CSS tokens + * @param [opt] - options + * @returns result - [tokens, resolvedValue] + */ +export function resolveCustomProperty( + tokens: CSSToken[], + opt: Options = {} +): [CSSToken[], string] { + if (!Array.isArray(tokens)) { + throw new TypeError(`${tokens} is not an array.`); + } + const { customProperty = {} } = opt; + const items: string[] = []; + while (tokens.length) { + const token = tokens.shift(); + if (!token) { + break; + } + if (!Array.isArray(token)) { + throw new TypeError(`${token} is not an array.`); + } + const [type, value] = token as [TokenType, string]; + // end of var() + if (type === PAREN_CLOSE) { + break; + } + // nested var() + if (value === FN_VAR) { + const [, item] = resolveCustomProperty(tokens, opt); + if (item) { + items.push(item); + } + } else if (type === IDENT) { + if (value.startsWith('--')) { + let item; + if (Object.hasOwn(customProperty, value)) { + item = customProperty[value] as string; + } else if (typeof customProperty.callback === 'function') { + item = customProperty.callback(value); + } + if (item) { + items.push(item); + } + } else if (value) { + items.push(value); + } + } + } + let resolveAsColor = false; + if (items.length > 1) { + resolveAsColor = isColor(items[items.length - 1]); + } + let resolvedValue = ''; + for (let item of items) { + item = item.trim(); + if (REG_FN_VAR.test(item)) { + // recurse resolveVar() + const resolvedItem = resolveVar(item, opt); + if (isString(resolvedItem)) { + if (!resolveAsColor || isColor(resolvedItem)) { + resolvedValue = resolvedItem; + } + } + } else if (REG_FN_CALC.test(item)) { + item = cssCalc(item, opt); + if (!resolveAsColor || isColor(item)) { + resolvedValue = item; + } + } else if (item && !REG_CSS_WIDE_KEYWORD.test(item)) { + if (!resolveAsColor || isColor(item)) { + resolvedValue = item; + } + } + if (resolvedValue) { + break; + } + } + return [tokens, resolvedValue]; +} + +/** + * parse tokens + * @param tokens - CSS tokens + * @param [opt] - options + * @returns parsed tokens + */ +export function parseTokens( + tokens: CSSToken[], + opt: Options = {} +): string[] | NullObject { + const res: string[] = []; + while (tokens.length) { + const token = tokens.shift(); + if (!token) break; + const [type = '', value = ''] = token as [TokenType, string]; + if (value === FN_VAR) { + const [, resolvedValue] = resolveCustomProperty(tokens, opt); + if (!resolvedValue) { + return new NullObject(); + } + res.push(resolvedValue); + } else { + switch (type) { + case PAREN_CLOSE: { + if (res.length) { + if (res[res.length - 1] === ' ') { + res[res.length - 1] = value; + } else { + res.push(value); + } + } else { + res.push(value); + } + break; + } + case W_SPACE: { + if (res.length) { + const lastValue = res[res.length - 1]; + if ( + isString(lastValue) && + !lastValue.endsWith('(') && + lastValue !== ' ' + ) { + res.push(value); + } + } + break; + } + default: { + if (type !== COMMENT && type !== EOF) { + res.push(value); + } + } + } + } + } + return res; +} + +/** + * resolve CSS var() + * @param value - CSS value including var() + * @param [opt] - options + * @returns resolved value + */ +export function resolveVar( + value: string, + opt: Options = {} +): string | NullObject { + const { format = '' } = opt; + if (isString(value)) { + if (!REG_FN_VAR.test(value) || format === VAL_SPEC) { + return value; + } + value = value.trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'resolveVar', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + return cachedResult.item as string; + } + const tokens = tokenize({ css: value }); + const values = parseTokens(tokens, opt); + if (Array.isArray(values)) { + let color = values.join(''); + if (REG_FN_CALC.test(color)) { + color = cssCalc(color, opt); + } + setCache(cacheKey, color); + return color; + } else { + setCache(cacheKey, null); + return new NullObject(); + } +} + +/** + * CSS var() + * @param value - CSS value including var() + * @param [opt] - options + * @returns resolved value + */ +export const cssVar = (value: string, opt: Options = {}): string => { + const resolvedValue = resolveVar(value, opt); + if (isString(resolvedValue)) { + return resolvedValue; + } + return ''; +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/relative-color.ts b/node_modules/@asamuzakjp/css-color/src/js/relative-color.ts new file mode 100644 index 0000000..dedee92 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/relative-color.ts @@ -0,0 +1,673 @@ +/** + * relative-color + */ + +import { SyntaxFlag, color as colorParser } from '@csstools/css-color-parser'; +import { + ComponentValue, + parseComponentValue +} from '@csstools/css-parser-algorithms'; +import { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer'; +import { + CacheItem, + NullObject, + createCacheKey, + getCache, + setCache +} from './cache'; +import { NAMED_COLORS, convertColorToRgb } from './color'; +import { isString, isStringOrNumber } from './common'; +import { resolveDimension, serializeCalc } from './css-calc'; +import { resolveColor } from './resolve'; +import { roundToPrecision, splitValue } from './util'; +import { + ColorChannels, + MatchedRegExp, + Options, + StringColorChannels +} from './typedef'; + +/* constants */ +import { + CS_LAB, + CS_LCH, + FN_LIGHT_DARK, + FN_REL, + FN_REL_CAPT, + FN_VAR, + NONE, + SYN_COLOR_TYPE, + SYN_FN_MATH_START, + SYN_FN_VAR, + SYN_MIX, + VAL_SPEC +} from './constant'; +const { + CloseParen: PAREN_CLOSE, + Comment: COMMENT, + Delim: DELIM, + Dimension: DIM, + EOF, + Function: FUNC, + Ident: IDENT, + Number: NUM, + OpenParen: PAREN_OPEN, + Percentage: PCT, + Whitespace: W_SPACE +} = TokenType; +const { HasNoneKeywords: KEY_NONE } = SyntaxFlag; +const NAMESPACE = 'relative-color'; + +/* constants */ +const OCT = 8; +const DEC = 10; +const HEX = 16; +const MAX_PCT = 100; +const MAX_RGB = 255; +const COLOR_CHANNELS = new Map([ + ['color', ['r', 'g', 'b', 'alpha']], + ['hsl', ['h', 's', 'l', 'alpha']], + ['hsla', ['h', 's', 'l', 'alpha']], + ['hwb', ['h', 'w', 'b', 'alpha']], + ['lab', ['l', 'a', 'b', 'alpha']], + ['lch', ['l', 'c', 'h', 'alpha']], + ['oklab', ['l', 'a', 'b', 'alpha']], + ['oklch', ['l', 'c', 'h', 'alpha']], + ['rgb', ['r', 'g', 'b', 'alpha']], + ['rgba', ['r', 'g', 'b', 'alpha']] +]); + +/* type definitions */ +/** + * @type NumberOrStringColorChannels - color channel + */ +type NumberOrStringColorChannels = ColorChannels & StringColorChannels; + +/* regexp */ +const REG_COLOR_CAPT = new RegExp( + `^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\s+` +); +const REG_CS_HSL = /(?:hsla?|hwb)$/; +const REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`); +const REG_FN_CALC_SUM = /^(?:abs|sig?n|cos|tan)\(/; +const REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START); +const REG_FN_REL = new RegExp(FN_REL); +const REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`); +const REG_FN_REL_START = new RegExp(`^${FN_REL}`); +const REG_FN_VAR = new RegExp(SYN_FN_VAR); + +/** + * resolve relative color channels + * @param value + * - CSS color value + * - system colors are not supported + * @param [opt] - options + * @param [opt.currentColor] + * - color to use for `currentcolor` keyword + * - if omitted, it will be treated as a missing color + * i.e. `rgb(none none none / none)` + * @param [opt.customProperty] + * - custom properties + * - pair of `--` prefixed property name and value, + * e.g. `customProperty: { '--some-color': '#0000ff' }` + * - and/or `callback` function to get the value of the custom property, + * e.g. `customProperty: { callback: someDeclaration.getPropertyValue }` + * @param [opt.dimension] + * - dimension, convert relative length to pixels + * - pair of unit and it's value as a number in pixels, + * e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }` + * - and/or `callback` function to get the value as a number in pixels, + * e.g. `dimension: { callback: convertUnitToPixel }` + * @param [opt.format] + * - output format, one of below + * - `computedValue` (default), [computed value][139] of the color + * - `specifiedValue`, [specified value][140] of the color + * - `hex`, hex color notation, i.e. `rrggbb` + * - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa` + * @returns + * - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)', + * color(color-space r g b / alpha), color(color-space x y z / alpha), + * lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha), + * oklch(l c h / alpha), null + * - in `computedValue`, values are numbers, however `rgb()` values are + * integers + * - in `specifiedValue`, returns `empty string` for unknown and/or invalid + * color + * - in `hex`, returns `null` for `transparent`, and also returns `null` if + * any of `r`, `g`, `b`, `alpha` is not a number + * - in `hexAlpha`, returns `#00000000` for `transparent`, + * however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number + */ +export function resolveColorChannels( + tokens: CSSToken[], + opt: Options = {} +): NumberOrStringColorChannels | NullObject { + if (!Array.isArray(tokens)) { + throw new TypeError(`${tokens} is not an array.`); + } + const { colorSpace = '', format = '' } = opt; + const colorChannel = COLOR_CHANNELS.get(colorSpace); + // invalid color channel + if (!colorChannel) { + return new NullObject(); + } + const mathFunc = new Set(); + const channels: [ + (number | string)[], + (number | string)[], + (number | string)[], + (number | string)[] + ] = [[], [], [], []]; + let i = 0; + let nest = 0; + let func = ''; + let precededPct = false; + for (const token of tokens) { + if (!Array.isArray(token)) { + throw new TypeError(`${token} is not an array.`); + } + const [type, value, , , detail] = token as [ + TokenType, + string, + number, + number, + { value: string | number } | undefined + ]; + const channel = channels[i]; + if (Array.isArray(channel)) { + switch (type) { + case DELIM: { + if (func) { + if ( + (value === '+' || value === '-') && + precededPct && + !REG_FN_CALC_SUM.test(func) + ) { + return new NullObject(); + } + precededPct = false; + channel.push(value); + } + break; + } + case DIM: { + if (!func || !REG_FN_CALC_SUM.test(func)) { + return new NullObject(); + } + const resolvedValue = resolveDimension(token, opt); + if (isString(resolvedValue)) { + channel.push(resolvedValue); + } else { + channel.push(value); + } + break; + } + case FUNC: { + channel.push(value); + func = value; + nest++; + if (REG_FN_MATH_START.test(value)) { + mathFunc.add(nest); + } + break; + } + case IDENT: { + // invalid channel key + if (!colorChannel.includes(value)) { + return new NullObject(); + } + channel.push(value); + if (!func) { + i++; + } + break; + } + case NUM: { + channel.push(Number(detail?.value)); + if (!func) { + i++; + } + break; + } + case PAREN_OPEN: { + channel.push(value); + nest++; + break; + } + case PAREN_CLOSE: { + if (func) { + const lastValue = channel[channel.length - 1]; + if (lastValue === ' ') { + channel[channel.length - 1] = value; + } else { + channel.push(value); + } + if (mathFunc.has(nest)) { + mathFunc.delete(nest); + } + nest--; + if (nest === 0) { + func = ''; + i++; + } + } + break; + } + case PCT: { + if (!func) { + return new NullObject(); + } else if (!REG_FN_CALC_SUM.test(func)) { + let lastValue: string | number | undefined; + for (let j = channel.length - 1; j >= 0; j--) { + if (channel[j] !== ' ') { + lastValue = channel[j]; + break; + } + } + if (lastValue === '+' || lastValue === '-') { + return new NullObject(); + } else if (lastValue === '*' || lastValue === '/') { + precededPct = false; + } else { + precededPct = true; + } + } + channel.push(Number(detail?.value) / MAX_PCT); + break; + } + case W_SPACE: { + if (channel.length && func) { + const lastValue = channel[channel.length - 1]; + if (typeof lastValue === 'number') { + channel.push(value); + } else if ( + isString(lastValue) && + !lastValue.endsWith('(') && + lastValue !== ' ' + ) { + channel.push(value); + } + } + break; + } + default: { + if (type !== COMMENT && type !== EOF && func) { + channel.push(value); + } + } + } + } + } + const channelValues = []; + for (const channel of channels) { + if (channel.length === 1) { + const [resolvedValue] = channel; + if (isStringOrNumber(resolvedValue)) { + channelValues.push(resolvedValue); + } + } else if (channel.length) { + const resolvedValue = serializeCalc(channel.join(''), { + format + }); + channelValues.push(resolvedValue); + } + } + return channelValues as NumberOrStringColorChannels; +} + +/** + * extract origin color + * @param value - CSS color value + * @param [opt] - options + * @returns origin color value + */ +export function extractOriginColor( + value: string, + opt: Options = {} +): string | NullObject { + const { colorScheme = 'normal', currentColor = '', format = '' } = opt; + if (isString(value)) { + value = value.toLowerCase().trim(); + if (!value) { + return new NullObject(); + } + if (!REG_FN_REL_START.test(value)) { + return value; + } + } else { + return new NullObject(); + } + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'extractOriginColor', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + return cachedResult.item as string; + } + if (/currentcolor/.test(value)) { + if (currentColor) { + value = value.replace(/currentcolor/g, currentColor); + } else { + setCache(cacheKey, null); + return new NullObject(); + } + } + let colorSpace = ''; + if (REG_FN_REL_CAPT.test(value)) { + [, colorSpace] = value.match(REG_FN_REL_CAPT) as MatchedRegExp; + } + opt.colorSpace = colorSpace; + if (value.includes(FN_LIGHT_DARK)) { + const colorParts = value + .replace(new RegExp(`^${colorSpace}\\(`), '') + .replace(/\)$/, ''); + const [, originColor = ''] = splitValue(colorParts); + const specifiedOriginColor = resolveColor(originColor, { + colorScheme, + format: VAL_SPEC + }) as string; + if (specifiedOriginColor === '') { + setCache(cacheKey, null); + return new NullObject(); + } + if (format === VAL_SPEC) { + value = value.replace(originColor, specifiedOriginColor); + } else { + const resolvedOriginColor = resolveColor(specifiedOriginColor, opt); + if (isString(resolvedOriginColor)) { + value = value.replace(originColor, resolvedOriginColor); + } + } + } + if (REG_COLOR_CAPT.test(value)) { + const [, originColor] = value.match(REG_COLOR_CAPT) as MatchedRegExp; + const [, restValue] = value.split(originColor) as MatchedRegExp; + if (/^[a-z]+$/.test(originColor)) { + if ( + !/^transparent$/.test(originColor) && + !Object.hasOwn(NAMED_COLORS, originColor) + ) { + setCache(cacheKey, null); + return new NullObject(); + } + } else if (format === VAL_SPEC) { + const resolvedOriginColor = resolveColor(originColor, opt); + if (isString(resolvedOriginColor)) { + value = value.replace(originColor, resolvedOriginColor); + } + } + if (format === VAL_SPEC) { + const tokens = tokenize({ css: restValue }); + const channelValues = resolveColorChannels(tokens, opt); + if (channelValues instanceof NullObject) { + setCache(cacheKey, null); + return channelValues; + } + const [v1, v2, v3, v4] = channelValues; + let channelValue = ''; + if (isStringOrNumber(v4)) { + channelValue = ` ${v1} ${v2} ${v3} / ${v4})`; + } else { + channelValue = ` ${channelValues.join(' ')})`; + } + if (restValue !== channelValue) { + value = value.replace(restValue, channelValue); + } + } + } else { + // nested relative color + const [, restValue] = value.split(REG_FN_REL_START) as MatchedRegExp; + const tokens = tokenize({ css: restValue }); + const originColor: string[] = []; + let nest = 0; + let tokenIndex = 0; + for (const [type, tokenValue] of tokens) { + tokenIndex++; + switch (type) { + case FUNC: + case PAREN_OPEN: { + originColor.push(tokenValue); + nest++; + break; + } + case PAREN_CLOSE: { + const lastValue = originColor[originColor.length - 1]; + if (lastValue === ' ') { + originColor[originColor.length - 1] = tokenValue; + } else if (isString(lastValue)) { + originColor.push(tokenValue); + } + nest--; + break; + } + case W_SPACE: { + const lastValue = originColor[originColor.length - 1]; + if ( + isString(lastValue) && + !lastValue.endsWith('(') && + lastValue !== ' ' + ) { + originColor.push(tokenValue); + } + break; + } + default: { + if (type !== COMMENT && type !== EOF) { + originColor.push(tokenValue); + } + } + } + if (nest === 0) { + break; + } + } + const resolvedOriginColor = resolveRelativeColor( + originColor.join('').trim(), + opt + ); + if (resolvedOriginColor instanceof NullObject) { + setCache(cacheKey, null); + return resolvedOriginColor; + } + const channelValues = resolveColorChannels(tokens.slice(tokenIndex), opt); + if (channelValues instanceof NullObject) { + setCache(cacheKey, null); + return channelValues; + } + const [v1, v2, v3, v4] = channelValues; + let channelValue = ''; + if (isStringOrNumber(v4)) { + channelValue = ` ${v1} ${v2} ${v3} / ${v4})`; + } else { + channelValue = ` ${channelValues.join(' ')})`; + } + value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`); + } + setCache(cacheKey, value); + return value; +} + +/** + * resolve relative color + * @param value - CSS relative color value + * @param [opt] - options + * @returns resolved value + */ +export function resolveRelativeColor( + value: string, + opt: Options = {} +): string | NullObject { + const { format = '' } = opt; + if (isString(value)) { + if (REG_FN_VAR.test(value)) { + // var() must be resolved before resolveRelativeColor() + if (format !== VAL_SPEC) { + throw new SyntaxError(`Unexpected token ${FN_VAR} found.`); + } + return value; + } else if (!REG_FN_REL.test(value)) { + return value; + } + value = value.toLowerCase().trim(); + } else { + throw new TypeError(`${value} is not a string.`); + } + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'resolveRelativeColor', + value + }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + return cachedResult.item as string; + } + const originColor = extractOriginColor(value, opt); + if (originColor instanceof NullObject) { + setCache(cacheKey, null); + return originColor; + } + value = originColor; + if (format === VAL_SPEC) { + if (value.startsWith('rgba(')) { + value = value.replace('rgba(', 'rgb('); + } else if (value.startsWith('hsla(')) { + value = value.replace('hsla(', 'hsl('); + } + return value; + } + const tokens = tokenize({ css: value }); + const components = parseComponentValue(tokens) as ComponentValue; + const parsedComponents = colorParser(components); + if (!parsedComponents) { + setCache(cacheKey, null); + return new NullObject(); + } + const { + alpha: alphaComponent, + channels: channelsComponent, + colorNotation, + syntaxFlags + } = parsedComponents; + let alpha: number | string; + if (Number.isNaN(Number(alphaComponent))) { + if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) { + alpha = NONE; + } else { + alpha = 0; + } + } else { + alpha = roundToPrecision(Number(alphaComponent), OCT); + } + let v1: number | string; + let v2: number | string; + let v3: number | string; + [v1, v2, v3] = channelsComponent; + let resolvedValue; + if (REG_CS_CIE.test(colorNotation)) { + const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE); + if (Number.isNaN(v1)) { + if (hasNone) { + v1 = NONE; + } else { + v1 = 0; + } + } else { + v1 = roundToPrecision(v1, HEX); + } + if (Number.isNaN(v2)) { + if (hasNone) { + v2 = NONE; + } else { + v2 = 0; + } + } else { + v2 = roundToPrecision(v2, HEX); + } + if (Number.isNaN(v3)) { + if (hasNone) { + v3 = NONE; + } else { + v3 = 0; + } + } else { + v3 = roundToPrecision(v3, HEX); + } + if (alpha === 1) { + resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`; + } else { + resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`; + } + } else if (REG_CS_HSL.test(colorNotation)) { + if (Number.isNaN(v1)) { + v1 = 0; + } + if (Number.isNaN(v2)) { + v2 = 0; + } + if (Number.isNaN(v3)) { + v3 = 0; + } + let [r, g, b] = convertColorToRgb( + `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})` + ) as ColorChannels; + r = roundToPrecision(r / MAX_RGB, DEC); + g = roundToPrecision(g / MAX_RGB, DEC); + b = roundToPrecision(b / MAX_RGB, DEC); + if (alpha === 1) { + resolvedValue = `color(srgb ${r} ${g} ${b})`; + } else { + resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`; + } + } else { + const cs = colorNotation === 'rgb' ? 'srgb' : colorNotation; + const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE); + if (Number.isNaN(v1)) { + if (hasNone) { + v1 = NONE; + } else { + v1 = 0; + } + } else { + v1 = roundToPrecision(v1, DEC); + } + if (Number.isNaN(v2)) { + if (hasNone) { + v2 = NONE; + } else { + v2 = 0; + } + } else { + v2 = roundToPrecision(v2, DEC); + } + if (Number.isNaN(v3)) { + if (hasNone) { + v3 = NONE; + } else { + v3 = 0; + } + } else { + v3 = roundToPrecision(v3, DEC); + } + if (alpha === 1) { + resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`; + } else { + resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`; + } + } + setCache(cacheKey, resolvedValue); + return resolvedValue; +} diff --git a/node_modules/@asamuzakjp/css-color/src/js/resolve.ts b/node_modules/@asamuzakjp/css-color/src/js/resolve.ts new file mode 100644 index 0000000..4768778 --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/resolve.ts @@ -0,0 +1,322 @@ +/** + * resolve + */ + +import { + CacheItem, + NullObject, + createCacheKey, + getCache, + setCache +} from './cache'; +import { + convertRgbToHex, + resolveColorFunc, + resolveColorMix, + resolveColorValue +} from './color'; +import { isString } from './common'; +import { cssCalc } from './css-calc'; +import { resolveVar } from './css-var'; +import { resolveRelativeColor } from './relative-color'; +import { splitValue } from './util'; +import { + ComputedColorChannels, + Options, + SpecifiedColorChannels +} from './typedef'; + +/* constants */ +import { + FN_COLOR, + FN_MIX, + SYN_FN_CALC, + SYN_FN_LIGHT_DARK, + SYN_FN_REL, + SYN_FN_VAR, + VAL_COMP, + VAL_SPEC +} from './constant'; +const NAMESPACE = 'resolve'; +const RGB_TRANSPARENT = 'rgba(0, 0, 0, 0)'; + +/* regexp */ +const REG_FN_CALC = new RegExp(SYN_FN_CALC); +const REG_FN_LIGHT_DARK = new RegExp(SYN_FN_LIGHT_DARK); +const REG_FN_REL = new RegExp(SYN_FN_REL); +const REG_FN_VAR = new RegExp(SYN_FN_VAR); + +/** + * resolve color + * @param value - CSS color value + * @param [opt] - options + * @returns resolved color + */ +export const resolveColor = ( + value: string, + opt: Options = {} +): string | NullObject => { + if (!isString(value)) { + throw new TypeError(`${value} is not a string.`); + } + value = value.trim(); + const { + colorScheme = 'normal', + currentColor = '', + format = VAL_COMP, + nullable = false + } = opt; + const cacheKey: string = createCacheKey( + { namespace: NAMESPACE, name: 'resolve', value }, + opt + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + if (cachedResult.isNull) { + return cachedResult as NullObject; + } + return cachedResult.item as string; + } + // 1. var() resolution + if (REG_FN_VAR.test(value)) { + if (format === VAL_SPEC) { + setCache(cacheKey, value); + return value; + } + const resolvedVar = resolveVar(value, opt); + if (resolvedVar instanceof NullObject) { + const res = + format === 'hex' || format === 'hexAlpha' || nullable + ? resolvedVar + : RGB_TRANSPARENT; + setCache(cacheKey, res); + return res; + } + value = resolvedVar; + } + if (opt.format !== format) { + opt.format = format; + } + value = value.toLowerCase(); + // 2. light-dark() resolution + if (REG_FN_LIGHT_DARK.test(value) && value.endsWith(')')) { + const colorParts = value.replace(REG_FN_LIGHT_DARK, '').replace(/\)$/, ''); + const [light = '', dark = ''] = splitValue(colorParts, { delimiter: ',' }); + if (light && dark) { + if (format === VAL_SPEC) { + const lightColor = resolveColor(light, opt); + const darkColor = resolveColor(dark, opt); + const res = + lightColor && darkColor + ? `light-dark(${lightColor}, ${darkColor})` + : ''; + setCache(cacheKey, res); + return res; + } + const chosen = colorScheme === 'dark' ? dark : light; + const resolved = resolveColor(chosen, opt); + const res = + resolved instanceof NullObject && !nullable + ? RGB_TRANSPARENT + : resolved; + setCache(cacheKey, res); + return res; + } + // fallback for invalid light-dark + const invalidRes = + format === VAL_SPEC + ? '' + : format === 'hex' || format === 'hexAlpha' + ? new NullObject() + : RGB_TRANSPARENT; + setCache(cacheKey, invalidRes); + return invalidRes; + } + // 3. Relative Color resolution + if (REG_FN_REL.test(value)) { + const resolvedRel = resolveRelativeColor(value, opt); + if (format === VAL_COMP) { + const res = + resolvedRel instanceof NullObject && !nullable + ? RGB_TRANSPARENT + : resolvedRel; + setCache(cacheKey, res); + return res; + } + if (format === VAL_SPEC) { + const res = resolvedRel instanceof NullObject ? '' : resolvedRel; + setCache(cacheKey, res); + return res; + } + value = resolvedRel instanceof NullObject ? '' : resolvedRel; + } + // 4. calc() resolution + if (REG_FN_CALC.test(value)) { + value = cssCalc(value, opt); + } + // 5. Keyword & Color-space resolution + let cs = ''; + let r = NaN; + let g = NaN; + let b = NaN; + let alpha = NaN; + if (value === 'transparent') { + let res: string | NullObject; + switch (format) { + case VAL_SPEC: { + res = value; + break; + } + case 'hex': { + res = new NullObject(); + break; + } + case 'hexAlpha': { + res = '#00000000'; + break; + } + default: { + res = RGB_TRANSPARENT; + } + } + setCache(cacheKey, res); + return res; + } + if (value === 'currentcolor') { + if (format === VAL_SPEC) { + setCache(cacheKey, value); + return value; + } + if (currentColor) { + let resolvedCurrent; + if (currentColor.startsWith(FN_MIX)) { + resolvedCurrent = resolveColorMix(currentColor, opt); + } else if (currentColor.startsWith(FN_COLOR)) { + resolvedCurrent = resolveColorFunc(currentColor, opt); + } else { + resolvedCurrent = resolveColorValue(currentColor, opt); + } + if (resolvedCurrent instanceof NullObject) { + setCache(cacheKey, resolvedCurrent); + return resolvedCurrent; + } + [cs, r, g, b, alpha] = resolvedCurrent as ComputedColorChannels; + } else { + // value is handled below if not VAL_COMP + const res = format === VAL_COMP ? RGB_TRANSPARENT : value; + if (format === VAL_COMP) { + setCache(cacheKey, res); + return res; + } + } + } else if (format === VAL_SPEC) { + let res = ''; + if (value.startsWith(FN_MIX)) { + res = resolveColorMix(value, opt) as string; + } else if (value.startsWith(FN_COLOR)) { + const [scs, rr, gg, bb, aa] = resolveColorFunc( + value, + opt + ) as SpecifiedColorChannels; + res = + aa === 1 + ? `color(${scs} ${rr} ${gg} ${bb})` + : `color(${scs} ${rr} ${gg} ${bb} / ${aa})`; + } else { + const rgb = resolveColorValue(value, opt); + if (isString(rgb)) { + res = rgb; + } else { + const [scs, rr, gg, bb, aa] = rgb as SpecifiedColorChannels; + if (scs === 'rgb') { + res = + aa === 1 + ? `${scs}(${rr}, ${gg}, ${bb})` + : `${scs}a(${rr}, ${gg}, ${bb}, ${aa})`; + } else { + res = + aa === 1 + ? `${scs}(${rr} ${gg} ${bb})` + : `${scs}(${rr} ${gg} ${bb} / ${aa})`; + } + } + } + setCache(cacheKey, res); + return res; + } else if (value.startsWith(FN_MIX)) { + if (currentColor) { + value = value.replace(/currentcolor/g, currentColor); + } + value = value.replace(/transparent/g, RGB_TRANSPARENT); + const resolvedMix = resolveColorMix(value, opt); + if (resolvedMix instanceof NullObject) { + setCache(cacheKey, resolvedMix); + return resolvedMix; + } + [cs, r, g, b, alpha] = resolvedMix as ComputedColorChannels; + } else if (value.startsWith(FN_COLOR)) { + const resolvedFunc = resolveColorFunc(value, opt); + if (resolvedFunc instanceof NullObject) { + setCache(cacheKey, resolvedFunc); + return resolvedFunc; + } + [cs, r, g, b, alpha] = resolvedFunc as ComputedColorChannels; + } else if (value) { + const resolvedVal = resolveColorValue(value, opt); + if (resolvedVal instanceof NullObject) { + setCache(cacheKey, resolvedVal); + return resolvedVal; + } + [cs, r, g, b, alpha] = resolvedVal as ComputedColorChannels; + } + // 6. Format Finalization + let finalRes: string | NullObject = ''; + switch (format) { + case 'hex': + case 'hexAlpha': { + if ( + Number.isNaN(r) || + Number.isNaN(g) || + Number.isNaN(b) || + Number.isNaN(alpha) || + (format === 'hex' && alpha === 0) + ) { + finalRes = new NullObject(); + } else { + finalRes = convertRgbToHex([r, g, b, format === 'hex' ? 1 : alpha]); + } + break; + } + default: { + if (cs === 'rgb') { + finalRes = + alpha === 1 + ? `${cs}(${r}, ${g}, ${b})` + : `${cs}a(${r}, ${g}, ${b}, ${alpha})`; + } else if (['lab', 'lch', 'oklab', 'oklch'].includes(cs)) { + finalRes = + alpha === 1 + ? `${cs}(${r} ${g} ${b})` + : `${cs}(${r} ${g} ${b} / ${alpha})`; + } else { + finalRes = + alpha === 1 + ? `color(${cs} ${r} ${g} ${b})` + : `color(${cs} ${r} ${g} ${b} / ${alpha})`; + } + } + } + setCache(cacheKey, finalRes); + return finalRes; +}; + +/** + * resolve CSS color + * @param value - CSS color value. system colors are not supported + * @param [opt] - options + */ +export const resolve = (value: string, opt: Options = {}): string | null => { + opt.nullable = false; + const resolvedValue = resolveColor(value, opt); + return resolvedValue instanceof NullObject ? null : (resolvedValue as string); +}; diff --git a/node_modules/@asamuzakjp/css-color/src/js/typedef.ts b/node_modules/@asamuzakjp/css-color/src/js/typedef.ts new file mode 100644 index 0000000..007363e --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/typedef.ts @@ -0,0 +1,88 @@ +/** + * typedef + */ + +/* type definitions */ +/** + * @typedef Options - options + * @property [alpha] - enable alpha + * @property [colorSpace] - color space + * @property [currentColor] - color for currentcolor + * @property [customProperty] - custom properties + * @property [d50] - white point in d50 + * @property [dimension] - dimension + * @property [format] - output format + * @property [key] - key + */ +export interface Options { + alpha?: boolean; + colorScheme?: string; + colorSpace?: string; + currentColor?: string; + customProperty?: Record string)>; + d50?: boolean; + delimiter?: string | string[]; + dimension?: Record number)>; + format?: string; + nullable?: boolean; + preserveComment?: boolean; +} + +/** + * @type ColorChannels - color channels + */ +export type ColorChannels = [x: number, y: number, z: number, alpha: number]; + +/** + * @type StringColorChannels - color channels + */ +export type StringColorChannels = [ + x: string, + y: string, + z: string, + alpha: string | undefined +]; + +/** + * @type StringColorSpacedChannels - specified value + */ +export type StringColorSpacedChannels = [ + cs: string, + x: string, + y: string, + z: string, + alpha: string | undefined +]; + +/** + * @type ComputedColorChannels - computed value + */ +export type ComputedColorChannels = [ + cs: string, + x: number, + y: number, + z: number, + alpha: number +]; + +/** + * @type SpecifiedColorChannels - specified value + */ +export type SpecifiedColorChannels = [ + cs: string, + x: number | string, + y: number | string, + z: number | string, + alpha: number | string +]; + +/** + * @type MatchedRegExp - matched regexp array + */ +export type MatchedRegExp = [ + match: string, + gr1: string, + gr2: string, + gr3: string, + gr4: string +]; diff --git a/node_modules/@asamuzakjp/css-color/src/js/util.ts b/node_modules/@asamuzakjp/css-color/src/js/util.ts new file mode 100644 index 0000000..e7a7c4d --- /dev/null +++ b/node_modules/@asamuzakjp/css-color/src/js/util.ts @@ -0,0 +1,423 @@ +/** + * util + */ + +import { TokenType, tokenize } from '@csstools/css-tokenizer'; +import { CacheItem, createCacheKey, getCache, setCache } from './cache'; +import { isString } from './common'; +import { resolveColor } from './resolve'; +import { Options } from './typedef'; + +/* constants */ +import { NAMED_COLORS } from './color'; +import { SYN_COLOR_TYPE, SYN_MIX, VAL_SPEC } from './constant'; +const { + CloseParen: PAREN_CLOSE, + Comma: COMMA, + Comment: COMMENT, + Delim: DELIM, + EOF, + Function: FUNC, + OpenParen: PAREN_OPEN, + Whitespace: W_SPACE +} = TokenType; +const NAMESPACE = 'util'; + +/* numeric constants */ +const DEC = 10; +const HEX = 16; +const DEG = 360; +const DEG_HALF = 180; + +/* regexp */ +const REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`); +const REG_DIMENSION = /^([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)([a-z]*)$/i; +const REG_FN_COLOR = + /^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\(/; +const REG_MIX = new RegExp(SYN_MIX); +const REG_DASHED_IDENT = /--[\w-]+/g; +const REG_COMMA = /^,$/; +const REG_SLASH = /^\/$/; +const REG_WHITESPACE = /^\s+$/; + +/** + * split value + * NOTE: comments are stripped, it can be preserved if, in the options param, + * `delimiter` is either ',' or '/' and with `preserveComment` set to `true` + * @param value - CSS value + * @param [opt] - options + * @returns array of values + */ +export const splitValue = (value: string, opt: Options = {}): string[] => { + if (!isString(value)) { + throw new TypeError(`${value} is not a string.`); + } + const strValue = value.trim(); + const { delimiter = ' ', preserveComment = false } = opt; + const cacheKey: string = createCacheKey( + { + namespace: NAMESPACE, + name: 'splitValue', + value: strValue + }, + { delimiter, preserveComment } + ); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + return cachedResult.item as string[]; + } + let regDelimiter; + switch (delimiter) { + case ',': { + regDelimiter = REG_COMMA; + break; + } + case '/': { + regDelimiter = REG_SLASH; + break; + } + default: { + regDelimiter = REG_WHITESPACE; + } + } + const tokens = tokenize({ css: strValue }); + let nest = 0; + let currentStr = ''; + const res: string[] = []; + for (const [type, val] of tokens) { + switch (type) { + case COMMA: + case DELIM: { + if (nest === 0 && regDelimiter.test(val)) { + res.push(currentStr.trim()); + currentStr = ''; + } else { + currentStr += val; + } + break; + } + case COMMENT: { + if (preserveComment && (delimiter === ',' || delimiter === '/')) { + currentStr += val; + } + break; + } + case FUNC: + case PAREN_OPEN: { + currentStr += val; + nest++; + break; + } + case PAREN_CLOSE: { + currentStr += val; + nest--; + break; + } + case W_SPACE: { + if (regDelimiter.test(val)) { + if (nest === 0) { + if (currentStr) { + res.push(currentStr.trim()); + currentStr = ''; + } + } else { + currentStr += ' '; + } + } else if (!currentStr.endsWith(' ')) { + currentStr += ' '; + } + break; + } + default: { + if (type === EOF) { + res.push(currentStr.trim()); + currentStr = ''; + } else { + currentStr += val; + } + } + } + } + setCache(cacheKey, res); + return res; +}; + +/** + * extract dashed-ident tokens + * @param value - CSS value + * @returns array of dashed-ident tokens + */ +export const extractDashedIdent = (value: string): string[] => { + if (!isString(value)) { + throw new TypeError(`${value} is not a string.`); + } + const strValue = value.trim(); + const cacheKey: string = createCacheKey({ + namespace: NAMESPACE, + name: 'extractDashedIdent', + value: strValue + }); + const cachedResult = getCache(cacheKey); + if (cachedResult instanceof CacheItem) { + return cachedResult.item as string[]; + } + const matches = strValue.match(REG_DASHED_IDENT); + const res = matches ? [...new Set(matches)] : []; + setCache(cacheKey, res); + return res; +}; + +/** + * is color + * @param value - CSS value + * @param [opt] - options + * @returns result + */ +export const isColor = (value: unknown, opt: Options = {}): boolean => { + if (!isString(value)) { + return false; + } + const str = value.toLowerCase().trim(); + if (!str) { + return false; + } + if (/^[a-z]+$/.test(str)) { + return ( + str === 'currentcolor' || + str === 'transparent' || + Object.hasOwn(NAMED_COLORS, str) + ); + } + if (REG_COLOR.test(str) || REG_MIX.test(str)) { + return true; + } + if (REG_FN_COLOR.test(str)) { + const colorOpt = { ...opt, nullable: true }; + if (!colorOpt.format) colorOpt.format = VAL_SPEC; + return !!resolveColor(str, colorOpt); + } + return false; +}; + +/** + * round to specified precision + * @param value - numeric value + * @param bit - minimum bits + * @returns rounded value + */ +export const roundToPrecision = (value: number, bit: number = 0): number => { + if (!Number.isFinite(value)) { + throw new TypeError(`${value} is not a finite number.`); + } + if (!Number.isFinite(bit)) { + throw new TypeError(`${bit} is not a finite number.`); + } + if (bit < 0 || bit > HEX) { + throw new RangeError(`${bit} is not between 0 and ${HEX}.`); + } + if (bit === 0) { + return Math.round(value); + } + const precision = bit === HEX ? 6 : bit < DEC ? 4 : 5; + return parseFloat(value.toPrecision(precision)); +}; + +/** + * interpolate hue + * @param hueA - hue value + * @param hueB - hue value + * @param arc - shorter | longer | increasing | decreasing + * @returns result - [hueA, hueB] + */ +export const interpolateHue = ( + hueA: number, + hueB: number, + arc: string = 'shorter' +): [number, number] => { + if (!Number.isFinite(hueA)) { + throw new TypeError(`${hueA} is not a finite number.`); + } + if (!Number.isFinite(hueB)) { + throw new TypeError(`${hueB} is not a finite number.`); + } + let a = hueA; + let b = hueB; + switch (arc) { + case 'decreasing': { + if (b > a) { + a += DEG; + } + break; + } + case 'increasing': { + if (b < a) { + b += DEG; + } + break; + } + case 'longer': { + if (b > a && b < a + DEG_HALF) { + a += DEG; + } else if (b > a - DEG_HALF && b <= a) { + b += DEG; + } + break; + } + case 'shorter': + default: { + if (b > a + DEG_HALF) { + a += DEG; + } else if (b < a - DEG_HALF) { + b += DEG; + } + } + } + return [a, b]; +}; + +/* absolute font size to pixel ratio */ +const absoluteFontSize = new Map([ + ['xx-small', 9 / 16], + ['x-small', 5 / 8], + ['small', 13 / 16], + ['medium', 1], + ['large', 9 / 8], + ['x-large', 3 / 2], + ['xx-large', 2], + ['xxx-large', 3] +]); + +/* relative font size to pixel ratio */ +const relativeFontSize = new Map([ + ['smaller', 1 / 1.2], + ['larger', 1.2] +]); + +/* absolute length to pixel ratio */ +const absoluteLength = new Map([ + ['cm', 96 / 2.54], + ['mm', 96 / 25.4], + ['q', 96 / 101.6], + ['in', 96], + ['pc', 16], + ['pt', 96 / 72], + ['px', 1] +]); + +/* relative length to pixel ratio */ +const relativeLength = new Map([ + ['rcap', 1], + ['rch', 0.5], + ['rem', 1], + ['rex', 0.5], + ['ric', 1], + ['rlh', 1.2] +]); + +/** + * resolve length in pixels + * @param value - value + * @param unit - unit + * @param [opt] - options + * @returns pixelated value + */ +export const resolveLengthInPixels = ( + value: number | string, + unit: string | undefined, + opt: Options = {} +): number => { + const { dimension = {} } = opt; + const { callback, em, rem, vh, vw } = dimension as { + callback: (K: string) => number; + em: number; + rem: number; + vh: number; + vw: number; + }; + if (isString(value)) { + const str = value.toLowerCase().trim(); + const ratio = absoluteFontSize.get(str); + if (ratio !== undefined) { + return ratio * rem; + } + const relRatio = relativeFontSize.get(str); + if (relRatio !== undefined) { + return relRatio * em; + } + return Number.NaN; + } + if (Number.isFinite(value) && unit) { + const u = unit.toLowerCase(); + if (Object.hasOwn(dimension, u)) { + return value * Number(dimension[u]); + } + if (typeof callback === 'function') { + return value * (callback(u) ?? Number.NaN); + } + const absRatio = absoluteLength.get(u); + if (absRatio !== undefined) { + return value * absRatio; + } + const relRatio = relativeLength.get(u); + if (relRatio !== undefined) { + return value * relRatio * rem; + } + const rUnitRatio = relativeLength.get(`r${u}`); + if (rUnitRatio !== undefined) { + return value * rUnitRatio * em; + } + switch (u) { + case 'vb': + case 'vi': { + return value * vw; + } + case 'vmax': { + return value * Math.max(vh, vw); + } + case 'vmin': { + return value * Math.min(vh, vw); + } + default: + } + } + // unsupported or invalid value + return Number.NaN; +}; + +/** + * is absolute size or length + * @param value - value + * @param unit - unit + * @returns result + */ +export const isAbsoluteSizeOrLength = ( + value: number | string, + unit: string | undefined +): boolean => { + if (isString(value)) { + return absoluteFontSize.has(value.toLowerCase().trim()); + } + if (isString(unit)) { + return absoluteLength.has(unit.toLowerCase().trim()); + } + return value === 0; +}; + +/** + * is absolute font size + * @param css - css + * @returns result + */ +export const isAbsoluteFontSize = (css: unknown): boolean => { + if (!isString(css)) { + return false; + } + const str = css.trim(); + if (isAbsoluteSizeOrLength(str, undefined)) { + return true; + } + const match = str.match(REG_DIMENSION); + return match + ? isAbsoluteSizeOrLength(Number(match[1]), match[2] || undefined) + : false; +}; diff --git a/node_modules/@asamuzakjp/dom-selector/LICENSE b/node_modules/@asamuzakjp/dom-selector/LICENSE new file mode 100644 index 0000000..f3f97a3 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 asamuzaK (Kazz) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@asamuzakjp/dom-selector/README.md b/node_modules/@asamuzakjp/dom-selector/README.md new file mode 100644 index 0000000..50099f3 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/README.md @@ -0,0 +1,324 @@ +# DOM Selector + +[![build](https://github.com/asamuzaK/domSelector/actions/workflows/node.js.yml/badge.svg)](https://github.com/asamuzaK/domSelector/actions/workflows/node.js.yml) +[![CodeQL](https://github.com/asamuzaK/domSelector/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/asamuzaK/domSelector/actions/workflows/github-code-scanning/codeql) +[![npm (scoped)](https://img.shields.io/npm/v/@asamuzakjp/dom-selector)](https://www.npmjs.com/package/@asamuzakjp/dom-selector) + +A CSS selector engine. + +## Install + +```console +npm i @asamuzakjp/dom-selector +``` + +## Usage + +```javascript +import { DOMSelector } from '@asamuzakjp/dom-selector'; +import { JSDOM } from 'jsdom'; + +const { window } = new JSDOM(); +const { + closest, matches, querySelector, querySelectorAll +} = new DOMSelector(window); +``` + + + +### matches(selector, node, opt) + +matches - equivalent to [Element.matches()][64] + +#### Parameters + +- `selector` **[string][59]** CSS selector +- `node` **[object][60]** Element node +- `opt` **[object][60]?** options + - `opt.noexcept` **[boolean][61]?** no exception + - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class + +Returns **[boolean][61]** `true` if matched, `false` otherwise + + +### closest(selector, node, opt) + +closest - equivalent to [Element.closest()][65] + +#### Parameters + +- `selector` **[string][59]** CSS selector +- `node` **[object][60]** Element node +- `opt` **[object][60]?** options + - `opt.noexcept` **[boolean][61]?** no exception + - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class + +Returns **[object][60]?** matched node + + +### querySelector(selector, node, opt) + +querySelector - equivalent to [Document.querySelector()][66], [DocumentFragment.querySelector()][67] and [Element.querySelector()][68] + +#### Parameters + +- `selector` **[string][59]** CSS selector +- `node` **[object][60]** Document, DocumentFragment or Element node +- `opt` **[object][60]?** options + - `opt.noexcept` **[boolean][61]?** no exception + - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class + +Returns **[object][60]?** matched node + + +### querySelectorAll(selector, node, opt) + +querySelectorAll - equivalent to [Document.querySelectorAll()][69], [DocumentFragment.querySelectorAll()][70] and [Element.querySelectorAll()][71] +**NOTE**: returns Array, not NodeList + +#### Parameters + +- `selector` **[string][59]** CSS selector +- `node` **[object][60]** Document, DocumentFragment or Element node +- `opt` **[object][60]?** options + - `opt.noexcept` **[boolean][61]?** no exception + - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class + +Returns **[Array][62]<([object][60] \| [undefined][63])>** array of matched nodes + + +## Monkey patch jsdom + +``` javascript +import { DOMSelector } from '@asamuzakjp/dom-selector'; +import { JSDOM } from 'jsdom'; + +const dom = new JSDOM('', { + runScripts: 'dangerously', + url: 'http://localhost/', + beforeParse: window => { + const domSelector = new DOMSelector(window); + + const matches = domSelector.matches.bind(domSelector); + window.Element.prototype.matches = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return matches(selector, this); + }; + + const closest = domSelector.closest.bind(domSelector); + window.Element.prototype.closest = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return closest(selector, this); + }; + + const querySelector = domSelector.querySelector.bind(domSelector); + window.Document.prototype.querySelector = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return querySelector(selector, this); + }; + window.DocumentFragment.prototype.querySelector = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return querySelector(selector, this); + }; + window.Element.prototype.querySelector = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return querySelector(selector, this); + }; + + const querySelectorAll = domSelector.querySelectorAll.bind(domSelector); + window.Document.prototype.querySelectorAll = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return querySelectorAll(selector, this); + }; + window.DocumentFragment.prototype.querySelectorAll = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return querySelectorAll(selector, this); + }; + window.Element.prototype.querySelectorAll = function (...args) { + if (!args.length) { + throw new window.TypeError('1 argument required, but only 0 present.'); + } + const [selector] = args; + return querySelectorAll(selector, this); + }; + } +}); +``` + + +## Supported CSS selectors + +|Pattern|Supported|Note| +|:--------|:-------:|:--------| +|\*|✓| | +|E|✓| | +|ns\|E|✓| | +|\*\|E|✓| | +|\|E|✓| | +|E F|✓| | +|E > F|✓| | +|E + F|✓| | +|E ~ F|✓| | +|F \|\| E|Unsupported| | +|E.warning|✓| | +|E#myid|✓| | +|E\[foo\]|✓| | +|E\[foo="bar"\]|✓| | +|E\[foo="bar" i\]|✓| | +|E\[foo="bar" s\]|✓| | +|E\[foo~="bar"\]|✓| | +|E\[foo^="bar"\]|✓| | +|E\[foo$="bar"\]|✓| | +|E\[foo*="bar"\]|✓| | +|E\[foo\|="en"\]|✓| | +|E:is(s1, s2, …)|✓| | +|E:not(s1, s2, …)|✓| | +|E:where(s1, s2, …)|✓| | +|E:has(rs1, rs2, …)|✓| | +|E:defined|Partially supported|Matching with MathML is not yet supported.| +|E:dir(ltr)|✓| | +|E:lang(en)|✓| | +|E:any‑link|✓| | +|E:link|✓| | +|E:visited|✓|Returns `false` or `null` to prevent fingerprinting.| +|E:local‑link|✓| | +|E:target|✓| | +|E:target‑within|✓| | +|E:scope|✓| | +|E:hover|✓| | +|E:active|✓| | +|E:focus|✓| | +|E:focus‑visible|✓| | +|E:focus‑within|✓| | +|E:current|Unsupported| | +|E:current(s)|Unsupported| | +|E:past|Unsupported| | +|E:future|Unsupported| | +|E:open
E:closed|Partially supported|Matching with <select>, e.g. `select:open`, is not supported.| +|E:popover-open|Unsupported| | +|E:enabled
E:disabled|✓| | +|E:read‑write
E:read‑only|✓| | +|E:placeholder‑shown|✓| | +|E:default|✓| | +|E:checked|✓| | +|E:indeterminate|✓| | +|E:blank|Unsupported| | +|E:valid
E:invalid|✓| | +|E:in-range
E:out-of-range|✓| | +|E:required
E:optional|✓| | +|E:user‑valid
E:user‑invalid|Unsupported| | +|E:root|✓| | +|E:empty|✓| | +|E:nth‑child(n [of S]?)|✓| | +|E:nth‑last‑child(n [of S]?)|✓| | +|E:first‑child|✓| | +|E:last‑child|✓| | +|E:only‑child|✓| | +|E:nth‑of‑type(n)|✓| | +|E:nth‑last‑of‑type(n)|✓| | +|E:first‑of‑type|✓| | +|E:last‑of‑type|✓| | +|E:only‑of‑type|✓| | +|E:nth‑col(n)|Unsupported| | +|E:nth‑last‑col(n)|Unsupported| | +|CE:state(v)|✓|*1| +|:host|✓| | +|:host(s)|✓| | +|:host(:state(v))|✓|*1| +|:host:has(rs1, rs2, ...)|✓| | +|:host(s):has(rs1, rs2, ...)|✓| | +|:host‑context(s)|✓| | +|:host‑context(s):has(rs1, rs2, ...)|✓| | +|&|✓|Only supports outermost `&`, i.e. equivalent to `:scope`| + +*1: `ElementInternals.states`, i.e. `CustomStateSet`, is not implemented in jsdom, so you need to apply a patch in the custom element constructor. + +``` javascript +class LabeledCheckbox extends window.HTMLElement { + #internals; + constructor() { + super(); + this.#internals = this.attachInternals(); + // patch CustomStateSet + if (!this.#internals.states) { + this.#internals.states = new Set(); + } + this.addEventListener('click', this._onClick.bind(this)); + } + get checked() { + return this.#internals.states.has('checked'); + } + set checked(flag) { + if (flag) { + this.#internals.states.add('checked'); + } else { + this.#internals.states.delete('checked'); + } + } + _onClick(event) { + this.checked = !this.checked; + } +} +``` + + +## Performance + +See [benchmark](https://github.com/asamuzaK/domSelector/actions/workflows/benchmark.yml) for the latest results. + + +## Acknowledgments + +The following resources have been of great help in the development of the DOM Selector. + +- [CSSTree](https://github.com/csstree/csstree) +- [selery](https://github.com/danburzo/selery) +- [jsdom](https://github.com/jsdom/jsdom) +- [nwsapi](https://github.com/dperini/nwsapi) + +--- +Copyright (c) 2023 [asamuzaK (Kazz)](https://github.com/asamuzaK/) + + +[1]: #matches +[2]: #parameters +[3]: #closest +[4]: #parameters-1 +[5]: #queryselector +[6]: #parameters-2 +[7]: #queryselectorall +[8]: #parameters-3 +[59]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String +[60]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object +[61]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean +[62]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array +[63]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined +[64]: https://developer.mozilla.org/docs/Web/API/Element/matches +[65]: https://developer.mozilla.org/docs/Web/API/Element/closest +[66]: https://developer.mozilla.org/docs/Web/API/Document/querySelector +[67]: https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelector +[68]: https://developer.mozilla.org/docs/Web/API/Element/querySelector +[69]: https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll +[70]: https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelectorAll +[71]: https://developer.mozilla.org/docs/Web/API/Element/querySelectorAll diff --git a/node_modules/@asamuzakjp/dom-selector/package.json b/node_modules/@asamuzakjp/dom-selector/package.json new file mode 100644 index 0000000..598114c --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/package.json @@ -0,0 +1,75 @@ +{ + "name": "@asamuzakjp/dom-selector", + "description": "A CSS selector engine.", + "author": "asamuzaK", + "license": "MIT", + "homepage": "https://github.com/asamuzaK/domSelector#readme", + "bugs": { + "url": "https://github.com/asamuzaK/domSelector/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/asamuzaK/domSelector.git" + }, + "files": [ + "src", + "types" + ], + "type": "module", + "exports": { + ".": { + "types": "./types/index.d.ts", + "default": "./src/index.js" + }, + "./package.json": "./package.json" + }, + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1" + }, + "devDependencies": { + "@types/css-tree": "^2.3.11", + "@types/node": "^25.5.2", + "benchmark": "^2.1.4", + "c8": "^11.0.0", + "chai": "^6.2.2", + "commander": "^14.0.3", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-jsdoc": "^62.9.0", + "eslint-plugin-prettier": "^5.5.5", + "eslint-plugin-regexp": "^3.1.0", + "eslint-plugin-unicorn": "^64.0.0", + "globals": "^17.4.0", + "jsdom": "^29.0.2", + "mocha": "^11.7.5", + "neostandard": "^0.13.0", + "prettier": "^3.8.1", + "sinon": "^21.0.3", + "typescript": "^6.0.2", + "wpt-runner": "^7.0.0" + }, + "overrides": { + "c8": { + "yargs": "^18.0.0" + }, + "jsdom": "$jsdom", + "serialize-javascript": "^7.0.4" + }, + "scripts": { + "bench": "node benchmark/bench.js", + "bench:sizzle": "node benchmark/bench-sizzle.js", + "build": "npm run tsc && npm run lint && npm test", + "lint": "eslint --fix .", + "test": "c8 --reporter=text mocha --parallel --exit test/**/*.test.js", + "test:wpt": "node test/wpt/wpt-runner.js", + "tsc": "node scripts/index clean --dir=types -i && npx tsc", + "update:wpt": "git submodule update --init --recursive --remote" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "version": "7.0.9" +} diff --git a/node_modules/@asamuzakjp/dom-selector/src/index.js b/node_modules/@asamuzakjp/dom-selector/src/index.js new file mode 100644 index 0000000..40f6f8d --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/index.js @@ -0,0 +1,335 @@ +/*! + * DOM Selector - A CSS selector engine. + * @license MIT + * @copyright asamuzaK (Kazz) + * @see {@link https://github.com/asamuzaK/domSelector/blob/main/LICENSE} + */ + +/* import */ +import { GenerationalCache } from './js/cache.js'; +import { Finder } from './js/finder.js'; +import { filterSelector, getType, initNwsapi } from './js/utility.js'; + +/* constants */ +import { + DOCUMENT_NODE, + DOCUMENT_FRAGMENT_NODE, + ELEMENT_NODE, + TARGET_ALL, + TARGET_FIRST, + TARGET_LINEAL, + TARGET_SELF +} from './js/constant.js'; +const MAX_CACHE = 1024; + +/** + * @typedef {object} CheckResult + * @property {boolean} match - The match result. + * @property {string?} pseudoElement - The pseudo-element, if any. + * @property {object?} ast - The AST object. + */ + +/* DOMSelector */ +export class DOMSelector { + /* private fields */ + #window; + #document; + #finder; + #idlUtils; + #nwsapi; + #cache; + + /** + * Creates an instance of DOMSelector. + * @param {Window} window - The window object. + * @param {Document} document - The document object. + * @param {object} [opt] - Options. + */ + constructor(window, document, opt = {}) { + const { idlUtils } = opt; + this.#window = window; + this.#document = document ?? window.document; + this.#finder = new Finder(window); + this.#idlUtils = idlUtils; + this.#nwsapi = initNwsapi(window, document); + this.#cache = new GenerationalCache(MAX_CACHE); + } + + /** + * Clears the internal cache of finder results. + * @returns {void} + */ + clear = () => { + this.#finder.clearResults(true); + }; + + /** + * Checks if an element matches a CSS selector. + * @param {string} selector - The CSS selector to check against. + * @param {Element} node - The element node to check. + * @param {object} [opt] - Optional parameters. + * @returns {CheckResult} An object containing the check result. + */ + check = (selector, node, opt = {}) => { + if (!node?.nodeType) { + const e = new this.#window.TypeError(`Unexpected type ${getType(node)}`); + return this.#finder.onError(e, opt); + } else if (node.nodeType !== ELEMENT_NODE) { + const e = new this.#window.TypeError(`Unexpected node ${node.nodeName}`); + return this.#finder.onError(e, opt); + } + const document = node.ownerDocument; + if ( + document === this.#document && + document.contentType === 'text/html' && + document.documentElement && + node.parentNode + ) { + const cacheKey = `check_${selector}`; + let filterMatches = this.#cache.get(cacheKey); + if (filterMatches === undefined) { + filterMatches = filterSelector(selector, TARGET_SELF); + this.#cache.set(cacheKey, filterMatches); + } + if (filterMatches) { + try { + const n = this.#idlUtils ? this.#idlUtils.wrapperForImpl(node) : node; + const match = this.#nwsapi.match(selector, n); + let ast = null; + if (match) { + const astCacheKey = `check_ast_${selector}`; + ast = this.#cache.get(astCacheKey); + if (ast === undefined) { + ast = this.#finder.getAST(selector); + this.#cache.set(astCacheKey, ast); + } + } + return { + match, + ast, + pseudoElement: null + }; + } catch (e) { + // fall through + } + } + } + if (this.#idlUtils) { + node = this.#idlUtils.wrapperForImpl(node); + } + opt.check = true; + opt.noexcept = true; + opt.warn = false; + return this.#finder.setup(selector, node, opt).find(TARGET_SELF); + }; + + /** + * Returns true if the element matches the selector. + * @param {string} selector - The CSS selector to match against. + * @param {Element} node - The element node to test. + * @param {object} [opt] - Optional parameters. + * @returns {boolean} `true` if the element matches, or `false` otherwise. + */ + matches = (selector, node, opt = {}) => { + if (!node?.nodeType) { + const e = new this.#window.TypeError(`Unexpected type ${getType(node)}`); + return this.#finder.onError(e, opt); + } else if (node.nodeType !== ELEMENT_NODE) { + const e = new this.#window.TypeError(`Unexpected node ${node.nodeName}`); + return this.#finder.onError(e, opt); + } + const document = node.ownerDocument; + if ( + document === this.#document && + document.contentType === 'text/html' && + document.documentElement && + node.parentNode + ) { + const cacheKey = `matches_${selector}`; + let filterMatches = this.#cache.get(cacheKey); + if (filterMatches === undefined) { + filterMatches = filterSelector(selector, TARGET_SELF); + this.#cache.set(cacheKey, filterMatches); + } + if (filterMatches) { + try { + const n = this.#idlUtils ? this.#idlUtils.wrapperForImpl(node) : node; + return this.#nwsapi.match(selector, n); + } catch (e) { + // fall through + } + } + } + let res; + try { + if (this.#idlUtils) { + node = this.#idlUtils.wrapperForImpl(node); + } + const nodes = this.#finder.setup(selector, node, opt).find(TARGET_SELF); + res = nodes.size; + } catch (e) { + this.#finder.onError(e, opt); + } + return !!res; + }; + + /** + * Traverses up the DOM tree to find the first node that matches the selector. + * @param {string} selector - The CSS selector to match against. + * @param {Element} node - The element from which to start traversing. + * @param {object} [opt] - Optional parameters. + * @returns {?Element} The first matching ancestor element, or `null`. + */ + closest = (selector, node, opt = {}) => { + if (!node?.nodeType) { + const e = new this.#window.TypeError(`Unexpected type ${getType(node)}`); + return this.#finder.onError(e, opt); + } else if (node.nodeType !== ELEMENT_NODE) { + const e = new this.#window.TypeError(`Unexpected node ${node.nodeName}`); + return this.#finder.onError(e, opt); + } + const document = node.ownerDocument; + if ( + document === this.#document && + document.contentType === 'text/html' && + document.documentElement && + node.parentNode + ) { + const cacheKey = `closest_${selector}`; + let filterMatches = this.#cache.get(cacheKey); + if (filterMatches === undefined) { + filterMatches = filterSelector(selector, TARGET_LINEAL); + this.#cache.set(cacheKey, filterMatches); + } + if (filterMatches) { + try { + const n = this.#idlUtils ? this.#idlUtils.wrapperForImpl(node) : node; + return this.#nwsapi.closest(selector, n); + } catch (e) { + // fall through + } + } + } + let res; + try { + if (this.#idlUtils) { + node = this.#idlUtils.wrapperForImpl(node); + } + const nodes = this.#finder.setup(selector, node, opt).find(TARGET_LINEAL); + if (nodes.size) { + let refNode = node; + while (refNode) { + if (nodes.has(refNode)) { + res = refNode; + break; + } + refNode = refNode.parentNode; + } + } + } catch (e) { + this.#finder.onError(e, opt); + } + return res ?? null; + }; + + /** + * Returns the first element within the subtree that matches the selector. + * @param {string} selector - The CSS selector to match. + * @param {Document|DocumentFragment|Element} node - The node to find within. + * @param {object} [opt] - Optional parameters. + * @returns {?Element} The first matching element, or `null`. + */ + querySelector = (selector, node, opt = {}) => { + if (!node?.nodeType) { + const e = new this.#window.TypeError(`Unexpected type ${getType(node)}`); + return this.#finder.onError(e, opt); + } + const document = + node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument; + if ( + document === this.#document && + document.contentType === 'text/html' && + document.documentElement && + (node.nodeType !== DOCUMENT_FRAGMENT_NODE || !node.host) + ) { + const cacheKey = `querySelector_${selector}`; + let filterMatches = this.#cache.get(cacheKey); + if (filterMatches === undefined) { + filterMatches = filterSelector(selector, TARGET_FIRST); + this.#cache.set(cacheKey, filterMatches); + } + if (filterMatches) { + try { + const n = this.#idlUtils ? this.#idlUtils.wrapperForImpl(node) : node; + return this.#nwsapi.first(selector, n); + } catch (e) { + // fall through + } + } + } + let res; + try { + if (this.#idlUtils) { + node = this.#idlUtils.wrapperForImpl(node); + } + const nodes = this.#finder.setup(selector, node, opt).find(TARGET_FIRST); + if (nodes.size) { + [res] = [...nodes]; + } + } catch (e) { + this.#finder.onError(e, opt); + } + return res ?? null; + }; + + /** + * Returns an array of elements within the subtree that match the selector. + * Note: This method returns an Array, not a NodeList. + * @param {string} selector - The CSS selector to match. + * @param {Document|DocumentFragment|Element} node - The node to find within. + * @param {object} [opt] - Optional parameters. + * @returns {Array} An array of elements, or an empty array. + */ + querySelectorAll = (selector, node, opt = {}) => { + if (!node?.nodeType) { + const e = new this.#window.TypeError(`Unexpected type ${getType(node)}`); + return this.#finder.onError(e, opt); + } + const document = + node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument; + if ( + document === this.#document && + document.contentType === 'text/html' && + document.documentElement && + (node.nodeType !== DOCUMENT_FRAGMENT_NODE || !node.host) + ) { + const cacheKey = `querySelectorAll_${selector}`; + let filterMatches = this.#cache.get(cacheKey); + if (filterMatches === undefined) { + filterMatches = filterSelector(selector, TARGET_ALL); + this.#cache.set(cacheKey, filterMatches); + } + if (filterMatches) { + try { + const n = this.#idlUtils ? this.#idlUtils.wrapperForImpl(node) : node; + return this.#nwsapi.select(selector, n); + } catch (e) { + // fall through + } + } + } + let res; + try { + if (this.#idlUtils) { + node = this.#idlUtils.wrapperForImpl(node); + } + const nodes = this.#finder.setup(selector, node, opt).find(TARGET_ALL); + if (nodes.size) { + res = [...nodes]; + } + } catch (e) { + this.#finder.onError(e, opt); + } + return res ?? []; + }; +} diff --git a/node_modules/@asamuzakjp/dom-selector/src/js/cache.js b/node_modules/@asamuzakjp/dom-selector/src/js/cache.js new file mode 100644 index 0000000..670dc09 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/js/cache.js @@ -0,0 +1,77 @@ +/** + * cache.js + */ + +/* Generational Cache */ +export class GenerationalCache { + #max; + #boundary; + #current; + #old; + + /** + * constructor + * @param {number} max - max cache size + */ + constructor(max) { + this.#current = new Map(); + this.#old = new Map(); + this.max = max; + } + + get size() { + return this.#current.size + this.#old.size; + } + + /** + * @returns {number} max cache size + */ + get max() { + return this.#max; + } + + set max(value) { + if (Number.isFinite(value) && value > 4) { + this.#max = value; + this.#boundary = Math.ceil(value / 2); + } else { + this.#max = 4; + this.#boundary = 2; + } + this.clear(); + } + + get(key) { + if (this.#current.has(key)) { + return this.#current.get(key); + } + const value = this.#old.get(key); + if (value !== undefined) { + this.set(key, value); + return value; + } + return undefined; + } + + set(key, value) { + this.#current.set(key, value); + if (this.#current.size >= this.#boundary) { + this.#old = this.#current; + this.#current = new Map(); + } + } + + has(key) { + return this.#current.has(key) || this.#old.has(key); + } + + delete(key) { + this.#current.delete(key); + this.#old.delete(key); + } + + clear() { + this.#current.clear(); + this.#old.clear(); + } +} diff --git a/node_modules/@asamuzakjp/dom-selector/src/js/constant.js b/node_modules/@asamuzakjp/dom-selector/src/js/constant.js new file mode 100644 index 0000000..02986ec --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/js/constant.js @@ -0,0 +1,129 @@ +/** + * constant.js + */ + +/* string */ +export const ATRULE = 'Atrule'; +export const ATTR_SELECTOR = 'AttributeSelector'; +export const CLASS_SELECTOR = 'ClassSelector'; +export const COMBINATOR = 'Combinator'; +export const IDENT = 'Identifier'; +export const ID_SELECTOR = 'IdSelector'; +export const NOT_SUPPORTED_ERR = 'NotSupportedError'; +export const NTH = 'Nth'; +export const OPERATOR = 'Operator'; +export const PS_CLASS_SELECTOR = 'PseudoClassSelector'; +export const PS_ELEMENT_SELECTOR = 'PseudoElementSelector'; +export const RULE = 'Rule'; +export const SCOPE = 'Scope'; +export const SELECTOR = 'Selector'; +export const SELECTOR_LIST = 'SelectorList'; +export const STRING = 'String'; +export const SYNTAX_ERR = 'SyntaxError'; +export const TARGET_ALL = 'all'; +export const TARGET_FIRST = 'first'; +export const TARGET_LINEAL = 'lineal'; +export const TARGET_SELF = 'self'; +export const TYPE_SELECTOR = 'TypeSelector'; + +/* numeric */ +export const BIT_01 = 1; +export const BIT_02 = 2; +export const BIT_04 = 4; +export const BIT_08 = 8; +export const BIT_16 = 0x10; +export const BIT_32 = 0x20; +export const BIT_FFFF = 0xffff; +export const DUO = 2; +export const HEX = 16; +export const TYPE_FROM = 8; +export const TYPE_TO = -1; + +/* Node */ +export const ELEMENT_NODE = 1; +export const TEXT_NODE = 3; +export const DOCUMENT_NODE = 9; +export const DOCUMENT_FRAGMENT_NODE = 11; +export const DOCUMENT_POSITION_PRECEDING = 2; +export const DOCUMENT_POSITION_CONTAINS = 8; +export const DOCUMENT_POSITION_CONTAINED_BY = 0x10; + +/* NodeFilter */ +export const SHOW_ALL = 0xffffffff; +export const SHOW_CONTAINER = 0x501; +export const SHOW_DOCUMENT = 0x100; +export const SHOW_DOCUMENT_FRAGMENT = 0x400; +export const SHOW_ELEMENT = 1; + +/* selectors */ +export const ALPHA_NUM = '[A-Z\\d]+'; +export const CHILD_IDX = '(?:first|last|only)-(?:child|of-type)'; +export const DIGIT = '(?:0|[1-9]\\d*)'; +export const LANG_PART = `(?:-${ALPHA_NUM})*`; +export const PSEUDO_CLASS = `(?:any-)?link|${CHILD_IDX}|checked|empty|indeterminate|read-(?:only|write)|target`; +export const ANB = `[+-]?(?:${DIGIT}n?|n)|(?:[+-]?${DIGIT})?n\\s*[+-]\\s*${DIGIT}`; +// combinators +export const COMBO = '\\s?[\\s>~+]\\s?'; +export const DESCEND = '\\s?[\\s>]\\s?'; +export const SIBLING = '\\s?[+~]\\s?'; +// LOGIC_IS: :is() +export const LOGIC_IS = `:is\\(\\s*[^)]+\\s*\\)`; +// N_TH: excludes An+B with selector list, e.g. :nth-child(2n+1 of .foo) +export const N_TH = `nth-(?:last-)?(?:child|of-type)\\(\\s*(?:even|odd|${ANB})\\s*\\)`; +// SUB_TYPE: attr, id, class, pseudo-class, note that [foo|=bar] is excluded +export const SUB_TYPE = '\\[[^|\\]]+\\]|[#.:][\\w-]+'; +export const SUB_TYPE_WO_PSEUDO = '\\[[^|\\]]+\\]|[#.][\\w-]+'; +// TAG_TYPE: *, tag +export const TAG_TYPE = '\\*|[A-Za-z][\\w-]*'; +export const TAG_TYPE_I = '\\*|[A-Z][\\w-]*'; +export const COMPOUND = `(?:${TAG_TYPE}|(?:${TAG_TYPE})?(?:${SUB_TYPE})+)`; +export const COMPOUND_L = `(?:${TAG_TYPE}|(?:${TAG_TYPE})?(?:${SUB_TYPE}|${LOGIC_IS})+)`; +export const COMPOUND_I = `(?:${TAG_TYPE_I}|(?:${TAG_TYPE_I})?(?:${SUB_TYPE})+)`; +export const COMPOUND_WO_PSEUDO = `(?:${TAG_TYPE}|(?:${TAG_TYPE})?(?:${SUB_TYPE_WO_PSEUDO})+)`; +export const COMPLEX = `${COMPOUND}(?:${COMBO}${COMPOUND})*`; +export const COMPLEX_L = `${COMPOUND_L}(?:${COMBO}${COMPOUND_L})*`; +export const HAS_COMPOUND = `has\\([\\s>]?\\s*${COMPOUND_WO_PSEUDO}\\s*\\)`; +export const LOGIC_COMPOUND = `(?:is|not)\\(\\s*${COMPOUND_L}(?:\\s*,\\s*${COMPOUND_L})*\\s*\\)`; +export const LOGIC_COMPLEX = `(?:is|not)\\(\\s*${COMPLEX_L}(?:\\s*,\\s*${COMPLEX_L})*\\s*\\)`; + +/* forms and input types */ +export const FORM_PARTS = Object.freeze([ + 'button', + 'input', + 'select', + 'textarea' +]); +export const INPUT_BUTTON = Object.freeze(['button', 'reset', 'submit']); +export const INPUT_CHECK = Object.freeze(['checkbox', 'radio']); +export const INPUT_DATE = Object.freeze([ + 'date', + 'datetime-local', + 'month', + 'time', + 'week' +]); +export const INPUT_TEXT = Object.freeze([ + 'email', + 'password', + 'search', + 'tel', + 'text', + 'url' +]); +export const INPUT_EDIT = Object.freeze([ + ...INPUT_DATE, + ...INPUT_TEXT, + 'number' +]); +export const INPUT_LTR = Object.freeze([ + ...INPUT_CHECK, + 'color', + 'date', + 'image', + 'number', + 'range', + 'time' +]); + +/* logical combination pseudo-classes */ +export const KEYS_LOGICAL = new Set(['has', 'is', 'not', 'where']); diff --git a/node_modules/@asamuzakjp/dom-selector/src/js/finder.js b/node_modules/@asamuzakjp/dom-selector/src/js/finder.js new file mode 100644 index 0000000..ccbd3db --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/js/finder.js @@ -0,0 +1,3144 @@ +/** + * finder.js + */ + +/* import */ +import { + matchAttributeSelector, + matchDirectionPseudoClass, + matchDisabledPseudoClass, + matchLanguagePseudoClass, + matchPseudoElementSelector, + matchReadOnlyPseudoClass, + matchTypeSelector +} from './matcher.js'; +import { + findAST, + generateCSS, + parseSelector, + sortAST, + unescapeSelector, + walkAST +} from './parser.js'; +import { + filterNodesByAnB, + findLogicalWithNestedHas, + generateException, + isCustomElement, + isFocusVisible, + isFocusableArea, + isVisible, + resolveContent, + sortNodes, + traverseNode +} from './utility.js'; + +/* constants */ +import { + ATTR_SELECTOR, + CLASS_SELECTOR, + COMBINATOR, + DOCUMENT_FRAGMENT_NODE, + ELEMENT_NODE, + FORM_PARTS, + ID_SELECTOR, + INPUT_CHECK, + INPUT_DATE, + INPUT_EDIT, + INPUT_TEXT, + KEYS_LOGICAL, + NOT_SUPPORTED_ERR, + PS_CLASS_SELECTOR, + PS_ELEMENT_SELECTOR, + SHOW_ALL, + SHOW_CONTAINER, + SYNTAX_ERR, + TARGET_ALL, + TARGET_FIRST, + TARGET_LINEAL, + TARGET_SELF, + TEXT_NODE, + TYPE_SELECTOR +} from './constant.js'; +const DIR_NEXT = 'next'; +const DIR_PREV = 'prev'; +const KEYS_FORM = new Set([...FORM_PARTS, 'fieldset', 'form']); +const KEYS_FORM_PS_VALID = new Set([...FORM_PARTS, 'form']); +const KEYS_INPUT_CHECK = new Set(INPUT_CHECK); +const KEYS_INPUT_PLACEHOLDER = new Set([...INPUT_TEXT, 'number']); +const KEYS_INPUT_RANGE = new Set([...INPUT_DATE, 'number', 'range']); +const KEYS_INPUT_REQUIRED = new Set([...INPUT_CHECK, ...INPUT_EDIT, 'file']); +const KEYS_INPUT_RESET = new Set(['button', 'reset']); +const KEYS_INPUT_SUBMIT = new Set(['image', 'submit']); +const KEYS_MODIFIER = new Set([ + 'Alt', + 'AltGraph', + 'CapsLock', + 'Control', + 'Fn', + 'FnLock', + 'Hyper', + 'Meta', + 'NumLock', + 'ScrollLock', + 'Shift', + 'Super', + 'Symbol', + 'SymbolLock' +]); +const KEYS_PS_UNCACHE = new Set([ + 'any-link', + 'defined', + 'dir', + 'link', + 'scope' +]); +const KEYS_PS_NTH_OF_TYPE = new Set([ + 'first-of-type', + 'last-of-type', + 'only-of-type' +]); + +/** + * Finder + * NOTE: #ast[i] corresponds to #nodes[i] + */ +export class Finder { + /* private fields */ + #ast; + #astCache; + #check; + #descendant; + #document; + #documentCache; + #documentURL; + #event; + #eventHandlers; + #filterLeavesCache; + #focus; + #invalidate; + #invalidateResults; + #lastFocusVisible; + #node; + #nodeWalker; + #nodes; + #noexcept; + #pseudoElement; + #results; + #root; + #rootWalker; + #scoped; + #selector; + #selectorAST; + #shadow; + #verifyShadowHost; + #walkers; + #warn; + #window; + + /** + * constructor + * @param {object} window - The window object. + */ + constructor(window) { + this.#window = window; + this.#astCache = new WeakMap(); + this.#documentCache = new WeakMap(); + this.#event = null; + this.#focus = null; + this.#lastFocusVisible = null; + this.#eventHandlers = new Set([ + { + keys: ['focus', 'focusin'], + handler: this._handleFocusEvent + }, + { + keys: ['keydown', 'keyup'], + handler: this._handleKeyboardEvent + }, + { + keys: ['mouseover', 'mousedown', 'mouseup', 'click', 'mouseout'], + handler: this._handleMouseEvent + } + ]); + this.#filterLeavesCache = new WeakMap(); + this._registerEventListeners(); + this.clearResults(true); + } + + /** + * Handles errors. + * @param {Error} e - The error object. + * @param {object} [opt] - Options. + * @param {boolean} [opt.noexcept] - If true, exceptions are not thrown. + * @throws {Error} Throws an error. + * @returns {void} + */ + onError = (e, opt = {}) => { + const noexcept = opt.noexcept ?? this.#noexcept; + if (noexcept) { + return; + } + const isDOMException = + e instanceof DOMException || e instanceof this.#window.DOMException; + if (isDOMException) { + if (e.name === NOT_SUPPORTED_ERR) { + if (this.#warn) { + console.warn(e.message); + } + return; + } + throw new this.#window.DOMException(e.message, e.name); + } + if (e.name in this.#window) { + throw new this.#window[e.name](e.message, { cause: e }); + } + throw e; + }; + + /** + * Sets up the finder. + * @param {string} selector - The CSS selector. + * @param {object} node - Document, DocumentFragment, or Element. + * @param {object} [opt] - Options. + * @param {boolean} [opt.check] - Indicates if running in internal check(). + * @param {boolean} [opt.noexcept] - If true, exceptions are not thrown. + * @param {boolean} [opt.warn] - If true, console warnings are enabled. + * @returns {object} The finder instance. + */ + setup = (selector, node, opt = {}) => { + const { check, noexcept, warn } = opt; + this.#check = !!check; + this.#noexcept = !!noexcept; + this.#warn = !!warn; + [this.#document, this.#root, this.#shadow] = resolveContent(node); + this.#documentURL = null; + this.#node = node; + this.#scoped = + this.#node !== this.#root && this.#node.nodeType === ELEMENT_NODE; + this.#selector = selector; + this.#pseudoElement = []; + this.#walkers = new WeakMap(); + this.#nodeWalker = null; + this.#rootWalker = null; + this.#verifyShadowHost = null; + this.clearResults(); + return this; + }; + + /** + * Clear cached results. + * @param {boolean} all - clear all results + * @returns {void} + */ + clearResults = (all = false) => { + this.#invalidateResults = new WeakMap(); + if (all) { + this.#results = new WeakMap(); + this.#filterLeavesCache = new WeakMap(); + } + }; + + /** + * Handles focus events. + * @private + * @param {Event} evt - The event object. + * @returns {void} + */ + _handleFocusEvent = evt => { + this.#focus = evt; + }; + + /** + * Handles keyboard events. + * @private + * @param {Event} evt - The event object. + * @returns {void} + */ + _handleKeyboardEvent = evt => { + const { key } = evt; + if (!KEYS_MODIFIER.has(key)) { + this.#event = evt; + } + }; + + /** + * Handles mouse events. + * @private + * @param {Event} evt - The event object. + * @returns {void} + */ + _handleMouseEvent = evt => { + this.#event = evt; + }; + + /** + * Registers event listeners. + * @private + * @returns {Array.} An array of return values from addEventListener. + */ + _registerEventListeners = () => { + const func = []; + for (const eventHandler of this.#eventHandlers) { + const { keys, handler } = eventHandler; + const l = keys.length; + for (let i = 0; i < l; i++) { + const key = keys[i]; + func.push( + this.#window.addEventListener(key, handler, { + capture: true, + passive: true + }) + ); + } + } + return func; + }; + + /** + * Processes selector branches into the internal AST structure. + * @private + * @param {Array.>} branches - The branches from walkAST. + * @param {string} selector - The original selector for error reporting. + * @returns {{ast: Array, descendant: boolean}} + * An object with the AST, descendant flag. + */ + _processSelectorBranches = (branches, selector) => { + let descendant = false; + const ast = []; + const l = branches.length; + for (let i = 0; i < l; i++) { + const items = [...branches[i]]; + const branch = []; + let item = items.shift(); + if (item && item.type !== COMBINATOR) { + const leaves = new Set(); + while (item) { + if (item.type === COMBINATOR) { + const [nextItem] = items; + if (!nextItem || nextItem.type === COMBINATOR) { + const msg = `Invalid selector ${selector}`; + this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + // Stop processing on invalid selector. + return { ast: [], descendant: false, invalidate: false }; + } + if (item.name === ' ' || item.name === '>') { + descendant = true; + } + branch.push({ combo: item, leaves: sortAST(leaves) }); + leaves.clear(); + } else { + if (item.name && typeof item.name === 'string') { + const unescapedName = unescapeSelector(item.name); + if (unescapedName !== item.name) { + item.name = unescapedName; + } + if (/[|:]/.test(unescapedName)) { + item.namespace = true; + } + } + leaves.add(item); + } + if (items.length) { + item = items.shift(); + } else { + branch.push({ combo: null, leaves: sortAST(leaves) }); + leaves.clear(); + break; + } + } + } + ast.push({ branch, dir: null, filtered: false, find: false }); + } + return { ast, descendant }; + }; + + /** + * Corresponds AST and nodes. + * @private + * @param {string} selector - The CSS selector. + * @returns {Array.>} An array with the AST and nodes. + */ + _correspond = selector => { + const nodes = []; + this.#descendant = false; + this.#invalidate = false; + let ast; + if (this.#documentCache.has(this.#document)) { + const cachedItem = this.#documentCache.get(this.#document); + if (cachedItem && cachedItem.has(`${selector}`)) { + const item = cachedItem.get(`${selector}`); + ast = item.ast; + this.#descendant = item.descendant; + this.#invalidate = item.invalidate; + this.#selectorAST = item.selectorAST; + } + } + if (ast) { + const l = ast.length; + for (let i = 0; i < l; i++) { + ast[i].dir = null; + ast[i].filtered = false; + ast[i].find = false; + nodes[i] = []; + } + } else { + this.#selectorAST = parseSelector(selector); + const { branches, info } = walkAST(this.#selectorAST, true); + const { + hasHasPseudoFunc, + hasLogicalPseudoFunc, + hasNthChildOfSelector, + hasStatePseudoClass + } = info; + this.#invalidate = + hasHasPseudoFunc || + hasStatePseudoClass || + !!(hasLogicalPseudoFunc && hasNthChildOfSelector); + const processed = this._processSelectorBranches(branches, selector); + ast = processed.ast; + this.#descendant = processed.descendant; + let cachedItem; + if (this.#documentCache.has(this.#document)) { + cachedItem = this.#documentCache.get(this.#document); + } else { + cachedItem = new Map(); + } + cachedItem.set(`${selector}`, { + ast, + descendant: this.#descendant, + invalidate: this.#invalidate, + selectorAST: this.#selectorAST + }); + this.#documentCache.set(this.#document, cachedItem); + // Initialize nodes array for each branch. + for (let i = 0; i < ast.length; i++) { + nodes[i] = []; + } + } + return [ast, nodes]; + }; + + /** + * Creates a TreeWalker. + * @private + * @param {object} node - The Document, DocumentFragment, or Element node. + * @param {object} [opt] - Options. + * @param {boolean} [opt.force] - Force creation of a new TreeWalker. + * @param {number} [opt.whatToShow] - The NodeFilter whatToShow value. + * @returns {object} The TreeWalker object. + */ + _createTreeWalker = (node, opt = {}) => { + const { force = false, whatToShow = SHOW_CONTAINER } = opt; + if (force) { + return this.#document.createTreeWalker(node, whatToShow); + } else if (this.#walkers.has(node)) { + return this.#walkers.get(node); + } + const walker = this.#document.createTreeWalker(node, whatToShow); + this.#walkers.set(node, walker); + return walker; + }; + + /** + * Gets selector branches from cache or parses them. + * @private + * @param {object} selector - The AST. + * @returns {Array.>} The selector branches. + */ + _getSelectorBranches = selector => { + if (this.#astCache.has(selector)) { + return this.#astCache.get(selector); + } + const { branches } = walkAST(selector); + this.#astCache.set(selector, branches); + return branches; + }; + + /** + * Gets the children of a node, optionally filtered by a selector. + * @private + * @param {object} parentNode - The parent element. + * @param {Array.>} selectorBranches - The selector branches. + * @param {object} opt - Options. + * @returns {Array.} An array of child nodes. + */ + _getFilteredChildren = (parentNode, selectorBranches, opt) => { + const children = []; + let childNode = parentNode.firstElementChild; + while (childNode) { + if (selectorBranches) { + let isMatch = false; + const l = selectorBranches.length; + for (let i = 0; i < l; i++) { + const leaves = selectorBranches[i]; + if (this._matchLeaves(leaves, childNode, opt)) { + isMatch = true; + break; + } + } + if (isMatch) { + if (this.#node === childNode) { + children.push(childNode); + } else if (isVisible(childNode)) { + children.push(childNode); + } + } + } else { + children.push(childNode); + } + childNode = childNode.nextElementSibling; + } + return children; + }; + + /** + * Collects nth-child nodes. + * @private + * @param {object} anb - An+B options. + * @param {number} anb.a - The 'a' value. + * @param {number} anb.b - The 'b' value. + * @param {boolean} [anb.reverse] - If true, reverses the order. + * @param {object} [anb.selector] - The AST. + * @param {object} node - The Element node. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _collectNthChild = (anb, node, opt) => { + const { a, b, selector } = anb; + const { parentNode } = node; + if (!parentNode) { + const matchedNode = new Set(); + if (node === this.#root && a * 1 + b * 1 === 1) { + if (selector) { + const selectorBranches = this._getSelectorBranches(selector); + const l = selectorBranches.length; + for (let i = 0; i < l; i++) { + const leaves = selectorBranches[i]; + if (this._matchLeaves(leaves, node, opt)) { + matchedNode.add(node); + break; + } + } + } else { + matchedNode.add(node); + } + } + return matchedNode; + } + const selectorBranches = selector + ? this._getSelectorBranches(selector) + : null; + const children = this._getFilteredChildren( + parentNode, + selectorBranches, + opt + ); + const matchedNodes = filterNodesByAnB(children, anb); + return new Set(matchedNodes); + }; + + /** + * Collects nth-of-type nodes. + * @private + * @param {object} anb - An+B options. + * @param {number} anb.a - The 'a' value. + * @param {number} anb.b - The 'b' value. + * @param {boolean} [anb.reverse] - If true, reverses the order. + * @param {object} node - The Element node. + * @returns {Set.} A collection of matched nodes. + */ + _collectNthOfType = (anb, node) => { + const { parentNode } = node; + if (!parentNode) { + if (node === this.#root && anb.a * 1 + anb.b * 1 === 1) { + return new Set([node]); + } + return new Set(); + } + const typedSiblings = []; + let sibling = parentNode.firstElementChild; + while (sibling) { + if ( + sibling.localName === node.localName && + sibling.namespaceURI === node.namespaceURI && + sibling.prefix === node.prefix + ) { + typedSiblings.push(sibling); + } + sibling = sibling.nextElementSibling; + } + const matchedNodes = filterNodesByAnB(typedSiblings, anb); + return new Set(matchedNodes); + }; + + /** + * Matches An+B. + * @private + * @param {object} ast - The AST. + * @param {object} node - The Element node. + * @param {string} nthName - The name of the nth pseudo-class. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _matchAnPlusB = (ast, node, nthName, opt) => { + const { + nth: { a, b, name: nthIdentName }, + selector + } = ast; + const anbMap = new Map(); + if (nthIdentName) { + if (nthIdentName === 'even') { + anbMap.set('a', 2); + anbMap.set('b', 0); + } else if (nthIdentName === 'odd') { + anbMap.set('a', 2); + anbMap.set('b', 1); + } + if (nthName.indexOf('last') > -1) { + anbMap.set('reverse', true); + } + } else { + if (typeof a === 'string' && /-?\d+/.test(a)) { + anbMap.set('a', a * 1); + } else { + anbMap.set('a', 0); + } + if (typeof b === 'string' && /-?\d+/.test(b)) { + anbMap.set('b', b * 1); + } else { + anbMap.set('b', 0); + } + if (nthName.indexOf('last') > -1) { + anbMap.set('reverse', true); + } + } + if (nthName === 'nth-child' || nthName === 'nth-last-child') { + if (selector) { + anbMap.set('selector', selector); + } + const anb = Object.fromEntries(anbMap); + const nodes = this._collectNthChild(anb, node, opt); + return nodes; + } else if (nthName === 'nth-of-type' || nthName === 'nth-last-of-type') { + const anb = Object.fromEntries(anbMap); + const nodes = this._collectNthOfType(anb, node); + return nodes; + } + return new Set(); + }; + + /** + * Matches the :has() pseudo-class function. + * @private + * @param {Array.} astLeaves - The AST leaves. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @returns {boolean} The result. + */ + _matchHasPseudoFunc = (astLeaves, node, opt = {}) => { + if (Array.isArray(astLeaves) && astLeaves.length) { + // Prepare a copy to avoid astLeaves being consumed. + const leaves = [...astLeaves]; + const [leaf] = leaves; + const { type: leafType } = leaf; + let combo; + if (leafType === COMBINATOR) { + combo = leaves.shift(); + } else { + combo = { + name: ' ', + type: COMBINATOR + }; + } + const twigLeaves = []; + while (leaves.length) { + const [item] = leaves; + const { type: itemType } = item; + if (itemType === COMBINATOR) { + break; + } else { + twigLeaves.push(leaves.shift()); + } + } + const twig = { + combo, + leaves: twigLeaves + }; + opt.dir = DIR_NEXT; + const nodes = this._collectCombinatorMatches(twig, node, opt, []); + if (nodes.length) { + if (leaves.length) { + let bool = false; + for (const nextNode of nodes) { + bool = this._matchHasPseudoFunc(leaves, nextNode, opt); + if (bool) { + break; + } + } + return bool; + } + return true; + } + } + return false; + }; + + /** + * Evaluates the :has() pseudo-class. + * @private + * @param {object} astData - The AST data. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @returns {?object} The matched node. + */ + _evaluateHasPseudo = (astData, node, opt = {}) => { + const { branches } = astData; + let bool = false; + const l = branches.length; + for (let i = 0; i < l; i++) { + const leaves = branches[i]; + bool = this._matchHasPseudoFunc(leaves, node, opt); + if (bool) { + break; + } + } + if (!bool) { + return null; + } + if ( + (opt.isShadowRoot || this.#shadow) && + node.nodeType === DOCUMENT_FRAGMENT_NODE + ) { + return this.#verifyShadowHost ? node : null; + } + return node; + }; + + /** + * Matches logical pseudo-class functions. + * @private + * @param {object} astData - The AST data. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @returns {?object} The matched node. + */ + _matchLogicalPseudoFunc = (astData, node, opt = {}) => { + const { astName, branches, twigBranches } = astData; + // Handle :has(). + if (astName === 'has') { + return this._evaluateHasPseudo(astData, node, opt); + } + // Handle :is(), :not(), :where(). + const isShadowRoot = + (opt.isShadowRoot || this.#shadow) && + node.nodeType === DOCUMENT_FRAGMENT_NODE; + // Check for invalid shadow root. + if (isShadowRoot) { + let invalid = false; + for (const branch of branches) { + if (branch.length > 1) { + invalid = true; + break; + } else if (astName === 'not') { + const [{ type: childAstType }] = branch; + if (childAstType !== PS_CLASS_SELECTOR) { + invalid = true; + break; + } + } + } + if (invalid) { + return null; + } + } + opt.forgive = astName === 'is' || astName === 'where'; + const l = twigBranches.length; + let bool; + for (let i = 0; i < l; i++) { + const branch = twigBranches[i]; + const lastIndex = branch.length - 1; + const { leaves } = branch[lastIndex]; + bool = this._matchLeaves(leaves, node, opt); + if (bool && lastIndex > 0) { + let nextNodes = new Set([node]); + for (let j = lastIndex - 1; j >= 0; j--) { + const twig = branch[j]; + const arr = []; + opt.dir = DIR_PREV; + for (const nextNode of nextNodes) { + this._collectCombinatorMatches(twig, nextNode, opt, arr); + } + if (arr.length) { + if (j === 0) { + bool = true; + } else { + nextNodes = new Set(arr); + } + } else { + bool = false; + break; + } + } + } + if (bool) { + break; + } + } + if (astName === 'not') { + if (bool) { + return null; + } + return node; + } else if (bool) { + return node; + } + return null; + }; + + /** + * Matches pseudo-class selector. + * @private + * @see https://html.spec.whatwg.org/#pseudo-classes + * @param {object} ast - The AST. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @param {boolean} [opt.forgive] - Ignores unknown or invalid selectors. + * @param {boolean} [opt.warn] - If true, console warnings are enabled. + * @returns {Set.} A collection of matched nodes. + */ + _matchPseudoClassSelector(ast, node, opt = {}) { + const { children: astChildren, name: astName } = ast; + const { localName, parentNode } = node; + const { forgive, warn = this.#warn } = opt; + const matched = new Set(); + // :has(), :is(), :not(), :where() + if (Array.isArray(astChildren) && KEYS_LOGICAL.has(astName)) { + if (!astChildren.length && astName !== 'is' && astName !== 'where') { + const css = generateCSS(ast); + const msg = `Invalid selector ${css}`; + return this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + } + let astData; + if (this.#astCache.has(ast)) { + astData = this.#astCache.get(ast); + } else { + const { branches } = walkAST(ast); + if (astName === 'has') { + // Check for nested :has(). + let forgiven = false; + const l = astChildren.length; + for (let i = 0; i < l; i++) { + const child = astChildren[i]; + const item = findAST(child, findLogicalWithNestedHas); + if (item) { + const itemName = item.name; + if (itemName === 'is' || itemName === 'where') { + forgiven = true; + break; + } else { + const css = generateCSS(ast); + const msg = `Invalid selector ${css}`; + return this.onError( + generateException(msg, SYNTAX_ERR, this.#window) + ); + } + } + } + if (forgiven) { + return matched; + } + astData = { + astName, + branches + }; + } else { + const twigBranches = []; + const l = branches.length; + for (let i = 0; i < l; i++) { + const [...leaves] = branches[i]; + const branch = []; + const leavesSet = new Set(); + let item = leaves.shift(); + while (item) { + if (item.type === COMBINATOR) { + branch.push({ + combo: item, + leaves: [...leavesSet] + }); + leavesSet.clear(); + } else if (item) { + leavesSet.add(item); + } + if (leaves.length) { + item = leaves.shift(); + } else { + branch.push({ + combo: null, + leaves: [...leavesSet] + }); + leavesSet.clear(); + break; + } + } + twigBranches.push(branch); + } + astData = { + astName, + branches, + twigBranches + }; + this.#astCache.set(ast, astData); + } + } + const res = this._matchLogicalPseudoFunc(astData, node, opt); + if (res) { + matched.add(res); + } + } else if (Array.isArray(astChildren)) { + // :nth-child(), :nth-last-child(), nth-of-type(), :nth-last-of-type() + if (/^nth-(?:last-)?(?:child|of-type)$/.test(astName)) { + if (astChildren.length !== 1) { + const css = generateCSS(ast); + return this.onError( + generateException( + `Invalid selector ${css}`, + SYNTAX_ERR, + this.#window + ) + ); + } + const [branch] = astChildren; + const nodes = this._matchAnPlusB(branch, node, astName, opt); + return nodes; + } else { + switch (astName) { + // :dir() + case 'dir': { + if (astChildren.length !== 1) { + const css = generateCSS(ast); + return this.onError( + generateException( + `Invalid selector ${css}`, + SYNTAX_ERR, + this.#window + ) + ); + } + const [astChild] = astChildren; + const res = matchDirectionPseudoClass(astChild, node); + if (res) { + matched.add(node); + } + break; + } + // :lang() + case 'lang': { + if (!astChildren.length) { + const css = generateCSS(ast); + return this.onError( + generateException( + `Invalid selector ${css}`, + SYNTAX_ERR, + this.#window + ) + ); + } + let bool; + for (const astChild of astChildren) { + bool = matchLanguagePseudoClass(astChild, node); + if (bool) { + break; + } + } + if (bool) { + matched.add(node); + } + break; + } + // :state() + case 'state': { + if (isCustomElement(node)) { + const [{ value: stateValue }] = astChildren; + if (stateValue) { + if (node[stateValue]) { + matched.add(node); + } else { + for (const i in node) { + const prop = node[i]; + if (prop instanceof this.#window.ElementInternals) { + if (prop?.states?.has(stateValue)) { + matched.add(node); + } + break; + } + } + } + } + } + break; + } + case 'current': + case 'heading': + case 'nth-col': + case 'nth-last-col': { + if (warn) { + this.onError( + generateException( + `Unsupported pseudo-class :${astName}()`, + NOT_SUPPORTED_ERR, + this.#window + ) + ); + } + break; + } + // Ignore :host() and :host-context(). + case 'host': + case 'host-context': { + break; + } + // Deprecated in CSS Selectors 3. + case 'contains': { + if (warn) { + this.onError( + generateException( + `Unknown pseudo-class :${astName}()`, + NOT_SUPPORTED_ERR, + this.#window + ) + ); + } + break; + } + default: { + if (!forgive) { + this.onError( + generateException( + `Unknown pseudo-class :${astName}()`, + SYNTAX_ERR, + this.#window + ) + ); + } + } + } + } + } else if (KEYS_PS_NTH_OF_TYPE.has(astName)) { + if (node === this.#root) { + matched.add(node); + } else if (parentNode) { + switch (astName) { + case 'first-of-type': { + const [node1] = this._collectNthOfType( + { + a: 0, + b: 1 + }, + node + ); + if (node1) { + matched.add(node1); + } + break; + } + case 'last-of-type': { + const [node1] = this._collectNthOfType( + { + a: 0, + b: 1, + reverse: true + }, + node + ); + if (node1) { + matched.add(node1); + } + break; + } + // 'only-of-type' is handled by default. + default: { + const [node1] = this._collectNthOfType( + { + a: 0, + b: 1 + }, + node + ); + if (node1 === node) { + const [node2] = this._collectNthOfType( + { + a: 0, + b: 1, + reverse: true + }, + node + ); + if (node2 === node) { + matched.add(node); + } + } + } + } + } + } else { + switch (astName) { + case 'disabled': + case 'enabled': { + const isMatch = matchDisabledPseudoClass(astName, node); + if (isMatch) { + matched.add(node); + } + break; + } + case 'read-only': + case 'read-write': { + const isMatch = matchReadOnlyPseudoClass(astName, node); + if (isMatch) { + matched.add(node); + } + break; + } + case 'any-link': + case 'link': { + if ( + (localName === 'a' || localName === 'area') && + node.hasAttribute('href') + ) { + matched.add(node); + } + break; + } + case 'local-link': { + if ( + (localName === 'a' || localName === 'area') && + node.hasAttribute('href') + ) { + if (!this.#documentURL) { + this.#documentURL = new URL(this.#document.URL); + } + const { href, origin, pathname } = this.#documentURL; + const attrURL = new URL(node.getAttribute('href'), href); + if (attrURL.origin === origin && attrURL.pathname === pathname) { + matched.add(node); + } + } + break; + } + case 'visited': { + // prevent fingerprinting + break; + } + case 'hover': { + const { target, type } = this.#event ?? {}; + if ( + /^(?:click|mouse(?:down|over|up))$/.test(type) && + node.contains(target) + ) { + matched.add(node); + } + break; + } + case 'active': { + const { buttons, target, type } = this.#event ?? {}; + if (type === 'mousedown' && buttons & 1 && node.contains(target)) { + matched.add(node); + } + break; + } + case 'target': { + if (!this.#documentURL) { + this.#documentURL = new URL(this.#document.URL); + } + const { hash } = this.#documentURL; + if ( + node.id && + hash === `#${node.id}` && + this.#document.contains(node) + ) { + matched.add(node); + } + break; + } + case 'target-within': { + if (!this.#documentURL) { + this.#documentURL = new URL(this.#document.URL); + } + const { hash } = this.#documentURL; + if (hash) { + const id = hash.replace(/^#/, ''); + let current = this.#document.getElementById(id); + while (current) { + if (current === node) { + matched.add(node); + break; + } + current = current.parentNode; + } + } + break; + } + case 'scope': { + if (this.#node.nodeType === ELEMENT_NODE) { + if (!this.#shadow && node === this.#node) { + matched.add(node); + } + } else if (node === this.#document.documentElement) { + matched.add(node); + } + break; + } + case 'focus': { + const activeElement = this.#document.activeElement; + if (node === activeElement && isFocusableArea(node)) { + matched.add(node); + } else if (activeElement.shadowRoot) { + const activeShadowElement = activeElement.shadowRoot.activeElement; + let current = activeShadowElement; + while (current) { + if (current.nodeType === DOCUMENT_FRAGMENT_NODE) { + const { host } = current; + if (host === activeElement) { + if (isFocusableArea(node)) { + matched.add(node); + } else { + matched.add(host); + } + } + break; + } else { + current = current.parentNode; + } + } + } + break; + } + case 'focus-visible': { + if (node === this.#document.activeElement && isFocusableArea(node)) { + let bool; + if (isFocusVisible(node)) { + bool = true; + } else if (this.#focus) { + const { relatedTarget, target: focusTarget } = this.#focus; + if (focusTarget === node) { + if (isFocusVisible(relatedTarget)) { + bool = true; + } else if (this.#event) { + const { + altKey: eventAltKey, + ctrlKey: eventCtrlKey, + key: eventKey, + metaKey: eventMetaKey, + target: eventTarget, + type: eventType + } = this.#event; + // this.#event is irrelevant if eventTarget === relatedTarget + if (eventTarget === relatedTarget) { + if (this.#lastFocusVisible === null) { + bool = true; + } else if (focusTarget === this.#lastFocusVisible) { + bool = true; + } + } else if (eventKey === 'Tab') { + if ( + (eventType === 'keydown' && eventTarget !== node) || + (eventType === 'keyup' && eventTarget === node) + ) { + if (eventTarget === focusTarget) { + if (this.#lastFocusVisible === null) { + bool = true; + } else if ( + eventTarget === this.#lastFocusVisible && + relatedTarget === null + ) { + bool = true; + } + } else { + bool = true; + } + } + } else if (eventKey) { + if ( + (eventType === 'keydown' || eventType === 'keyup') && + !eventAltKey && + !eventCtrlKey && + !eventMetaKey && + eventTarget === node + ) { + bool = true; + } + } + } else if ( + relatedTarget === null || + relatedTarget === this.#lastFocusVisible + ) { + bool = true; + } + } + } + if (bool) { + this.#lastFocusVisible = node; + matched.add(node); + } else if (this.#lastFocusVisible === node) { + this.#lastFocusVisible = null; + } + } + break; + } + case 'focus-within': { + const activeElement = this.#document.activeElement; + if (node.contains(activeElement) && isFocusableArea(activeElement)) { + matched.add(node); + } else if (activeElement.shadowRoot) { + const activeShadowElement = activeElement.shadowRoot.activeElement; + if (node.contains(activeShadowElement)) { + matched.add(node); + } else { + let current = activeShadowElement; + while (current) { + if (current.nodeType === DOCUMENT_FRAGMENT_NODE) { + const { host } = current; + if (host === activeElement && node.contains(host)) { + matched.add(node); + } + break; + } else { + current = current.parentNode; + } + } + } + } + break; + } + case 'open': + case 'closed': { + if (localName === 'details' || localName === 'dialog') { + if (node.hasAttribute('open')) { + if (astName === 'open') { + matched.add(node); + } + } else if (astName === 'closed') { + matched.add(node); + } + } + break; + } + case 'placeholder-shown': { + let placeholder; + if (node.placeholder) { + placeholder = node.placeholder; + } else if (node.hasAttribute('placeholder')) { + placeholder = node.getAttribute('placeholder'); + } + if (typeof placeholder === 'string' && !/[\r\n]/.test(placeholder)) { + let targetNode; + if (localName === 'textarea') { + targetNode = node; + } else if (localName === 'input') { + if (node.hasAttribute('type')) { + if (KEYS_INPUT_PLACEHOLDER.has(node.getAttribute('type'))) { + targetNode = node; + } + } else { + targetNode = node; + } + } + if (targetNode && node.value === '') { + matched.add(node); + } + } + break; + } + case 'checked': { + const attrType = node.getAttribute('type'); + if ( + (node.checked && + localName === 'input' && + (attrType === 'checkbox' || attrType === 'radio')) || + (node.selected && localName === 'option') + ) { + matched.add(node); + } + break; + } + case 'indeterminate': { + if ( + (node.indeterminate && + localName === 'input' && + node.type === 'checkbox') || + (localName === 'progress' && !node.hasAttribute('value')) + ) { + matched.add(node); + } else if ( + localName === 'input' && + node.type === 'radio' && + !node.hasAttribute('checked') + ) { + const nodeName = node.name; + let parent = node.parentNode; + while (parent) { + if (parent.localName === 'form') { + break; + } + parent = parent.parentNode; + } + if (!parent) { + parent = this.#document.documentElement; + } + const walker = this._createTreeWalker(parent); + let refNode = traverseNode(parent, walker); + refNode = walker.firstChild(); + let checked; + while (refNode) { + if ( + refNode.localName === 'input' && + refNode.getAttribute('type') === 'radio' + ) { + if (refNode.hasAttribute('name')) { + if (refNode.getAttribute('name') === nodeName) { + checked = !!refNode.checked; + } + } else { + checked = !!refNode.checked; + } + if (checked) { + break; + } + } + refNode = walker.nextNode(); + } + if (!checked) { + matched.add(node); + } + } + break; + } + case 'default': { + // button[type="submit"], input[type="submit"], input[type="image"] + const attrType = node.getAttribute('type'); + if ( + (localName === 'button' && + !(node.hasAttribute('type') && KEYS_INPUT_RESET.has(attrType))) || + (localName === 'input' && + node.hasAttribute('type') && + KEYS_INPUT_SUBMIT.has(attrType)) + ) { + let form = node.parentNode; + while (form) { + if (form.localName === 'form') { + break; + } + form = form.parentNode; + } + if (form) { + const walker = this._createTreeWalker(form); + let refNode = traverseNode(form, walker); + refNode = walker.firstChild(); + while (refNode) { + const nodeName = refNode.localName; + const nodeAttrType = refNode.getAttribute('type'); + let m; + if (nodeName === 'button') { + m = !( + refNode.hasAttribute('type') && + KEYS_INPUT_RESET.has(nodeAttrType) + ); + } else if (nodeName === 'input') { + m = + refNode.hasAttribute('type') && + KEYS_INPUT_SUBMIT.has(nodeAttrType); + } + if (m) { + if (refNode === node) { + matched.add(node); + } + break; + } + refNode = walker.nextNode(); + } + } + // input[type="checkbox"], input[type="radio"] + } else if ( + localName === 'input' && + node.hasAttribute('type') && + node.hasAttribute('checked') && + KEYS_INPUT_CHECK.has(attrType) + ) { + matched.add(node); + // option + } else if (localName === 'option' && node.hasAttribute('selected')) { + matched.add(node); + } + break; + } + case 'valid': + case 'invalid': { + if (KEYS_FORM_PS_VALID.has(localName)) { + let valid; + if (node.checkValidity()) { + if (node.maxLength >= 0) { + if (node.maxLength >= node.value.length) { + valid = true; + } + } else { + valid = true; + } + } + if (valid) { + if (astName === 'valid') { + matched.add(node); + } + } else if (astName === 'invalid') { + matched.add(node); + } + } else if (localName === 'fieldset') { + const walker = this._createTreeWalker(node); + let refNode = traverseNode(node, walker); + refNode = walker.firstChild(); + let valid; + if (!refNode) { + valid = true; + } else { + while (refNode) { + if (KEYS_FORM_PS_VALID.has(refNode.localName)) { + if (refNode.checkValidity()) { + if (refNode.maxLength >= 0) { + valid = refNode.maxLength >= refNode.value.length; + } else { + valid = true; + } + } else { + valid = false; + } + if (!valid) { + break; + } + } + refNode = walker.nextNode(); + } + } + if (valid) { + if (astName === 'valid') { + matched.add(node); + } + } else if (astName === 'invalid') { + matched.add(node); + } + } + break; + } + case 'in-range': + case 'out-of-range': { + const attrType = node.getAttribute('type'); + if ( + localName === 'input' && + !(node.readOnly || node.hasAttribute('readonly')) && + !(node.disabled || node.hasAttribute('disabled')) && + KEYS_INPUT_RANGE.has(attrType) + ) { + const flowed = + node.validity.rangeUnderflow || node.validity.rangeOverflow; + if (astName === 'out-of-range' && flowed) { + matched.add(node); + } else if ( + astName === 'in-range' && + !flowed && + (node.hasAttribute('min') || + node.hasAttribute('max') || + attrType === 'range') + ) { + matched.add(node); + } + } + break; + } + case 'required': + case 'optional': { + let required; + let optional; + if (localName === 'select' || localName === 'textarea') { + if (node.required || node.hasAttribute('required')) { + required = true; + } else { + optional = true; + } + } else if (localName === 'input') { + if (node.hasAttribute('type')) { + const attrType = node.getAttribute('type'); + if (KEYS_INPUT_REQUIRED.has(attrType)) { + if (node.required || node.hasAttribute('required')) { + required = true; + } else { + optional = true; + } + } else { + optional = true; + } + } else if (node.required || node.hasAttribute('required')) { + required = true; + } else { + optional = true; + } + } + if (astName === 'required' && required) { + matched.add(node); + } else if (astName === 'optional' && optional) { + matched.add(node); + } + break; + } + case 'root': { + if (node === this.#document.documentElement) { + matched.add(node); + } + break; + } + case 'empty': { + if (node.hasChildNodes()) { + const walker = this._createTreeWalker(node, { + force: true, + whatToShow: SHOW_ALL + }); + let refNode = walker.firstChild(); + let bool; + while (refNode) { + bool = + refNode.nodeType !== ELEMENT_NODE && + refNode.nodeType !== TEXT_NODE; + if (!bool) { + break; + } + refNode = walker.nextSibling(); + } + if (bool) { + matched.add(node); + } + } else { + matched.add(node); + } + break; + } + case 'first-child': { + if ( + (parentNode && node === parentNode.firstElementChild) || + node === this.#root + ) { + matched.add(node); + } + break; + } + case 'last-child': { + if ( + (parentNode && node === parentNode.lastElementChild) || + node === this.#root + ) { + matched.add(node); + } + break; + } + case 'only-child': { + if ( + (parentNode && + node === parentNode.firstElementChild && + node === parentNode.lastElementChild) || + node === this.#root + ) { + matched.add(node); + } + break; + } + case 'defined': { + if (node.hasAttribute('is') || localName.includes('-')) { + if (isCustomElement(node)) { + matched.add(node); + } + // NOTE: MathMLElement is not implemented in jsdom. + } else if ( + node instanceof this.#window.HTMLElement || + node instanceof this.#window.SVGElement + ) { + matched.add(node); + } + break; + } + case 'popover-open': { + // FIXME: not implemented in jsdom + // @see https://github.com/jsdom/jsdom/issues/3721 + /* + if (node.popover && isVisible(node)) { + matched.add(node); + } + */ + break; + } + // Ignore :host. + case 'host': { + break; + } + // Legacy pseudo-elements. + case 'after': + case 'before': + case 'first-letter': + case 'first-line': { + if (warn) { + this.onError( + generateException( + `Unsupported pseudo-element ::${astName}`, + NOT_SUPPORTED_ERR, + this.#window + ) + ); + } + break; + } + // Not supported. + case 'autofill': + case 'blank': + case 'buffering': + case 'current': + case 'fullscreen': + case 'future': + case 'has-slotted': + case 'heading': + case 'modal': + case 'muted': + case 'past': + case 'paused': + case 'picture-in-picture': + case 'playing': + case 'seeking': + case 'stalled': + case 'user-invalid': + case 'user-valid': + case 'volume-locked': + case '-webkit-autofill': { + if (warn) { + this.onError( + generateException( + `Unsupported pseudo-class :${astName}`, + NOT_SUPPORTED_ERR, + this.#window + ) + ); + } + break; + } + default: { + if (astName.startsWith('-webkit-')) { + if (warn) { + this.onError( + generateException( + `Unsupported pseudo-class :${astName}`, + NOT_SUPPORTED_ERR, + this.#window + ) + ); + } + } else if (!forgive) { + this.onError( + generateException( + `Unknown pseudo-class :${astName}`, + SYNTAX_ERR, + this.#window + ) + ); + } + } + } + } + return matched; + } + + /** + * Evaluates the :host() pseudo-class. + * @private + * @param {Array.} leaves - The AST leaves. + * @param {object} host - The host element. + * @param {object} ast - The original AST for error reporting. + * @returns {boolean} True if matched. + */ + _evaluateHostPseudo = (leaves, host, ast) => { + const l = leaves.length; + for (let i = 0; i < l; i++) { + const leaf = leaves[i]; + if (leaf.type === COMBINATOR) { + const css = generateCSS(ast); + const msg = `Invalid selector ${css}`; + this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + return false; + } + if (!this._matchSelector(leaf, host).has(host)) { + return false; + } + } + return true; + }; + + /** + * Evaluates the :host-context() pseudo-class. + * @private + * @param {Array.} leaves - The AST leaves. + * @param {object} host - The host element. + * @param {object} ast - The original AST for error reporting. + * @returns {boolean} True if matched. + */ + _evaluateHostContextPseudo = (leaves, host, ast) => { + let parent = host; + while (parent) { + let bool; + const l = leaves.length; + for (let i = 0; i < l; i++) { + const leaf = leaves[i]; + if (leaf.type === COMBINATOR) { + const css = generateCSS(ast); + const msg = `Invalid selector ${css}`; + this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + return false; + } + bool = this._matchSelector(leaf, parent).has(parent); + if (!bool) { + break; + } + } + if (bool) { + return true; + } + parent = parent.parentNode; + } + return false; + }; + + /** + * Matches shadow host pseudo-classes. + * @private + * @param {object} ast - The AST. + * @param {object} node - The DocumentFragment node. + * @returns {?object} The matched node. + */ + _matchShadowHostPseudoClass = (ast, node) => { + const { children: astChildren, name: astName } = ast; + // Handle simple pseudo-class (no arguments). + if (!Array.isArray(astChildren)) { + if (astName === 'host') { + return node; + } + const msg = `Invalid selector :${astName}`; + return this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + } + // Handle functional pseudo-class like :host(...). + if (astName !== 'host' && astName !== 'host-context') { + const msg = `Invalid selector :${astName}()`; + return this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + } + if (astChildren.length !== 1) { + const css = generateCSS(ast); + const msg = `Invalid selector ${css}`; + return this.onError(generateException(msg, SYNTAX_ERR, this.#window)); + } + const { host } = node; + const { branches } = walkAST(astChildren[0]); + const [branch] = branches; + const [...leaves] = branch; + let isMatch = false; + if (astName === 'host') { + isMatch = this._evaluateHostPseudo(leaves, host, ast); + // astName === 'host-context'. + } else { + isMatch = this._evaluateHostContextPseudo(leaves, host, ast); + } + return isMatch ? node : null; + }; + + /** + * Matches a selector for element nodes. + * @private + * @param {object} ast - The AST. + * @param {object} node - The Element node. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _matchSelectorForElement = (ast, node, opt) => { + const { type: astType } = ast; + const astName = unescapeSelector(ast.name); + const matched = new Set(); + switch (astType) { + case ATTR_SELECTOR: { + if (matchAttributeSelector(ast, node, opt)) { + matched.add(node); + } + break; + } + case ID_SELECTOR: { + if (node.id === astName) { + matched.add(node); + } + break; + } + case CLASS_SELECTOR: { + if (node.classList.contains(astName)) { + matched.add(node); + } + break; + } + case PS_CLASS_SELECTOR: { + return this._matchPseudoClassSelector(ast, node, opt); + } + case TYPE_SELECTOR: { + if (matchTypeSelector(ast, node, opt)) { + matched.add(node); + } + break; + } + // PS_ELEMENT_SELECTOR is handled by default. + default: { + try { + if (this.#check) { + const css = generateCSS(ast); + this.#pseudoElement.push(css); + matched.add(node); + } else { + matchPseudoElementSelector(astName, astType, opt); + } + } catch (e) { + this.onError(e); + } + } + } + return matched; + }; + + /** + * Matches a selector for a shadow root. + * @private + * @param {object} ast - The AST. + * @param {object} node - The DocumentFragment node. + * @param {object} [opt] - Options. + * @returns {Set.} A collection of matched nodes. + */ + _matchSelectorForShadowRoot = (ast, node, opt = {}) => { + const { name: astName } = ast; + if (KEYS_LOGICAL.has(astName)) { + opt.isShadowRoot = true; + return this._matchPseudoClassSelector(ast, node, opt); + } + const matched = new Set(); + if (astName === 'host' || astName === 'host-context') { + const res = this._matchShadowHostPseudoClass(ast, node, opt); + if (res) { + this.#verifyShadowHost = true; + matched.add(res); + } + } + return matched; + }; + + /** + * Matches a selector. + * @private + * @param {object} ast - The AST. + * @param {object} node - The Document, DocumentFragment, or Element node. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _matchSelector = (ast, node, opt) => { + if (node.nodeType === ELEMENT_NODE) { + return this._matchSelectorForElement(ast, node, opt); + } + if ( + this.#shadow && + node.nodeType === DOCUMENT_FRAGMENT_NODE && + ast.type === PS_CLASS_SELECTOR + ) { + return this._matchSelectorForShadowRoot(ast, node, opt); + } + return new Set(); + }; + + /** + * Matches leaves. + * @private + * @param {Array.} leaves - The AST leaves. + * @param {object} node - The node. + * @param {object} opt - Options. + * @returns {boolean} The result. + */ + _matchLeaves = (leaves, node, opt) => { + const results = this.#invalidate ? this.#invalidateResults : this.#results; + let result = results.get(leaves); + if (result && result.has(node)) { + const { matched } = result.get(node); + return matched; + } + let cacheable = true; + if (node.nodeType === ELEMENT_NODE && KEYS_FORM.has(node.localName)) { + cacheable = false; + } + let bool; + const l = leaves.length; + for (let i = 0; i < l; i++) { + const leaf = leaves[i]; + switch (leaf.type) { + case ATTR_SELECTOR: + case ID_SELECTOR: { + cacheable = false; + break; + } + case PS_CLASS_SELECTOR: { + if (KEYS_PS_UNCACHE.has(leaf.name)) { + cacheable = false; + } + break; + } + default: { + // No action needed for other types. + } + } + bool = this._matchSelector(leaf, node, opt).has(node); + if (!bool) { + break; + } + } + if (cacheable) { + if (!result) { + result = new WeakMap(); + } + result.set(node, { + matched: bool + }); + results.set(leaves, result); + } + return bool; + }; + + /** + * Returns a cached slice of the leaves array (excluding the first item). + * @private + * @param {Array.} leaves - The original AST leaves array. + * @returns {Array.} The filtered leaves. + */ + _getFilterLeaves = leaves => { + if (this.#filterLeavesCache.has(leaves)) { + return this.#filterLeavesCache.get(leaves); + } + const filterLeaves = leaves.slice(1); + this.#filterLeavesCache.set(leaves, filterLeaves); + return filterLeaves; + }; + + /** + * Traverses all descendant nodes and collects matches. + * @private + * @param {object} baseNode - The base Element node or Element.shadowRoot. + * @param {Array.} leaves - The AST leaves. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _traverseAllDescendants = (baseNode, leaves, opt) => { + const walker = this._createTreeWalker(baseNode); + traverseNode(baseNode, walker); + let currentNode = walker.firstChild(); + const nodes = new Set(); + while (currentNode) { + if (this._matchLeaves(leaves, currentNode, opt)) { + nodes.add(currentNode); + } + currentNode = walker.nextNode(); + } + return nodes; + }; + + /** + * Finds descendant nodes. + * @private + * @param {Array.} leaves - The AST leaves. + * @param {object} baseNode - The base Element node or Element.shadowRoot. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _findDescendantNodes = (leaves, baseNode, opt) => { + const [leaf] = leaves; + const filterLeaves = this._getFilterLeaves(leaves); + const { type: leafType } = leaf; + switch (leafType) { + case ID_SELECTOR: { + const canUseGetElementById = + !this.#shadow && + baseNode.nodeType === ELEMENT_NODE && + this.#root.nodeType !== ELEMENT_NODE; + if (canUseGetElementById) { + const leafName = unescapeSelector(leaf.name); + const nodes = new Set(); + const foundNode = this.#root.getElementById(leafName); + if ( + foundNode && + foundNode !== baseNode && + baseNode.contains(foundNode) + ) { + const isCompoundSelector = filterLeaves.length > 0; + if ( + !isCompoundSelector || + this._matchLeaves(filterLeaves, foundNode, opt) + ) { + nodes.add(foundNode); + } + } + return nodes; + } + // Fallback to default traversal if fast path is not applicable. + return this._traverseAllDescendants(baseNode, leaves, opt); + } + case PS_ELEMENT_SELECTOR: { + const leafName = unescapeSelector(leaf.name); + matchPseudoElementSelector(leafName, leafType, opt); + return new Set(); + } + default: { + return this._traverseAllDescendants(baseNode, leaves, opt); + } + } + }; + + /** + * Collects combinator matches into an array without creating intermediate sets. + * @private + * @param {object} twig - The twig object. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @param {string} [opt.dir] - The find direction. + * @param {Array.} matched - The collector array. + * @returns {Array.} The collector array. + */ + _collectCombinatorMatches = (twig, node, opt = {}, matched = []) => { + const { + combo: { name: comboName }, + leaves + } = twig; + const { dir } = opt; + switch (comboName) { + case '+': { + const refNode = + dir === DIR_NEXT + ? node.nextElementSibling + : node.previousElementSibling; + if (refNode && this._matchLeaves(leaves, refNode, opt)) { + matched.push(refNode); + } + break; + } + case '~': { + let refNode = + dir === DIR_NEXT + ? node.nextElementSibling + : node.previousElementSibling; + while (refNode) { + if (this._matchLeaves(leaves, refNode, opt)) { + matched.push(refNode); + } + refNode = + dir === DIR_NEXT + ? refNode.nextElementSibling + : refNode.previousElementSibling; + } + break; + } + case '>': { + if (dir === DIR_NEXT) { + let refNode = node.firstElementChild; + while (refNode) { + if (this._matchLeaves(leaves, refNode, opt)) { + matched.push(refNode); + } + refNode = refNode.nextElementSibling; + } + } else { + const { parentNode } = node; + if (parentNode && this._matchLeaves(leaves, parentNode, opt)) { + matched.push(parentNode); + } + } + break; + } + case ' ': + default: { + if (dir === DIR_NEXT) { + for (const refNode of this._findDescendantNodes(leaves, node, opt)) { + matched.push(refNode); + } + } else { + const ancestors = []; + let refNode = node.parentNode; + while (refNode) { + if (this._matchLeaves(leaves, refNode, opt)) { + ancestors.push(refNode); + } + refNode = refNode.parentNode; + } + if (ancestors.length) { + matched.push(...ancestors.reverse()); + } + } + } + } + return matched; + }; + + /** + * Matches a combinator. + * @private + * @param {object} twig - The twig object. + * @param {object} node - The Element node. + * @param {object} opt - Options. + * @returns {Set.} A collection of matched nodes. + */ + _matchCombinator = (twig, node, opt) => + new Set(this._collectCombinatorMatches(twig, node, opt)); + + /** + * Traverses with a TreeWalker and collects nodes matching the leaves. + * @private + * @param {TreeWalker} walker - The TreeWalker instance to use. + * @param {Array} leaves - The AST leaves to match against. + * @param {object} [opt] - Traversal options. + * @param {Node} [opt.boundaryNode] - The node to stop traversal at. + * @param {boolean} [opt.force] - Force traversal to the next node. + * @param {Node} [opt.startNode] - The node to start traversal from. + * @param {string} [opt.targetType] - The type of target ('all' or 'first'). + * @returns {Array.} An array of matched nodes. + */ + _traverseAndCollectNodes = (walker, leaves, opt = {}) => { + const { boundaryNode, force, startNode, targetType } = opt; + const collectedNodes = []; + let currentNode = traverseNode(startNode, walker, !!force); + if (!currentNode) { + return []; + } + // Adjust starting node. + if (currentNode.nodeType !== ELEMENT_NODE) { + currentNode = walker.nextNode(); + } else if (currentNode === startNode && currentNode !== this.#root) { + currentNode = walker.nextNode(); + } + const matchOpt = { + warn: this.#warn + }; + while (currentNode) { + // Stop when we reach the boundary. + if (boundaryNode) { + if (currentNode === boundaryNode) { + break; + } else if ( + targetType === TARGET_ALL && + !boundaryNode.contains(currentNode) + ) { + break; + } + } + if ( + this._matchLeaves(leaves, currentNode, matchOpt) && + currentNode !== this.#node + ) { + collectedNodes.push(currentNode); + // Stop after the first match if not collecting all. + if (targetType !== TARGET_ALL) { + break; + } + } + currentNode = walker.nextNode(); + } + return collectedNodes; + }; + + /** + * Finds matched node(s) preceding this.#node. + * @private + * @param {Array.} leaves - The AST leaves. + * @param {object} node - The node to start from. + * @param {object} [opt] - Options. + * @param {boolean} [opt.force] - If true, traverses only to the next node. + * @param {string} [opt.targetType] - The target type. + * @returns {Array.} A collection of matched nodes. + */ + _findPrecede = (leaves, node, opt = {}) => { + const { force, targetType } = opt; + if (!this.#rootWalker) { + this.#rootWalker = this._createTreeWalker(this.#root); + } + return this._traverseAndCollectNodes(this.#rootWalker, leaves, { + force, + targetType, + boundaryNode: this.#node, + startNode: node + }); + }; + + /** + * Finds matched node(s) in #nodeWalker. + * @private + * @param {Array.} leaves - The AST leaves. + * @param {object} node - The node to start from. + * @param {object} [opt] - Options. + * @param {boolean} [opt.precede] - If true, finds preceding nodes. + * @returns {Array.} A collection of matched nodes. + */ + _findNodeWalker = (leaves, node, opt = {}) => { + const { precede, ...traversalOpts } = opt; + if (precede) { + const precedeNodes = this._findPrecede(leaves, this.#root, opt); + if (precedeNodes.length) { + return precedeNodes; + } + } + if (!this.#nodeWalker) { + this.#nodeWalker = this._createTreeWalker(this.#node); + } + return this._traverseAndCollectNodes(this.#nodeWalker, leaves, { + startNode: node, + ...traversalOpts + }); + }; + + /** + * Matches the node itself. + * @private + * @param {Array} leaves - The AST leaves. + * @returns {Array} An array containing [nodes, filtered, pseudoElement]. + */ + _matchSelf = leaves => { + const matched = this._matchLeaves(leaves, this.#node, { + check: this.#check, + warn: this.#warn + }); + const nodes = matched ? [this.#node] : []; + return [nodes, matched, this.#pseudoElement]; + }; + + /** + * Finds lineal nodes (self and ancestors). + * @private + * @param {Array} leaves - The AST leaves. + * @param {object} [opt] - Options. + * @param {boolean} [opt.complex] - If true, the selector is complex. + * @returns {Array} An array containing [nodes, filtered]. + */ + _findLineal = (leaves, opt = {}) => { + const { complex } = opt; + const nodes = []; + const matchOpts = { warn: this.#warn }; + const selfMatched = this._matchLeaves(leaves, this.#node, matchOpts); + if (selfMatched) { + nodes.push(this.#node); + } + if (!selfMatched || complex) { + let currentNode = this.#node.parentNode; + while (currentNode) { + if (this._matchLeaves(leaves, currentNode, matchOpts)) { + nodes.push(currentNode); + } + currentNode = currentNode.parentNode; + } + } + const filtered = nodes.length > 0; + return [nodes, filtered]; + }; + + /** + * Finds entry nodes for pseudo-element selectors. + * @private + * @param {object} leaf - The pseudo-element leaf from the AST. + * @param {Array.} filterLeaves - Leaves for compound selectors. + * @param {string} targetType - The type of target to find. + * @returns {object} The result { nodes, filtered, pending }. + */ + _findEntryNodesForPseudoElement = (leaf, filterLeaves, targetType) => { + let nodes = []; + let filtered = false; + if (targetType === TARGET_SELF && this.#check) { + const css = generateCSS(leaf); + this.#pseudoElement.push(css); + if (filterLeaves.length) { + [nodes, filtered] = this._matchSelf(filterLeaves); + } else { + nodes.push(this.#node); + filtered = true; + } + } else { + matchPseudoElementSelector(leaf.name, leaf.type, { warn: this.#warn }); + } + return { nodes, filtered, pending: false }; + }; + + /** + * Finds entry nodes for ID selectors. + * @private + * @param {object} twig - The current twig from the AST branch. + * @param {string} targetType - The type of target to find. + * @param {object} [opt] - Options. + * @param {boolean} [opt.complex] - If true, the selector is complex. + * @param {boolean} [opt.precede] - If true, finds preceding nodes. + * @returns {object} The result { nodes, filtered, pending }. + */ + _findEntryNodesForId = (twig, targetType, opt = {}) => { + const { leaves } = twig; + const [leaf] = leaves; + const filterLeaves = this._getFilterLeaves(leaves); + const { complex, precede } = opt; + let nodes = []; + let filtered = false; + if (targetType === TARGET_SELF) { + [nodes, filtered] = this._matchSelf(leaves); + } else if (targetType === TARGET_LINEAL) { + [nodes, filtered] = this._findLineal(leaves, { complex }); + } else if ( + targetType === TARGET_FIRST && + this.#root.nodeType !== ELEMENT_NODE + ) { + const node = this.#root.getElementById(leaf.name); + if (node) { + if (filterLeaves.length) { + if (this._matchLeaves(filterLeaves, node, { warn: this.#warn })) { + nodes.push(node); + filtered = true; + } + } else { + nodes.push(node); + filtered = true; + } + } + } else { + nodes = this._findNodeWalker(leaves, this.#node, { precede, targetType }); + filtered = nodes.length > 0; + } + return { nodes, filtered, pending: false }; + }; + + /** + * Finds entry nodes for class selectors. + * @private + * @param {Array.} leaves - The AST leaves for the selector. + * @param {string} targetType - The type of target to find. + * @param {object} [opt] - Options. + * @param {boolean} [opt.complex] - If true, the selector is complex. + * @param {boolean} [opt.precede] - If true, finds preceding nodes. + * @returns {object} The result { nodes, filtered, pending }. + */ + _findEntryNodesForClass = (leaves, targetType, opt = {}) => { + const { complex, precede } = opt; + let nodes = []; + let filtered = false; + if (targetType === TARGET_SELF) { + [nodes, filtered] = this._matchSelf(leaves); + } else if (targetType === TARGET_LINEAL) { + [nodes, filtered] = this._findLineal(leaves, { complex }); + } else { + nodes = this._findNodeWalker(leaves, this.#node, { precede, targetType }); + filtered = nodes.length > 0; + } + return { nodes, filtered, pending: false }; + }; + + /** + * Finds entry nodes for type selectors. + * @private + * @param {Array.} leaves - The AST leaves for the selector. + * @param {string} targetType - The type of target to find. + * @param {object} [opt] - Options. + * @param {boolean} [opt.complex] - If true, the selector is complex. + * @param {boolean} [opt.precede] - If true, finds preceding nodes. + * @returns {object} The result { nodes, filtered, pending }. + */ + _findEntryNodesForType = (leaves, targetType, opt = {}) => { + const { complex, precede } = opt; + let nodes = []; + let filtered = false; + if (targetType === TARGET_SELF) { + [nodes, filtered] = this._matchSelf(leaves); + } else if (targetType === TARGET_LINEAL) { + [nodes, filtered] = this._findLineal(leaves, { complex }); + } else { + nodes = this._findNodeWalker(leaves, this.#node, { precede, targetType }); + filtered = nodes.length > 0; + } + return { nodes, filtered, pending: false }; + }; + + /** + * Finds entry nodes for other selector types (default case). + * @private + * @param {object} twig - The current twig from the AST branch. + * @param {string} targetType - The type of target to find. + * @param {object} [opt] - Options. + * @param {boolean} [opt.complex] - If true, the selector is complex. + * @param {boolean} [opt.precede] - If true, finds preceding nodes. + * @returns {object} The result { nodes, filtered, pending }. + */ + _findEntryNodesForOther = (twig, targetType, opt = {}) => { + const { leaves } = twig; + const [leaf] = leaves; + const filterLeaves = this._getFilterLeaves(leaves); + const { complex, precede } = opt; + let nodes = []; + let filtered = false; + let pending = false; + if (targetType !== TARGET_LINEAL && /host(?:-context)?/.test(leaf.name)) { + let shadowRoot = null; + if (this.#shadow && this.#node.nodeType === DOCUMENT_FRAGMENT_NODE) { + shadowRoot = this._matchShadowHostPseudoClass(leaf, this.#node); + } else if (filterLeaves.length && this.#node.nodeType === ELEMENT_NODE) { + shadowRoot = this._matchShadowHostPseudoClass( + leaf, + this.#node.shadowRoot + ); + } + if (shadowRoot) { + let bool = true; + const l = filterLeaves.length; + for (let i = 0; i < l; i++) { + const filterLeaf = filterLeaves[i]; + switch (filterLeaf.name) { + case 'host': + case 'host-context': { + const matchedNode = this._matchShadowHostPseudoClass( + filterLeaf, + shadowRoot + ); + bool = matchedNode === shadowRoot; + break; + } + case 'has': { + bool = this._matchPseudoClassSelector( + filterLeaf, + shadowRoot, + {} + ).has(shadowRoot); + break; + } + default: { + bool = false; + } + } + if (!bool) { + break; + } + } + if (bool) { + nodes.push(shadowRoot); + filtered = true; + } + } + } else if (targetType === TARGET_SELF) { + [nodes, filtered] = this._matchSelf(leaves); + } else if (targetType === TARGET_LINEAL) { + [nodes, filtered] = this._findLineal(leaves, { complex }); + } else if (targetType === TARGET_FIRST) { + nodes = this._findNodeWalker(leaves, this.#node, { precede, targetType }); + filtered = nodes.length > 0; + } else { + pending = true; + } + return { nodes, filtered, pending }; + }; + + /** + * Finds entry nodes. + * @private + * @param {object} twig - The twig object. + * @param {string} targetType - The target type. + * @param {object} [opt] - Options. + * @param {boolean} [opt.complex] - If true, the selector is complex. + * @param {string} [opt.dir] - The find direction. + * @returns {object} An object with nodes and their state. + */ + _findEntryNodes = (twig, targetType, opt = {}) => { + const { leaves } = twig; + const [leaf] = leaves; + const filterLeaves = this._getFilterLeaves(leaves); + const { complex = false, dir = DIR_PREV } = opt; + const precede = + dir === DIR_NEXT && + this.#node.nodeType === ELEMENT_NODE && + this.#node !== this.#root; + let result; + switch (leaf.type) { + case PS_ELEMENT_SELECTOR: { + result = this._findEntryNodesForPseudoElement( + leaf, + filterLeaves, + targetType + ); + break; + } + case ID_SELECTOR: { + result = this._findEntryNodesForId(twig, targetType, { + complex, + precede + }); + break; + } + case CLASS_SELECTOR: { + result = this._findEntryNodesForClass(leaves, targetType, { + complex, + precede + }); + break; + } + case TYPE_SELECTOR: { + result = this._findEntryNodesForType(leaves, targetType, { + complex, + precede + }); + break; + } + default: { + result = this._findEntryNodesForOther(twig, targetType, { + complex, + precede + }); + } + } + return { + compound: filterLeaves.length > 0, + filtered: result.filtered, + nodes: result.nodes, + pending: result.pending + }; + }; + + /** + * Determines the direction and starting twig for a selector branch. + * @private + * @param {Array.} branch - The AST branch. + * @param {string} targetType - The type of target to find. + * @returns {object} An object with the direction and starting twig. + */ + _determineTraversalStrategy = (branch, targetType) => { + const branchLen = branch.length; + const firstTwig = branch[0]; + const lastTwig = branch[branchLen - 1]; + if (branchLen === 1) { + return { dir: DIR_PREV, twig: firstTwig }; + } + // Complex selector (branchLen > 1). + const { + leaves: [{ name: firstName, type: firstType }] + } = firstTwig; + const { + leaves: [{ name: lastName, type: lastType }] + } = lastTwig; + const { combo: firstCombo } = firstTwig; + if ( + this.#selector.includes(':scope') || + lastType === PS_ELEMENT_SELECTOR || + lastType === ID_SELECTOR + ) { + return { dir: DIR_PREV, twig: lastTwig }; + } + if (firstType === ID_SELECTOR) { + return { dir: DIR_NEXT, twig: firstTwig }; + } + if (firstName === '*' && firstType === TYPE_SELECTOR) { + return { dir: DIR_PREV, twig: lastTwig }; + } + if (lastName === '*' && lastType === TYPE_SELECTOR) { + return { dir: DIR_NEXT, twig: firstTwig }; + } + if (branchLen === 2) { + if (targetType === TARGET_FIRST) { + return { dir: DIR_PREV, twig: lastTwig }; + } + const { name: comboName } = firstCombo; + if (comboName === '+' || comboName === '~') { + return { dir: DIR_PREV, twig: lastTwig }; + } + } else if (branchLen > 2 && this.#scoped && targetType === TARGET_FIRST) { + if (lastType === TYPE_SELECTOR) { + return { dir: DIR_PREV, twig: lastTwig }; + } + let isChildOrDescendant = false; + for (const { combo } of branch) { + if (combo) { + const { name: comboName } = combo; + isChildOrDescendant = comboName === '>' || comboName === ' '; + if (!isChildOrDescendant) { + break; + } + } + } + if (isChildOrDescendant) { + return { dir: DIR_PREV, twig: lastTwig }; + } + } + // Default strategy for complex selectors. + return { dir: DIR_NEXT, twig: firstTwig }; + }; + + /** + * Processes pending items not resolved with a direct strategy. + * @private + * @param {Set.} pendingItems - The set of pending items. + */ + _processPendingItems = pendingItems => { + if (!pendingItems.size) { + return; + } + if (!this.#rootWalker) { + this.#rootWalker = this._createTreeWalker(this.#root); + } + const walker = this.#rootWalker; + let node = this.#root; + if (this.#scoped) { + node = this.#node; + } + let nextNode = traverseNode(node, walker); + while (nextNode) { + const isWithinScope = + this.#node.nodeType !== ELEMENT_NODE || + nextNode === this.#node || + this.#node.contains(nextNode); + if (isWithinScope) { + for (const pendingItem of pendingItems) { + const { leaves } = pendingItem.get('twig'); + if (this._matchLeaves(leaves, nextNode, { warn: this.#warn })) { + const index = pendingItem.get('index'); + this.#ast[index].filtered = true; + this.#ast[index].find = true; + this.#nodes[index].push(nextNode); + } + } + } else if (this.#scoped) { + break; + } + nextNode = walker.nextNode(); + } + }; + + /** + * Collects nodes. + * @private + * @param {string} targetType - The target type. + * @returns {Array.>} An array containing the AST and nodes. + */ + _collectNodes = targetType => { + [this.#ast, this.#nodes] = this._correspond(this.#selector); + const ast = this.#ast.values(); + if (targetType === TARGET_ALL || targetType === TARGET_FIRST) { + const pendingItems = new Set(); + let i = 0; + for (const { branch } of ast) { + const complex = branch.length > 1; + const { dir, twig } = this._determineTraversalStrategy( + branch, + targetType + ); + const { compound, filtered, nodes, pending } = this._findEntryNodes( + twig, + targetType, + { complex, dir } + ); + if (nodes.length) { + this.#ast[i].find = true; + this.#nodes[i] = nodes; + } else if (pending) { + pendingItems.add( + new Map([ + ['index', i], + ['twig', twig] + ]) + ); + } + this.#ast[i].dir = dir; + this.#ast[i].filtered = filtered || !compound; + i++; + } + this._processPendingItems(pendingItems); + } else { + let i = 0; + for (const { branch } of ast) { + const twig = branch[branch.length - 1]; + const complex = branch.length > 1; + const dir = DIR_PREV; + const { compound, filtered, nodes } = this._findEntryNodes( + twig, + targetType, + { complex, dir } + ); + if (nodes.length) { + this.#ast[i].find = true; + this.#nodes[i] = nodes; + } + this.#ast[i].dir = dir; + this.#ast[i].filtered = filtered || !compound; + i++; + } + } + return [this.#ast, this.#nodes]; + }; + + /** + * Gets combined nodes. + * @private + * @param {object} twig - The twig object. + * @param {object} nodes - A collection of nodes. + * @param {string} dir - The direction. + * @returns {Array.} A collection of matched nodes. + */ + _getCombinedNodes = (twig, nodes, dir) => { + const arr = []; + for (const node of nodes) { + this._collectCombinatorMatches( + twig, + node, + { dir, warn: this.#warn }, + arr + ); + } + return arr; + }; + + /** + * Matches a node in the 'next' direction. + * @private + * @param {Array} branch - The branch. + * @param {Set.} nodes - A collection of Element nodes. + * @param {object} [opt] - Options. + * @param {object} [opt.combo] - The combo object. + * @param {number} [opt.index] - The index. + * @returns {?object} The matched node. + */ + _matchNodeNext = (branch, nodes, opt = {}) => { + const { combo, index } = opt; + const { combo: nextCombo, leaves } = branch[index]; + const twig = { + combo, + leaves + }; + const nextNodes = this._getCombinedNodes(twig, nodes, DIR_NEXT); + if (nextNodes.length) { + if (index === branch.length - 1) { + if (nextNodes.length === 1) { + return nextNodes[0]; + } + const [nextNode] = sortNodes(nextNodes); + return nextNode; + } + return this._matchNodeNext(branch, nextNodes, { + combo: nextCombo, + index: index + 1 + }); + } + return null; + }; + + /** + * Matches a node in the 'previous' direction. + * @private + * @param {Array} branch - The branch. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @param {number} [opt.index] - The index. + * @returns {?object} The node. + */ + _matchNodePrev = (branch, node, opt = {}) => { + const { index } = opt; + const twig = branch[index]; + const nextNodes = this._getCombinedNodes(twig, [node], DIR_PREV); + if (nextNodes.length) { + if (index === 0) { + return node; + } + let matched; + for (const nextNode of nextNodes) { + matched = this._matchNodePrev(branch, nextNode, { + index: index - 1 + }); + if (matched) { + break; + } + } + if (matched) { + return node; + } + } + return null; + }; + + /** + * Processes a complex selector branch to find all matching nodes. + * @private + * @param {Array} branch - The selector branch from the AST. + * @param {Array} entryNodes - The initial set of nodes to start from. + * @param {string} dir - The direction of traversal ('next' or 'prev'). + * @returns {Set.} A set of all matched nodes. + */ + _processComplexBranchAll = (branch, entryNodes, dir) => { + const matchedNodes = new Set(); + const branchLen = branch.length; + const lastIndex = branchLen - 1; + + if (dir === DIR_NEXT) { + const { combo: firstCombo } = branch[0]; + for (const node of entryNodes) { + let combo = firstCombo; + let nextNodes = [node]; + for (let j = 1; j < branchLen; j++) { + const { combo: nextCombo, leaves } = branch[j]; + const twig = { combo, leaves }; + const nodesArr = this._getCombinedNodes(twig, nextNodes, dir); + if (nodesArr.length) { + if (j === lastIndex) { + for (const nextNode of nodesArr) { + matchedNodes.add(nextNode); + } + } + combo = nextCombo; + nextNodes = nodesArr; + } else { + break; + } + } + } + // DIR_PREV + } else { + for (const node of entryNodes) { + let nextNodes = [node]; + for (let j = lastIndex - 1; j >= 0; j--) { + const twig = branch[j]; + const nodesArr = this._getCombinedNodes(twig, nextNodes, dir); + if (nodesArr.length) { + // The entry node is the final match + if (j === 0) { + matchedNodes.add(node); + } + nextNodes = nodesArr; + } else { + break; + } + } + } + } + return matchedNodes; + }; + + /** + * Processes a complex selector branch to find the first matching node. + * @private + * @param {Array} branch - The selector branch from the AST. + * @param {Array} entryNodes - The initial set of nodes to start from. + * @param {string} dir - The direction of traversal ('next' or 'prev'). + * @param {string} targetType - The type of search (e.g., 'first'). + * @returns {?object} The first matched node, or null. + */ + _processComplexBranchFirst = (branch, entryNodes, dir, targetType) => { + const branchLen = branch.length; + const lastIndex = branchLen - 1; + // DIR_NEXT logic for finding the first match. + if (dir === DIR_NEXT) { + const { combo: entryCombo } = branch[0]; + for (const node of entryNodes) { + const matchedNode = this._matchNodeNext(branch, new Set([node]), { + combo: entryCombo, + index: 1 + }); + if (matchedNode) { + if (this.#node.nodeType === ELEMENT_NODE) { + if ( + matchedNode !== this.#node && + this.#node.contains(matchedNode) + ) { + return matchedNode; + } + } else { + return matchedNode; + } + } + } + // Fallback logic if no direct match found. + const { leaves: entryLeaves } = branch[0]; + const [entryNode] = entryNodes; + if (this.#node.contains(entryNode)) { + let [refNode] = this._findNodeWalker(entryLeaves, entryNode, { + targetType + }); + while (refNode) { + const matchedNode = this._matchNodeNext(branch, new Set([refNode]), { + combo: entryCombo, + index: 1 + }); + if (matchedNode) { + if (this.#node.nodeType === ELEMENT_NODE) { + if ( + matchedNode !== this.#node && + this.#node.contains(matchedNode) + ) { + return matchedNode; + } + } else { + return matchedNode; + } + } + [refNode] = this._findNodeWalker(entryLeaves, refNode, { + targetType, + force: true + }); + } + } + // DIR_PREV logic for finding the first match. + } else { + for (const node of entryNodes) { + const matchedNode = this._matchNodePrev(branch, node, { + index: lastIndex - 1 + }); + if (matchedNode) { + return matchedNode; + } + } + // Fallback for TARGET_FIRST. + if (targetType === TARGET_FIRST) { + const { leaves: entryLeaves } = branch[lastIndex]; + const [entryNode] = entryNodes; + let [refNode] = this._findNodeWalker(entryLeaves, entryNode, { + targetType + }); + while (refNode) { + const matchedNode = this._matchNodePrev(branch, refNode, { + index: lastIndex - 1 + }); + if (matchedNode) { + return refNode; + } + [refNode] = this._findNodeWalker(entryLeaves, refNode, { + targetType, + force: true + }); + } + } + } + return null; + }; + + /** + * Finds matched nodes. + * @param {string} targetType - The target type. + * @returns {Set.} A collection of matched nodes. + */ + find = targetType => { + let collection; + try { + collection = this._collectNodes(targetType); + } catch (e) { + if (this.#check) { + let pseudoElement; + if (this.#pseudoElement.length) { + pseudoElement = this.#pseudoElement.join(''); + } else { + pseudoElement = null; + } + return { + pseudoElement, + match: false, + ast: this.#selectorAST ?? null + }; + } else { + throw e; + } + } + const [[...branches], collectedNodes] = collection; + const l = branches.length; + let sort = + l > 1 && targetType === TARGET_ALL && this.#selector.includes(':scope'); + let nodes = new Set(); + for (let i = 0; i < l; i++) { + const { branch, dir, find } = branches[i]; + if (!branch.length || !find) { + continue; + } + const entryNodes = collectedNodes[i]; + const lastIndex = branch.length - 1; + // Handle simple selectors (no combinators). + if (lastIndex === 0) { + if ( + (targetType === TARGET_ALL || targetType === TARGET_FIRST) && + this.#node.nodeType === ELEMENT_NODE + ) { + for (const node of entryNodes) { + if (node !== this.#node && this.#node.contains(node)) { + nodes.add(node); + if (targetType === TARGET_FIRST) { + break; + } + } + } + } else if (targetType === TARGET_ALL) { + if (nodes.size) { + for (const node of entryNodes) { + nodes.add(node); + } + sort = true; + } else { + nodes = new Set(entryNodes); + } + } else { + if (entryNodes.length) { + nodes.add(entryNodes[0]); + } + } + // Handle complex selectors. + } else { + if (targetType === TARGET_ALL) { + const newNodes = this._processComplexBranchAll( + branch, + entryNodes, + dir + ); + if (nodes.size) { + for (const newNode of newNodes) { + nodes.add(newNode); + } + sort = true; + } else { + nodes = newNodes; + } + } else { + const matchedNode = this._processComplexBranchFirst( + branch, + entryNodes, + dir, + targetType + ); + if (matchedNode) { + nodes.add(matchedNode); + } + } + } + } + if (this.#check) { + const match = !!nodes.size; + let pseudoElement; + if (this.#pseudoElement.length) { + pseudoElement = this.#pseudoElement.join(''); + } else { + pseudoElement = null; + } + return { + match, + pseudoElement, + ast: this.#selectorAST + }; + } + if (targetType === TARGET_FIRST || targetType === TARGET_ALL) { + nodes.delete(this.#node); + } + if ((sort || targetType === TARGET_FIRST) && nodes.size > 1) { + return new Set(sortNodes(nodes)); + } + return nodes; + }; + + /** + * Gets AST for selector. + * @param {string} selector - The selector text. + * @returns {object} The AST for the selector. + */ + getAST = selector => { + return parseSelector(selector); + }; +} diff --git a/node_modules/@asamuzakjp/dom-selector/src/js/matcher.js b/node_modules/@asamuzakjp/dom-selector/src/js/matcher.js new file mode 100644 index 0000000..f0393cc --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/js/matcher.js @@ -0,0 +1,609 @@ +/** + * matcher.js + */ + +/* import */ +import { generateCSS, parseAstName, unescapeSelector } from './parser.js'; +import { + generateException, + getDirectionality, + getLanguageAttribute, + getType, + isContentEditable, + isCustomElement, + isNamespaceDeclared +} from './utility.js'; + +/* constants */ +import { + ALPHA_NUM, + FORM_PARTS, + IDENT, + INPUT_EDIT, + LANG_PART, + NOT_SUPPORTED_ERR, + PS_ELEMENT_SELECTOR, + STRING, + SYNTAX_ERR +} from './constant.js'; +const KEYS_FORM_PS_DISABLED = new Set([ + ...FORM_PARTS, + 'fieldset', + 'optgroup', + 'option' +]); +const KEYS_INPUT_EDIT = new Set(INPUT_EDIT); +const REG_LANG_VALID = new RegExp(`^(?:\\*-)?${ALPHA_NUM}${LANG_PART}$`, 'i'); + +/** + * Validates a pseudo-element selector. + * @param {string} astName - The name of the pseudo-element from the AST. + * @param {string} astType - The type of the selector from the AST. + * @param {object} [opt] - Optional parameters. + * @param {boolean} [opt.forgive] - If true, ignores unknown pseudo-elements. + * @param {boolean} [opt.warn] - If true, throws an error for unsupported ones. + * @throws {DOMException} If the selector is invalid or unsupported. + * @returns {void} + */ +export const matchPseudoElementSelector = (astName, astType, opt = {}) => { + const { forgive, globalObject, warn } = opt; + if (astType !== PS_ELEMENT_SELECTOR) { + // Ensure the AST node is a pseudo-element selector. + throw new TypeError(`Unexpected ast type ${getType(astType)}`); + } + switch (astName) { + case 'after': + case 'backdrop': + case 'before': + case 'cue': + case 'cue-region': + case 'first-letter': + case 'first-line': + case 'file-selector-button': + case 'marker': + case 'placeholder': + case 'selection': + case 'target-text': { + // Warn if the pseudo-element is known but unsupported. + if (warn) { + throw generateException( + `Unsupported pseudo-element ::${astName}`, + NOT_SUPPORTED_ERR, + globalObject + ); + } + break; + } + case 'part': + case 'slotted': { + // Warn if the functional pseudo-element is known but unsupported. + if (warn) { + throw generateException( + `Unsupported pseudo-element ::${astName}()`, + NOT_SUPPORTED_ERR, + globalObject + ); + } + break; + } + default: { + // Handle vendor-prefixed or unknown pseudo-elements. + if (astName.startsWith('-webkit-')) { + if (warn) { + throw generateException( + `Unsupported pseudo-element ::${astName}`, + NOT_SUPPORTED_ERR, + globalObject + ); + } + // Throw an error for unknown pseudo-elements if not forgiven. + } else if (!forgive) { + throw generateException( + `Unknown pseudo-element ::${astName}`, + SYNTAX_ERR, + globalObject + ); + } + } + } +}; + +/** + * Matches the :dir() pseudo-class against an element's directionality. + * @param {object} ast - The AST object for the pseudo-class. + * @param {object} node - The element node to match against. + * @throws {TypeError} If the AST does not contain a valid direction value. + * @returns {boolean} - True if the directionality matches, otherwise false. + */ +export const matchDirectionPseudoClass = (ast, node) => { + const { name } = ast; + // The :dir() pseudo-class requires a direction argument (e.g., "ltr"). + if (!name) { + const type = name === '' ? '(empty String)' : getType(name); + throw new TypeError(`Unexpected ast type ${type}`); + } + // Get the computed directionality of the element. + const dir = getDirectionality(node); + // Compare the expected direction with the element's actual direction. + return name === dir; +}; + +/** + * Matches the :lang() pseudo-class against an element's language. + * @see https://datatracker.ietf.org/doc/html/rfc4647#section-3.3.1 + * @param {object} ast - The AST object for the pseudo-class. + * @param {object} node - The element node to match against. + * @returns {boolean} - True if the language matches, otherwise false. + */ +export const matchLanguagePseudoClass = (ast, node) => { + // Get the effective language attribute for the current node. + const elementLang = getLanguageAttribute(node); + // If the element has no language, it cannot match a specific pattern. + if (elementLang === null) { + return false; + } + // Use cached regex. + if (ast._langRegex !== undefined) { + if (ast._langPattern === '*') { + return elementLang !== ''; + } + if (ast._langRegex === null) { + return false; + } + return ast._langRegex.test(elementLang); + } + const { name, type, value } = ast; + let langPattern; + // Determine the language pattern from the AST. + if (type === STRING && value) { + langPattern = value; + } else if (type === IDENT && name) { + langPattern = unescapeSelector(name); + } + // Cache lang pattern. + ast._langPattern = langPattern; + // If no valid language pattern is provided, it cannot match. + if (typeof langPattern !== 'string') { + ast._langRegex = null; + return false; + } + // Handle the universal selector '*' for :lang. + if (langPattern === '*') { + ast._langRegex = null; + return elementLang !== ''; + } + // Validate the provided language pattern structure. + if (!REG_LANG_VALID.test(langPattern)) { + ast._langRegex = null; + return false; + } + // Build a regex for extended language range matching. + let matcherRegex; + if (langPattern.indexOf('-') > -1) { + const [langMain, langSub, ...langRest] = langPattern.split('-'); + const extendedMain = + langMain === '*' ? `${ALPHA_NUM}${LANG_PART}` : `${langMain}${LANG_PART}`; + const extendedSub = `-${langSub}${LANG_PART}`; + let extendedRest = ''; + for (let i = 0; i < langRest.length; i++) { + extendedRest += `-${langRest[i]}${LANG_PART}`; + } + matcherRegex = new RegExp( + `^${extendedMain}${extendedSub}${extendedRest}$`, + 'i' + ); + } else { + matcherRegex = new RegExp(`^${langPattern}${LANG_PART}$`, 'i'); + } + ast._langRegex = matcherRegex; + // Test the element's language against the constructed regex. + return matcherRegex.test(elementLang); +}; + +/** + * Matches the :disabled and :enabled pseudo-classes. + * @param {string} astName - pseudo-class name + * @param {object} node - Element node + * @returns {boolean} - True if matched + */ +export const matchDisabledPseudoClass = (astName, node) => { + const { localName, parentNode } = node; + if ( + !KEYS_FORM_PS_DISABLED.has(localName) && + !isCustomElement(node, { formAssociated: true }) + ) { + return false; + } + let isDisabled = false; + if (node.disabled || node.hasAttribute('disabled')) { + isDisabled = true; + } else if (localName === 'option') { + if ( + parentNode && + parentNode.localName === 'optgroup' && + (parentNode.disabled || parentNode.hasAttribute('disabled')) + ) { + isDisabled = true; + } + } else if (localName !== 'optgroup') { + let current = parentNode; + while (current) { + if ( + current.localName === 'fieldset' && + (current.disabled || current.hasAttribute('disabled')) + ) { + // The first in a disabled
is not disabled. + let legend; + let element = current.firstElementChild; + while (element) { + if (element.localName === 'legend') { + legend = element; + break; + } + element = element.nextElementSibling; + } + if (!legend || !legend.contains(node)) { + isDisabled = true; + } + // Found the containing fieldset, stop searching up. + break; + } + current = current.parentNode; + } + } + if (astName === 'disabled') { + return isDisabled; + } + return !isDisabled; +}; + +/** + * Match the :read-only and :read-write pseudo-classes + * @param {string} astName - pseudo-class name + * @param {object} node - Element node + * @returns {boolean} - True if matched + */ +export const matchReadOnlyPseudoClass = (astName, node) => { + const { localName } = node; + let isReadOnly = false; + switch (localName) { + case 'textarea': + case 'input': { + const isEditableInput = !node.type || KEYS_INPUT_EDIT.has(node.type); + if (localName === 'textarea' || isEditableInput) { + isReadOnly = + node.readOnly || + node.hasAttribute('readonly') || + node.disabled || + node.hasAttribute('disabled'); + } else { + // Non-editable input types are always read-only + isReadOnly = true; + } + break; + } + default: { + isReadOnly = !isContentEditable(node); + } + } + if (astName === 'read-only') { + return isReadOnly; + } + return !isReadOnly; +}; + +/** + * Matches an attribute selector against an element. + * This function handles various attribute matchers like '=', '~=', '^=', etc., + * and considers namespaces and case sensitivity based on document type. + * @param {object} ast - The AST for the attribute selector. + * @param {object} node - The element node to match against. + * @param {object} [opt] - Optional parameters. + * @param {boolean} [opt.check] - True if running in an internal check. + * @param {boolean} [opt.forgive] - True to forgive certain syntax errors. + * @returns {boolean} - True if the attribute selector matches, otherwise false. + */ +export const matchAttributeSelector = (ast, node, opt = {}) => { + const { + flags: astFlags, + matcher: astMatcher, + name: astName, + value: astValue + } = ast; + const { check, forgive, globalObject } = opt; + // Validate selector flags ('i' or 's'). + if (typeof astFlags === 'string' && !/^[is]$/i.test(astFlags) && !forgive) { + const css = generateCSS(ast); + throw generateException( + `Invalid selector ${css}`, + SYNTAX_ERR, + globalObject + ); + } + const { attributes } = node; + // An element with no attributes cannot match. + if (!attributes || !attributes.length) { + return false; + } + // Determine case sensitivity based on document type and flags. + let caseInsensitive; + if (node.ownerDocument.contentType === 'text/html') { + if (typeof astFlags === 'string' && /^s$/i.test(astFlags)) { + caseInsensitive = false; + } else { + caseInsensitive = true; + } + } else if (typeof astFlags === 'string' && /^i$/i.test(astFlags)) { + caseInsensitive = true; + } else { + caseInsensitive = false; + } + // Prepare the attribute name from the selector for matching. + let astAttrName = unescapeSelector(astName.name); + if (caseInsensitive) { + astAttrName = astAttrName.toLowerCase(); + } + // A set to store the values of attributes whose names match. + const attrValues = new Set(); + // Handle namespaced attribute names (e.g., [*|attr], [ns|attr]). + if (astAttrName.indexOf('|') > -1) { + const { prefix: astPrefix, localName: astLocalName } = + parseAstName(astAttrName); + for (const item of attributes) { + let { name: itemName, value: itemValue } = item; + if (caseInsensitive) { + itemName = itemName.toLowerCase(); + itemValue = itemValue.toLowerCase(); + } + const colonIdx = itemName.indexOf(':'); + switch (astPrefix) { + case '': { + if (astLocalName === itemName) { + attrValues.add(itemValue); + } + break; + } + case '*': { + if (colonIdx > -1) { + const itemLocalName = itemName + .substring(colonIdx + 1) + .replace(/^:/, ''); + if (itemLocalName === astLocalName) { + attrValues.add(itemValue); + } + } else if (astLocalName === itemName) { + attrValues.add(itemValue); + } + break; + } + default: { + if (!check) { + if (forgive) { + return false; + } + const css = generateCSS(ast); + throw generateException( + `Invalid selector ${css}`, + SYNTAX_ERR, + globalObject + ); + } + if (colonIdx > -1) { + const itemPrefix = itemName.substring(0, colonIdx); + const itemLocalName = itemName + .substring(colonIdx + 1) + .replace(/^:/, ''); + // Ignore the 'xml:lang' attribute. + if (itemPrefix === 'xml' && itemLocalName === 'lang') { + continue; + } else if ( + astPrefix === itemPrefix && + astLocalName === itemLocalName + ) { + const namespaceDeclared = isNamespaceDeclared(astPrefix, node); + if (namespaceDeclared) { + attrValues.add(itemValue); + } + } + } + } + } + } + // Handle non-namespaced attribute names. + } else { + for (let { name: itemName, value: itemValue } of attributes) { + if (caseInsensitive) { + itemName = itemName.toLowerCase(); + itemValue = itemValue.toLowerCase(); + } + const colonIdx = itemName.indexOf(':'); + if (colonIdx > -1) { + const itemPrefix = itemName.substring(0, colonIdx); + const itemLocalName = itemName + .substring(colonIdx + 1) + .replace(/^:/, ''); + // The attribute is starting with ':'. + if (!itemPrefix && astAttrName === `:${itemLocalName}`) { + attrValues.add(itemValue); + // Ignore the 'xml:lang' attribute. + } else if (itemPrefix === 'xml' && itemLocalName === 'lang') { + continue; + } else if (astAttrName === itemLocalName) { + attrValues.add(itemValue); + } + } else if (astAttrName === itemName) { + attrValues.add(itemValue); + } + } + } + if (!attrValues.size) { + return false; + } + // Prepare the value from the selector's RHS for comparison. + const { name: astIdentValue, value: astStringValue } = astValue ?? {}; + let attrValue; + if (astIdentValue) { + if (caseInsensitive) { + attrValue = astIdentValue.toLowerCase().replace(/\\(?!\\)/g, ''); + } else { + attrValue = astIdentValue.replace(/\\(?!\\)/g, ''); + } + } else if (astStringValue) { + if (caseInsensitive) { + attrValue = astStringValue.toLowerCase().replace(/\\(?!\\)/g, ''); + } else { + attrValue = astStringValue.replace(/\\(?!\\)/g, ''); + } + } else if (astStringValue === '') { + attrValue = astStringValue; + } + // Perform the final match based on the specified matcher. + switch (astMatcher) { + case '=': { + return typeof attrValue === 'string' && attrValues.has(attrValue); + } + case '~=': { + if (attrValue && typeof attrValue === 'string') { + if (/\s/.test(attrValue)) { + return false; + } + if (ast._tildeTarget === undefined) { + ast._tildeTarget = ` ${attrValue} `; + } + const target = ast._tildeTarget; + for (const value of attrValues) { + if (` ${value.replace(/[\t\r\n\f]/g, ' ')} `.includes(target)) { + return true; + } + } + } + return false; + } + case '|=': { + if (attrValue && typeof attrValue === 'string') { + for (const value of attrValues) { + if (value === attrValue || value.startsWith(`${attrValue}-`)) { + return true; + } + } + } + return false; + } + case '^=': { + if (attrValue && typeof attrValue === 'string') { + for (const value of attrValues) { + if (value.startsWith(`${attrValue}`)) { + return true; + } + } + } + return false; + } + case '$=': { + if (attrValue && typeof attrValue === 'string') { + for (const value of attrValues) { + if (value.endsWith(`${attrValue}`)) { + return true; + } + } + } + return false; + } + case '*=': { + if (attrValue && typeof attrValue === 'string') { + for (const value of attrValues) { + if (value.includes(`${attrValue}`)) { + return true; + } + } + } + return false; + } + case null: + default: { + // This case handles attribute existence checks (e.g., '[disabled]'). + return true; + } + } +}; + +/** + * match type selector + * @param {object} ast - AST + * @param {object} node - Element node + * @param {object} [opt] - options + * @param {boolean} [opt.check] - running in internal check() + * @param {boolean} [opt.forgive] - forgive undeclared namespace + * @returns {boolean} - result + */ +export const matchTypeSelector = (ast, node, opt = {}) => { + const astName = unescapeSelector(ast.name); + const { localName, namespaceURI, prefix } = node; + const { check, forgive, globalObject } = opt; + let { prefix: astPrefix, localName: astLocalName } = parseAstName( + astName, + node + ); + const isHTML = + node.ownerDocument.contentType === 'text/html' && + (!namespaceURI || namespaceURI === 'http://www.w3.org/1999/xhtml'); + if (isHTML && localName === astLocalName && !astName.includes('|')) { + return true; + } + const firstChar = localName.charCodeAt(0); + const isAlphabet = + (firstChar >= 65 && firstChar <= 90) || + (firstChar >= 97 && firstChar <= 122); + if (isHTML && isAlphabet) { + astPrefix = astPrefix.toLowerCase(); + astLocalName = astLocalName.toLowerCase(); + } + let nodePrefix; + let nodeLocalName; + const colonIdx = localName.indexOf(':'); + if (colonIdx > -1) { + nodePrefix = localName.substring(0, colonIdx); + nodeLocalName = localName.substring(colonIdx + 1); + } else { + nodePrefix = prefix || ''; + nodeLocalName = localName; + } + const isUniversal = astLocalName === '*'; + switch (astPrefix) { + case '': { + return ( + !nodePrefix && + !namespaceURI && + (isUniversal || astLocalName === nodeLocalName) + ); + } + case '*': { + return isUniversal || astLocalName === nodeLocalName; + } + default: { + if (!check) { + if (forgive) { + return false; + } + const css = generateCSS(ast); + throw generateException( + `Invalid selector ${css}`, + SYNTAX_ERR, + globalObject + ); + } + const astNS = node.lookupNamespaceURI(astPrefix); + const nodeNS = node.lookupNamespaceURI(nodePrefix); + if (astNS === nodeNS && astPrefix === nodePrefix) { + return isUniversal || astLocalName === nodeLocalName; + } else if (!forgive && !astNS) { + throw generateException( + `Undeclared namespace ${astPrefix}`, + SYNTAX_ERR, + globalObject + ); + } + return false; + } + } +}; diff --git a/node_modules/@asamuzakjp/dom-selector/src/js/parser.js b/node_modules/@asamuzakjp/dom-selector/src/js/parser.js new file mode 100644 index 0000000..bfee8a6 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/js/parser.js @@ -0,0 +1,434 @@ +/** + * parser.js + */ + +/* import */ +import * as cssTree from 'css-tree'; +import { getType } from './utility.js'; + +/* constants */ +import { + ATTR_SELECTOR, + BIT_01, + BIT_02, + BIT_04, + BIT_08, + BIT_16, + BIT_32, + BIT_FFFF, + CLASS_SELECTOR, + DUO, + HEX, + ID_SELECTOR, + KEYS_LOGICAL, + NTH, + PS_CLASS_SELECTOR, + PS_ELEMENT_SELECTOR, + SELECTOR, + SYNTAX_ERR, + TYPE_SELECTOR +} from './constant.js'; +const AST_SORT_ORDER = new Map([ + [PS_ELEMENT_SELECTOR, BIT_01], + [ID_SELECTOR, BIT_02], + [CLASS_SELECTOR, BIT_04], + [TYPE_SELECTOR, BIT_08], + [ATTR_SELECTOR, BIT_16], + [PS_CLASS_SELECTOR, BIT_32] +]); +const KEYS_PS_CLASS_STATE = new Set([ + 'checked', + 'closed', + 'disabled', + 'empty', + 'enabled', + 'in-range', + 'indeterminate', + 'invalid', + 'open', + 'out-of-range', + 'placeholder-shown', + 'read-only', + 'read-write', + 'valid' +]); +const KEYS_SHADOW_HOST = new Set(['host', 'host-context']); +const REG_EMPTY_PS_FUNC = + /(?<=:(?:dir|has|host(?:-context)?|is|lang|not|nth-(?:last-)?(?:child|of-type)|where))\(\s+\)/g; +const REG_SHADOW_PS_ELEMENT = /^part|slotted$/; +const U_FFFD = '\uFFFD'; + +/** + * Unescapes a CSS selector string. + * @param {string} selector - The CSS selector to unescape. + * @returns {string} The unescaped selector string. + */ +export const unescapeSelector = (selector = '') => { + if (typeof selector === 'string' && selector.indexOf('\\', 0) >= 0) { + const arr = selector.split('\\'); + const selectorItems = [arr[0]]; + const l = arr.length; + for (let i = 1; i < l; i++) { + const item = arr[i]; + if (item === '' && i === l - 1) { + selectorItems.push(U_FFFD); + } else { + const hexExists = /^([\da-f]{1,6}\s?)/i.exec(item); + if (hexExists) { + const [, hex] = hexExists; + let str; + try { + const low = parseInt('D800', HEX); + const high = parseInt('DFFF', HEX); + const deci = parseInt(hex, HEX); + if (deci === 0 || (deci >= low && deci <= high)) { + str = U_FFFD; + } else { + str = String.fromCodePoint(deci); + } + } catch (e) { + str = U_FFFD; + } + let postStr = ''; + if (item.length > hex.length) { + postStr = item.substring(hex.length); + } + selectorItems.push(`${str}${postStr}`); + // whitespace + } else if (/^[\n\r\f]/.test(item)) { + selectorItems.push(`\\${item}`); + } else { + selectorItems.push(item); + } + } + } + return selectorItems.join(''); + } + return selector; +}; + +/** + * Preprocesses a selector string according to the specification. + * @see https://drafts.csswg.org/css-syntax-3/#input-preprocessing + * @param {string} value - The value to preprocess. + * @returns {string} The preprocessed selector string. + */ +export const preprocess = value => { + // Non-string values will be converted to string. + if (typeof value !== 'string') { + if (value === undefined || value === null) { + return getType(value).toLowerCase(); + } else if (Array.isArray(value)) { + return value.join(','); + } else if (Object.hasOwn(value, 'toString')) { + return value.toString(); + } else { + throw new DOMException(`Invalid selector ${value}`, SYNTAX_ERR); + } + } + let selector = value; + let index = 0; + while (index >= 0) { + // @see https://drafts.csswg.org/selectors/#id-selectors + index = selector.indexOf('#', index); + if (index < 0) { + break; + } + const preHash = selector.substring(0, index + 1); + let postHash = selector.substring(index + 1); + const codePoint = postHash.codePointAt(0); + if (codePoint > BIT_FFFF) { + const str = `\\${codePoint.toString(HEX)} `; + if (postHash.length === DUO) { + postHash = str; + } else { + postHash = `${str}${postHash.substring(DUO)}`; + } + } + selector = `${preHash}${postHash}`; + index++; + } + selector = selector + .replace(/\f|\r\n?/g, '\n') + .replace(/[\0\uD800-\uDFFF]|\\$/g, U_FFFD); + if (selector === '&') { + return ''; + } + return selector.replace(/\x26/g, ':scope'); +}; + +/** + * Creates an Abstract Syntax Tree (AST) from a CSS selector string. + * @param {string} sel - The CSS selector string. + * @returns {object} The parsed AST object. + */ +export const parseSelector = sel => { + const selector = preprocess(sel); + // invalid selectors + if (/^$|^\s*>|,\s*$/.test(selector)) { + throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR); + } + try { + return cssTree.parse(selector, { + context: 'selectorList' + }); + } catch (e) { + const { message } = e; + if ( + /^(?:"\]"|Attribute selector [()\s,=~^$*|]+) is expected$/.test( + message + ) && + !selector.endsWith(']') + ) { + const index = selector.lastIndexOf('['); + const selPart = selector.substring(index); + if (selPart.includes('"')) { + const quotes = selPart.match(/"/g).length; + if (quotes % 2) { + return parseSelector(`${selector}"]`); + } + return parseSelector(`${selector}]`); + } + return parseSelector(`${selector}]`); + } else if (message === '")" is expected') { + // workaround for https://github.com/csstree/csstree/issues/283 + if (REG_EMPTY_PS_FUNC.test(selector)) { + return parseSelector(`${selector.replaceAll(REG_EMPTY_PS_FUNC, '()')}`); + } else if (!selector.endsWith(')')) { + return parseSelector(`${selector})`); + } else { + throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR); + } + } else { + throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR); + } + } +}; + +/** + * Walks the provided AST to collect selector branches and gather information + * about its contents. + * @param {object} ast - The AST to traverse. + * @param {boolean} toObject - True if converts ast to object, false otherwise. + * @returns {{branches: Array, info: object}} An object containing the selector branches and info. + */ +export const walkAST = (ast = {}, toObject = false) => { + const branches = new Set(); + const info = { + hasForgivenPseudoFunc: false, + hasHasPseudoFunc: false, + hasLogicalPseudoFunc: false, + hasNotPseudoFunc: false, + hasNthChildOfSelector: false, + hasNestedSelector: false, + hasStatePseudoClass: false + }; + const opt = { + enter(node) { + switch (node.type) { + case CLASS_SELECTOR: { + if (/^-?\d/.test(node.name)) { + throw new DOMException( + `Invalid selector .${node.name}`, + SYNTAX_ERR + ); + } + break; + } + case ID_SELECTOR: { + if (/^-?\d/.test(node.name)) { + throw new DOMException( + `Invalid selector #${node.name}`, + SYNTAX_ERR + ); + } + break; + } + case PS_CLASS_SELECTOR: { + if (KEYS_LOGICAL.has(node.name)) { + info.hasNestedSelector = true; + info.hasLogicalPseudoFunc = true; + if (node.name === 'has') { + info.hasHasPseudoFunc = true; + } else if (node.name === 'not') { + info.hasNotPseudoFunc = true; + } else { + info.hasForgivenPseudoFunc = true; + } + } else if (KEYS_PS_CLASS_STATE.has(node.name)) { + info.hasStatePseudoClass = true; + } else if ( + KEYS_SHADOW_HOST.has(node.name) && + Array.isArray(node.children) && + node.children.length + ) { + info.hasNestedSelector = true; + } + break; + } + case PS_ELEMENT_SELECTOR: { + if (REG_SHADOW_PS_ELEMENT.test(node.name)) { + info.hasNestedSelector = true; + } + break; + } + case NTH: { + if (node.selector) { + info.hasNestedSelector = true; + info.hasNthChildOfSelector = true; + } + break; + } + case SELECTOR: { + branches.add(node.children); + break; + } + default: + } + } + }; + const clonedAst = cssTree.clone(ast); + cssTree.walk(toObject ? cssTree.toPlainObject(clonedAst) : clonedAst, opt); + if (info.hasNestedSelector === true) { + cssTree.findAll(clonedAst, (node, item, list) => { + if (list) { + if (node.type === PS_CLASS_SELECTOR && KEYS_LOGICAL.has(node.name)) { + const itemList = list.filter(i => { + const { name, type } = i; + return type === PS_CLASS_SELECTOR && KEYS_LOGICAL.has(name); + }); + for (const { children } of itemList) { + // SelectorList + for (const { children: grandChildren } of children) { + // Selector + for (const { children: greatGrandChildren } of grandChildren) { + if (branches.has(greatGrandChildren)) { + branches.delete(greatGrandChildren); + } + } + } + } + } else if ( + node.type === PS_CLASS_SELECTOR && + KEYS_SHADOW_HOST.has(node.name) && + Array.isArray(node.children) && + node.children.length + ) { + const itemList = list.filter(i => { + const { children, name, type } = i; + const res = + type === PS_CLASS_SELECTOR && + KEYS_SHADOW_HOST.has(name) && + Array.isArray(children) && + children.length; + return res; + }); + for (const { children } of itemList) { + // Selector + for (const { children: grandChildren } of children) { + if (branches.has(grandChildren)) { + branches.delete(grandChildren); + } + } + } + } else if ( + node.type === PS_ELEMENT_SELECTOR && + REG_SHADOW_PS_ELEMENT.test(node.name) + ) { + const itemList = list.filter(i => { + const { name, type } = i; + const res = + type === PS_ELEMENT_SELECTOR && REG_SHADOW_PS_ELEMENT.test(name); + return res; + }); + for (const { children } of itemList) { + // Selector + for (const { children: grandChildren } of children) { + if (branches.has(grandChildren)) { + branches.delete(grandChildren); + } + } + } + } else if (node.type === NTH && node.selector) { + const itemList = list.filter(i => { + const { selector, type } = i; + const res = type === NTH && selector; + return res; + }); + for (const { selector } of itemList) { + const { children } = selector; + // Selector + for (const { children: grandChildren } of children) { + if (branches.has(grandChildren)) { + branches.delete(grandChildren); + } + } + } + } + } + }); + } + return { + info, + branches: [...branches] + }; +}; + +/** + * Comparison function for sorting AST nodes based on specificity. + * @param {object} a - The first AST node. + * @param {object} b - The second AST node. + * @returns {number} -1, 0 or 1, depending on the sort order. + */ +export const compareASTNodes = (a, b) => { + const bitA = AST_SORT_ORDER.get(a.type); + const bitB = AST_SORT_ORDER.get(b.type); + if (bitA === bitB) { + return 0; + } else if (bitA > bitB) { + return 1; + } else { + return -1; + } +}; + +/** + * Sorts a collection of AST nodes based on CSS specificity rules. + * @param {Array} asts - A collection of AST nodes to sort. + * @returns {Array} A new array containing the sorted AST nodes. + */ +export const sortAST = asts => { + const arr = [...asts]; + if (arr.length > 1) { + arr.sort(compareASTNodes); + } + return arr; +}; + +/** + * Parses a type selector's name, which may include a namespace prefix. + * @param {string} selector - The type selector name (e.g., 'ns|E' or 'E'). + * @returns {{prefix: string, localName: string}} An object with `prefix` and + * `localName` properties. + */ +export const parseAstName = selector => { + let prefix; + let localName; + if (selector && typeof selector === 'string') { + if (selector.indexOf('|') > -1) { + [prefix, localName] = selector.split('|'); + } else { + prefix = '*'; + localName = selector; + } + } else { + throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR); + } + return { + prefix, + localName + }; +}; + +/* Re-exported from css-tree. */ +export { find as findAST, generate as generateCSS } from 'css-tree'; diff --git a/node_modules/@asamuzakjp/dom-selector/src/js/utility.js b/node_modules/@asamuzakjp/dom-selector/src/js/utility.js new file mode 100644 index 0000000..c4c9f66 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/src/js/utility.js @@ -0,0 +1,1113 @@ +/** + * utility.js + */ + +/* import */ +import nwsapi from '@asamuzakjp/nwsapi'; +import bidiFactory from 'bidi-js'; +import * as cssTree from 'css-tree'; +import isCustomElementName from 'is-potential-custom-element-name'; + +/* constants */ +import { + ATRULE, + COMBO, + COMPOUND_I, + DESCEND, + DOCUMENT_FRAGMENT_NODE, + DOCUMENT_NODE, + DOCUMENT_POSITION_CONTAINS, + DOCUMENT_POSITION_PRECEDING, + ELEMENT_NODE, + HAS_COMPOUND, + INPUT_BUTTON, + INPUT_EDIT, + INPUT_LTR, + INPUT_TEXT, + KEYS_LOGICAL, + LOGIC_COMPLEX, + LOGIC_COMPOUND, + N_TH, + PSEUDO_CLASS, + RULE, + SCOPE, + SELECTOR_LIST, + TAG_TYPE, + TARGET_ALL, + TARGET_FIRST, + TEXT_NODE, + TYPE_FROM, + TYPE_TO +} from './constant.js'; +const KEYS_DIR_AUTO = new Set([...INPUT_BUTTON, ...INPUT_TEXT, 'hidden']); +const KEYS_DIR_LTR = new Set(INPUT_LTR); +const KEYS_INPUT_EDIT = new Set(INPUT_EDIT); +const KEYS_NODE_DIR_EXCLUDE = new Set(['bdi', 'script', 'style', 'textarea']); +const KEYS_NODE_FOCUSABLE = new Set(['button', 'select', 'textarea']); +const KEYS_NODE_FOCUSABLE_SVG = new Set([ + 'clipPath', + 'defs', + 'desc', + 'linearGradient', + 'marker', + 'mask', + 'metadata', + 'pattern', + 'radialGradient', + 'script', + 'style', + 'symbol', + 'title' +]); +const REG_ATTR_SIMPLE = /^\[[A-Z\d-]{1,255}(?:="?[A-Z\d\s-]{1,255}"?)?\]$/i; +const REG_TAG_SIMPLE = new RegExp(`^(?:${TAG_TYPE})$`); +const REG_EXCLUDE_BASIC = + /[|\\]|::|[^\u0021-\u007F\s]|\[\s*[\w$*=^|~-]+(?:(?:"[\w$*=^|~\s'-]+"|'[\w$*=^|~\s"-]+')?(?:\s+[\w$*=^|~-]+)+|"[^"\]]{1,255}|'[^'\]]{1,255})\s*\]|:(?:is|where)\(\s*\)/; +const REG_COMPLEX = new RegExp(`${COMPOUND_I}${COMBO}${COMPOUND_I}`, 'i'); +const REG_DESCEND = new RegExp(`${COMPOUND_I}${DESCEND}${COMPOUND_I}`, 'i'); +const REG_LOGIC_COMPLEX = new RegExp( + `:(?!${PSEUDO_CLASS}|${N_TH}|${LOGIC_COMPLEX})` +); +const REG_LOGIC_COMPOUND = new RegExp( + `:(?!${PSEUDO_CLASS}|${N_TH}|${LOGIC_COMPOUND})` +); +const REG_LOGIC_HAS_COMPOUND = new RegExp( + `:(?!${PSEUDO_CLASS}|${N_TH}|${LOGIC_COMPOUND}|${HAS_COMPOUND})` +); +const REG_END_WITH_HAS = new RegExp(`:${HAS_COMPOUND}$`); +const REG_WO_LOGICAL = new RegExp(`:(?!${PSEUDO_CLASS}|${N_TH})`); +const REG_IS_HTML = /^(?:application\/xhtml\+x|text\/ht)ml$/; +const REG_IS_XML = + /^(?:application\/(?:[\w\-.]+\+)?|image\/[\w\-.]+\+|text\/)xml$/; + +/** + * Manages state for extracting nested selectors from a CSS AST. + */ +class SelectorExtractor { + constructor() { + this.selectors = []; + this.isScoped = false; + } + + /** + * Walker enter function. + * @param {object} node - The AST node. + */ + enter(node) { + switch (node.type) { + case ATRULE: { + if (node.name === 'scope') { + this.isScoped = true; + } + break; + } + case SCOPE: { + const { children, type } = node.root; + const arr = []; + if (type === SELECTOR_LIST) { + for (const child of children) { + const selector = cssTree.generate(child); + arr.push(selector); + } + this.selectors.push(arr); + } + break; + } + case RULE: { + const { children, type } = node.prelude; + const arr = []; + if (type === SELECTOR_LIST) { + let hasAmp = false; + for (const child of children) { + const selector = cssTree.generate(child); + if (this.isScoped && !hasAmp) { + hasAmp = /\x26/.test(selector); + } + arr.push(selector); + } + if (this.isScoped) { + if (hasAmp) { + this.selectors.push(arr); + /* FIXME: + } else { + this.selectors = arr; + this.isScoped = false; + */ + } + } else { + this.selectors.push(arr); + } + } + } + } + } + + /** + * Walker leave function. + * @param {object} node - The AST node. + */ + leave(node) { + if (node.type === ATRULE) { + if (node.name === 'scope') { + this.isScoped = false; + } + } + } +} + +/** + * Get type of an object. + * @param {object} o - Object to check. + * @returns {string} - Type of the object. + */ +export const getType = o => + Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO); + +/** + * Verify array contents. + * @param {Array} arr - The array. + * @param {string} type - Expected type, e.g. 'String'. + * @throws {TypeError} - Throws if array or its items are of unexpected type. + * @returns {Array} - The verified array. + */ +export const verifyArray = (arr, type) => { + if (!Array.isArray(arr)) { + throw new TypeError(`Unexpected type ${getType(arr)}`); + } + if (typeof type !== 'string') { + throw new TypeError(`Unexpected type ${getType(type)}`); + } + for (const item of arr) { + if (getType(item) !== type) { + throw new TypeError(`Unexpected type ${getType(item)}`); + } + } + return arr; +}; + +/** + * Generate a DOMException. + * @param {string} msg - The error message. + * @param {string} name - The error name. + * @param {object} globalObject - The global object (e.g., window). + * @returns {DOMException} The generated DOMException object. + */ +export const generateException = (msg, name, globalObject = globalThis) => { + return new globalObject.DOMException(msg, name); +}; + +/** + * Find a nested :has() pseudo-class. + * @param {object} leaf - The AST leaf to check. + * @returns {?object} The leaf if it's :has, otherwise null. + */ +export const findNestedHas = leaf => { + return leaf.name === 'has'; +}; + +/** + * Find a logical pseudo-class that contains a nested :has(). + * @param {object} leaf - The AST leaf to check. + * @returns {?object} The leaf if it matches, otherwise null. + */ +export const findLogicalWithNestedHas = leaf => { + if (KEYS_LOGICAL.has(leaf.name) && cssTree.find(leaf, findNestedHas)) { + return leaf; + } + return null; +}; + +/** + * Filter a list of nodes based on An+B logic + * @param {Array.} nodes - array of nodes to filter + * @param {object} anb - An+B options + * @param {number} anb.a - a + * @param {number} anb.b - b + * @param {boolean} [anb.reverse] - reverse order + * @returns {Array.} - array of matched nodes + */ +export const filterNodesByAnB = (nodes, anb) => { + const { a, b, reverse } = anb; + const processedNodes = reverse ? [...nodes].reverse() : nodes; + const l = nodes.length; + const matched = []; + if (a === 0) { + if (b > 0 && b <= l) { + matched.push(processedNodes[b - 1]); + } + return matched; + } + let startIndex = b - 1; + if (a > 0) { + while (startIndex < 0) { + startIndex += a; + } + for (let i = startIndex; i < l; i += a) { + matched.push(processedNodes[i]); + } + } else if (startIndex >= 0) { + for (let i = startIndex; i >= 0; i += a) { + matched.push(processedNodes[i]); + } + return matched.reverse(); + } + return matched; +}; + +/** + * Resolve content document, root node, and check if it's in a shadow DOM. + * @param {object} node - Document, DocumentFragment, or Element node. + * @returns {Array.} - [document, root, isInShadow]. + */ +export const resolveContent = node => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + let document; + let root; + let shadow; + switch (node.nodeType) { + case DOCUMENT_NODE: { + document = node; + root = node; + break; + } + case DOCUMENT_FRAGMENT_NODE: { + const { host, mode, ownerDocument } = node; + document = ownerDocument; + root = node; + shadow = host && (mode === 'close' || mode === 'open'); + break; + } + case ELEMENT_NODE: { + document = node.ownerDocument; + let refNode = node; + while (refNode) { + const { host, mode, nodeType, parentNode } = refNode; + if (nodeType === DOCUMENT_FRAGMENT_NODE) { + shadow = host && (mode === 'close' || mode === 'open'); + break; + } else if (parentNode) { + refNode = parentNode; + } else { + break; + } + } + root = refNode; + break; + } + default: { + throw new TypeError(`Unexpected node ${node.nodeName}`); + } + } + return [document, root, !!shadow]; +}; + +/** + * Traverse node tree with a TreeWalker. + * @param {object} node - The target node. + * @param {object} walker - The TreeWalker instance. + * @param {boolean} [force] - Traverse only to the next node. + * @returns {?object} - The current node if found, otherwise null. + */ +export const traverseNode = (node, walker, force = false) => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (!walker) { + return null; + } + let refNode = walker.currentNode; + if (refNode === node) { + return refNode; + } else if (force || refNode.contains(node)) { + refNode = walker.nextNode(); + while (refNode) { + if (refNode === node) { + break; + } + refNode = walker.nextNode(); + } + return refNode; + } else { + if (refNode !== walker.root) { + let bool; + while (refNode) { + if (refNode === node) { + bool = true; + break; + } else if (refNode === walker.root || refNode.contains(node)) { + break; + } + refNode = walker.parentNode(); + } + if (bool) { + return refNode; + } + } + if (node.nodeType === ELEMENT_NODE) { + let bool; + while (refNode) { + if (refNode === node) { + bool = true; + break; + } + refNode = walker.nextNode(); + } + if (bool) { + return refNode; + } + } + } + return null; +}; + +/** + * Check if a node is a custom element. + * @param {object} node - The Element node. + * @param {object} [opt] - Options. + * @returns {boolean} - True if it's a custom element. + */ +export const isCustomElement = (node, opt = {}) => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (node.nodeType !== ELEMENT_NODE) { + return false; + } + const { localName, ownerDocument } = node; + const { formAssociated } = opt; + const window = ownerDocument.defaultView; + let elmConstructor; + const attr = node.getAttribute('is'); + if (attr) { + elmConstructor = + isCustomElementName(attr) && window.customElements.get(attr); + } else { + elmConstructor = + isCustomElementName(localName) && window.customElements.get(localName); + } + if (elmConstructor) { + if (formAssociated) { + return !!elmConstructor.formAssociated; + } + return true; + } + return false; +}; + +/** + * Get slotted text content. + * @param {object} node - The Element node (likely a ). + * @returns {?string} - The text content. + */ +export const getSlottedTextContent = node => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (typeof node.assignedNodes !== 'function') { + return null; + } + const nodes = node.assignedNodes(); + if (nodes.length) { + let text = ''; + const l = nodes.length; + for (let i = 0; i < l; i++) { + const item = nodes[i]; + text = item.textContent.trim(); + if (text) { + break; + } + } + return text; + } + return node.textContent.trim(); +}; + +/** + * Get directionality of a node. + * @see https://html.spec.whatwg.org/multipage/dom.html#the-dir-attribute + * @param {object} node - The Element node. + * @returns {?string} - 'ltr' or 'rtl'. + */ +export const getDirectionality = node => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (node.nodeType !== ELEMENT_NODE) { + return null; + } + const { dir: dirAttr, localName, parentNode } = node; + const { getEmbeddingLevels } = bidiFactory(); + if (dirAttr === 'ltr' || dirAttr === 'rtl') { + return dirAttr; + } else if (dirAttr === 'auto') { + let text = ''; + switch (localName) { + case 'input': { + if (!node.type || KEYS_DIR_AUTO.has(node.type)) { + text = node.value; + } else if (KEYS_DIR_LTR.has(node.type)) { + return 'ltr'; + } + break; + } + case 'slot': { + text = getSlottedTextContent(node); + break; + } + case 'textarea': { + text = node.value; + break; + } + default: { + const items = [].slice.call(node.childNodes); + for (const item of items) { + const { + dir: itemDir, + localName: itemLocalName, + nodeType: itemNodeType, + textContent: itemTextContent + } = item; + if (itemNodeType === TEXT_NODE) { + text = itemTextContent.trim(); + } else if ( + itemNodeType === ELEMENT_NODE && + !KEYS_NODE_DIR_EXCLUDE.has(itemLocalName) && + (!itemDir || (itemDir !== 'ltr' && itemDir !== 'rtl')) + ) { + if (itemLocalName === 'slot') { + text = getSlottedTextContent(item); + } else { + text = itemTextContent.trim(); + } + } + if (text) { + break; + } + } + } + } + if (text) { + const { + paragraphs: [{ level }] + } = getEmbeddingLevels(text); + if (level % 2 === 1) { + return 'rtl'; + } + } else if (parentNode) { + const { nodeType: parentNodeType } = parentNode; + if (parentNodeType === ELEMENT_NODE) { + return getDirectionality(parentNode); + } + } + } else if (localName === 'input' && node.type === 'tel') { + return 'ltr'; + } else if (localName === 'bdi') { + const text = node.textContent.trim(); + if (text) { + const { + paragraphs: [{ level }] + } = getEmbeddingLevels(text); + if (level % 2 === 1) { + return 'rtl'; + } + } + } else if (parentNode) { + if (localName === 'slot') { + const text = getSlottedTextContent(node); + if (text) { + const { + paragraphs: [{ level }] + } = getEmbeddingLevels(text); + if (level % 2 === 1) { + return 'rtl'; + } + return 'ltr'; + } + } + const { nodeType: parentNodeType } = parentNode; + if (parentNodeType === ELEMENT_NODE) { + return getDirectionality(parentNode); + } + } + return 'ltr'; +}; + +/** + * Traverses up the DOM tree to find the language attribute for a node. + * It checks for 'lang' in HTML and 'xml:lang' in XML contexts. + * @param {object} node - The starting element node. + * @returns {string|null} The language attribute value, or null if not found. + */ +export const getLanguageAttribute = node => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (node.nodeType !== ELEMENT_NODE) { + return null; + } + const { contentType } = node.ownerDocument; + const isHtml = REG_IS_HTML.test(contentType); + const isXml = REG_IS_XML.test(contentType); + let isShadow = false; + // Traverse up from the current node to the root. + let current = node; + while (current) { + // Check if the current node is an element. + switch (current.nodeType) { + case ELEMENT_NODE: { + // Check for and return the language attribute if present. + if (isHtml && current.hasAttribute('lang')) { + return current.getAttribute('lang'); + } else if (isXml && current.hasAttribute('xml:lang')) { + return current.getAttribute('xml:lang'); + } + break; + } + case DOCUMENT_FRAGMENT_NODE: { + // Continue traversal if the current node is a shadow root. + if (current.host) { + isShadow = true; + } + break; + } + case DOCUMENT_NODE: + default: { + // Stop if we reach the root document node. + return null; + } + } + if (isShadow) { + current = current.host; + isShadow = false; + } else if (current.parentNode) { + current = current.parentNode; + } else { + break; + } + } + // No language attribute was found in the hierarchy. + return null; +}; + +/** + * Check if content is editable. + * NOTE: Not implemented in jsdom https://github.com/jsdom/jsdom/issues/1670 + * @param {object} node - The Element node. + * @returns {boolean} - True if content is editable. + */ +export const isContentEditable = node => { + if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (node.nodeType !== ELEMENT_NODE) { + return false; + } + if (typeof node.isContentEditable === 'boolean') { + return node.isContentEditable; + } else if (node.ownerDocument.designMode === 'on') { + return true; + } else { + let attr; + if (node.hasAttribute('contenteditable')) { + attr = node.getAttribute('contenteditable'); + } else { + attr = 'inherit'; + } + switch (attr) { + case '': + case 'true': { + return true; + } + case 'plaintext-only': { + // FIXME: + // @see https://github.com/w3c/editing/issues/470 + // @see https://github.com/whatwg/html/issues/10651 + return true; + } + case 'false': { + return false; + } + default: { + if (node?.parentNode?.nodeType === ELEMENT_NODE) { + return isContentEditable(node.parentNode); + } + return false; + } + } + } +}; + +/** + * Check if a node is visible. + * @param {object} node - The Element node. + * @returns {boolean} - True if the node is visible. + */ +export const isVisible = node => { + if (node?.nodeType !== ELEMENT_NODE) { + return false; + } + // TODO: switch to node.checkVisibility() + const window = node.ownerDocument.defaultView; + const { display, visibility } = window.getComputedStyle(node); + return display !== 'none' && visibility === 'visible'; +}; + +/** + * Check if focus is visible on the node. + * @param {object} node - The Element node. + * @returns {boolean} - True if focus is visible. + */ +export const isFocusVisible = node => { + if (node?.nodeType !== ELEMENT_NODE) { + return false; + } + const { localName, type } = node; + switch (localName) { + case 'input': { + if (!type || KEYS_INPUT_EDIT.has(type)) { + return true; + } + return false; + } + case 'textarea': { + return true; + } + default: { + return isContentEditable(node); + } + } +}; + +/** + * Check if an area is focusable. + * @param {object} node - The Element node. + * @returns {boolean} - True if the area is focusable. + */ +export const isFocusableArea = node => { + if (node?.nodeType !== ELEMENT_NODE) { + return false; + } + if (!node.isConnected) { + return false; + } + const window = node.ownerDocument.defaultView; + if (node instanceof window.HTMLElement) { + if (Number.isInteger(parseInt(node.getAttribute('tabindex')))) { + return true; + } + if (isContentEditable(node)) { + return true; + } + const { localName, parentNode } = node; + switch (localName) { + case 'a': { + if (node.href || node.hasAttribute('href')) { + return true; + } + return false; + } + case 'iframe': { + return true; + } + case 'input': { + if ( + node.disabled || + node.hasAttribute('disabled') || + node.hidden || + node.hasAttribute('hidden') + ) { + return false; + } + return true; + } + case 'summary': { + if (parentNode.localName === 'details') { + let child = parentNode.firstElementChild; + let bool = false; + while (child) { + if (child.localName === 'summary') { + bool = child === node; + break; + } + child = child.nextElementSibling; + } + return bool; + } + return false; + } + default: { + if ( + KEYS_NODE_FOCUSABLE.has(localName) && + !(node.disabled || node.hasAttribute('disabled')) + ) { + return true; + } + } + } + } else if (node instanceof window.SVGElement) { + if (Number.isInteger(parseInt(node.getAttributeNS(null, 'tabindex')))) { + const ns = 'http://www.w3.org/2000/svg'; + let bool; + let refNode = node; + while (refNode.namespaceURI === ns) { + bool = KEYS_NODE_FOCUSABLE_SVG.has(refNode.localName); + if (bool) { + break; + } + if (refNode?.parentNode?.namespaceURI === ns) { + refNode = refNode.parentNode; + } else { + break; + } + } + if (bool) { + return false; + } + return true; + } + if ( + node.localName === 'a' && + (node.href || node.hasAttributeNS(null, 'href')) + ) { + return true; + } + } + return false; +}; + +/** + * Check if a node is focusable. + * NOTE: Not applied, needs fix in jsdom itself. + * @see https://github.com/whatwg/html/pull/8392 + * @see https://phabricator.services.mozilla.com/D156219 + * @see https://github.com/jsdom/jsdom/issues/3029 + * @see https://github.com/jsdom/jsdom/issues/3464 + * @param {object} node - The Element node. + * @returns {boolean} - True if the node is focusable. + */ +export const isFocusable = node => { + if (node?.nodeType !== ELEMENT_NODE) { + return false; + } + const window = node.ownerDocument.defaultView; + let refNode = node; + let res = true; + while (refNode) { + if (refNode.disabled || refNode.hasAttribute('disabled')) { + res = false; + break; + } + if (refNode.hidden || refNode.hasAttribute('hidden')) { + res = false; + } + const { contentVisibility, display, visibility } = + window.getComputedStyle(refNode); + if ( + display === 'none' || + visibility !== 'visible' || + (contentVisibility === 'hidden' && refNode !== node) + ) { + res = false; + } else { + res = true; + } + if (res && refNode?.parentNode?.nodeType === ELEMENT_NODE) { + refNode = refNode.parentNode; + } else { + break; + } + } + return res; +}; + +/** + * Get namespace URI. + * @param {string} ns - The namespace prefix. + * @param {object} node - The Element node. + * @returns {?string} - The namespace URI. + */ +export const getNamespaceURI = (ns, node) => { + if (typeof ns !== 'string') { + throw new TypeError(`Unexpected type ${getType(ns)}`); + } else if (!node?.nodeType) { + throw new TypeError(`Unexpected type ${getType(node)}`); + } + if (!ns || node.nodeType !== ELEMENT_NODE) { + return null; + } + const { attributes } = node; + let res; + for (const attr of attributes) { + const { name, namespaceURI, prefix, value } = attr; + if (name === `xmlns:${ns}`) { + res = value; + } else if (prefix === ns) { + res = namespaceURI; + } + if (res) { + break; + } + } + return res ?? null; +}; + +/** + * Check if a namespace is declared. + * @param {string} ns - The namespace. + * @param {object} node - The Element node. + * @returns {boolean} - True if the namespace is declared. + */ +export const isNamespaceDeclared = (ns = '', node = {}) => { + if (!ns || typeof ns !== 'string' || node?.nodeType !== ELEMENT_NODE) { + return false; + } + if (node.lookupNamespaceURI(ns)) { + return true; + } + const root = node.ownerDocument.documentElement; + let parent = node; + let res; + while (parent) { + res = getNamespaceURI(ns, parent); + if (res || parent === root) { + break; + } + parent = parent.parentNode; + } + return !!res; +}; + +/** + * Check if nodeA precedes and/or contains nodeB. + * @param {object} nodeA - The first Element node. + * @param {object} nodeB - The second Element node. + * @returns {boolean} - True if nodeA precedes nodeB. + */ +export const isPreceding = (nodeA, nodeB) => { + if (!nodeA?.nodeType) { + throw new TypeError(`Unexpected type ${getType(nodeA)}`); + } else if (!nodeB?.nodeType) { + throw new TypeError(`Unexpected type ${getType(nodeB)}`); + } + if (nodeA.nodeType !== ELEMENT_NODE || nodeB.nodeType !== ELEMENT_NODE) { + return false; + } + const posBit = nodeB.compareDocumentPosition(nodeA); + const res = + posBit & DOCUMENT_POSITION_PRECEDING || posBit & DOCUMENT_POSITION_CONTAINS; + return !!res; +}; + +/** + * Comparison function for sorting nodes based on document position. + * @param {object} a - The first node. + * @param {object} b - The second node. + * @returns {number} - Sort order. + */ +export const compareNodes = (a, b) => { + if (isPreceding(b, a)) { + return 1; + } + return -1; +}; + +/** + * Sort a collection of nodes. + * @param {Array.|Set.} nodes - Collection of nodes. + * @returns {Array.} - Collection of sorted nodes. + */ +export const sortNodes = (nodes = []) => { + const arr = [...nodes]; + if (arr.length > 1) { + arr.sort(compareNodes); + } + return arr; +}; + +/** + * Concat an array of nested selectors into an equivalent single selector. + * @param {Array.>} selectors - [parents, children, ...]. + * @returns {string} - The concatenated selector. + */ +export const concatNestedSelectors = selectors => { + if (!Array.isArray(selectors)) { + throw new TypeError(`Unexpected type ${getType(selectors)}`); + } + let selector = ''; + if (selectors.length) { + const revSelectors = selectors.toReversed(); + let child = verifyArray(revSelectors.shift(), 'String'); + if (child.length === 1) { + [child] = child; + } + while (revSelectors.length) { + const parentArr = verifyArray(revSelectors.shift(), 'String'); + if (!parentArr.length) { + continue; + } + let parent; + if (parentArr.length === 1) { + [parent] = parentArr; + if (!/^[>~+]/.test(parent) && /[\s>~+]/.test(parent)) { + parent = `:is(${parent})`; + } + } else { + parent = `:is(${parentArr.join(', ')})`; + } + if (selector.includes('\x26')) { + selector = selector.replace(/\x26/g, parent); + } + if (Array.isArray(child)) { + const items = []; + for (let item of child) { + if (item.includes('\x26')) { + if (/^[>~+]/.test(item)) { + item = `${parent} ${item.replace(/\x26/g, parent)} ${selector}`; + } else { + item = `${item.replace(/\x26/g, parent)} ${selector}`; + } + } else { + item = `${parent} ${item} ${selector}`; + } + items.push(item.trim()); + } + selector = items.join(', '); + } else if (revSelectors.length) { + selector = `${child} ${selector}`; + } else { + if (child.includes('\x26')) { + if (/^[>~+]/.test(child)) { + selector = `${parent} ${child.replace(/\x26/g, parent)} ${selector}`; + } else { + selector = `${child.replace(/\x26/g, parent)} ${selector}`; + } + } else { + selector = `${parent} ${child} ${selector}`; + } + } + selector = selector.trim(); + if (revSelectors.length) { + child = parentArr.length > 1 ? parentArr : parent; + } else { + break; + } + } + selector = selector.replace(/\x26/g, ':scope').trim(); + } + return selector; +}; + +/** + * Extract nested selectors from CSSRule.cssText. + * @param {string} css - CSSRule.cssText. + * @returns {Array.>} - Array of nested selectors. + */ +export const extractNestedSelectors = css => { + const ast = cssTree.parse(css, { + context: 'rule' + }); + const extractor = new SelectorExtractor(); + cssTree.walk(ast, { + enter: extractor.enter.bind(extractor), + leave: extractor.leave.bind(extractor) + }); + return extractor.selectors; +}; + +/** + * Initialize nwsapi. + * @param {object} window - The Window object. + * @param {object} document - The Document object. + * @returns {object} - The nwsapi instance. + */ +export const initNwsapi = (window, document) => { + if (!window?.DOMException) { + throw new TypeError(`Unexpected global object ${getType(window)}`); + } + if (document?.nodeType !== DOCUMENT_NODE) { + document = window.document; + } + const nw = nwsapi({ + document, + DOMException: window.DOMException + }); + nw.configure({ + LOGERRORS: false + }); + return nw; +}; + +/** + * Filter a selector for use with nwsapi. + * @param {string} selector - The selector string. + * @param {string} target - The target type. + * @returns {boolean} - True if the selector is valid for nwsapi. + */ +export const filterSelector = (selector, target) => { + const isQuerySelectorAll = target === TARGET_ALL; + if ( + !selector || + typeof selector !== 'string' || + /null|undefined/.test(selector) + ) { + return false; + } + // Exclude missing close square bracket. + if (selector.includes('[')) { + const index = selector.lastIndexOf('['); + const sel = selector.substring(index); + if (sel.indexOf(']') < 0) { + return false; + } + } + // Match only simple attribute selector for TARGET_FIRST. + if (target === TARGET_FIRST) { + if (REG_ATTR_SIMPLE.test(selector)) { + return true; + } + return false; + } + + // Exclude simple tag selector for TARGET_ALL + if (target === TARGET_ALL && REG_TAG_SIMPLE.test(selector)) { + return false; + } + + // Exclude various complex or unsupported selectors. + // - selectors containing '/' + // - namespaced selectors + // - escaped selectors + // - pseudo-element selectors + // - selectors containing non-ASCII + // - selectors containing control character other than whitespace + // - attribute selectors with case flag, e.g. [attr i] + // - attribute selectors with unclosed quotes + // - empty :is() or :where() + if (selector.includes('/') || REG_EXCLUDE_BASIC.test(selector)) { + return false; + } + // Include pseudo-classes that are known to work correctly. + if (selector.includes(':')) { + if (isQuerySelectorAll && REG_DESCEND.test(selector)) { + return false; + } + const complex = isQuerySelectorAll ? false : REG_COMPLEX.test(selector); + if (!isQuerySelectorAll && /:has\(/.test(selector)) { + if (!complex || REG_LOGIC_HAS_COMPOUND.test(selector)) { + return false; + } + return REG_END_WITH_HAS.test(selector); + } else if (/:(?:is|not)\(/.test(selector)) { + if (complex) { + return !REG_LOGIC_COMPLEX.test(selector); + } else { + return !REG_LOGIC_COMPOUND.test(selector); + } + } else { + return !REG_WO_LOGICAL.test(selector); + } + } + return true; +}; diff --git a/node_modules/@asamuzakjp/dom-selector/types/index.d.ts b/node_modules/@asamuzakjp/dom-selector/types/index.d.ts new file mode 100644 index 0000000..61db0ec --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/index.d.ts @@ -0,0 +1,15 @@ +export class DOMSelector { + constructor(window: Window, document: Document, opt?: object); + clear: () => void; + check: (selector: string, node: Element, opt?: object) => CheckResult; + matches: (selector: string, node: Element, opt?: object) => boolean; + closest: (selector: string, node: Element, opt?: object) => Element | null; + querySelector: (selector: string, node: Document | DocumentFragment | Element, opt?: object) => Element | null; + querySelectorAll: (selector: string, node: Document | DocumentFragment | Element, opt?: object) => Array; + #private; +} +export type CheckResult = { + match: boolean; + pseudoElement: string | null; + ast: object | null; +}; diff --git a/node_modules/@asamuzakjp/dom-selector/types/js/cache.d.ts b/node_modules/@asamuzakjp/dom-selector/types/js/cache.d.ts new file mode 100644 index 0000000..ce9c8b1 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/js/cache.d.ts @@ -0,0 +1,12 @@ +export class GenerationalCache { + constructor(max: number); + set max(value: number); + get max(): number; + get size(): number; + get(key: any): any; + set(key: any, value: any): void; + has(key: any): boolean; + delete(key: any): void; + clear(): void; + #private; +} diff --git a/node_modules/@asamuzakjp/dom-selector/types/js/constant.d.ts b/node_modules/@asamuzakjp/dom-selector/types/js/constant.d.ts new file mode 100644 index 0000000..f999a78 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/js/constant.d.ts @@ -0,0 +1,77 @@ +export const ATRULE: "Atrule"; +export const ATTR_SELECTOR: "AttributeSelector"; +export const CLASS_SELECTOR: "ClassSelector"; +export const COMBINATOR: "Combinator"; +export const IDENT: "Identifier"; +export const ID_SELECTOR: "IdSelector"; +export const NOT_SUPPORTED_ERR: "NotSupportedError"; +export const NTH: "Nth"; +export const OPERATOR: "Operator"; +export const PS_CLASS_SELECTOR: "PseudoClassSelector"; +export const PS_ELEMENT_SELECTOR: "PseudoElementSelector"; +export const RULE: "Rule"; +export const SCOPE: "Scope"; +export const SELECTOR: "Selector"; +export const SELECTOR_LIST: "SelectorList"; +export const STRING: "String"; +export const SYNTAX_ERR: "SyntaxError"; +export const TARGET_ALL: "all"; +export const TARGET_FIRST: "first"; +export const TARGET_LINEAL: "lineal"; +export const TARGET_SELF: "self"; +export const TYPE_SELECTOR: "TypeSelector"; +export const BIT_01: 1; +export const BIT_02: 2; +export const BIT_04: 4; +export const BIT_08: 8; +export const BIT_16: 16; +export const BIT_32: 32; +export const BIT_FFFF: 65535; +export const DUO: 2; +export const HEX: 16; +export const TYPE_FROM: 8; +export const TYPE_TO: -1; +export const ELEMENT_NODE: 1; +export const TEXT_NODE: 3; +export const DOCUMENT_NODE: 9; +export const DOCUMENT_FRAGMENT_NODE: 11; +export const DOCUMENT_POSITION_PRECEDING: 2; +export const DOCUMENT_POSITION_CONTAINS: 8; +export const DOCUMENT_POSITION_CONTAINED_BY: 16; +export const SHOW_ALL: 4294967295; +export const SHOW_CONTAINER: 1281; +export const SHOW_DOCUMENT: 256; +export const SHOW_DOCUMENT_FRAGMENT: 1024; +export const SHOW_ELEMENT: 1; +export const ALPHA_NUM: "[A-Z\\d]+"; +export const CHILD_IDX: "(?:first|last|only)-(?:child|of-type)"; +export const DIGIT: "(?:0|[1-9]\\d*)"; +export const LANG_PART: "(?:-[A-Z\\d]+)*"; +export const PSEUDO_CLASS: "(?:any-)?link|(?:first|last|only)-(?:child|of-type)|checked|empty|indeterminate|read-(?:only|write)|target"; +export const ANB: "[+-]?(?:(?:0|[1-9]\\d*)n?|n)|(?:[+-]?(?:0|[1-9]\\d*))?n\\s*[+-]\\s*(?:0|[1-9]\\d*)"; +export const COMBO: "\\s?[\\s>~+]\\s?"; +export const DESCEND: "\\s?[\\s>]\\s?"; +export const SIBLING: "\\s?[+~]\\s?"; +export const LOGIC_IS: ":is\\(\\s*[^)]+\\s*\\)"; +export const N_TH: "nth-(?:last-)?(?:child|of-type)\\(\\s*(?:even|odd|[+-]?(?:(?:0|[1-9]\\d*)n?|n)|(?:[+-]?(?:0|[1-9]\\d*))?n\\s*[+-]\\s*(?:0|[1-9]\\d*))\\s*\\)"; +export const SUB_TYPE: "\\[[^|\\]]+\\]|[#.:][\\w-]+"; +export const SUB_TYPE_WO_PSEUDO: "\\[[^|\\]]+\\]|[#.][\\w-]+"; +export const TAG_TYPE: "\\*|[A-Za-z][\\w-]*"; +export const TAG_TYPE_I: "\\*|[A-Z][\\w-]*"; +export const COMPOUND: "(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+)+)"; +export const COMPOUND_L: "(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+)"; +export const COMPOUND_I: "(?:\\*|[A-Z][\\w-]*|(?:\\*|[A-Z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+)+)"; +export const COMPOUND_WO_PSEUDO: "(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.][\\w-]+)+)"; +export const COMPLEX: "(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+)+)(?:\\s?[\\s>~+]\\s?(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+)+))*"; +export const COMPLEX_L: "(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+)(?:\\s?[\\s>~+]\\s?(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+))*"; +export const HAS_COMPOUND: "has\\([\\s>]?\\s*(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.][\\w-]+)+)\\s*\\)"; +export const LOGIC_COMPOUND: "(?:is|not)\\(\\s*(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+)(?:\\s*,\\s*(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+))*\\s*\\)"; +export const LOGIC_COMPLEX: "(?:is|not)\\(\\s*(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+)(?:\\s?[\\s>~+]\\s?(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+))*(?:\\s*,\\s*(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+)(?:\\s?[\\s>~+]\\s?(?:\\*|[A-Za-z][\\w-]*|(?:\\*|[A-Za-z][\\w-]*)?(?:\\[[^|\\]]+\\]|[#.:][\\w-]+|:is\\(\\s*[^)]+\\s*\\))+))*)*\\s*\\)"; +export const FORM_PARTS: readonly string[]; +export const INPUT_BUTTON: readonly string[]; +export const INPUT_CHECK: readonly string[]; +export const INPUT_DATE: readonly string[]; +export const INPUT_TEXT: readonly string[]; +export const INPUT_EDIT: readonly string[]; +export const INPUT_LTR: readonly string[]; +export const KEYS_LOGICAL: Set; diff --git a/node_modules/@asamuzakjp/dom-selector/types/js/finder.d.ts b/node_modules/@asamuzakjp/dom-selector/types/js/finder.d.ts new file mode 100644 index 0000000..a01fc66 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/js/finder.d.ts @@ -0,0 +1,62 @@ +export class Finder { + constructor(window: object); + onError: (e: Error, opt?: { + noexcept?: boolean | undefined; + }) => void; + setup: (selector: string, node: object, opt?: { + check?: boolean | undefined; + noexcept?: boolean | undefined; + warn?: boolean | undefined; + }) => object; + clearResults: (all?: boolean) => void; + private _handleFocusEvent; + private _handleKeyboardEvent; + private _handleMouseEvent; + private _registerEventListeners; + private _processSelectorBranches; + private _correspond; + private _createTreeWalker; + private _getSelectorBranches; + private _getFilteredChildren; + private _collectNthChild; + private _collectNthOfType; + private _matchAnPlusB; + private _matchHasPseudoFunc; + private _evaluateHasPseudo; + private _matchLogicalPseudoFunc; + private _matchPseudoClassSelector; + private _evaluateHostPseudo; + private _evaluateHostContextPseudo; + private _matchShadowHostPseudoClass; + private _matchSelectorForElement; + private _matchSelectorForShadowRoot; + private _matchSelector; + private _matchLeaves; + private _getFilterLeaves; + private _traverseAllDescendants; + private _findDescendantNodes; + private _collectCombinatorMatches; + private _matchCombinator; + private _traverseAndCollectNodes; + private _findPrecede; + private _findNodeWalker; + private _matchSelf; + private _findLineal; + private _findEntryNodesForPseudoElement; + private _findEntryNodesForId; + private _findEntryNodesForClass; + private _findEntryNodesForType; + private _findEntryNodesForOther; + private _findEntryNodes; + private _determineTraversalStrategy; + private _processPendingItems; + private _collectNodes; + private _getCombinedNodes; + private _matchNodeNext; + private _matchNodePrev; + private _processComplexBranchAll; + private _processComplexBranchFirst; + find: (targetType: string) => Set; + getAST: (selector: string) => object; + #private; +} diff --git a/node_modules/@asamuzakjp/dom-selector/types/js/matcher.d.ts b/node_modules/@asamuzakjp/dom-selector/types/js/matcher.d.ts new file mode 100644 index 0000000..d4105d8 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/js/matcher.d.ts @@ -0,0 +1,16 @@ +export function matchPseudoElementSelector(astName: string, astType: string, opt?: { + forgive?: boolean | undefined; + warn?: boolean | undefined; +}): void; +export function matchDirectionPseudoClass(ast: object, node: object): boolean; +export function matchLanguagePseudoClass(ast: object, node: object): boolean; +export function matchDisabledPseudoClass(astName: string, node: object): boolean; +export function matchReadOnlyPseudoClass(astName: string, node: object): boolean; +export function matchAttributeSelector(ast: object, node: object, opt?: { + check?: boolean | undefined; + forgive?: boolean | undefined; +}): boolean; +export function matchTypeSelector(ast: object, node: object, opt?: { + check?: boolean | undefined; + forgive?: boolean | undefined; +}): boolean; diff --git a/node_modules/@asamuzakjp/dom-selector/types/js/parser.d.ts b/node_modules/@asamuzakjp/dom-selector/types/js/parser.d.ts new file mode 100644 index 0000000..20b0782 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/js/parser.d.ts @@ -0,0 +1,14 @@ +export function unescapeSelector(selector?: string): string; +export function preprocess(value: string): string; +export function parseSelector(sel: string): object; +export function walkAST(ast?: object, toObject?: boolean): { + branches: Array; + info: object; +}; +export function compareASTNodes(a: object, b: object): number; +export function sortAST(asts: Array): Array; +export function parseAstName(selector: string): { + prefix: string; + localName: string; +}; +export { find as findAST, generate as generateCSS } from "css-tree"; diff --git a/node_modules/@asamuzakjp/dom-selector/types/js/utility.d.ts b/node_modules/@asamuzakjp/dom-selector/types/js/utility.d.ts new file mode 100644 index 0000000..6120af0 --- /dev/null +++ b/node_modules/@asamuzakjp/dom-selector/types/js/utility.d.ts @@ -0,0 +1,30 @@ +export function getType(o: object): string; +export function verifyArray(arr: any[], type: string): any[]; +export function generateException(msg: string, name: string, globalObject?: object): DOMException; +export function findNestedHas(leaf: object): object | null; +export function findLogicalWithNestedHas(leaf: object): object | null; +export function filterNodesByAnB(nodes: Array, anb: { + a: number; + b: number; + reverse?: boolean | undefined; +}): Array; +export function resolveContent(node: object): Array; +export function traverseNode(node: object, walker: object, force?: boolean): object | null; +export function isCustomElement(node: object, opt?: object): boolean; +export function getSlottedTextContent(node: object): string | null; +export function getDirectionality(node: object): string | null; +export function getLanguageAttribute(node: object): string | null; +export function isContentEditable(node: object): boolean; +export function isVisible(node: object): boolean; +export function isFocusVisible(node: object): boolean; +export function isFocusableArea(node: object): boolean; +export function isFocusable(node: object): boolean; +export function getNamespaceURI(ns: string, node: object): string | null; +export function isNamespaceDeclared(ns?: string, node?: object): boolean; +export function isPreceding(nodeA: object, nodeB: object): boolean; +export function compareNodes(a: object, b: object): number; +export function sortNodes(nodes?: Array | Set): Array; +export function concatNestedSelectors(selectors: Array>): string; +export function extractNestedSelectors(css: string): Array>; +export function initNwsapi(window: object, document: object): object; +export function filterSelector(selector: string, target: string): boolean; diff --git a/node_modules/@asamuzakjp/nwsapi/LICENSE b/node_modules/@asamuzakjp/nwsapi/LICENSE new file mode 100644 index 0000000..cc3621a --- /dev/null +++ b/node_modules/@asamuzakjp/nwsapi/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2007-2019 Diego Perini (http://www.iport.it/) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@asamuzakjp/nwsapi/README.md b/node_modules/@asamuzakjp/nwsapi/README.md new file mode 100644 index 0000000..f74b87d --- /dev/null +++ b/node_modules/@asamuzakjp/nwsapi/README.md @@ -0,0 +1,132 @@ +# [NWSAPI](http://dperini.github.io/nwsapi/) + +Fast CSS Selectors API Engine + +![](https://img.shields.io/npm/v/nwsapi.svg?colorB=orange&style=flat) ![](https://img.shields.io/github/tag/dperini/nwsapi.svg?style=flat) ![](https://img.shields.io/npm/dw/nwsapi.svg?style=flat) ![](https://img.shields.io/github/issues/dperini/nwsapi.svg?style=flat) + +NWSAPI is the development progress of [NWMATCHER](https://github.com/dperini/nwmatcher) aiming at [Selectors Level 4](https://www.w3.org/TR/selectors-4/) conformance. It has been completely reworked to be easily extended and maintained. It is a right-to-left selector parser and compiler written in pure Javascript with no external dependencies. It was initially thought as a cross browser library to improve event delegation and web page scraping in various frameworks but it has become a popular replacement of the native CSS selection and matching functionality in newer browsers and headless environments. + +It uses [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) to parse CSS selector strings and [metaprogramming](https://en.wikipedia.org/wiki/Metaprogramming) to transforms these selector strings into Javascript function resolvers. This process is executed only once for each selector string allowing memoization of the function resolvers and achieving unmatched performances. + +## Installation + +To include NWSAPI in a standard web page: + +```html + +``` + +To include NWSAPI in a standard web page and automatically replace the native QSA: + +```html + +``` + +To use NWSAPI with Node.js: + +``` +$ npm install nwsapi +``` + +NWSAPI currently supports browsers (as a global, `NW.Dom`) and headless environments (as a CommonJS module). + + +## Supported Selectors + +Here is a list of all the CSS2/CSS3/CSS4 [Supported selectors](https://github.com/dperini/nwsapi/wiki/CSS-supported-selectors). + + +## Features and Compliance + +You can read more about NWSAPI [features and compliance](https://github.com/dperini/nwsapi/wiki/Features-and-compliance) on the wiki. + + +## API + +### DOM Selection + +#### `ancestor( selector, context, callback )` + +Returns a reference to the nearest ancestor element matching `selector`, starting at `context`. Returns `null` if no element is found. If `callback` is provided, it is invoked for the matched element. + +#### `first( selector, context, callback )` + +Returns a reference to the first element matching `selector`, starting at `context`. Returns `null` if no element matches. If `callback` is provided, it is invoked for the matched element. + +#### `match( selector, element, callback )` + +Returns `true` if `element` matches `selector`, starting at `context`; returns `false` otherwise. If `callback` is provided, it is invoked for the matched element. + +#### `select( selector, context, callback )` + +Returns an array of all the elements matching `selector`, starting at `context`; returns empty `Array` otherwise. If `callback` is provided, it is invoked for each matching element. + + +### DOM Helpers + +#### `byId( id, from )` + +Returns a reference to the first element with ID `id`, optionally filtered to descendants of the element `from`. + +#### `byTag( tag, from )` + +Returns an array of elements having the specified tag name `tag`, optionally filtered to descendants of the element `from`. + +#### `byClass( class, from )` + +Returns an array of elements having the specified class name `class`, optionally filtered to descendants of the element `from`. + + +### Engine Configuration + +#### `configure( options )` + +The following is the list of currently available configuration options, their default values and descriptions, they are boolean flags that can be set to `true` or `false`: + +* `IDS_DUPES`: true - true to allow using multiple elements having the same id, false to disallow +* `LIVECACHE`: true - true for caching both results and resolvers, false for caching only resolvers +* `MIXEDCASE`: true - true to match tag names case insensitive, false to match using case sensitive +* `LOGERRORS`: true - true to print errors and warnings to the console, false to mute both of them + + +### Examples on extending the basic functionalities + +#### `configure( { : [ true | false ] } )` + +Disable logging errors/warnings to console, disallow duplicate ids. Example: + +```js +NW.Dom.configure( { LOGERRORS: false, IDS_DUPES: false } ); +``` +NOTE: NW.Dom.configure() without parameters return the current configuration. + +#### `registerCombinator( symbol, resolver )` + +Registers a new symbol and its matching resolver in the combinators table. Example: + +```js +NW.Dom.registerCombinator( '^', 'e.parentElement' ); +``` + +#### `registerOperator( symbol, resolver )` + +Registers a new symbol and its matching resolver in the attribute operators table. Example: + +```js +NW.Dom.registerOperator( '!=', { p1: '^', p2: '$', p3: 'false' } ); +``` + +#### `registerSelector( name, rexp, func )` + +Registers a new selector, the matching RE and the resolver function, in the selectors table. Example: + +```js +NW.Dom.registerSelector('Controls', /^\:(control)(.*)/i, + (function(global) { + return function(match, source, mode, callback) { + var status = true; + source = 'if(/^(button|input|select|textarea)/i.test(e.nodeName)){' + source + '}'; + return { 'source': source, 'status': status }; + }; + })(this)); +``` diff --git a/node_modules/@asamuzakjp/nwsapi/package.json b/node_modules/@asamuzakjp/nwsapi/package.json new file mode 100644 index 0000000..6a44b9c --- /dev/null +++ b/node_modules/@asamuzakjp/nwsapi/package.json @@ -0,0 +1,43 @@ +{ + "name": "@asamuzakjp/nwsapi", + "version": "2.3.9", + "description": "Fast CSS Selectors API Engine", + "homepage": "http://javascript.nwbox.com/nwsapi/", + "main": "./src/nwsapi", + "keywords": [ + "css", + "css3", + "css4", + "matcher", + "selector" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://javascript.nwbox.com/nwsapi/MIT-LICENSE" + } + ], + "license": "MIT", + "author": { + "name": "Diego Perini", + "email": "diego.perini@gmail.com", + "web": "http://www.iport.it/" + }, + "maintainers": [ + { + "name": "Diego Perini", + "email": "diego.perini@gmail.com", + "web": "http://www.iport.it/" + } + ], + "bugs": { + "url": "http://github.com/dperini/nwsapi/issues" + }, + "repository": { + "type": "git", + "url": "git://github.com/dperini/nwsapi.git" + }, + "scripts": { + "lint": "eslint ./src/nwsapi.js" + } +} diff --git a/node_modules/@asamuzakjp/nwsapi/src/nwsapi.js b/node_modules/@asamuzakjp/nwsapi/src/nwsapi.js new file mode 100644 index 0000000..e118fd5 --- /dev/null +++ b/node_modules/@asamuzakjp/nwsapi/src/nwsapi.js @@ -0,0 +1,1855 @@ +/** + * Forked and modified from nwsapi@2.2.2 + * - Export to cjs only + * - Remove ./modules directory + * - Remove unused exported properties + * - Remove unused pseudo-classes + * - Remove Snapshot.root and resolve document.documentElement on runtime + * - Use `let` and `const` as much as possible + * - Use `===` and `!==` + * - Fix `:nth-of-type()` + * - Fix function source for :root, :target and :indeterminate pseudo-classes + * - Fix + * - Support complex selectors within `:is()` and `:not()` + * - Add ::slotted() and ::part() to pseudo-elements list + * - Add isContentEditable() function + * - Add createMatchingParensRegex() function from upstream + * - Invalidate cache for :has() pseudo class + * - Optimize some regular expressions + */ +/* + * Copyright (C) 2007-2019 Diego Perini + * All rights reserved. + * + * nwsapi.js - Fast CSS Selectors API Engine + * + * Author: Diego Perini + * Version: 2.2.0 + * Created: 20070722 + * Release: 20220901 + * + * License: + * http://javascript.nwbox.com/nwsapi/MIT-LICENSE + * Download: + * http://javascript.nwbox.com/nwsapi/nwsapi.js + */ + +(function Export(global, factory) { + 'use strict'; + module.exports = factory; +})(this, function Factory(global, Export) { + const version = 'nwsapi-2.2.2'; + + let doc = global.document; + + /** + * Generate a regex that matches a balanced set of parentheses. + * Outermost parentheses are excluded so any amount of children can be handled. + * See https://stackoverflow.com/a/35271017 for reference + * + * @param {number} depth + * @return {string} + */ + function createMatchingParensRegex(depth = 1) { + const out = '\\([^)(]*?(?:'.repeat(depth) + '\\([^)(]*?\\)' + '[^)(]*?)*?\\)'.repeat(depth); + // remove outermost escaped parens + return out.slice(2, out.length - 2); + } + + const CFG = { + // extensions + operators: '[~*^$|]=|=', + combinators: '[\\s>+~](?=[^>+~])' + }; + + const NOT = { + // not enclosed in double/single/parens/square + doubleEnc: '(?=(?:[^"]*"[^"]*")*[^"]*$)', + singleEnc: "(?=(?:[^']*'[^']*')*[^']*$)", + parensEnc: '(?![^\\x28]*\\x29)', + squareEnc: '(?![^\\x5b]*\\x5d)' + }; + + const REX = { + // regular expressions + hasEscapes: /\\/, + hexNumbers: /^[0-9a-f]/i, + escOrQuote: /^\\|[\x22\x27]/, + regExpChar: /(?:(?!\\)[\\^$.*+?()[\]{}|/])/g, + trimSpaces: /[\r\n\f]|^\s+|\s+$/g, + commaGroup: RegExp('(\\s{0,255},\\s{0,255})' + NOT.squareEnc + NOT.parensEnc, 'g'), + splitGroup: /((?:\x28[^\x29]{0,255}\x29|\[[^\]]{0,255}\]|\\.|[^,])+)/g, + fixEscapes: /\\([0-9a-f]{1,6}\s?|.)|([\x22\x27])/gi, + combineWSP: RegExp('\\s{1,255}' + NOT.singleEnc + NOT.doubleEnc, 'g'), + tabCharWSP: RegExp('(\\s?\\t{1,255}\\s?)' + NOT.singleEnc + NOT.doubleEnc, 'g'), + pseudosWSP: RegExp('\\s{1,255}([-+])\\s{1,255}' + NOT.squareEnc, 'g') + }; + + const STD = { + combinator: /\s?([>+~])\s?/g, + apimethods: /^(?:[a-z]+|\*)\|/i, + namespaces: /(\*|[a-z]+)\|[-a-z]+/i + }; + + const GROUPS = { + // pseudo-classes requiring parameters + logicalsel: '(is|where|matches|not|has)(?:\\x28\\s?(' + createMatchingParensRegex(3) + ')\\s?\\x29)', + treestruct: '(nth(?:-last)?(?:-child|-of-type))(?:\\x28\\s?(even|odd|(?:[-+]?\\d*)(?:n\\s?[-+]?\\s?\\d*)?)\\s?(?:\\x29|$))', + // pseudo-classes not requiring parameters + locationpc: '(any-link|link|visited|target)\\b', + structural: '(root|empty|(?:(?:first|last|only)(?:-child|-of-type)))\\b', + inputstate: '(enabled|disabled|read-(?:only|write)|placeholder-shown|default)\\b', + inputvalue: '(checked|indeterminate)\\b', + // pseudo-classes for parsing only selectors + pseudoNop: '(autofill|-webkit-autofill)\\b', + // pseudo-elements starting with single colon (:) + pseudoSng: '(after|before|first-letter|first-line)\\b', + // pseudo-elements starting with double colon (::) + pseudoDbl: ':(after|before|first-letter|first-line|selection|part|placeholder|slotted|-webkit-[-a-z0-9]{2,})\\b' + }; + + const Patterns = { + // pseudo-classes + treestruct: RegExp('^:(?:' + GROUPS.treestruct + ')(.*)', 'i'), + structural: RegExp('^:(?:' + GROUPS.structural + ')(.*)', 'i'), + inputstate: RegExp('^:(?:' + GROUPS.inputstate + ')(.*)', 'i'), + inputvalue: RegExp('^:(?:' + GROUPS.inputvalue + ')(.*)', 'i'), + locationpc: RegExp('^:(?:' + GROUPS.locationpc + ')(.*)', 'i'), + logicalsel: RegExp('^:(?:' + GROUPS.logicalsel + ')(.*)', 'i'), + pseudoNop: RegExp('^:(?:' + GROUPS.pseudoNop + ')(.*)', 'i'), + pseudoSng: RegExp('^:(?:' + GROUPS.pseudoSng + ')(.*)', 'i'), + pseudoDbl: RegExp('^:(?:' + GROUPS.pseudoDbl + ')(.*)', 'i'), + // combinator symbols + children: /^\s?>\s?(.*)/, + adjacent: /^\s?\+\s?(.*)/, + relative: /^\s?~\s?(.*)/, + ancestor: /^\s+(.*)/, + // universal & namespace + universal: /^\*(.*)/, + namespace: /^(\w+|\*)?\|(.*)/ + }; + + // emulate firefox error strings + const qsNotArgs = 'Not enough arguments'; + const qsInvalid = ' is not a valid selector'; + + // detect structural pseudo-classes in selectors + const reNthElem = /(:nth(?:-last)?-child)/i; + const reNthType = /(:nth(?:-last)?-of-type)/i; + + // placeholder for global regexp + let reOptimizer; + let reValidator; + + // special handling configuration flags + const Config = { + IDS_DUPES: true, + MIXEDCASE: true, + LOGERRORS: true, + VERBOSITY: true + }; + + let NAMESPACE; + let QUIRKS_MODE; + let HTML_DOCUMENT; + + const ATTR_STD_OPS = { + '=': 1, + '^=': 1, + '$=': 1, + '|=': 1, + '*=': 1, + '~=': 1 + }; + + const HTML_TABLE = { + accept: 1, + 'accept-charset': 1, + align: 1, + alink: 1, + axis: 1, + bgcolor: 1, + charset: 1, + checked: 1, + clear: 1, + codetype: 1, + color: 1, + compact: 1, + declare: 1, + defer: 1, + dir: 1, + direction: 1, + disabled: 1, + enctype: 1, + face: 1, + frame: 1, + hreflang: 1, + 'http-equiv': 1, + lang: 1, + language: 1, + link: 1, + media: 1, + method: 1, + multiple: 1, + nohref: 1, + noresize: 1, + noshade: 1, + nowrap: 1, + readonly: 1, + rel: 1, + rev: 1, + rules: 1, + scope: 1, + scrolling: 1, + selected: 1, + shape: 1, + target: 1, + text: 1, + type: 1, + valign: 1, + valuetype: 1, + vlink: 1 + }; + + const Combinators = {}; + + const Selectors = {}; + + const Operators = { + '=': { + p1: '^', + p2: '$', + p3: 'true' + }, + '^=': { + p1: '^', + p2: '', + p3: 'true' + }, + '$=': { + p1: '', + p2: '$', + p3: 'true' + }, + '*=': { + p1: '', + p2: '', + p3: 'true' + }, + '|=': { + p1: '^', + p2: '(-|$)', + p3: 'true' + }, + '~=': { + p1: '(^|\\s)', + p2: '(\\s|$)', + p3: 'true' + } + }; + + const concatCall = function (nodes, callback) { + let i = 0; + const l = nodes.length; + const list = Array(l); + while (l > i) { + if (callback(list[i] = nodes[i]) === false) { + break; + } + ++i; + } + return list; + }; + + const concatList = function (list, nodes) { + let i = -1; + let l = nodes.length; + while (l--) { + list[list.length] = nodes[++i]; + } + return list; + }; + + let hasDupes = false; + + const documentOrder = function (a, b) { + if (!hasDupes && a === b) { + hasDupes = true; + return 0; + } + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + + const unique = function (nodes) { + let i = 0; + let j = -1; + let l = nodes.length + 1; + const list = []; + while (--l) { + if (nodes[i++] === nodes[i]) { + continue; + } + list[++j] = nodes[i - 1]; + } + hasDupes = false; + return list; + }; + + // check context for mixed content + const hasMixedCaseTagNames = function (context) { + const api = 'getElementsByTagNameNS'; + + // current host context (ownerDocument) + context = context.ownerDocument || context; + + // documentElement (root) element namespace or default html/xhtml namespace + const ns = context.documentElement && context.documentElement.namespaceURI + ? context.documentElement.namespaceURI + : 'http://www.w3.org/1999/xhtml'; + + // checking the number of non HTML nodes in the document + return (context[api]('*', '*').length - context[api](ns, '*').length) > 0; + }; + + // check if the document type is HTML + const isHTML = function (node) { + const doc = node.ownerDocument || node; + return doc.nodeType === 9 && doc.contentType === 'text/html'; + }; + + // convert single codepoint to UTF-16 encoding + const codePointToUTF16 = function (codePoint) { + // out of range, use replacement character + if (codePoint < 1 || codePoint > 0x10ffff || + (codePoint > 0xd7ff && codePoint < 0xe000)) { + return '\\ufffd'; + } + // javascript strings are UTF-16 encoded + if (codePoint < 0x10000) { + const lowHex = '000' + codePoint.toString(16); + return '\\u' + lowHex.substr(lowHex.length - 4); + } + // supplementary high + low surrogates + return '\\u' + (((codePoint - 0x10000) >> 0x0a) + 0xd800).toString(16) + + '\\u' + (((codePoint - 0x10000) % 0x400) + 0xdc00).toString(16); + }; + + // convert single codepoint to string + const stringFromCodePoint = function (codePoint) { + // out of range, use replacement character + if (codePoint < 1 || codePoint > 0x10ffff || + (codePoint > 0xd7ff && codePoint < 0xe000)) { + return '\ufffd'; + } + if (codePoint < 0x10000) { + return String.fromCharCode(codePoint); + } + return String.fromCodePoint(codePoint); + }; + + // convert escape sequence in a CSS string or identifier + // to javascript string with javascript escape sequences + const convertEscapes = function (str) { + return REX.hasEscapes.test(str) + ? str.replace(REX.fixEscapes, function (substring, p1, p2) { + // unescaped " or ' + return p2 + ? '\\' + p2 + // javascript strings are UTF-16 encoded + : REX.hexNumbers.test(p1) + ? codePointToUTF16(parseInt(p1, 16)) + // \' \" + : REX.escOrQuote.test(p1) + ? substring + // \g \h \. \# etc + : p1; + }) + : str; + }; + + // convert escape sequence in a CSS string or identifier + // to javascript string with characters representations + const unescapeIdentifier = function (str) { + return REX.hasEscapes.test(str) + ? str.replace(REX.fixEscapes, function (substring, p1, p2) { + // unescaped " or ' + return p2 || (REX.hexNumbers.test(p1) + ? stringFromCodePoint(parseInt(p1, 16)) + // \' \" + : REX.escOrQuote.test(p1) + ? substring + // \g \h \. \# etc + : p1); + }) + : str; + }; + + // empty set + const none = []; + + // cached lambdas + const matchLambdas = {}; + const selectLambdas = {}; + + // cached resolvers + let matchResolvers = {}; + let selectResolvers = {}; + + const method = { + '#': 'getElementById', + '*': 'getElementsByTagName', + '|': 'getElementsByTagNameNS', + '.': 'getElementsByClassName' + }; + + // find duplicate ids using iterative walk + const byIdRaw = function (id, context) { + let node = context; + const nodes = []; + let next = node.firstElementChild; + while ((node = next)) { + node.id === id && nodes.push(node); + if ((next = node.firstElementChild || node.nextElementSibling)) { + continue; + } + while (!next && (node = node.parentElement) && node !== context) { + next = node.nextElementSibling; + } + } + return nodes; + }; + + // context agnostic getElementById + const byId = function (id, context) { + let e; + const api = method['#']; + + // duplicates id allowed + if (Config.IDS_DUPES === false) { + if (api in context) { + e = context[api](id); + return e ? [e] : none; + } + } else if ('all' in context) { + if ((e = context.all[id])) { + if (e.nodeType === 1) { + return e.getAttribute('id') !== id ? [] : [e]; + } else if (id === 'length') { + e = context[api](id); + return e ? [e] : none; + } + const nodes = []; + for (let i = 0, l = e.length; l > i; ++i) { + if (e[i].id === id) { + nodes.push(e[i]); + } + } + return nodes.length ? nodes : none; + } else { + return none; + } + } + + return byIdRaw(id, context); + }; + + // context agnostic getElementsByTagName + const byTag = function (tag, context) { + let e; + let nodes; + const api = method['*']; + + // DOCUMENT_NODE (9) & ELEMENT_NODE (1) + if (api in context) { + return Array.prototype.slice.call(context[api](tag)); + } else { + tag = tag.toLowerCase(); + // DOCUMENT_FRAGMENT_NODE (11) + if ((e = context.firstElementChild)) { + if (!(e.nextElementSibling || tag === '*' || e.localName === tag)) { + return Array.prototype.slice.call(e[api](tag)); + } else { + nodes = []; + do { + if (tag === '*' || e.localName === tag) { + nodes.push(e); + } + concatList(nodes, e[api](tag)); + } while ((e = e.nextElementSibling)); + } + } else { + nodes = none; + } + } + return nodes; + }; + + // context agnostic getElementsByClassName + const byClass = function (cls, context) { + let e; + let nodes; + const api = method['.']; + let reCls; + // DOCUMENT_NODE (9) & ELEMENT_NODE (1) + if (api in context) { + return Array.prototype.slice.call(context[api](cls)); + } else { + // DOCUMENT_FRAGMENT_NODE (11) + if ((e = context.firstElementChild)) { + reCls = RegExp('(^|\\s)' + cls + '(\\s|$)', QUIRKS_MODE ? 'i' : ''); + if (!(e.nextElementSibling || reCls.test(e.className))) { + return Array.prototype.slice.call(e[api](cls)); + } else { + nodes = []; + do { + if (reCls.test(e.className)) { + nodes.push(e); + } + concatList(nodes, e[api](cls)); + } while ((e = e.nextElementSibling)); + } + } else nodes = none; + } + return nodes; + }; + + const compat = { + '#': function (c, n) { + REX.hasEscapes.test(n) && (n = unescapeIdentifier(n)); + return function (e, f) { + return byId(n, c); + }; + }, + '*': function (c, n) { + REX.hasEscapes.test(n) && (n = unescapeIdentifier(n)); + return function (e, f) { + return byTag(n, c); + }; + }, + '|': function (c, n) { + REX.hasEscapes.test(n) && (n = unescapeIdentifier(n)); + return function (e, f) { + return byTag(n, c); + }; + }, + '.': function (c, n) { + REX.hasEscapes.test(n) && (n = unescapeIdentifier(n)); + return function (e, f) { + return byClass(n, c); + }; + } + }; + + // namespace aware hasAttribute + // helper for XML/XHTML documents + const hasAttributeNS = function (e, name) { + let i; + let l; + const attr = e.getAttributeNames(); + name = RegExp(':?' + name + '$', HTML_DOCUMENT ? 'i' : ''); + for (i = 0, l = attr.length; l > i; ++i) { + if (name.test(attr[i])) { + return true; + } + } + return false; + }; + + // fast resolver for the :nth-child() and :nth-last-child() pseudo-classes + const nthElement = (function () { + let idx = 0; + let len = 0; + let set = 0; + let parent; + let parents = []; + let nodes = []; + return function (element, dir) { + // ensure caches are emptied after each run, invoking with dir = 2 + if (dir === 2) { + idx = 0; len = 0; set = 0; nodes = []; parents = []; parent = undefined; + return -1; + } + let e, i, j, k, l; + if (parent === element.parentElement) { + i = set; j = idx; l = len; + } else { + l = parents.length; + parent = element.parentElement; + for (i = -1, j = 0, k = l - 1; l > j; ++j, --k) { + if (parents[j] === parent) { + i = j; + break; + } + if (parents[k] === parent) { + i = k; + break; + } + } + if (i < 0) { + parents[i = l] = parent; + l = 0; nodes[i] = []; + e = (parent && parent.firstElementChild) || element; + while (e) { + nodes[i][l] = e; + if (e === element) { + j = l; + } + e = e.nextElementSibling; + ++l; + } + set = i; idx = 0; len = l; + if (l < 2) { + return l; + } + } else { + l = nodes[i].length; + set = i; + } + } + if (element !== nodes[i][j] && element !== nodes[i][j = 0]) { + for (j = 0, e = nodes[i], k = l - 1; l > j; ++j, --k) { + if (e[j] === element) { + break; + } + if (e[k] === element) { + j = k; + break; + } + } + } + idx = j + 1; len = l; + return dir ? l - j : idx; + }; + })(); + + // fast resolver for the :nth-of-type() and :nth-last-of-type() pseudo-classes + const nthOfType = (function () { + let idx = 0; + let len = 0; + let set = 0; + let parent; + let parents = []; + let nodes = []; + return function (element, dir) { + // ensure caches are emptied after each run, invoking with dir = 2 + if (dir === 2) { + idx = 0; len = 0; set = 0; nodes = []; parents = []; parent = undefined; + return -1; + } + const name = element.localName; + const nsURI = element.namespaceURI; + if (nsURI !== 'http://www.w3.org/1999/xhtml') { + idx = 0; len = 0; set = 0; nodes = []; parents = []; parent = undefined; + } + let e; + let i; + let j; + let k; + let l; + if (nodes[set] && nodes[set][name] && parent === element.parentElement) { + i = set; + j = idx; + l = len; + } else { + l = parents.length; + parent = element.parentElement; + for (i = -1, j = 0, k = l - 1; l > j; ++j, --k) { + if (parents[j] === parent) { + i = j; + break; + } + if (parents[k] === parent) { + i = k; + break; + } + } + if (i < 0 || !nodes[i][name]) { + parents[i = l] = parent; + nodes[i] || (nodes[i] = Object()); + l = 0; nodes[i][name] = []; + e = (parent && parent.firstElementChild) || element; + while (e) { + if (e === element) { + j = l; + } + if (e.localName === name && e.namespaceURI === nsURI) { + nodes[i][name][l] = e; + ++l; + } + e = e.nextElementSibling; + } + set = i; idx = j; len = l; + if (l < 2) { + return l; + } + } else { + l = nodes[i][name].length; + set = i; + } + } + if (element !== nodes[i][name][j] && element !== nodes[i][name][j = 0]) { + for (j = 0, e = nodes[i][name], k = l - 1; l > j; ++j, --k) { + if (e[j] === element) { + break; + } + if (e[k] === element) { + j = k; + break; + } + } + } + idx = j + 1; len = l; + return dir ? l - j : idx; + }; + })(); + + // check if the node is the target + const isTarget = function (node) { + const doc = node.ownerDocument || node; + const { hash } = new URL(doc.URL); + if (node.id && hash === `#${node.id}` && doc.contains(node)) { + return true; + } + return false; + }; + + // check if node is indeterminate + const isIndeterminate = function (node) { + if ((node.indeterminate && node.localName === 'input' && + node.type === 'checkbox') || + (node.localName === 'progress' && !node.hasAttribute('value'))) { + return true; + } + if (node.localName === 'input' && node.type === 'radio' && + !node.hasAttribute('checked')) { + const nodeName = node.name; + let parent = node.parentNode; + while (parent) { + if (parent.localName === 'form') { + break; + } + parent = parent.parentNode; + } + if (!parent) { + const doc = node.ownerDocument; + parent = doc.documentElement; + } + const items = parent.getElementsByTagName('input'); + const l = items.length; + let checked; + for (let i = 0; i < l; i++) { + const item = items[i]; + if (item.getAttribute('type') === 'radio') { + if (nodeName) { + if (item.getAttribute('name') === nodeName) { + checked = !!item.checked; + } + } else if (!item.hasAttribute('name')) { + checked = !!item.checked; + } + if (checked) { + break; + } + } + } + if (!checked) { + return true; + } + } + return false; + }; + + // check if node content is editable + const isContentEditable = function (node) { + let attrValue = 'inherit'; + if (node.hasAttribute('contenteditable')) { + attrValue = node.getAttribute('contenteditable'); + } + switch (attrValue) { + case '': + case 'plaintext-only': + case 'true': + return true; + case 'false': + return false; + default: + if (node.parentNode && node.parentNode.nodeType === 1) { + return isContentEditable(node.parentNode); + } + return false; + } + }; + + // build validation regexps used by the engine + const setIdentifierSyntax = function () { + // + // NOTE: SPECIAL CASES IN CSS SYNTAX PARSING RULES + // + // The https://drafts.csswg.org/css-syntax/#typedef-eof-token + // allow mangled|unclosed selector syntax at the end of selectors strings + // + // Literal equivalent hex representations of the characters: " ' ` ] ) + // + // \\x22 = " - double quotes \\x5b = [ - open square bracket + // \\x27 = ' - single quote \\x5d = ] - closed square bracket + // \\x60 = ` - back tick \\x28 = ( - open round parens + // \\x5c = \ - back slash \\x29 = ) - closed round parens + // + // using hex format prevents false matches of opened/closed instances + // pairs, coloring breakage and other editors highlightning problems. + // + + // @see https://drafts.csswg.org/css-syntax-3/#ident-token-diagram + const nonascii = '[^\\x00-\\x9f]'; + const esctoken = '\\\\(?:[^\\r\\n\\f\\da-f]|[\\da-f]{1,6}\\s{0,255})'; + const identifier = + '(?:--|-?(?:[a-z_]|' + nonascii + '|' + esctoken + '))' + + '(?:[\\w-]|' + nonascii + '|' + esctoken + ')*'; + + const pseudonames = '[-\\w]+'; + const pseudoparms = '(?:[-+]?\\d*)(?:n\\s?[-+]?\\s?\\d*)'; + const doublequote = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*(?:"|$)'; + const singlequote = "'[^'\\\\]*(?:\\\\.[^'\\\\]*)*(?:'|$)"; + + const attrparser = identifier + '|' + doublequote + '|' + singlequote; + + const attrvalues = '([\\x22\\x27]?)((?!\\3)*|(?:\\\\?.)*?)(?:\\3|$)'; + + const attributes = + '\\[' + + // attribute presence + '(?:\\*\\|)?\\s?(' + identifier + '(?::' + identifier + ')?)\\s?' + + '(?:(' + CFG.operators + ')\\s?(?:' + attrparser + '))?' + + // attribute case sensitivity + '(?:\\s?\\b(i))?\\s?' + + '(?:\\]|$)'; + + const attrmatcher = attributes.replace(attrparser, attrvalues); + + const pseudoclass = + '(?:\\x28\\s*' + + '(?:' + pseudoparms + '?)?|' + + // universal * & + // namespace *|* + '[*|]|' + + '(?:' + + '(?::' + pseudonames + '(?:\\x28' + pseudoparms + '?(?:\\x29|$))?)|' + + '(?:[.#]?' + identifier + ')|' + + '(?:' + attributes + ')' + + ')+|' + + '\\s?[>+~]\\s?|' + + '\\s?,\\s?|' + + '\\s|' + + '\\x29|$' + + ')*'; + + const standardValidator = + '(?=\\s?[^>+~(){}<])' + + '(?:' + + // universal * & + // namespace *|* + '\\*|\\||' + + '(?:[.#]?' + identifier + ')+|' + + '(?:' + attributes + ')+|' + + '(?:::?' + pseudonames + pseudoclass + ')|' + + '(?:\\s?' + CFG.combinators + '\\s?)|' + + '\\s?,\\s?|' + + '\\s?' + + ')+'; + + // the following global RE is used to return the + // deepest localName in selector strings and then + // use it to retrieve all possible matching nodes + // that will be filtered by compiled resolvers + reOptimizer = RegExp( + '(?:([.:#*]?)(' + identifier + ')' + + '(?::[-\\w]+|\\[[^\\]]+(?:\\]|$)|\\x28[^\\x29]+(?:\\x29|$))*' + + ')$', 'i'); + + // global + reValidator = RegExp(standardValidator, 'gi'); + + Patterns.id = RegExp('^#(' + identifier + ')(.*)', 'i'); + Patterns.tagName = RegExp('^(' + identifier + ')(.*)', 'i'); + Patterns.className = RegExp('^\\.(' + identifier + ')(.*)', 'i'); + Patterns.attribute = RegExp('^(?:' + attrmatcher + ')(.*)'); + }; + + // configure the engine to use special handling + const configure = function (option, clear) { + if (typeof option === 'string') { + return !!Config[option]; + } + if (typeof option !== 'object') { + return Config; + } + for (const i in option) { + Config[i] = !!option[i]; + } + // clear lambda cache + if (clear) { + matchResolvers = {}; + selectResolvers = {}; + } + setIdentifierSyntax(); + return true; + }; + + // centralized error and exceptions handling + const emit = function (message, proto) { + let err; + if (Config.VERBOSITY) { + if (global[proto]) { + err = new global[proto](message); + } else { + err = new global.DOMException(message, 'SyntaxError'); + } + throw err; + } + if (Config.LOGERRORS && console && console.log) { + console.log(message); + } + }; + + // passed to resolvers + const Snapshot = { + doc: null, + from: null, + byTag: null, + first: null, + match: null, + ancestor: null, + nthOfType: null, + nthElement: null, + hasAttributeNS: null, + isTarget: null, + isIndeterminate: null, + isContentEditable: null + }; + + // context + let lastContext; + + const switchContext = function (context, force) { + const oldDoc = doc; + doc = context.ownerDocument || context; + if (force || oldDoc !== doc) { + // force a new check for each document change + // performed before the next select operation + HTML_DOCUMENT = isHTML(doc); + QUIRKS_MODE = HTML_DOCUMENT && doc.compatMode.indexOf('CSS') < 0; + NAMESPACE = doc.documentElement && doc.documentElement.namespaceURI; + Snapshot.doc = doc; + } + Snapshot.from = context; + return context; + }; + + // selector + let lastMatched; + let lastSelected; + + const F_INIT = '"use strict";return function Resolver(c,f,x,r)'; + + const S_HEAD = 'var e,n,o,j=r.length-1,k=-1'; + const M_HEAD = 'var e,n,o'; + + const S_LOOP = 'main:while((e=c[++k]))'; + const N_LOOP = 'main:while((e=c.item(++k)))'; + const M_LOOP = 'e=c;'; + + const S_BODY = 'r[++j]=c[k];'; + const N_BODY = 'r[++j]=c.item(k);'; + const M_BODY = ''; + + const S_TAIL = 'continue main;'; + const M_TAIL = 'r=true;'; + + const S_TEST = 'if(f(c[k])){break main;}'; + const N_TEST = 'if(f(c.item(k))){break main;}'; + const M_TEST = 'f(c);'; + + let S_VARS = []; + let M_VARS = []; + + // build conditional code to check components of selector strings + const compileSelector = function (expression, source, mode, callback) { + // N is the negation pseudo-class flag + // D is the default inverted negation flag + let a; + let b; + let n; + let f; + let name; + let NS; + const N = ''; + const D = '!'; + let compat; + let expr; + let match; + let result; + let status; + let symbol; + let test; + let type; + let selector = expression; + let vars; + + // original 'select' or 'match' selector string before normalization + const selectorString = mode ? lastSelected : lastMatched; + + // isolate selector combinators/components and normalize whitespace + selector = selector.replace(STD.combinator, '$1'); // .replace(STD.whitespace, ' '); + + let selectorRecursion = true; + while (selector) { + // get namespace prefix if present or get first char of selector + symbol = STD.apimethods.test(selector) ? '|' : selector[0]; + + switch (symbol) { + // universal resolver + case '*': + match = selector.match(Patterns.universal); + if (N === '!') { + source = 'if(' + N + 'true' + '){' + source + '}'; + } + break; + // id resolver + case '#': + match = selector.match(Patterns.id); + source = 'if(' + N + '(/^' + match[1] + '$/.test(e.getAttribute("id"))' + + ')){' + source + '}'; + break; + // class name resolver + case '.': + match = selector.match(Patterns.className); + compat = (QUIRKS_MODE ? 'i' : '') + '.test(e.getAttribute("class"))'; + source = 'if(' + N + '(/(^|\\s)' + match[1] + '(\\s|$)/' + compat + + ')){' + source + '}'; + break; + // tag name resolver + case (/[_a-z]/i.test(symbol) ? symbol : undefined): + match = selector.match(Patterns.tagName); + source = 'if(' + N + '(e.localName' + + (Config.MIXEDCASE || hasMixedCaseTagNames(doc) + ? '=="' + match[1].toLowerCase() + '"' + : '=="' + match[1].toUpperCase() + '"') + + ')){' + source + '}'; + break; + // namespace resolver + case '|': + match = selector.match(Patterns.namespace); + if (match[1] === '*') { + source = 'if(' + N + 'true){' + source + '}'; + } else if (!match[1]) { + source = 'if(' + N + '(!e.namespaceURI)){' + source + '}'; + } else if (typeof match[1] === 'string' && doc.documentElement && + doc.documentElement.prefix === match[1]) { + source = 'if(' + N + '(e.namespaceURI=="' + NAMESPACE + '")){' + source + '}'; + } else { + emit('\'' + selectorString + '\'' + qsInvalid); + } + break; + // attributes resolver + case '[': + match = selector.match(Patterns.attribute); + NS = match[0].match(STD.namespaces); + name = match[1]; + expr = name.split(':'); + expr = expr.length === 2 ? expr[1] : expr[0]; + if (match[2] && !(test = Operators[match[2]])) { + emit('\'' + selectorString + '\'' + qsInvalid); + return ''; + } + if (match[4] === '') { + test = match[2] === '~=' + ? { p1: '^\\s', p2: '+$', p3: 'true' } + : match[2] in ATTR_STD_OPS && match[2] !== '~=' + ? { p1: '^', p2: '$', p3: 'true' } + : test; + } else if (match[2] === '~=' && match[4].includes(' ')) { + // whitespace separated list but value contains space + source = 'if(' + N + 'false){' + source + '}'; + break; + } else if (match[4]) { + match[4] = convertEscapes(match[4]).replace(REX.regExpChar, '\\$&'); + } + type = match[5] === 'i' || (HTML_DOCUMENT && HTML_TABLE[expr.toLowerCase()]) + ? 'i' + : ''; + source = + 'if(' + N + '(' + + (!match[2] + ? (NS ? 's.hasAttributeNS(e,"' + name + '")' : 'e.hasAttribute&&e.hasAttribute("' + name + '")') + : !match[4] && ATTR_STD_OPS[match[2]] && match[2] !== '~=' + ? 'e.getAttribute&&e.getAttribute("' + name + '")==""' + : '(/' + test.p1 + match[4] + test.p2 + '/' + type + ').test(e.getAttribute&&e.getAttribute("' + name + '"))==' + test.p3) + + ')){' + source + '}'; + break; + // *** General sibling combinator + // E ~ F (F relative sibling of E) + case '~': + match = selector.match(Patterns.relative); + source = 'n=e;while((e=e.previousElementSibling)){' + source + '}e=n;'; + break; + // *** Adjacent sibling combinator + // E + F (F adiacent sibling of E) + case '+': + match = selector.match(Patterns.adjacent); + source = 'n=e;if((e=e.previousElementSibling)){' + source + '}e=n;'; + break; + // *** Descendant combinator + // E F (E ancestor of F) + case '\x09': + case '\x20': + match = selector.match(Patterns.ancestor); + source = 'n=e;while((e=e.parentElement)){' + source + '}e=n;'; + break; + // *** Child combinator + // E > F (F children of E) + case '>': + match = selector.match(Patterns.children); + source = 'n=e;if((e=e.parentElement)){' + source + '}e=n;'; + break; + // *** user supplied combinators extensions + case (symbol in Combinators ? symbol : undefined): + // for other registered combinators extensions + match[match.length - 1] = '*'; + source = Combinators[symbol](match) + source; + break; + // *** tree-structural pseudo-classes + // :root, :empty, :first-child, :last-child, :only-child, :first-of-type, :last-of-type, :only-of-type + case ':': + if ((match = selector.match(Patterns.structural))) { + match[1] = match[1].toLowerCase(); + switch (match[1]) { + case 'root': + // there can only be one :root element, so exit the loop once found + source = 'if(' + N + '(e===s.doc.documentElement)){' + source + (mode ? 'break main;' : '') + '}'; + break; + case 'empty': + // matches elements that don't contain elements or text nodes + source = 'n=e.firstChild;while(n&&!(/1|3/).test(n.nodeType)){n=n.nextSibling}if(' + D + 'n){' + source + '}'; + break; + // *** child-indexed pseudo-classes + // :first-child, :last-child, :only-child + case 'only-child': + source = 'if(' + N + '(!e.nextElementSibling&&!e.previousElementSibling)){' + source + '}'; + break; + case 'last-child': + source = 'if(' + N + '(!e.nextElementSibling)){' + source + '}'; + break; + case 'first-child': + source = 'if(' + N + '(!e.previousElementSibling)){' + source + '}'; + break; + // *** typed child-indexed pseudo-classes + // :only-of-type, :last-of-type, :first-of-type + case 'only-of-type': + source = 'o=e.localName;' + + 'n=e;while((n=n.nextElementSibling)&&n.localName!=o);if(!n){' + + 'n=e;while((n=n.previousElementSibling)&&n.localName!=o);}if(' + D + 'n){' + source + '}'; + break; + case 'last-of-type': + source = 'n=e;o=e.localName;while((n=n.nextElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}'; + break; + case 'first-of-type': + source = 'n=e;o=e.localName;while((n=n.previousElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}'; + break; + default: + emit('\'' + selectorString + '\'' + qsInvalid); + } + // *** child-indexed & typed child-indexed pseudo-classes + // :nth-child, :nth-of-type, :nth-last-child, :nth-last-of-type + } else if ((match = selector.match(Patterns.treestruct))) { + match[1] = match[1].toLowerCase(); + switch (match[1]) { + case 'nth-child': + case 'nth-of-type': + case 'nth-last-child': + case 'nth-last-of-type': + expr = /-of-type/i.test(match[1]); + if (match[1] && match[2]) { + type = /last/i.test(match[1]); + if (match[2] === 'n') { + source = 'if(' + N + 'true){' + source + '}'; + break; + } else if (match[2] === '1') { + test = type ? 'next' : 'previous'; + source = expr + ? 'n=e;o=e.localName;' + + 'while((n=n.' + test + 'ElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}' + : 'if(' + N + '!e.' + test + 'ElementSibling){' + source + '}'; + break; + } else if (match[2] === 'even' || match[2] === '2n0' || match[2] === '2n+0' || match[2] === '2n') { + test = 'n%2==0'; + } else if (match[2] === 'odd' || match[2] === '2n1' || match[2] === '2n+1') { + test = 'n%2==1'; + } else { + f = /n/i.test(match[2]); + n = match[2].split('n'); + a = parseInt(n[0], 10) || 0; + b = parseInt(n[1], 10) || 0; + if (n[0] === '-') { + a = -1; + } + if (n[0] === '+') { + a = +1; + } + test = (b ? '(n' + (b > 0 ? '-' : '+') + Math.abs(b) + ')' : 'n') + '%' + a + '==0'; + test = a >= +1 + ? (f + ? 'n>' + (b - 1) + (Math.abs(a) !== 1 + ? '&&' + test + : '') + : 'n==' + a) + : a <= -1 + ? (f + ? 'n<' + (b + 1) + (Math.abs(a) !== 1 + ? '&&' + test + : '') + : 'n==' + a) + : a === 0 + ? (n[0] + ? 'n==' + b + : 'n>' + (b - 1)) + : 'false'; + } + expr = expr ? 'OfType' : 'Element'; + type = type ? 'true' : 'false'; + source = 'n=s.nth' + expr + '(e,' + type + ');if(' + N + '(' + test + ')){' + source + '}'; + } else { + emit('\'' + selectorString + '\'' + qsInvalid); + } + break; + default: + emit('\'' + selectorString + '\'' + qsInvalid); + } + // *** logical combination pseudo-classes + // :is( s1, [ s2, ... ]), :not( s1, [ s2, ... ]) + } else if ((match = selector.match(Patterns.logicalsel))) { + match[1] = match[1].toLowerCase(); + expr = match[2].replace(REX.CommaGroup, ',').replace(REX.TrimSpaces, ''); + switch (match[1]) { + // FIXME: + case 'is': + case 'where': + case 'matches': + source = 'if(s.match("' + expr.replace(/\x22/g, '\\"') + '",e)){' + source + '}'; + break; + // FIXME: + case 'not': + source = 'if(!s.match("' + expr.replace(/\x22/g, '\\"') + '",e)){' + source + '}'; + break; + // FIXME: + case 'has': + // clear cache + matchResolvers = {}; + source = 'if(e.querySelector(":scope ' + expr.replace(/\x22/g, '\\"') + '")){' + source + '}'; + break; + default: + emit('\'' + selectorString + '\'' + qsInvalid); + } + // *** location pseudo-classes + // :any-link, :link, :visited, :target + } else if ((match = selector.match(Patterns.locationpc))) { + match[1] = match[1].toLowerCase(); + switch (match[1]) { + case 'any-link': + source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href")||e.visited)){' + source + '}'; + break; + case 'link': + source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href"))){' + source + '}'; + break; + // FIXME: + case 'visited': + source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href")&&e.visited)){' + source + '}'; + break; + case 'target': + source = 'if(s.isTarget(e)){' + source + '}'; + break; + default: + emit('\'' + selectorString + '\'' + qsInvalid); + } + // *** user interface and form pseudo-classes + // :enabled, :disabled, :read-only, :read-write, :placeholder-shown, :default + } else if ((match = selector.match(Patterns.inputstate))) { + match[1] = match[1].toLowerCase(); + switch (match[1]) { + // FIXME: lacks custom element support + case 'enabled': + source = 'if((("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e &&e.disabled===false' + + ')){' + source + '}'; + break; + // FIXME: lacks custom element support + case 'disabled': + // https://html.spec.whatwg.org/#enabling-and-disabling-form-controls:-the-disabled-attribute + source = 'if((("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e)){' + + // F is true if any of the fieldset elements in the ancestry chain has the disabled attribute specified + // L is true if the first legend element of the fieldset contains the element + 'var x=0,N=[],F=false,L=false;' + + 'if(!(/^(optgroup|option)$/i.test(e.localName))){' + + 'n=e.parentElement;' + + 'while(n){' + + 'if(n.localName==="fieldset"){' + + 'N[x++]=n;' + + 'if(n.disabled===true){' + + 'F=true;' + + 'break;' + + '}' + + '}' + + 'n=n.parentElement;' + + '}' + + 'for(var x=0;x + // assert: e.type is in double-colon format, like ::after + } else if ((match = selector.match(Patterns.pseudoDbl))) { + source = 'if(e.element&&e.type.toLowerCase()=="' + + match[0].toLowerCase() + '"){e=e.element;' + source + '}'; + // placeholder for parsed only no-op selectors + } else if ((match = selector.match(Patterns.pseudoNop))) { + source = 'if(' + N + 'false' + '){' + source + '}'; + } else { + // reset + expr = false; + status = false; + // process registered selector extensions + for (expr in Selectors) { + if ((match = selector.match(Selectors[expr].Expression))) { + result = Selectors[expr].Callback(match, source, mode, callback); + if ('match' in result) { + match = result.match; + } + vars = result.modvar; + if (mode) { + // add extra select() vars + vars && !S_VARS.includes(vars) && S_VARS.push(vars); + } else { + // add extra match() vars + vars && M_VARS.includes(vars) && M_VARS.push(vars); + } + // extension source code + source = result.source; + // extension status code + status = result.status; + // break on status error + if (status) { break; } + } + } + if (!status) { + emit('unknown pseudo-class selector \'' + selector + '\''); + return ''; + } + if (!expr) { + emit('unknown token in selector \'' + selector + '\''); + return ''; + } + } + break; + default: + selectorRecursion = false; + emit('\'' + selectorString + '\'' + qsInvalid); + } + // end of switch symbol + if (!selectorRecursion) { + break; + } + if (!match) { + emit('\'' + selectorString + '\'' + qsInvalid); + return ''; + } + + // pop last component + selector = match.pop(); + } + // end of while selector + + return source; + }; + + // compile groups or single selector strings into + // executable functions for matching or selecting + const compile = function (selector, mode, callback) { + let head = ''; let loop = ''; let macro = ''; let source = ''; let vars = ''; + + // 'mode' can be boolean or null + // true = select / false = match + // null to use collection.item() + switch (mode) { + case true: + if (selectLambdas[selector]) { + return selectLambdas[selector]; + } + macro = S_BODY + (callback ? S_TEST : '') + S_TAIL; + head = S_HEAD; + loop = S_LOOP; + break; + case false: + if (matchLambdas[selector]) { + return matchLambdas[selector]; + } + macro = M_BODY + (callback ? M_TEST : '') + M_TAIL; + head = M_HEAD; + loop = M_LOOP; + break; + case null: + if (selectLambdas[selector]) { + return selectLambdas[selector]; + } + macro = N_BODY + (callback ? N_TEST : '') + S_TAIL; + head = S_HEAD; + loop = N_LOOP; + break; + default: + } + + source = compileSelector(selector, macro, mode, callback); + + loop += (mode || mode === null) ? '{' + source + '}' : source; + + if ((mode || mode === null) && selector.includes(':nth')) { + loop += reNthElem.test(selector) ? 's.nthElement(null, 2);' : ''; + loop += reNthType.test(selector) ? 's.nthOfType(null, 2);' : ''; + } + + if (S_VARS[0] || M_VARS[0]) { + vars = ',' + (S_VARS.join(',') || M_VARS.join(',')); + S_VARS = []; + M_VARS = []; + } + + const factory = Function('s', F_INIT + '{' + head + vars + ';' + loop + 'return r;}')(Snapshot); + + return mode || mode === null ? (selectLambdas[selector] = factory) : (matchLambdas[selector] = factory); + }; + + // optimize selectors avoiding duplicated checks + const optimize = function (selector, token) { + const index = token.index; + const length = token[1].length + token[2].length; + return selector.slice(0, index) + + (' >+~'.indexOf(selector.charAt(index - 1)) > -1 + ? (':['.indexOf(selector.charAt(index + length + 1)) > -1 + ? '*' + : '') + : '') + selector.slice(index + length - (token[1] === '*' ? 1 : 0)); + }; + + // prepare factory resolvers and closure collections + const collect = function (selectors, context, callback) { + let i; + let l; + const seen = { }; + let token = ['', '*', '*']; + const optimized = selectors; + const factory = []; + const htmlset = []; + const nodeset = []; + let results = []; + let type; + + for (i = 0, l = selectors.length; l > i; ++i) { + if (!seen[selectors[i]] && (seen[selectors[i]] = true)) { + type = selectors[i].match(reOptimizer); + if (type && type[1] !== ':' && (token = type)) { + token[1] || (token[1] = '*'); + optimized[i] = optimize(optimized[i], token); + } else { + token = ['', '*', '*']; + } + } + + nodeset[i] = token[1] + token[2]; + htmlset[i] = compat[token[1]](context, token[2]); + factory[i] = compile(optimized[i], true, null); + + factory[i] + ? factory[i](htmlset[i](), callback, context, results) + : results.concat(htmlset[i]()); + } + + if (l > 1) { + results.sort(documentOrder); + hasDupes && (results = unique(results)); + } + + return { + callback, + context, + factory, + htmlset, + nodeset, + results + }; + }; + + // replace ':scope' pseudo-class with element references + const makeref = function (selectors, element) { + // DOCUMENT_NODE (9) + if (element.nodeType === 9) { + element = element.documentElement; + } + + return selectors.replace(/:scope/gi, + element.localName + + (element.id ? '#' + element.id : '') + + (element.className ? '.' + element.classList[0] : '')); + }; + + const matchAssert = function (f, element, callback) { + let r = false; + for (let i = 0, l = f.length; l > i; ++i) { + f[i](element, callback, null, false) && (r = true); + } + return r; + }; + + const matchCollect = function (selectors, callback) { + const f = []; + for (let i = 0, l = selectors.length; l > i; ++i) { + f[i] = compile(selectors[i], false, callback); + } + return { factory: f }; + }; + + // equivalent of w3c 'matches' method + const match = function _matches(selectors, element, callback) { + let expressions; + + if (element && !/:has\(/.test(selectors) && matchResolvers[selectors]) { + return matchAssert(matchResolvers[selectors].factory, element, callback); + } + + lastMatched = selectors; + + // arguments validation + if (arguments.length === 0) { + emit(qsNotArgs, 'TypeError'); + return Config.VERBOSITY ? undefined : false; + } else if (arguments[0] === '') { + emit('\'\'' + qsInvalid); + return Config.VERBOSITY ? undefined : false; + } + + // input NULL or UNDEFINED + if (typeof selectors !== 'string') { + selectors = '' + selectors; + } + + if ((/:scope/i).test(selectors)) { + selectors = makeref(selectors, element); + } + + // normalize input string + const parsed = selectors + .replace(/\0|\\$/g, '\ufffd') + .replace(REX.combineWSP, '\x20') + .replace(REX.pseudosWSP, '$1') + .replace(REX.tabCharWSP, '\t') + .replace(REX.commaGroup, ',') + .replace(REX.trimSpaces, ''); + + // parse, validate and split possible compound selectors + if ((expressions = parsed.match(reValidator)) && expressions.join('') === parsed) { + expressions = parsed.match(REX.splitGroup); + if (parsed[parsed.length - 1] === ',') { + emit(qsInvalid); + return Config.VERBOSITY ? undefined : false; + } + } else { + emit('\'' + selectors + '\'' + qsInvalid); + return Config.VERBOSITY ? undefined : false; + } + + matchResolvers[selectors] = matchCollect(expressions, callback); + + return matchAssert(matchResolvers[selectors].factory, element, callback); + }; + + // equivalent of w3c 'closest' method + const ancestor = function _closest(selectors, element, callback) { + if ((/:scope/i).test(selectors)) { + selectors = makeref(selectors, element); + } + + while (element) { + if (match(selectors, element, callback)) break; + element = element.parentElement; + } + return element; + }; + + // equivalent of w3c 'querySelectorAll' method + const select = function _querySelectorAll(selectors, context, callback) { + let expressions; let nodes = []; let resolver; + + context || (context = doc); + + if (selectors) { + if ((resolver = selectResolvers[selectors])) { + if (resolver.context === context && resolver.callback === callback) { + const f = resolver.factory; + const h = resolver.htmlset; + const n = resolver.nodeset; + if (n.length > 1) { + const l = n.length; + for (let i = 0, l = n.length, list; l > i; ++i) { + list = compat[n[i][0]](context, n[i].slice(1))(); + if (f[i] !== null) { + f[i](list, callback, context, nodes); + } else { + nodes = nodes.concat(list); + } + } + if (l > 1 && nodes.length > 1) { + nodes.sort(documentOrder); + hasDupes && (nodes = unique(nodes)); + } + } else { + if (f[0]) { + nodes = f[0](h[0](), callback, context, nodes); + } else { + nodes = h[0](); + } + } + return typeof callback === 'function' + ? concatCall(nodes, callback) + : nodes; + } + } + } + + lastSelected = selectors; + + // arguments validation + if (arguments.length === 0) { + emit(qsNotArgs, 'TypeError'); + return Config.VERBOSITY ? undefined : none; + } else if (arguments[0] === '') { + emit('\'\'' + qsInvalid); + return Config.VERBOSITY ? undefined : none; + } else if (lastContext !== context) { + lastContext = switchContext(context); + } + + // input NULL or UNDEFINED + if (typeof selectors !== 'string') { + selectors = '' + selectors; + } + + if ((/:scope/i).test(selectors)) { + selectors = makeref(selectors, context); + } + + // normalize input string + const parsed = selectors + .replace(/\0|\\$/g, '\ufffd') + .replace(REX.combineWSP, '\x20') + .replace(REX.pseudosWSP, '$1') + .replace(REX.tabCharWSP, '\t') + .replace(REX.commaGroup, ',') + .replace(REX.trimSpaces, ''); + + // parse, validate and split possible compound selectors + if ((expressions = parsed.match(reValidator)) && expressions.join('') === parsed) { + expressions = parsed.match(REX.splitGroup); + if (parsed[parsed.length - 1] === ',') { + emit(qsInvalid); + return Config.VERBOSITY ? undefined : false; + } + } else { + emit('\'' + selectors + '\'' + qsInvalid); + return Config.VERBOSITY ? undefined : false; + } + + // save/reuse factory and closure collection + selectResolvers[selectors] = collect(expressions, context, callback); + + nodes = selectResolvers[selectors].results; + + return typeof callback === 'function' + ? concatCall(nodes, callback) + : nodes; + }; + + // equivalent of w3c 'querySelector' method + const first = function _querySelector(selectors, context, callback) { + if (arguments.length === 0) { + emit(qsNotArgs, 'TypeError'); + } + return select(selectors, context, typeof callback === 'function' + ? function firstMatch(element) { + callback(element); + return false; + } + : function firstMatch() { + return false; + } + )[0] || null; + }; + + // execute the engine initialization code + const initialize = function (d) { + setIdentifierSyntax(); + lastContext = switchContext(d, true); + Snapshot.doc = doc; + Snapshot.from = doc; + Snapshot.byTag = byTag; + Snapshot.first = first; + Snapshot.match = match; + Snapshot.ancestor = ancestor; + Snapshot.nthOfType = nthOfType; + Snapshot.nthElement = nthElement; + Snapshot.hasAttributeNS = hasAttributeNS; + Snapshot.isTarget = isTarget; + Snapshot.isIndeterminate = isIndeterminate; + Snapshot.isContentEditable = isContentEditable; + }; + + initialize(doc); + + // public exported methods/objects + const Dom = { + // exported engine methods + Version: version, + configure, + match, + closest: ancestor, + first, + select + }; + + return Dom; +}); diff --git a/node_modules/@bramus/specificity/LICENSE b/node_modules/@bramus/specificity/LICENSE new file mode 100644 index 0000000..34642d0 --- /dev/null +++ b/node_modules/@bramus/specificity/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 Bramus Van Damme - https://www.bram.us/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/@bramus/specificity/README.md b/node_modules/@bramus/specificity/README.md new file mode 100644 index 0000000..61c4223 --- /dev/null +++ b/node_modules/@bramus/specificity/README.md @@ -0,0 +1,164 @@ +[![Calculate CSS Specificity](./screenshots/calculate-specificity.png)](https://codepen.io/bramus/pen/WNXyoYm) + +# Specificity + +`@bramus/specificity` is a package to calculate the specificity of CSS Selectors. It also includes some convenience functions to compare, sort, and filter an array of specificity values. + +Supports [Selectors Level 4](https://www.w3.org/TR/selectors-4/), including those special cases `:is()`, `:where()`, `:not()`, etc. + +Demo: [https://codepen.io/bramus/pen/WNXyoYm](https://codepen.io/bramus/pen/WNXyoYm) + +## Installation + +```bash +npm i @bramus/specificity +``` + +## Usage / Example + +At its core, `@bramus/specificity` exposes a `Specificity` class. Its static `calculate` method can be used to calculate the specificity of a given CSS [Selector List](https://www.w3.org/TR/selectors-4/#grouping) string. + +```js +import Specificity from '@bramus/specificity'; + +const specificities = Specificity.calculate('header:where(#top) nav li:nth-child(2n), #doormat'); +``` + +Because `calculate` accepts a [Selector List](https://www.w3.org/TR/selectors-4/#grouping) — which can contain more than 1 [Selector](https://www.w3.org/TR/selectors-4/#selector) — it will always return an array, with each entry being a `Specificity` instance — one per found selector. + +```js +const specificities = Specificity.calculate('header:where(#top) nav li:nth-child(2n), #doormat'); +specificities.map((s) => s.toString()); // ~> ["(0,1,3)","(1,0,0)"] +``` + +💡 If you know you’re passing only a single Selector into `calculate()`, you can use JavaScript’s built-in destructuring to keep your variable names clean. + +```js +const [s] = Specificity.calculate('header:where(#top) nav li:nth-child(2n)'); +s.toString(); // ~> "(0,1,3)" +``` + +💡 Under the hood, `@bramus/specificity` uses [CSSTree](https://github.com/csstree/csstree) to do the parsing of strings to Selectors. As a result, the `calculate` method also accepts a [CSSTree AST](https://github.com/csstree/csstree/blob/master/docs/ast.md) of the types `Selector` and `SelectorList`. + +If you have a pre-parsed CSSTree AST of the type `Selector` you can pass it into `Specificity.calculateForAST()`. It [performs slightly better](#benchmark) than `Specificity.calculate()` as it needs to check fewer things. It differs from `Specificity.calculate()` in that it does not return an array of `Specificity` instances but only a single value. + +## The Return Format + +A calculated specificity is represented as an instance of the `Specificity` class. The `Specificity` class includes methods to get the specificity value in a certain format, along with some convenience methods to compare it against other instances. + +```js +// 🚀 Thunderbirds are go! +import Specificity from '@bramus/specificity'; + +// ✨ Calculate specificity for each Selector in the given Selector List +const specificities = Specificity.calculate('header:where(#top) nav li:nth-child(2n), #doormat'); + +// 🚚 The values in the array are instances of the Specificity class +const s = specificities[0]; // Instance of Specificity + +// 👀 Read the specificity value using one of its accessors +s.value; // { a: 0, b: 1, c: 3 } +s.a; // 0 +s.b; // 1 +s.c; // 3 + +// 🛠 Convert the calculated value to various formats using one of the toXXX() instance methods +s.toString(); // "(0,1,3)" +s.toArray(); // [0, 1, 3] +s.toObject(); // { a: 0, b: 1, c: 3 } + +// 💡 Extract the matched selector string +s.selectorString(); // "header:where(#top) nav li:nth-child(2n)" + +// 🔀 Use one of its instance comparison methods to compare it to another Specificity instance +s.isEqualTo(specificities[1]); // false +s.isGreaterThan(specificities[1]); // false +s.isLessThan(specificities[1]); // true + +// 💻 Don’t worry about JSON.stringify() +JSON.stringify(s); +// { +// "selector": 'header:where(#top) nav li:nth-child(2n)', +// "asObject": { "a": 0, "b": 1, "c": 3 }, +// "asArray": [0, 1, 3], +// "asString": "(0,1,3)", +// } +``` + +## Utility Functions (Static Methods) + +This package also exposes some utility functions to work with specificities. These utility functions are all exposed as static methods on the `Specificity` class. + +- Comparing: + + - `Specificity.compare(s1, s2)`: Compares s1 to s2. Returns a value that can be: + - `> 0` = Sort s2 before s1 _(i.e. s1 is more specific than s2)_ + - `0` = Keep original order of s1 and s2 _(i.e. s1 and s2 are equally specific)_ + - `< 0` = Sort s1 before s2 _(i.e. s1 is less specific than s2)_ + - `Specificity.equals(s1, s2)`: Returns `true` if s1 and s2 have the same specificity. If not, `false` is returned. + - `Specificity.greaterThan(s1, s2)`: Returns `true` if s1 has a higher specificity than s2. If not, `false` is returned. + - `Specificity.lessThan(s1, s2)`: Returns `true` if s1 has a lower specificity than s2. If not, `false` is returned. + +- Sorting: + + - `Specificity.sortAsc(s1, s2, …, sN)`: Sorts the given specificities in ascending order _(low specificity to high specificity)_ + - `Specificity.sortDesc(s1, s2, …, sN)`: Sorts the given specificities in descending order _(high specificity to low specificity)_ + +- Filtering: + - `Specificity.min(s1, s2, …, sN)`: Filters out the value with the lowest specificity + - `Specificity.max(s1, s2, …, sN)`: Filters out the value with the highest specificity + +A specificity passed into any of these utility functions can be any of: + +- An instance of the included `Specificity` class +- A simple Object such as `{'a': 1, 'b': 0, 'c': 2}` + +## Utility Functions (Standalone) + +All static methods the `Specificity` class exposes are also exported as standalone functions using [Subpath Exports](https://nodejs.org/api/packages.html#subpath-exports). + +If you're only interested in including some of these functions into your project you can import them from their Subpath. As a result, your bundle size will be reduced greatly _(except for including the standalone `calculate`, as it returns an array of `Specificity` instances that relies on the whole lot)_ + +```js +import { calculate, calculateForAST } from '@bramus/specificity/core'; +import { compare, equals, greaterThan, lessThan } from '@bramus/specificity/compare'; +import { min, max } from '@bramus/specificity/filter'; +import { sortAsc, sortDesc } from '@bramus/specificity/sort'; +``` + +## Type Definitions + +Although `@bramus/specificity` is written in Vanilla JavaScript, it does include [Type Definitions](https://www.typescriptlang.org/docs/handbook/2/type-declarations.html) which are exposed via its `package.json`. + +## Binary/CLI + +`@bramus/specificity` exposes a binary named `specificity` to calculate the specificity of a given selector list on the CLI. For each selector that it finds, it'll print out the calculated specificity as a string on a new line. + +```bash +$ specificity "header:where(#top) nav li:nth-child(2n), #doormat" +(0,1,3) +(1,0,0) +``` + +## Benchmark + +A benchmark is included, which you can invoke using `npm run benchmark`. + +Sample results (tested on a MacBook Air M3): + +``` +Specificity.calculate(string) x 420,682 ops/sec ±0.34% (98 runs sampled) +Specificity.calculate(ast) - using SelectorList x 8,994,080 ops/sec ±0.25% (98 runs sampled) +Specificity.calculate(ast) - using Selector x 11,054,856 ops/sec ±0.39% (91 runs sampled) +Specificity.calculateForAST(ast) x 12,652,322 ops/sec ±0.35% (96 runs sampled) +``` + +## License + +`@bramus/specificity` is released under the MIT public license. See the enclosed `LICENSE` for details. + +## Acknowledgements + +The idea to create this package was sparked by [the wonderful Specificity Calculator created by Kilian Valkhof / Polypane](https://polypane.app/css-specificity-calculator/), a highly educational tool that not only calculates the specificity, but also explains which parts are responsible for it. + +The heavy lifting of doing the actual parsing of Selectors is done by [CSSTree](https://github.com/csstree/csstree). diff --git a/node_modules/@bramus/specificity/bin/cli.js b/node_modules/@bramus/specificity/bin/cli.js new file mode 100755 index 0000000..9d26b68 --- /dev/null +++ b/node_modules/@bramus/specificity/bin/cli.js @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import Specificity from '../dist/index.js'; + +if (!process.argv[2]) { + console.error('❌ Missing selector argument'); + process.exit(1); +} + +try { + const specificities = Specificity.calculate(process.argv[2]); + console.log(specificities.map((specificity) => `${specificity}`).join('\n')); +} catch (e) { + console.error(`❌ ${e.message}`); +} diff --git a/node_modules/@bramus/specificity/dist/index.cjs b/node_modules/@bramus/specificity/dist/index.cjs new file mode 100644 index 0000000..f837723 --- /dev/null +++ b/node_modules/@bramus/specificity/dist/index.cjs @@ -0,0 +1,8 @@ +var Kn=Object.create;var Tt=Object.defineProperty;var Qn=Object.getOwnPropertyDescriptor;var $n=Object.getOwnPropertyNames;var Xn=Object.getPrototypeOf,Jn=Object.prototype.hasOwnProperty;var De=e=>Tt(e,"__esModule",{value:!0});var lt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),vt=(e,t)=>{for(var r in t)Tt(e,r,{get:t[r],enumerable:!0})},Pe=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of $n(t))!Jn.call(e,s)&&(r||s!=="default")&&Tt(e,s,{get:()=>t[s],enumerable:!(n=Qn(t,s))||n.enumerable});return e},Zn=(e,t)=>Pe(De(Tt(e!=null?Kn(Xn(e)):{},"default",!t&&e&&e.__esModule?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e),ti=(e=>(t,r)=>e&&e.get(t)||(r=Pe(De({}),t,1),e&&e.set(t,r),r))(typeof WeakMap!="undefined"?new WeakMap:0);var Ue=lt(se=>{var Be="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");se.encode=function(e){if(0<=e&&e{var We=Ue(),oe=5,Ve=1<>1;return t?-r:r}ae.encode=function(t){var r="",n,s=li(t);do n=s&He,s>>>=oe,s>0&&(n|=Ge),r+=We.encode(n);while(s>0);return r};ae.decode=function(t,r,n){var s=t.length,o=0,a=0,h,l;do{if(r>=s)throw new Error("Expected more digits in base 64 VLQ value.");if(l=We.decode(t.charCodeAt(r++)),l===-1)throw new Error("Invalid base64 digit: "+t.charAt(r-1));h=!!(l&Ge),l&=He,o=o+(l<{function ui(e,t,r){if(t in e)return e[t];if(arguments.length===3)return r;throw new Error('"'+t+'" is a required argument.')}N.getArg=ui;var Ye=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,fi=/^data:.+\,.+$/;function Ct(e){var t=e.match(Ye);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}N.urlParse=Ct;function ft(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}N.urlGenerate=ft;var pi=32;function mi(e){var t=[];return function(r){for(var n=0;npi&&t.pop(),o}}var ce=mi(function(t){var r=t,n=Ct(t);if(n){if(!n.path)return t;r=n.path}for(var s=N.isAbsolute(r),o=[],a=0,h=0;;)if(a=h,h=r.indexOf("/",a),h===-1){o.push(r.slice(a));break}else for(o.push(r.slice(a,h));h=0;h--)l=o[h],l==="."?o.splice(h,1):l===".."?i++:i>0&&(l===""?(o.splice(h+1,i),i=0):(o.splice(h,2),i--));return r=o.join("/"),r===""&&(r=s?"/":"."),n?(n.path=r,ft(n)):r});N.normalize=ce;function je(e,t){e===""&&(e="."),t===""&&(t=".");var r=Ct(t),n=Ct(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),ft(r);if(r||t.match(fi))return t;if(n&&!n.host&&!n.path)return n.host=t,ft(n);var s=t.charAt(0)==="/"?t:ce(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=s,ft(n)):s}N.join=je;N.isAbsolute=function(e){return e.charAt(0)==="/"||Ye.test(e)};function di(e,t){e===""&&(e="."),e=e.replace(/\/$/,"");for(var r=0;t.indexOf(e+"/")!==0;){var n=e.lastIndexOf("/");if(n<0||(e=e.slice(0,n),e.match(/^([^\/]+:\/)?\/*$/)))return t;++r}return Array(r+1).join("../")+t.substr(e.length+1)}N.relative=di;var ze=function(){var e=Object.create(null);return!("__proto__"in e)}();function Ke(e){return e}function xi(e){return Qe(e)?"$"+e:e}N.toSetString=ze?Ke:xi;function ki(e){return Qe(e)?e.slice(1):e}N.fromSetString=ze?Ke:ki;function Qe(e){if(!e)return!1;var t=e.length;if(t<9||e.charCodeAt(t-1)!==95||e.charCodeAt(t-2)!==95||e.charCodeAt(t-3)!==111||e.charCodeAt(t-4)!==116||e.charCodeAt(t-5)!==111||e.charCodeAt(t-6)!==114||e.charCodeAt(t-7)!==112||e.charCodeAt(t-8)!==95||e.charCodeAt(t-9)!==95)return!1;for(var r=t-10;r>=0;r--)if(e.charCodeAt(r)!==36)return!1;return!0}function Si(e,t,r){var n=K(e.source,t.source);return n!==0||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:K(e.name,t.name)}N.compareByOriginalPositions=Si;function gi(e,t,r){var n;return n=e.originalLine-t.originalLine,n!==0||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:K(e.name,t.name)}N.compareByOriginalPositionsNoSource=gi;function Ci(e,t,r){var n=e.generatedLine-t.generatedLine;return n!==0||(n=e.generatedColumn-t.generatedColumn,n!==0||r)||(n=K(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:K(e.name,t.name)}N.compareByGeneratedPositionsDeflated=Ci;function yi(e,t,r){var n=e.generatedColumn-t.generatedColumn;return n!==0||r||(n=K(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:K(e.name,t.name)}N.compareByGeneratedPositionsDeflatedNoLine=yi;function K(e,t){return e===t?0:e===null?1:t===null?-1:e>t?1:-1}function bi(e,t){var r=e.generatedLine-t.generatedLine;return r!==0||(r=e.generatedColumn-t.generatedColumn,r!==0)||(r=K(e.source,t.source),r!==0)||(r=e.originalLine-t.originalLine,r!==0)||(r=e.originalColumn-t.originalColumn,r!==0)?r:K(e.name,t.name)}N.compareByGeneratedPositionsInflated=bi;function Li(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}N.parseSourceMapInput=Li;function Ti(e,t,r){if(t=t||"",e&&(e[e.length-1]!=="/"&&t[0]!=="/"&&(e+="/"),t=e+t),r){var n=Ct(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var s=n.path.lastIndexOf("/");s>=0&&(n.path=n.path.substring(0,s+1))}t=je(ft(n),t)}return ce(t)}N.computeSourceURL=Ti});var Xe=lt($e=>{var le=Ut(),he=Object.prototype.hasOwnProperty,it=typeof Map<"u";function Q(){this._array=[],this._set=it?new Map:Object.create(null)}Q.fromArray=function(t,r){for(var n=new Q,s=0,o=t.length;s=0)return r}else{var n=le.toSetString(t);if(he.call(this._set,n))return this._set[n]}throw new Error('"'+t+'" is not in the set.')};Q.prototype.at=function(t){if(t>=0&&t{var Je=Ut();function vi(e,t){var r=e.generatedLine,n=t.generatedLine,s=e.generatedColumn,o=t.generatedColumn;return n>r||n==r&&o>=s||Je.compareByGeneratedPositionsInflated(e,t)<=0}function Wt(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}Wt.prototype.unsortedForEach=function(t,r){this._array.forEach(t,r)};Wt.prototype.add=function(t){vi(this._last,t)?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t))};Wt.prototype.toArray=function(){return this._sorted||(this._array.sort(Je.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};Ze.MappingList=Wt});var rr=lt(er=>{var yt=qe(),v=Ut(),Vt=Xe().ArraySet,Ei=tr().MappingList;function W(e){e||(e={}),this._file=v.getArg(e,"file",null),this._sourceRoot=v.getArg(e,"sourceRoot",null),this._skipValidation=v.getArg(e,"skipValidation",!1),this._sources=new Vt,this._names=new Vt,this._mappings=new Ei,this._sourcesContents=null}W.prototype._version=3;W.fromSourceMap=function(t){var r=t.sourceRoot,n=new W({file:t.file,sourceRoot:r});return t.eachMapping(function(s){var o={generated:{line:s.generatedLine,column:s.generatedColumn}};s.source!=null&&(o.source=s.source,r!=null&&(o.source=v.relative(r,o.source)),o.original={line:s.originalLine,column:s.originalColumn},s.name!=null&&(o.name=s.name)),n.addMapping(o)}),t.sources.forEach(function(s){var o=s;r!==null&&(o=v.relative(r,s)),n._sources.has(o)||n._sources.add(o);var a=t.sourceContentFor(s);a!=null&&n.setSourceContent(s,a)}),n};W.prototype.addMapping=function(t){var r=v.getArg(t,"generated"),n=v.getArg(t,"original",null),s=v.getArg(t,"source",null),o=v.getArg(t,"name",null);this._skipValidation||this._validateMapping(r,n,s,o),s!=null&&(s=String(s),this._sources.has(s)||this._sources.add(s)),o!=null&&(o=String(o),this._names.has(o)||this._names.add(o)),this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:s,name:o})};W.prototype.setSourceContent=function(t,r){var n=t;this._sourceRoot!=null&&(n=v.relative(this._sourceRoot,n)),r!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[v.toSetString(n)]=r):this._sourcesContents&&(delete this._sourcesContents[v.toSetString(n)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))};W.prototype.applySourceMap=function(t,r,n){var s=r;if(r==null){if(t.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);s=t.file}var o=this._sourceRoot;o!=null&&(s=v.relative(o,s));var a=new Vt,h=new Vt;this._mappings.unsortedForEach(function(l){if(l.source===s&&l.originalLine!=null){var i=t.originalPositionFor({line:l.originalLine,column:l.originalColumn});i.source!=null&&(l.source=i.source,n!=null&&(l.source=v.join(n,l.source)),o!=null&&(l.source=v.relative(o,l.source)),l.originalLine=i.line,l.originalColumn=i.column,i.name!=null&&(l.name=i.name))}var c=l.source;c!=null&&!a.has(c)&&a.add(c);var f=l.name;f!=null&&!h.has(f)&&h.add(f)},this),this._sources=a,this._names=h,t.sources.forEach(function(l){var i=t.sourceContentFor(l);i!=null&&(n!=null&&(l=v.join(n,l)),o!=null&&(l=v.relative(o,l)),this.setSourceContent(l,i))},this)};W.prototype._validateMapping=function(t,r,n,s){if(r&&typeof r.line!="number"&&typeof r.column!="number")throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!r&&!n&&!s)){if(t&&"line"in t&&"column"in t&&r&&"line"in r&&"column"in r&&t.line>0&&t.column>=0&&r.line>0&&r.column>=0&&n)return;throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:n,original:r,name:s}))}};W.prototype._serializeMappings=function(){for(var t=0,r=1,n=0,s=0,o=0,a=0,h="",l,i,c,f,k=this._mappings.toArray(),S=0,T=k.length;S0){if(!v.compareByGeneratedPositionsInflated(i,k[S-1]))continue;l+=","}l+=yt.encode(i.generatedColumn-t),t=i.generatedColumn,i.source!=null&&(f=this._sources.indexOf(i.source),l+=yt.encode(f-a),a=f,l+=yt.encode(i.originalLine-1-s),s=i.originalLine-1,l+=yt.encode(i.originalColumn-n),n=i.originalColumn,i.name!=null&&(c=this._names.indexOf(i.name),l+=yt.encode(c-o),o=c)),h+=l}return h};W.prototype._generateSourcesContent=function(t,r){return t.map(function(n){if(!this._sourcesContents)return null;r!=null&&(n=v.relative(r,n));var s=v.toSetString(n);return Object.prototype.hasOwnProperty.call(this._sourcesContents,s)?this._sourcesContents[s]:null},this)};W.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(t.file=this._file),this._sourceRoot!=null&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t};W.prototype.toString=function(){return JSON.stringify(this.toJSON())};er.SourceMapGenerator=W});var gs={};vt(gs,{default:()=>Ie});function I(e){return e>=48&&e<=57}function z(e){return I(e)||e>=65&&e<=70||e>=97&&e<=102}function wt(e){return e>=65&&e<=90}function ei(e){return e>=97&&e<=122}function ri(e){return wt(e)||ei(e)}function ni(e){return e>=128}function Et(e){return ri(e)||ni(e)||e===95}function At(e){return Et(e)||I(e)||e===45}function ii(e){return e>=0&&e<=8||e===11||e>=14&&e<=31||e===127}function dt(e){return e===10||e===13||e===12}function $(e){return dt(e)||e===32||e===9}function R(e,t){return!(e!==92||dt(t)||t===0)}function Nt(e,t,r){return e===45?Et(t)||t===45||R(t,r):Et(e)?!0:e===92?R(e,t):!1}function It(e,t,r){return e===43||e===45?I(t)?2:t===46&&I(r)?3:0:e===46?I(t)?2:0:I(e)?1:0}function Dt(e){return e===65279||e===65534?1:0}var Xt=new Array(128),si=128,xt=130,Jt=131,Pt=132,Zt=133;for(let e=0;ee.length)return!1;for(let s=t;s=0&&$(e.charCodeAt(t));t--);return t+1}function kt(e,t){for(;t=55296&&t<=57343||t>1114111)&&(t=65533),String.fromCodePoint(t)}var gt=["EOF-token","ident-token","function-token","at-keyword-token","hash-token","string-token","bad-string-token","url-token","bad-url-token","delim-token","number-token","percentage-token","dimension-token","whitespace-token","CDO-token","CDC-token","colon-token","semicolon-token","comma-token","[-token","]-token","(-token",")-token","{-token","}-token","comment-token"];function ut(e=null,t){return e===null||e.length0?Dt(t.charCodeAt(0)):0,s=ut(e.lines,r),o=ut(e.columns,r),a=e.startLine,h=e.startColumn;for(let l=n;l{}){t=String(t||"");let n=t.length,s=ut(this.offsetAndType,t.length+1),o=ut(this.balance,t.length+1),a=0,h=0,l=0,i=-1;for(this.offsetAndType=null,this.balance=null,r(t,(c,f,k)=>{switch(c){default:o[a]=n;break;case h:{let S=l&M;for(l=o[S],h=l>>V,o[a]=S,o[S++]=a;S>V:0}lookupTypeNonSC(t){for(let r=this.tokenIndex;r>V;if(n!==13&&n!==25&&t--===0)return n}return 0}lookupOffset(t){return t+=this.tokenIndex,t>V;if(n!==13&&n!==25&&t--===0)return r-this.tokenIndex}return 0}lookupValue(t,r){return t+=this.tokenIndex,t0?t>V,this.tokenEnd=r&M):(this.tokenIndex=this.tokenCount,this.next())}next(){let t=this.tokenIndex+1;t>V,this.tokenEnd=t&M):(this.eof=!0,this.tokenIndex=this.tokenCount,this.tokenType=0,this.tokenStart=this.tokenEnd=this.source.length)}skipSC(){for(;this.tokenType===13||this.tokenType===25;)this.next()}skipUntilBalanced(t,r){let n=t,s,o;t:for(;n0?this.offsetAndType[n-1]&M:this.firstCharOffset,r(this.source.charCodeAt(o))){case 1:break t;case 2:n++;break t;default:this.balance[s]===n&&(n=s)}}this.skip(n-this.tokenIndex)}forEachToken(t){for(let r=0,n=this.firstCharOffset;r>V;n=a,t(h,s,a,r)}}dump(){let t=new Array(this.tokenCount);return this.forEachToken((r,n,s,o)=>{t[o]={idx:o,type:gt[r],chunk:this.source.substring(n,s),balance:this.balance[o]}}),t}};function Bt(e,t){function r(f){return f=e.length){ife,spec:()=>Ii});var wi=43,Ai=45,ue=(e,t)=>{if(e===9&&(e=t),typeof e=="string"){let r=e.charCodeAt(0);return r>127?32768:r<<8}return e},or=[[1,1],[1,2],[1,7],[1,8],[1,"-"],[1,10],[1,11],[1,12],[1,15],[1,21],[3,1],[3,2],[3,7],[3,8],[3,"-"],[3,10],[3,11],[3,12],[3,15],[4,1],[4,2],[4,7],[4,8],[4,"-"],[4,10],[4,11],[4,12],[4,15],[12,1],[12,2],[12,7],[12,8],[12,"-"],[12,10],[12,11],[12,12],[12,15],["#",1],["#",2],["#",7],["#",8],["#","-"],["#",10],["#",11],["#",12],["#",15],["-",1],["-",2],["-",7],["-",8],["-","-"],["-",10],["-",11],["-",12],["-",15],[10,1],[10,2],[10,7],[10,8],[10,10],[10,11],[10,12],[10,"%"],[10,15],["@",1],["@",2],["@",7],["@",8],["@","-"],["@",15],[".",10],[".",11],[".",12],["+",10],["+",11],["+",12],["/","*"]],Ni=or.concat([[1,4],[12,4],[4,4],[3,21],[3,5],[3,16],[11,11],[11,12],[11,2],[11,"-"],[22,1],[22,2],[22,11],[22,12],[22,4],[22,"-"]]);function ar(e){let t=new Set(e.map(([r,n])=>ue(r)<<16|ue(n)));return function(r,n,s){let o=ue(n,s),a=s.charCodeAt(0);return(a===Ai&&n!==1&&n!==2&&n!==15||a===wi?t.has(r<<16|a<<8):t.has(r<<16|o))&&this.emit(" ",13,!0),o}}var Ii=ar(or),fe=ar(Ni);var Di=92;function Pi(e,t){if(typeof t=="function"){let r=null;e.children.forEach(n=>{r!==null&&t.call(this,r),this.node(n),r=n});return}e.children.forEach(this.node,this)}function Fi(e){Bt(e,(t,r,n)=>{this.token(t,e.slice(r,n))})}function cr(e){let t=new Map;for(let[r,n]of Object.entries(e.node))typeof(n.generate||n)=="function"&&t.set(r,n.generate||n);return function(r,n){let s="",o=0,a={node(l){if(t.has(l.type))t.get(l.type).call(h,l);else throw new Error("Unknown node type: "+l.type)},tokenBefore:fe,token(l,i){o=this.tokenBefore(o,l,i),this.emit(i,l,!1),l===9&&i.charCodeAt(0)===Di&&this.emit(` +`,13,!0)},emit(l){s+=l},result(){return s}};n&&(typeof n.decorator=="function"&&(a=n.decorator(a)),n.sourceMap&&(a=sr(a)),n.mode in Ht&&(a.tokenBefore=Ht[n.mode]));let h={node:l=>a.node(l),children:Pi,token:(l,i)=>a.token(l,i),tokenize:Fi};return a.node(r),a.result()}}var Se={};vt(Se,{AnPlusB:()=>hr,Atrule:()=>ur,AtrulePrelude:()=>fr,AttributeSelector:()=>dr,Block:()=>xr,Brackets:()=>kr,CDC:()=>Sr,CDO:()=>gr,ClassSelector:()=>yr,Combinator:()=>Tr,Comment:()=>vr,Condition:()=>Er,Declaration:()=>wr,DeclarationList:()=>Ar,Dimension:()=>Nr,Feature:()=>Ir,FeatureFunction:()=>Dr,FeatureRange:()=>Pr,Function:()=>Fr,GeneralEnclosed:()=>Rr,Hash:()=>Or,IdSelector:()=>Ur,Identifier:()=>Mr,Layer:()=>Wr,LayerList:()=>Vr,MediaQuery:()=>Hr,MediaQueryList:()=>Gr,NestingSelector:()=>Yr,Nth:()=>zr,Number:()=>Kr,Operator:()=>$r,Parentheses:()=>Xr,Percentage:()=>Zr,PseudoClassSelector:()=>en,PseudoElementSelector:()=>nn,Ratio:()=>sn,Raw:()=>an,Rule:()=>cn,Scope:()=>ln,Selector:()=>un,SelectorList:()=>pn,String:()=>Sn,StyleSheet:()=>gn,SupportsDeclaration:()=>Cn,TypeSelector:()=>Ln,UnicodeRange:()=>Tn,Url:()=>En,Value:()=>wn,WhiteSpace:()=>An});var Y=43,_=45,Gt=110,st=!0,Ri=!1;function qt(e,t){let r=this.tokenStart+e,n=this.charCodeAt(r);for((n===Y||n===_)&&(t&&this.error("Number sign is not allowed"),r++);r0&&this.skip(e),t===0&&(r=this.charCodeAt(this.tokenStart),r!==Y&&r!==_&&this.error("Number sign is expected")),pt.call(this,t!==0),t===_?"-"+this.consume(10):this.consume(10)}function lr(){let e=this.tokenStart,t=null,r=null;if(this.tokenType===10)pt.call(this,Ri),r=this.consume(10);else if(this.tokenType===1&&this.cmpChar(this.tokenStart,_))switch(t="-1",Z.call(this,1,Gt),this.tokenEnd-this.tokenStart){case 2:this.next(),r=pe.call(this);break;case 3:Z.call(this,2,_),this.next(),this.skipSC(),pt.call(this,st),r="-"+this.consume(10);break;default:Z.call(this,2,_),qt.call(this,3,st),this.next(),r=this.substrToCursor(e+2)}else if(this.tokenType===1||this.isDelim(Y)&&this.lookupType(1)===1){let n=0;switch(t="1",this.isDelim(Y)&&(n=1,this.next()),Z.call(this,0,Gt),this.tokenEnd-this.tokenStart){case 1:this.next(),r=pe.call(this);break;case 2:Z.call(this,1,_),this.next(),this.skipSC(),pt.call(this,st),r="-"+this.consume(10);break;default:Z.call(this,1,_),qt.call(this,2,st),this.next(),r=this.substrToCursor(e+n+1)}}else if(this.tokenType===12){let n=this.charCodeAt(this.tokenStart),s=n===Y||n===_,o=this.tokenStart+s;for(;o{t.type==="Declaration"&&this.token(17,";")})}function kr(e){this.token(9,"["),this.children(e),this.token(9,"]")}function Sr(){this.token(15,"-->")}function gr(){this.token(14,"\n\n return {\n type: 'CDC',\n loc: this.getLocation(start, this.tokenStart)\n };\n}\n\nexport function generate() {\n this.token(CDC, '-->');\n}\n", "import { CDO } from '../../tokenizer/index.js';\n\nexport const name = 'CDO';\nexport const structure = [];\n\nexport function parse() {\n const start = this.tokenStart;\n\n this.eat(CDO); // \n child = this.CDC();\n break;\n\n // CSS Syntax Module Level 3\n // \u00A72.2 Error handling\n // At the \"top level\" of a stylesheet, an starts an at-rule.\n case AtKeyword:\n child = this.parseWithFallback(this.Atrule, consumeRaw);\n break;\n\n // Anything else starts a qualified rule ...\n default:\n child = this.parseWithFallback(this.Rule, consumeRaw);\n }\n\n children.push(child);\n }\n\n return {\n type: 'StyleSheet',\n loc: this.getLocation(start, this.tokenStart),\n children\n };\n}\n\nexport function generate(node) {\n this.children(node);\n}\n", "import {\n LeftParenthesis,\n RightParenthesis\n} from '../../tokenizer/index.js';\n\nexport const name = 'SupportsDeclaration';\nexport const structure = {\n declaration: 'Declaration'\n};\n\nexport function parse() {\n const start = this.tokenStart;\n\n this.eat(LeftParenthesis);\n this.skipSC();\n\n const declaration = this.Declaration();\n\n if (!this.eof) {\n this.eat(RightParenthesis);\n }\n\n return {\n type: 'SupportsDeclaration',\n loc: this.getLocation(start, this.tokenStart),\n declaration\n };\n}\n\nexport function generate(node) {\n this.token(LeftParenthesis, '(');\n this.node(node.declaration);\n this.token(RightParenthesis, ')');\n}\n", "import { Ident } from '../../tokenizer/index.js';\n\nconst ASTERISK = 0x002A; // U+002A ASTERISK (*)\nconst VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)\n\nfunction eatIdentifierOrAsterisk() {\n if (this.tokenType !== Ident &&\n this.isDelim(ASTERISK) === false) {\n this.error('Identifier or asterisk is expected');\n }\n\n this.next();\n}\n\nexport const name = 'TypeSelector';\nexport const structure = {\n name: String\n};\n\n// ident\n// ident|ident\n// ident|*\n// *\n// *|ident\n// *|*\n// |ident\n// |*\nexport function parse() {\n const start = this.tokenStart;\n\n if (this.isDelim(VERTICALLINE)) {\n this.next();\n eatIdentifierOrAsterisk.call(this);\n } else {\n eatIdentifierOrAsterisk.call(this);\n\n if (this.isDelim(VERTICALLINE)) {\n this.next();\n eatIdentifierOrAsterisk.call(this);\n }\n }\n\n return {\n type: 'TypeSelector',\n loc: this.getLocation(start, this.tokenStart),\n name: this.substrToCursor(start)\n };\n}\n\nexport function generate(node) {\n this.tokenize(node.name);\n}\n", "import {\n isHexDigit,\n Ident,\n Number,\n Dimension\n} from '../../tokenizer/index.js';\n\nconst PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)\nconst HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)\nconst QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)\n\nfunction eatHexSequence(offset, allowDash) {\n let len = 0;\n\n for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) {\n const code = this.charCodeAt(pos);\n\n if (code === HYPHENMINUS && allowDash && len !== 0) {\n eatHexSequence.call(this, offset + len + 1, false);\n return -1;\n }\n\n if (!isHexDigit(code)) {\n this.error(\n allowDash && len !== 0\n ? 'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected'\n : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),\n pos\n );\n }\n\n if (++len > 6) {\n this.error('Too many hex digits', pos);\n };\n }\n\n this.next();\n return len;\n}\n\nfunction eatQuestionMarkSequence(max) {\n let count = 0;\n\n while (this.isDelim(QUESTIONMARK)) {\n if (++count > max) {\n this.error('Too many question marks');\n }\n\n this.next();\n }\n}\n\nfunction startsWith(code) {\n if (this.charCodeAt(this.tokenStart) !== code) {\n this.error((code === PLUSSIGN ? 'Plus sign' : 'Hyphen minus') + ' is expected');\n }\n}\n\n// https://drafts.csswg.org/css-syntax/#urange\n// Informally, the production has three forms:\n// U+0001\n// Defines a range consisting of a single code point, in this case the code point \"1\".\n// U+0001-00ff\n// Defines a range of codepoints between the first and the second value, in this case\n// the range between \"1\" and \"ff\" (255 in decimal) inclusive.\n// U+00??\n// Defines a range of codepoints where the \"?\" characters range over all hex digits,\n// in this case defining the same as the value U+0000-00ff.\n// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat \"?\" as a hexadecimal digit).\n//\n// =\n// u '+' '?'* |\n// u '?'* |\n// u '?'* |\n// u |\n// u |\n// u '+' '?'+\nfunction scanUnicodeRange() {\n let hexLength = 0;\n\n switch (this.tokenType) {\n case Number:\n // u '?'*\n // u \n // u \n hexLength = eatHexSequence.call(this, 1, true);\n\n if (this.isDelim(QUESTIONMARK)) {\n eatQuestionMarkSequence.call(this, 6 - hexLength);\n break;\n }\n\n if (this.tokenType === Dimension ||\n this.tokenType === Number) {\n startsWith.call(this, HYPHENMINUS);\n eatHexSequence.call(this, 1, false);\n break;\n }\n\n break;\n\n case Dimension:\n // u '?'*\n hexLength = eatHexSequence.call(this, 1, true);\n\n if (hexLength > 0) {\n eatQuestionMarkSequence.call(this, 6 - hexLength);\n }\n\n break;\n\n default:\n // u '+' '?'*\n // u '+' '?'+\n this.eatDelim(PLUSSIGN);\n\n if (this.tokenType === Ident) {\n hexLength = eatHexSequence.call(this, 0, true);\n if (hexLength > 0) {\n eatQuestionMarkSequence.call(this, 6 - hexLength);\n }\n break;\n }\n\n if (this.isDelim(QUESTIONMARK)) {\n this.next();\n eatQuestionMarkSequence.call(this, 5);\n break;\n }\n\n this.error('Hex digit or question mark is expected');\n }\n}\n\nexport const name = 'UnicodeRange';\nexport const structure = {\n value: String\n};\n\nexport function parse() {\n const start = this.tokenStart;\n\n // U or u\n this.eatIdent('u');\n scanUnicodeRange.call(this);\n\n return {\n type: 'UnicodeRange',\n loc: this.getLocation(start, this.tokenStart),\n value: this.substrToCursor(start)\n };\n}\n\nexport function generate(node) {\n this.tokenize(node.value);\n}\n", "import {\n isHexDigit,\n isWhiteSpace,\n isValidEscape,\n consumeEscaped,\n decodeEscaped\n} from '../tokenizer/index.js';\n\nconst SPACE = 0x0020; // U+0020 SPACE\nconst REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\\)\nconst QUOTATION_MARK = 0x0022; // \"\nconst APOSTROPHE = 0x0027; // '\nconst LEFTPARENTHESIS = 0x0028; // U+0028 LEFT PARENTHESIS (()\nconst RIGHTPARENTHESIS = 0x0029; // U+0029 RIGHT PARENTHESIS ())\n\nexport function decode(str) {\n const len = str.length;\n let start = 4; // length of \"url(\"\n let end = str.charCodeAt(len - 1) === RIGHTPARENTHESIS ? len - 2 : len - 1;\n let decoded = '';\n\n while (start < end && isWhiteSpace(str.charCodeAt(start))) {\n start++;\n }\n\n while (start < end && isWhiteSpace(str.charCodeAt(end))) {\n end--;\n }\n\n for (let i = start; i <= end; i++) {\n let code = str.charCodeAt(i);\n\n if (code === REVERSE_SOLIDUS) {\n // special case at the ending\n if (i === end) {\n // if the next input code point is EOF, do nothing\n // otherwise include last left parenthesis as escaped\n if (i !== len - 1) {\n decoded = str.substr(i + 1);\n }\n break;\n }\n\n code = str.charCodeAt(++i);\n\n // consume escaped\n if (isValidEscape(REVERSE_SOLIDUS, code)) {\n const escapeStart = i - 1;\n const escapeEnd = consumeEscaped(str, escapeStart);\n\n i = escapeEnd - 1;\n decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));\n } else {\n // \\r\\n\n if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {\n i++;\n }\n }\n } else {\n decoded += str[i];\n }\n }\n\n return decoded;\n}\n\nexport function encode(str) {\n let encoded = '';\n let wsBeforeHexIsNeeded = false;\n\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n\n // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).\n if (code === 0x0000) {\n encoded += '\\uFFFD';\n continue;\n }\n\n // If the character is in the range [\\1-\\1f] (U+0001 to U+001F) or is U+007F,\n // the character escaped as code point.\n // Note: Do not compare with 0x0001 since 0x0000 is precessed before\n if (code <= 0x001f || code === 0x007F) {\n encoded += '\\\\' + code.toString(16);\n wsBeforeHexIsNeeded = true;\n continue;\n }\n\n if (code === SPACE ||\n code === REVERSE_SOLIDUS ||\n code === QUOTATION_MARK ||\n code === APOSTROPHE ||\n code === LEFTPARENTHESIS ||\n code === RIGHTPARENTHESIS) {\n encoded += '\\\\' + str.charAt(i);\n wsBeforeHexIsNeeded = false;\n } else {\n if (wsBeforeHexIsNeeded && isHexDigit(code)) {\n encoded += ' ';\n }\n\n encoded += str.charAt(i);\n wsBeforeHexIsNeeded = false;\n }\n }\n\n return 'url(' + encoded + ')';\n}\n", "import * as url from '../../utils/url.js';\nimport * as string from '../../utils/string.js';\nimport {\n Function as FunctionToken,\n String as StringToken,\n Url,\n RightParenthesis\n} from '../../tokenizer/index.js';\n\nexport const name = 'Url';\nexport const structure = {\n value: String\n};\n\n// | )\nexport function parse() {\n const start = this.tokenStart;\n let value;\n\n switch (this.tokenType) {\n case Url:\n value = url.decode(this.consume(Url));\n break;\n\n case FunctionToken:\n if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) {\n this.error('Function name must be `url`');\n }\n\n this.eat(FunctionToken);\n this.skipSC();\n value = string.decode(this.consume(StringToken));\n this.skipSC();\n if (!this.eof) {\n this.eat(RightParenthesis);\n }\n break;\n\n default:\n this.error('Url or Function is expected');\n }\n\n return {\n type: 'Url',\n loc: this.getLocation(start, this.tokenStart),\n value\n };\n}\n\nexport function generate(node) {\n this.token(Url, url.encode(node.value));\n}\n", "export const name = 'Value';\nexport const structure = {\n children: [[]]\n};\n\nexport function parse() {\n const start = this.tokenStart;\n const children = this.readSequence(this.scope.Value);\n\n return {\n type: 'Value',\n loc: this.getLocation(start, this.tokenStart),\n children\n };\n}\n\nexport function generate(node) {\n this.children(node);\n}\n", "import { WhiteSpace } from '../../tokenizer/index.js';\n\nconst SPACE = Object.freeze({\n type: 'WhiteSpace',\n loc: null,\n value: ' '\n});\n\nexport const name = 'WhiteSpace';\nexport const structure = {\n value: String\n};\n\nexport function parse() {\n this.eat(WhiteSpace);\n return SPACE;\n\n // return {\n // type: 'WhiteSpace',\n // loc: this.getLocation(this.tokenStart, this.tokenEnd),\n // value: this.consume(WHITESPACE)\n // };\n}\n\nexport function generate(node) {\n this.token(WhiteSpace, node.value);\n}\n", "import * as node from '../node/index-generate.js';\n\nexport default {\n node\n};\n", "import { createGenerator } from './create.js';\nimport config from '../syntax/config/generator.js';\n\nexport default createGenerator(config);\n", "//\n// list\n// \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500head \u2502\n// \u2502 \u2502 tail\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n// \u25BC \u25BC\n// item item item item\n// \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// null \u25C0\u2500\u2500\u253C\u2500prev \u2502\u25C0\u2500\u2500\u2500\u253C\u2500prev \u2502\u25C0\u2500\u2500\u2500\u253C\u2500prev \u2502\u25C0\u2500\u2500\u2500\u253C\u2500prev \u2502\n// \u2502 next\u2500\u253C\u2500\u2500\u2500\u25B6\u2502 next\u2500\u253C\u2500\u2500\u2500\u25B6\u2502 next\u2500\u253C\u2500\u2500\u2500\u25B6\u2502 next\u2500\u253C\u2500\u2500\u25B6 null\n// \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n// \u2502 data \u2502 \u2502 data \u2502 \u2502 data \u2502 \u2502 data \u2502\n// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n//\n\nlet releasedCursors = null;\n\nexport class List {\n static createItem(data) {\n return {\n prev: null,\n next: null,\n data\n };\n }\n\n constructor() {\n this.head = null;\n this.tail = null;\n this.cursor = null;\n }\n createItem(data) {\n return List.createItem(data);\n }\n\n // cursor helpers\n allocateCursor(prev, next) {\n let cursor;\n\n if (releasedCursors !== null) {\n cursor = releasedCursors;\n releasedCursors = releasedCursors.cursor;\n cursor.prev = prev;\n cursor.next = next;\n cursor.cursor = this.cursor;\n } else {\n cursor = {\n prev,\n next,\n cursor: this.cursor\n };\n }\n\n this.cursor = cursor;\n\n return cursor;\n }\n releaseCursor() {\n const { cursor } = this;\n\n this.cursor = cursor.cursor;\n cursor.prev = null;\n cursor.next = null;\n cursor.cursor = releasedCursors;\n releasedCursors = cursor;\n }\n updateCursors(prevOld, prevNew, nextOld, nextNew) {\n let { cursor } = this;\n\n while (cursor !== null) {\n if (cursor.prev === prevOld) {\n cursor.prev = prevNew;\n }\n\n if (cursor.next === nextOld) {\n cursor.next = nextNew;\n }\n\n cursor = cursor.cursor;\n }\n }\n *[Symbol.iterator]() {\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n yield cursor.data;\n }\n }\n\n // getters\n get size() {\n let size = 0;\n\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n size++;\n }\n\n return size;\n }\n get isEmpty() {\n return this.head === null;\n }\n get first() {\n return this.head && this.head.data;\n }\n get last() {\n return this.tail && this.tail.data;\n }\n\n // convertors\n fromArray(array) {\n let cursor = null;\n this.head = null;\n\n for (let data of array) {\n const item = List.createItem(data);\n\n if (cursor !== null) {\n cursor.next = item;\n } else {\n this.head = item;\n }\n\n item.prev = cursor;\n cursor = item;\n }\n\n this.tail = cursor;\n return this;\n }\n toArray() {\n return [...this];\n }\n toJSON() {\n return [...this];\n }\n\n // array-like methods\n forEach(fn, thisArg = this) {\n // push cursor\n const cursor = this.allocateCursor(null, this.head);\n\n while (cursor.next !== null) {\n const item = cursor.next;\n cursor.next = item.next;\n fn.call(thisArg, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n }\n forEachRight(fn, thisArg = this) {\n // push cursor\n const cursor = this.allocateCursor(this.tail, null);\n\n while (cursor.prev !== null) {\n const item = cursor.prev;\n cursor.prev = item.prev;\n fn.call(thisArg, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n }\n reduce(fn, initialValue, thisArg = this) {\n // push cursor\n let cursor = this.allocateCursor(null, this.head);\n let acc = initialValue;\n let item;\n\n while (cursor.next !== null) {\n item = cursor.next;\n cursor.next = item.next;\n\n acc = fn.call(thisArg, acc, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n\n return acc;\n }\n reduceRight(fn, initialValue, thisArg = this) {\n // push cursor\n let cursor = this.allocateCursor(this.tail, null);\n let acc = initialValue;\n let item;\n\n while (cursor.prev !== null) {\n item = cursor.prev;\n cursor.prev = item.prev;\n\n acc = fn.call(thisArg, acc, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n\n return acc;\n }\n some(fn, thisArg = this) {\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n if (fn.call(thisArg, cursor.data, cursor, this)) {\n return true;\n }\n }\n\n return false;\n }\n map(fn, thisArg = this) {\n const result = new List();\n\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n result.appendData(fn.call(thisArg, cursor.data, cursor, this));\n }\n\n return result;\n }\n filter(fn, thisArg = this) {\n const result = new List();\n\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n if (fn.call(thisArg, cursor.data, cursor, this)) {\n result.appendData(cursor.data);\n }\n }\n\n return result;\n }\n\n nextUntil(start, fn, thisArg = this) {\n if (start === null) {\n return;\n }\n\n // push cursor\n const cursor = this.allocateCursor(null, start);\n\n while (cursor.next !== null) {\n const item = cursor.next;\n cursor.next = item.next;\n if (fn.call(thisArg, item.data, item, this)) {\n break;\n }\n }\n\n // pop cursor\n this.releaseCursor();\n }\n prevUntil(start, fn, thisArg = this) {\n if (start === null) {\n return;\n }\n\n // push cursor\n const cursor = this.allocateCursor(start, null);\n\n while (cursor.prev !== null) {\n const item = cursor.prev;\n cursor.prev = item.prev;\n if (fn.call(thisArg, item.data, item, this)) {\n break;\n }\n }\n\n // pop cursor\n this.releaseCursor();\n }\n\n // mutation\n clear() {\n this.head = null;\n this.tail = null;\n }\n copy() {\n const result = new List();\n\n for (let data of this) {\n result.appendData(data);\n }\n\n return result;\n }\n prepend(item) {\n // head\n // ^\n // item\n this.updateCursors(null, item, this.head, item);\n\n // insert to the beginning of the list\n if (this.head !== null) {\n // new item <- first item\n this.head.prev = item;\n // new item -> first item\n item.next = this.head;\n } else {\n // if list has no head, then it also has no tail\n // in this case tail points to the new item\n this.tail = item;\n }\n\n // head always points to new item\n this.head = item;\n return this;\n }\n prependData(data) {\n return this.prepend(List.createItem(data));\n }\n append(item) {\n return this.insert(item);\n }\n appendData(data) {\n return this.insert(List.createItem(data));\n }\n insert(item, before = null) {\n if (before !== null) {\n // prev before\n // ^\n // item\n this.updateCursors(before.prev, item, before, item);\n\n if (before.prev === null) {\n // insert to the beginning of list\n if (this.head !== before) {\n throw new Error('before doesn\\'t belong to list');\n }\n // since head points to before therefore list doesn't empty\n // no need to check tail\n this.head = item;\n before.prev = item;\n item.next = before;\n this.updateCursors(null, item);\n } else {\n // insert between two items\n before.prev.next = item;\n item.prev = before.prev;\n before.prev = item;\n item.next = before;\n }\n } else {\n // tail\n // ^\n // item\n this.updateCursors(this.tail, item, null, item);\n\n // insert to the ending of the list\n if (this.tail !== null) {\n // last item -> new item\n this.tail.next = item;\n // last item <- new item\n item.prev = this.tail;\n } else {\n // if list has no tail, then it also has no head\n // in this case head points to new item\n this.head = item;\n }\n\n // tail always points to new item\n this.tail = item;\n }\n\n return this;\n }\n insertData(data, before) {\n return this.insert(List.createItem(data), before);\n }\n remove(item) {\n // item\n // ^\n // prev next\n this.updateCursors(item, item.prev, item, item.next);\n\n if (item.prev !== null) {\n item.prev.next = item.next;\n } else {\n if (this.head !== item) {\n throw new Error('item doesn\\'t belong to list');\n }\n\n this.head = item.next;\n }\n\n if (item.next !== null) {\n item.next.prev = item.prev;\n } else {\n if (this.tail !== item) {\n throw new Error('item doesn\\'t belong to list');\n }\n\n this.tail = item.prev;\n }\n\n item.prev = null;\n item.next = null;\n\n return item;\n }\n push(data) {\n this.insert(List.createItem(data));\n }\n pop() {\n return this.tail !== null ? this.remove(this.tail) : null;\n }\n unshift(data) {\n this.prepend(List.createItem(data));\n }\n shift() {\n return this.head !== null ? this.remove(this.head) : null;\n }\n prependList(list) {\n return this.insertList(list, this.head);\n }\n appendList(list) {\n return this.insertList(list);\n }\n insertList(list, before) {\n // ignore empty lists\n if (list.head === null) {\n return this;\n }\n\n if (before !== undefined && before !== null) {\n this.updateCursors(before.prev, list.tail, before, list.head);\n\n // insert in the middle of dist list\n if (before.prev !== null) {\n // before.prev <-> list.head\n before.prev.next = list.head;\n list.head.prev = before.prev;\n } else {\n this.head = list.head;\n }\n\n before.prev = list.tail;\n list.tail.next = before;\n } else {\n this.updateCursors(this.tail, list.tail, null, list.head);\n\n // insert to end of the list\n if (this.tail !== null) {\n // if destination list has a tail, then it also has a head,\n // but head doesn't change\n // dest tail -> source head\n this.tail.next = list.head;\n // dest tail <- source head\n list.head.prev = this.tail;\n } else {\n // if list has no a tail, then it also has no a head\n // in this case points head to new item\n this.head = list.head;\n }\n\n // tail always start point to new item\n this.tail = list.tail;\n }\n\n list.head = null;\n list.tail = null;\n return this;\n }\n replace(oldItem, newItemOrList) {\n if ('head' in newItemOrList) {\n this.insertList(newItemOrList, oldItem);\n } else {\n this.insert(newItemOrList, oldItem);\n }\n\n this.remove(oldItem);\n }\n}\n", "export function createCustomError(name, message) {\n // use Object.create(), because some VMs prevent setting line/column otherwise\n // (iOS Safari 10 even throws an exception)\n const error = Object.create(SyntaxError.prototype);\n const errorStack = new Error();\n\n return Object.assign(error, {\n name,\n message,\n get stack() {\n return (errorStack.stack || '').replace(/^(.+\\n){1,3}/, `${name}: ${message}\\n`);\n }\n });\n};\n", "import { createCustomError } from '../utils/create-custom-error.js';\n\nconst MAX_LINE_LENGTH = 100;\nconst OFFSET_CORRECTION = 60;\nconst TAB_REPLACEMENT = ' ';\n\nfunction sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) {\n function processLines(start, end) {\n return lines\n .slice(start, end)\n .map((line, idx) =>\n String(start + idx + 1).padStart(maxNumLength) + ' |' + line\n ).join('\\n');\n }\n\n const prelines = '\\n'.repeat(Math.max(baseLine - 1, 0));\n const precolumns = ' '.repeat(Math.max(baseColumn - 1, 0));\n const lines = (prelines + precolumns + source).split(/\\r\\n?|\\n|\\f/);\n const startLine = Math.max(1, line - extraLines) - 1;\n const endLine = Math.min(line + extraLines, lines.length + 1);\n const maxNumLength = Math.max(4, String(endLine).length) + 1;\n let cutLeft = 0;\n\n // column correction according to replaced tab before column\n column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\\t/g) || []).length;\n\n if (column > MAX_LINE_LENGTH) {\n cutLeft = column - OFFSET_CORRECTION + 3;\n column = OFFSET_CORRECTION - 2;\n }\n\n for (let i = startLine; i <= endLine; i++) {\n if (i >= 0 && i < lines.length) {\n lines[i] = lines[i].replace(/\\t/g, TAB_REPLACEMENT);\n lines[i] =\n (cutLeft > 0 && lines[i].length > cutLeft ? '\\u2026' : '') +\n lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +\n (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\\u2026' : '');\n }\n }\n\n return [\n processLines(startLine, line),\n new Array(column + maxNumLength + 2).join('-') + '^',\n processLines(line, endLine)\n ].filter(Boolean)\n .join('\\n')\n .replace(/^(\\s+\\d+\\s+\\|\\n)+/, '')\n .replace(/\\n(\\s+\\d+\\s+\\|)+$/, '');\n}\n\nexport function SyntaxError(message, source, offset, line, column, baseLine = 1, baseColumn = 1) {\n const error = Object.assign(createCustomError('SyntaxError', message), {\n source,\n offset,\n line,\n column,\n sourceFragment(extraLines) {\n return sourceFragment({ source, line, column, baseLine, baseColumn }, isNaN(extraLines) ? 0 : extraLines);\n },\n get formattedMessage() {\n return (\n `Parse error: ${message}\\n` +\n sourceFragment({ source, line, column, baseLine, baseColumn }, 2)\n );\n }\n });\n\n return error;\n}\n", "import { WhiteSpace, Comment } from '../tokenizer/index.js';\n\nexport function readSequence(recognizer) {\n const children = this.createList();\n let space = false;\n const context = {\n recognizer\n };\n\n while (!this.eof) {\n switch (this.tokenType) {\n case Comment:\n this.next();\n continue;\n\n case WhiteSpace:\n space = true;\n this.next();\n continue;\n }\n\n let child = recognizer.getNode.call(this, context);\n\n if (child === undefined) {\n break;\n }\n\n if (space) {\n if (recognizer.onWhiteSpace) {\n recognizer.onWhiteSpace.call(this, child, children, context);\n }\n space = false;\n }\n\n children.push(child);\n }\n\n if (space && recognizer.onWhiteSpace) {\n recognizer.onWhiteSpace.call(this, null, children, context);\n }\n\n return children;\n};\n", "import { List } from '../utils/List.js';\nimport { SyntaxError } from './SyntaxError.js';\nimport {\n tokenize,\n OffsetToLocation,\n TokenStream,\n tokenNames,\n\n consumeNumber,\n findWhiteSpaceStart,\n cmpChar,\n cmpStr,\n\n WhiteSpace,\n Comment,\n Ident,\n Function as FunctionToken,\n Url,\n Hash,\n Percentage,\n Number as NumberToken\n} from '../tokenizer/index.js';\nimport { readSequence } from './sequence.js';\n\nconst NOOP = () => {};\nconst EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)\nconst NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)\nconst SEMICOLON = 0x003B; // U+003B SEMICOLON (;)\nconst LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({)\nconst NULL = 0;\n\nfunction createParseContext(name) {\n return function() {\n return this[name]();\n };\n}\n\nfunction fetchParseValues(dict) {\n const result = Object.create(null);\n\n for (const name of Object.keys(dict)) {\n const item = dict[name];\n const fn = item.parse || item;\n\n if (fn) {\n result[name] = fn;\n }\n }\n\n return result;\n}\n\nfunction processConfig(config) {\n const parseConfig = {\n context: Object.create(null),\n features: Object.assign(Object.create(null), config.features),\n scope: Object.assign(Object.create(null), config.scope),\n atrule: fetchParseValues(config.atrule),\n pseudo: fetchParseValues(config.pseudo),\n node: fetchParseValues(config.node)\n };\n\n for (const [name, context] of Object.entries(config.parseContext)) {\n switch (typeof context) {\n case 'function':\n parseConfig.context[name] = context;\n break;\n\n case 'string':\n parseConfig.context[name] = createParseContext(context);\n break;\n }\n }\n\n return {\n config: parseConfig,\n ...parseConfig,\n ...parseConfig.node\n };\n}\n\nexport function createParser(config) {\n let source = '';\n let filename = '';\n let needPositions = false;\n let onParseError = NOOP;\n let onParseErrorThrow = false;\n\n const locationMap = new OffsetToLocation();\n const parser = Object.assign(new TokenStream(), processConfig(config || {}), {\n parseAtrulePrelude: true,\n parseRulePrelude: true,\n parseValue: true,\n parseCustomProperty: false,\n\n readSequence,\n\n consumeUntilBalanceEnd: () => 0,\n consumeUntilLeftCurlyBracket(code) {\n return code === LEFTCURLYBRACKET ? 1 : 0;\n },\n consumeUntilLeftCurlyBracketOrSemicolon(code) {\n return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0;\n },\n consumeUntilExclamationMarkOrSemicolon(code) {\n return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0;\n },\n consumeUntilSemicolonIncluded(code) {\n return code === SEMICOLON ? 2 : 0;\n },\n\n createList() {\n return new List();\n },\n createSingleNodeList(node) {\n return new List().appendData(node);\n },\n getFirstListNode(list) {\n return list && list.first;\n },\n getLastListNode(list) {\n return list && list.last;\n },\n\n parseWithFallback(consumer, fallback) {\n const startIndex = this.tokenIndex;\n\n try {\n return consumer.call(this);\n } catch (e) {\n if (onParseErrorThrow) {\n throw e;\n }\n\n this.skip(startIndex - this.tokenIndex);\n const fallbackNode = fallback.call(this);\n\n onParseErrorThrow = true;\n onParseError(e, fallbackNode);\n onParseErrorThrow = false;\n\n return fallbackNode;\n }\n },\n\n lookupNonWSType(offset) {\n let type;\n\n do {\n type = this.lookupType(offset++);\n if (type !== WhiteSpace && type !== Comment) {\n return type;\n }\n } while (type !== NULL);\n\n return NULL;\n },\n\n charCodeAt(offset) {\n return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;\n },\n substring(offsetStart, offsetEnd) {\n return source.substring(offsetStart, offsetEnd);\n },\n substrToCursor(start) {\n return this.source.substring(start, this.tokenStart);\n },\n\n cmpChar(offset, charCode) {\n return cmpChar(source, offset, charCode);\n },\n cmpStr(offsetStart, offsetEnd, str) {\n return cmpStr(source, offsetStart, offsetEnd, str);\n },\n\n consume(tokenType) {\n const start = this.tokenStart;\n\n this.eat(tokenType);\n\n return this.substrToCursor(start);\n },\n consumeFunctionName() {\n const name = source.substring(this.tokenStart, this.tokenEnd - 1);\n\n this.eat(FunctionToken);\n\n return name;\n },\n consumeNumber(type) {\n const number = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart));\n\n this.eat(type);\n\n return number;\n },\n\n eat(tokenType) {\n if (this.tokenType !== tokenType) {\n const tokenName = tokenNames[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase());\n let message = `${/[[\\](){}]/.test(tokenName) ? `\"${tokenName}\"` : tokenName} is expected`;\n let offset = this.tokenStart;\n\n // tweak message and offset\n switch (tokenType) {\n case Ident:\n // when identifier is expected but there is a function or url\n if (this.tokenType === FunctionToken || this.tokenType === Url) {\n offset = this.tokenEnd - 1;\n message = 'Identifier is expected but function found';\n } else {\n message = 'Identifier is expected';\n }\n break;\n\n case Hash:\n if (this.isDelim(NUMBERSIGN)) {\n this.next();\n offset++;\n message = 'Name is expected';\n }\n break;\n\n case Percentage:\n if (this.tokenType === NumberToken) {\n offset = this.tokenEnd;\n message = 'Percent sign is expected';\n }\n break;\n }\n\n this.error(message, offset);\n }\n\n this.next();\n },\n eatIdent(name) {\n if (this.tokenType !== Ident || this.lookupValue(0, name) === false) {\n this.error(`Identifier \"${name}\" is expected`);\n }\n\n this.next();\n },\n eatDelim(code) {\n if (!this.isDelim(code)) {\n this.error(`Delim \"${String.fromCharCode(code)}\" is expected`);\n }\n\n this.next();\n },\n\n getLocation(start, end) {\n if (needPositions) {\n return locationMap.getLocationRange(\n start,\n end,\n filename\n );\n }\n\n return null;\n },\n getLocationFromList(list) {\n if (needPositions) {\n const head = this.getFirstListNode(list);\n const tail = this.getLastListNode(list);\n return locationMap.getLocationRange(\n head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart,\n tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart,\n filename\n );\n }\n\n return null;\n },\n\n error(message, offset) {\n const location = typeof offset !== 'undefined' && offset < source.length\n ? locationMap.getLocation(offset)\n : this.eof\n ? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1))\n : locationMap.getLocation(this.tokenStart);\n\n throw new SyntaxError(\n message || 'Unexpected input',\n source,\n location.offset,\n location.line,\n location.column,\n locationMap.startLine,\n locationMap.startColumn\n );\n }\n });\n\n const parse = function(source_, options) {\n source = source_;\n options = options || {};\n\n parser.setSource(source, tokenize);\n locationMap.setSource(\n source,\n options.offset,\n options.line,\n options.column\n );\n\n filename = options.filename || '';\n needPositions = Boolean(options.positions);\n onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP;\n onParseErrorThrow = false;\n\n parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;\n parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;\n parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;\n parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;\n\n const { context = 'default', onComment } = options;\n\n if (context in parser.context === false) {\n throw new Error('Unknown context `' + context + '`');\n }\n\n if (typeof onComment === 'function') {\n parser.forEachToken((type, start, end) => {\n if (type === Comment) {\n const loc = parser.getLocation(start, end);\n const value = cmpStr(source, end - 2, end, '*/')\n ? source.slice(start + 2, end - 2)\n : source.slice(start + 2, end);\n\n onComment(value, loc);\n }\n });\n }\n\n const ast = parser.context[context].call(parser, options);\n\n if (!parser.eof) {\n parser.error();\n }\n\n return ast;\n };\n\n return Object.assign(parse, {\n SyntaxError,\n config: parser.config\n });\n};\n", "import {\n Delim,\n Ident,\n Dimension,\n Percentage,\n Number as NumberToken,\n Hash,\n Colon,\n LeftSquareBracket\n} from '../../tokenizer/index.js';\n\nconst NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)\nconst AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)\nconst ASTERISK = 0x002A; // U+002A ASTERISK (*)\nconst PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)\nconst SOLIDUS = 0x002F; // U+002F SOLIDUS (/)\nconst FULLSTOP = 0x002E; // U+002E FULL STOP (.)\nconst GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)\nconst VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)\nconst TILDE = 0x007E; // U+007E TILDE (~)\n\nfunction onWhiteSpace(next, children) {\n if (children.last !== null && children.last.type !== 'Combinator' &&\n next !== null && next.type !== 'Combinator') {\n children.push({ // FIXME: this.Combinator() should be used instead\n type: 'Combinator',\n loc: null,\n name: ' '\n });\n }\n}\n\nfunction getNode() {\n switch (this.tokenType) {\n case LeftSquareBracket:\n return this.AttributeSelector();\n\n case Hash:\n return this.IdSelector();\n\n case Colon:\n if (this.lookupType(1) === Colon) {\n return this.PseudoElementSelector();\n } else {\n return this.PseudoClassSelector();\n }\n\n case Ident:\n return this.TypeSelector();\n\n case NumberToken:\n case Percentage:\n return this.Percentage();\n\n case Dimension:\n // throws when .123ident\n if (this.charCodeAt(this.tokenStart) === FULLSTOP) {\n this.error('Identifier is expected', this.tokenStart + 1);\n }\n break;\n\n case Delim: {\n const code = this.charCodeAt(this.tokenStart);\n\n switch (code) {\n case PLUSSIGN:\n case GREATERTHANSIGN:\n case TILDE:\n case SOLIDUS: // /deep/\n return this.Combinator();\n\n case FULLSTOP:\n return this.ClassSelector();\n\n case ASTERISK:\n case VERTICALLINE:\n return this.TypeSelector();\n\n case NUMBERSIGN:\n return this.IdSelector();\n\n case AMPERSAND:\n return this.NestingSelector();\n }\n\n break;\n }\n }\n};\n\nexport default {\n onWhiteSpace,\n getNode\n};\n", "import { Comma, String as StringToken, Ident, RightParenthesis } from '../../tokenizer/index.js';\n\nexport function parseLanguageRangeList() {\n const children = this.createList();\n\n this.skipSC();\n\n loop: while (!this.eof) {\n switch (this.tokenType) {\n case Ident:\n children.push(this.Identifier());\n break;\n\n case StringToken:\n children.push(this.String());\n break;\n\n case Comma:\n children.push(this.Operator());\n break;\n\n case RightParenthesis:\n break loop;\n\n default:\n this.error('Identifier, string or comma is expected');\n }\n\n this.skipSC();\n }\n\n return children;\n}\n", "import { parseLanguageRangeList } from './lang.js';\n\nconst selectorList = {\n parse() {\n return this.createSingleNodeList(\n this.SelectorList()\n );\n }\n};\n\nconst selector = {\n parse() {\n return this.createSingleNodeList(\n this.Selector()\n );\n }\n};\n\nconst identList = {\n parse() {\n return this.createSingleNodeList(\n this.Identifier()\n );\n }\n};\n\nconst langList = {\n parse: parseLanguageRangeList\n};\n\nconst nth = {\n parse() {\n return this.createSingleNodeList(\n this.Nth()\n );\n }\n};\n\nexport default {\n 'dir': identList,\n 'has': selectorList,\n 'lang': langList,\n 'matches': selectorList,\n 'is': selectorList,\n '-moz-any': selectorList,\n '-webkit-any': selectorList,\n 'where': selectorList,\n 'not': selectorList,\n 'nth-child': nth,\n 'nth-last-child': nth,\n 'nth-last-of-type': nth,\n 'nth-of-type': nth,\n 'slotted': selector,\n 'host': selector,\n 'host-context': selector\n};\n", "export { parse as AnPlusB } from './AnPlusB.js';\nexport { parse as AttributeSelector } from './AttributeSelector.js';\nexport { parse as ClassSelector } from './ClassSelector.js';\nexport { parse as Combinator } from './Combinator.js';\nexport { parse as Identifier } from './Identifier.js';\nexport { parse as IdSelector } from './IdSelector.js';\nexport { parse as NestingSelector } from './NestingSelector.js';\nexport { parse as Nth } from './Nth.js';\nexport { parse as Operator } from './Operator.js';\nexport { parse as Percentage } from './Percentage.js';\nexport { parse as PseudoClassSelector } from './PseudoClassSelector.js';\nexport { parse as PseudoElementSelector } from './PseudoElementSelector.js';\nexport { parse as Raw } from './Raw.js';\nexport { parse as Selector } from './Selector.js';\nexport { parse as SelectorList } from './SelectorList.js';\nexport { parse as String } from './String.js';\nexport { parse as TypeSelector } from './TypeSelector.js';\n", "import { Selector } from '../scope/index.js';\nimport pseudo from '../pseudo/index.js';\nimport * as node from '../node/index-parse-selector.js';\n\nexport default {\n parseContext: {\n default: 'SelectorList',\n selectorList: 'SelectorList',\n selector: 'Selector'\n },\n scope: { Selector },\n atrule: {},\n pseudo,\n node\n};\n", "import { createParser } from './create.js';\nimport config from '../syntax/config/parser-selector.js';\n\nexport default createParser(config);\n", "const compare = (s1, s2) => {\n if (s1.a === s2.a) {\n if (s1.b === s2.b) {\n return s1.c - s2.c;\n }\n return s1.b - s2.b;\n }\n return s1.a - s2.a;\n};\n\nconst equals = (s1, s2) => {\n return compare(s1, s2) === 0;\n};\n\nconst greaterThan = (s1, s2) => {\n return compare(s1, s2) > 0;\n};\n\nconst lessThan = (s1, s2) => {\n return compare(s1, s2) < 0;\n};\n\nexport { compare, equals, greaterThan, lessThan };\n", "import { compare } from './compare.js';\n\nconst sort = (specificities, order = 'ASC') => {\n const sorted = specificities.sort(compare);\n\n if (order === 'DESC') {\n return sorted.reverse();\n }\n\n return sorted;\n};\n\nconst sortAsc = (...specificities) => {\n return sort(specificities, 'ASC');\n};\n\nconst sortDesc = (...specificities) => {\n return sort(specificities, 'DESC');\n};\n\nexport { sortAsc, sortDesc };\n", "import { sortAsc, sortDesc } from './sort.js';\n\nconst max = (...specificities) => {\n const sorted = sortDesc(...specificities);\n return sorted[0];\n};\n\nconst min = (...specificities) => {\n const sorted = sortAsc(...specificities);\n return sorted[0];\n};\n\nexport { max, min };\n", "import parse from 'css-tree/selector-parser';\nimport Specificity from '../index.js';\nimport { max } from './../util/index.js';\n\n/** @param {import('css-tree').Selector} selectorAST */\nconst calculateForAST = (selectorAST) => {\n // Quit while you're ahead\n if (!selectorAST || selectorAST.type !== 'Selector') {\n throw new TypeError(`Passed in source is not a Selector AST`);\n }\n\n // https://www.w3.org/TR/selectors-4/#specificity-rules\n let a = 0; /* ID Selectors */\n let b = 0; /* Class selectors, Attributes selectors, and Pseudo-classes */\n let c = 0; /* Type selectors and Pseudo-elements */\n\n selectorAST.children.forEach((child) => {\n switch (child.type) {\n case 'IdSelector':\n a += 1;\n break;\n\n case 'AttributeSelector':\n case 'ClassSelector':\n b += 1;\n break;\n\n case 'PseudoClassSelector':\n switch (child.name.toLowerCase()) {\n // \u201CThe specificity of a :where() pseudo-class is replaced by zero.\u201D\n case 'where':\n // Noop :)\n break;\n\n case '-webkit-any':\n case 'any':\n if (child.children?.first) {\n b += 1;\n }\n break;\n\n // \u201CThe specificity of an :is(), :not(), or :has() pseudo-class is replaced by the specificity of the most specific complex selector in its selector list argument.\u201C\n case '-moz-any':\n case 'is':\n case 'matches':\n case 'not':\n case 'has':\n if (child.children?.first) {\n // Calculate Specificity from nested SelectorList\n const max1 = max(...calculate(child.children.first));\n\n // Adjust orig specificity\n a += max1.a;\n b += max1.b;\n c += max1.c;\n }\n\n break;\n\n // \u201CThe specificity of an :nth-child() or :nth-last-child() selector is the specificity of the pseudo class itself (counting as one pseudo-class selector) plus the specificity of the most specific complex selector in its selector list argument\u201D\n case 'nth-child':\n case 'nth-last-child':\n b += 1;\n\n if (child.children?.first?.selector) {\n // Calculate Specificity from SelectorList\n const max2 = max(...calculate(child.children.first.selector));\n\n // Adjust orig specificity\n a += max2.a;\n b += max2.b;\n c += max2.c;\n }\n break;\n\n // \u201CThe specificity of :host is that of a pseudo-class. The specificity of :host() is that of a pseudo-class, plus the specificity of its argument.\u201D\n // \u201CThe specificity of :host-context() is that of a pseudo-class, plus the specificity of its argument.\u201D\n case 'host-context':\n case 'host':\n b += 1;\n\n if (child.children?.first?.children) {\n // Workaround to a css-tree bug in which it allows complex selectors instead of only compound selectors\n // We work around it by filtering out any Combinator and successive Selectors\n const childAST = { type: 'Selector', children: [] };\n let foundCombinator = false;\n child.children.first.children.forEach((entry) => {\n if (foundCombinator) return false;\n if (entry.type === 'Combinator') {\n foundCombinator = true;\n return false;\n }\n childAST.children.push(entry);\n });\n\n // Calculate Specificity from Selector\n const childSpecificity = calculate(childAST)[0];\n\n // Adjust orig specificity\n a += childSpecificity.a;\n b += childSpecificity.b;\n c += childSpecificity.c;\n }\n break;\n\n // Improper use of Pseudo-Class Selectors instead of a Pseudo-Element\n // @ref https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements#index\n case 'after':\n case 'before':\n case 'first-letter':\n case 'first-line':\n c += 1;\n break;\n\n default:\n b += 1;\n break;\n }\n break;\n\n case 'PseudoElementSelector':\n switch (child.name) {\n // \u201CThe specificity of ::slotted() is that of a pseudo-element, plus the specificity of its argument.\u201D\n case 'slotted':\n c += 1;\n\n if (child.children?.first?.children) {\n // Workaround to a css-tree bug in which it allows complex selectors instead of only compound selectors\n // We work around it by filtering out any Combinator and successive Selectors\n const childAST = { type: 'Selector', children: [] };\n let foundCombinator = false;\n child.children.first.children.forEach((entry) => {\n if (foundCombinator) return false;\n if (entry.type === 'Combinator') {\n foundCombinator = true;\n return false;\n }\n childAST.children.push(entry);\n });\n\n // Calculate Specificity from Selector\n const childSpecificity = calculate(childAST)[0];\n\n // Adjust orig specificity\n a += childSpecificity.a;\n b += childSpecificity.b;\n c += childSpecificity.c;\n }\n break;\n\n case 'view-transition-group':\n case 'view-transition-image-pair':\n case 'view-transition-old':\n case 'view-transition-new':\n // The specificity of a view-transition selector with a * argument is zero.\n if (child.children?.first?.value === '*') {\n break;\n }\n // The specificity of a view-transition selector with an argument is the same\n // as for other pseudo - elements, and is equivalent to a type selector.\n c += 1;\n break;\n\n default:\n c += 1;\n break;\n }\n break;\n\n case 'TypeSelector':\n // Omit namespace\n let typeSelector = child.name;\n if (typeSelector.includes('|')) {\n typeSelector = typeSelector.split('|')[1];\n }\n\n // \u201CIgnore the universal selector\u201D\n if (typeSelector !== '*') {\n c += 1;\n }\n break;\n\n default:\n // NOOP\n break;\n }\n });\n\n return new Specificity({ a, b, c }, selectorAST);\n};\n\nconst convertToAST = (source) => {\n // The passed in argument was a String.\n // ~> Let's try and parse to an AST\n if (typeof source === 'string' || source instanceof String) {\n try {\n return parse(source, {\n context: 'selectorList',\n });\n } catch (e) {\n throw new TypeError(`Could not convert passed in source '${source}' to SelectorList: ${e.message}`);\n }\n }\n\n // The passed in argument was an Object.\n // ~> Let's verify if it's a AST of the type Selector or SelectorList\n if (source instanceof Object) {\n if (source.type && ['Selector', 'SelectorList'].includes(source.type)) {\n return source;\n }\n\n // Manually parsing subtree when the child is of the type Raw, most likely due to https://github.com/csstree/csstree/issues/151\n if (source.type && source.type === 'Raw') {\n try {\n return parse(source.value, {\n context: 'selectorList',\n });\n } catch (e) {\n throw new TypeError(`Could not convert passed in source to SelectorList: ${e.message}`);\n }\n }\n\n throw new TypeError(`Passed in source is an Object but no AST / AST of the type Selector or SelectorList`);\n }\n\n throw new TypeError(`Passed in source is not a String nor an Object. I don't know what to do with it.`);\n};\n\n/**\n * @param {string} selector\n * @returns {Specificity[]}\n */\nconst calculate = (selector) => {\n // Quit while you're ahead\n if (!selector) {\n return [];\n }\n\n // Make sure we have a SelectorList AST\n // If not, an exception will be thrown\n const ast = convertToAST(selector);\n\n // Selector?\n if (ast.type === 'Selector') {\n return [calculateForAST(selector)];\n }\n\n // SelectorList?\n // ~> Calculate Specificity for each contained Selector\n if (ast.type === 'SelectorList') {\n const specificities = [];\n ast.children.forEach((childAST) => {\n const specificity = calculateForAST(childAST);\n specificities.push(specificity);\n });\n return specificities;\n }\n};\n\nexport { calculate, calculateForAST };\n"], + "mappings": "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", + "names": [] +} diff --git a/node_modules/@bramus/specificity/dist/index.js b/node_modules/@bramus/specificity/dist/index.js new file mode 100644 index 0000000..b56a1f3 --- /dev/null +++ b/node_modules/@bramus/specificity/dist/index.js @@ -0,0 +1,8 @@ +var jn=Object.create;var Tt=Object.defineProperty;var zn=Object.getOwnPropertyDescriptor;var Kn=Object.getOwnPropertyNames;var Qn=Object.getPrototypeOf,$n=Object.prototype.hasOwnProperty;var Xn=e=>Tt(e,"__esModule",{value:!0});var lt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),$t=(e,t)=>{for(var r in t)Tt(e,r,{get:t[r],enumerable:!0})},Jn=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Kn(t))!$n.call(e,s)&&(r||s!=="default")&&Tt(e,s,{get:()=>t[s],enumerable:!(n=zn(t,s))||n.enumerable});return e},Zn=(e,t)=>Jn(Xn(Tt(e!=null?jn(Qn(e)):{},"default",!t&&e&&e.__esModule?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var _e=lt(se=>{var Oe="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");se.encode=function(e){if(0<=e&&e{var Me=_e(),oe=5,Be=1<>1;return t?-r:r}ae.encode=function(t){var r="",n,s=ci(t);do n=s&Ue,s>>>=oe,s>0&&(n|=We),r+=Me.encode(n);while(s>0);return r};ae.decode=function(t,r,n){var s=t.length,o=0,a=0,h,l;do{if(r>=s)throw new Error("Expected more digits in base 64 VLQ value.");if(l=Me.decode(t.charCodeAt(r++)),l===-1)throw new Error("Invalid base64 digit: "+t.charAt(r-1));h=!!(l&We),l&=Ue,o=o+(l<{function hi(e,t,r){if(t in e)return e[t];if(arguments.length===3)return r;throw new Error('"'+t+'" is a required argument.')}N.getArg=hi;var He=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,ui=/^data:.+\,.+$/;function Ct(e){var t=e.match(He);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}N.urlParse=Ct;function ft(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}N.urlGenerate=ft;var fi=32;function pi(e){var t=[];return function(r){for(var n=0;nfi&&t.pop(),o}}var ce=pi(function(t){var r=t,n=Ct(t);if(n){if(!n.path)return t;r=n.path}for(var s=N.isAbsolute(r),o=[],a=0,h=0;;)if(a=h,h=r.indexOf("/",a),h===-1){o.push(r.slice(a));break}else for(o.push(r.slice(a,h));h=0;h--)l=o[h],l==="."?o.splice(h,1):l===".."?i++:i>0&&(l===""?(o.splice(h+1,i),i=0):(o.splice(h,2),i--));return r=o.join("/"),r===""&&(r=s?"/":"."),n?(n.path=r,ft(n)):r});N.normalize=ce;function Ge(e,t){e===""&&(e="."),t===""&&(t=".");var r=Ct(t),n=Ct(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),ft(r);if(r||t.match(ui))return t;if(n&&!n.host&&!n.path)return n.host=t,ft(n);var s=t.charAt(0)==="/"?t:ce(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=s,ft(n)):s}N.join=Ge;N.isAbsolute=function(e){return e.charAt(0)==="/"||He.test(e)};function mi(e,t){e===""&&(e="."),e=e.replace(/\/$/,"");for(var r=0;t.indexOf(e+"/")!==0;){var n=e.lastIndexOf("/");if(n<0||(e=e.slice(0,n),e.match(/^([^\/]+:\/)?\/*$/)))return t;++r}return Array(r+1).join("../")+t.substr(e.length+1)}N.relative=mi;var qe=function(){var e=Object.create(null);return!("__proto__"in e)}();function Ye(e){return e}function di(e){return je(e)?"$"+e:e}N.toSetString=qe?Ye:di;function xi(e){return je(e)?e.slice(1):e}N.fromSetString=qe?Ye:xi;function je(e){if(!e)return!1;var t=e.length;if(t<9||e.charCodeAt(t-1)!==95||e.charCodeAt(t-2)!==95||e.charCodeAt(t-3)!==111||e.charCodeAt(t-4)!==116||e.charCodeAt(t-5)!==111||e.charCodeAt(t-6)!==114||e.charCodeAt(t-7)!==112||e.charCodeAt(t-8)!==95||e.charCodeAt(t-9)!==95)return!1;for(var r=t-10;r>=0;r--)if(e.charCodeAt(r)!==36)return!1;return!0}function ki(e,t,r){var n=K(e.source,t.source);return n!==0||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:K(e.name,t.name)}N.compareByOriginalPositions=ki;function Si(e,t,r){var n;return n=e.originalLine-t.originalLine,n!==0||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:K(e.name,t.name)}N.compareByOriginalPositionsNoSource=Si;function gi(e,t,r){var n=e.generatedLine-t.generatedLine;return n!==0||(n=e.generatedColumn-t.generatedColumn,n!==0||r)||(n=K(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:K(e.name,t.name)}N.compareByGeneratedPositionsDeflated=gi;function Ci(e,t,r){var n=e.generatedColumn-t.generatedColumn;return n!==0||r||(n=K(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:K(e.name,t.name)}N.compareByGeneratedPositionsDeflatedNoLine=Ci;function K(e,t){return e===t?0:e===null?1:t===null?-1:e>t?1:-1}function yi(e,t){var r=e.generatedLine-t.generatedLine;return r!==0||(r=e.generatedColumn-t.generatedColumn,r!==0)||(r=K(e.source,t.source),r!==0)||(r=e.originalLine-t.originalLine,r!==0)||(r=e.originalColumn-t.originalColumn,r!==0)?r:K(e.name,t.name)}N.compareByGeneratedPositionsInflated=yi;function bi(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}N.parseSourceMapInput=bi;function Li(e,t,r){if(t=t||"",e&&(e[e.length-1]!=="/"&&t[0]!=="/"&&(e+="/"),t=e+t),r){var n=Ct(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var s=n.path.lastIndexOf("/");s>=0&&(n.path=n.path.substring(0,s+1))}t=Ge(ft(n),t)}return ce(t)}N.computeSourceURL=Li});var Ke=lt(ze=>{var le=Bt(),he=Object.prototype.hasOwnProperty,it=typeof Map<"u";function Q(){this._array=[],this._set=it?new Map:Object.create(null)}Q.fromArray=function(t,r){for(var n=new Q,s=0,o=t.length;s=0)return r}else{var n=le.toSetString(t);if(he.call(this._set,n))return this._set[n]}throw new Error('"'+t+'" is not in the set.')};Q.prototype.at=function(t){if(t>=0&&t{var Qe=Bt();function Ti(e,t){var r=e.generatedLine,n=t.generatedLine,s=e.generatedColumn,o=t.generatedColumn;return n>r||n==r&&o>=s||Qe.compareByGeneratedPositionsInflated(e,t)<=0}function Ut(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}Ut.prototype.unsortedForEach=function(t,r){this._array.forEach(t,r)};Ut.prototype.add=function(t){Ti(this._last,t)?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t))};Ut.prototype.toArray=function(){return this._sorted||(this._array.sort(Qe.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};$e.MappingList=Ut});var Ze=lt(Je=>{var yt=Ve(),v=Bt(),Wt=Ke().ArraySet,vi=Xe().MappingList;function W(e){e||(e={}),this._file=v.getArg(e,"file",null),this._sourceRoot=v.getArg(e,"sourceRoot",null),this._skipValidation=v.getArg(e,"skipValidation",!1),this._sources=new Wt,this._names=new Wt,this._mappings=new vi,this._sourcesContents=null}W.prototype._version=3;W.fromSourceMap=function(t){var r=t.sourceRoot,n=new W({file:t.file,sourceRoot:r});return t.eachMapping(function(s){var o={generated:{line:s.generatedLine,column:s.generatedColumn}};s.source!=null&&(o.source=s.source,r!=null&&(o.source=v.relative(r,o.source)),o.original={line:s.originalLine,column:s.originalColumn},s.name!=null&&(o.name=s.name)),n.addMapping(o)}),t.sources.forEach(function(s){var o=s;r!==null&&(o=v.relative(r,s)),n._sources.has(o)||n._sources.add(o);var a=t.sourceContentFor(s);a!=null&&n.setSourceContent(s,a)}),n};W.prototype.addMapping=function(t){var r=v.getArg(t,"generated"),n=v.getArg(t,"original",null),s=v.getArg(t,"source",null),o=v.getArg(t,"name",null);this._skipValidation||this._validateMapping(r,n,s,o),s!=null&&(s=String(s),this._sources.has(s)||this._sources.add(s)),o!=null&&(o=String(o),this._names.has(o)||this._names.add(o)),this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:s,name:o})};W.prototype.setSourceContent=function(t,r){var n=t;this._sourceRoot!=null&&(n=v.relative(this._sourceRoot,n)),r!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[v.toSetString(n)]=r):this._sourcesContents&&(delete this._sourcesContents[v.toSetString(n)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))};W.prototype.applySourceMap=function(t,r,n){var s=r;if(r==null){if(t.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);s=t.file}var o=this._sourceRoot;o!=null&&(s=v.relative(o,s));var a=new Wt,h=new Wt;this._mappings.unsortedForEach(function(l){if(l.source===s&&l.originalLine!=null){var i=t.originalPositionFor({line:l.originalLine,column:l.originalColumn});i.source!=null&&(l.source=i.source,n!=null&&(l.source=v.join(n,l.source)),o!=null&&(l.source=v.relative(o,l.source)),l.originalLine=i.line,l.originalColumn=i.column,i.name!=null&&(l.name=i.name))}var c=l.source;c!=null&&!a.has(c)&&a.add(c);var f=l.name;f!=null&&!h.has(f)&&h.add(f)},this),this._sources=a,this._names=h,t.sources.forEach(function(l){var i=t.sourceContentFor(l);i!=null&&(n!=null&&(l=v.join(n,l)),o!=null&&(l=v.relative(o,l)),this.setSourceContent(l,i))},this)};W.prototype._validateMapping=function(t,r,n,s){if(r&&typeof r.line!="number"&&typeof r.column!="number")throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!r&&!n&&!s)){if(t&&"line"in t&&"column"in t&&r&&"line"in r&&"column"in r&&t.line>0&&t.column>=0&&r.line>0&&r.column>=0&&n)return;throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:n,original:r,name:s}))}};W.prototype._serializeMappings=function(){for(var t=0,r=1,n=0,s=0,o=0,a=0,h="",l,i,c,f,k=this._mappings.toArray(),S=0,T=k.length;S0){if(!v.compareByGeneratedPositionsInflated(i,k[S-1]))continue;l+=","}l+=yt.encode(i.generatedColumn-t),t=i.generatedColumn,i.source!=null&&(f=this._sources.indexOf(i.source),l+=yt.encode(f-a),a=f,l+=yt.encode(i.originalLine-1-s),s=i.originalLine-1,l+=yt.encode(i.originalColumn-n),n=i.originalColumn,i.name!=null&&(c=this._names.indexOf(i.name),l+=yt.encode(c-o),o=c)),h+=l}return h};W.prototype._generateSourcesContent=function(t,r){return t.map(function(n){if(!this._sourcesContents)return null;r!=null&&(n=v.relative(r,n));var s=v.toSetString(n);return Object.prototype.hasOwnProperty.call(this._sourcesContents,s)?this._sourcesContents[s]:null},this)};W.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(t.file=this._file),this._sourceRoot!=null&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t};W.prototype.toString=function(){return JSON.stringify(this.toJSON())};Je.SourceMapGenerator=W});function I(e){return e>=48&&e<=57}function z(e){return I(e)||e>=65&&e<=70||e>=97&&e<=102}function Et(e){return e>=65&&e<=90}function ti(e){return e>=97&&e<=122}function ei(e){return Et(e)||ti(e)}function ri(e){return e>=128}function vt(e){return ei(e)||ri(e)||e===95}function wt(e){return vt(e)||I(e)||e===45}function ni(e){return e>=0&&e<=8||e===11||e>=14&&e<=31||e===127}function dt(e){return e===10||e===13||e===12}function $(e){return dt(e)||e===32||e===9}function R(e,t){return!(e!==92||dt(t)||t===0)}function At(e,t,r){return e===45?vt(t)||t===45||R(t,r):vt(e)?!0:e===92?R(e,t):!1}function Nt(e,t,r){return e===43||e===45?I(t)?2:t===46&&I(r)?3:0:e===46?I(t)?2:0:I(e)?1:0}function It(e){return e===65279||e===65534?1:0}var Xt=new Array(128),ii=128,xt=130,Jt=131,Dt=132,Zt=133;for(let e=0;ee.length)return!1;for(let s=t;s=0&&$(e.charCodeAt(t));t--);return t+1}function kt(e,t){for(;t=55296&&t<=57343||t>1114111)&&(t=65533),String.fromCodePoint(t)}var gt=["EOF-token","ident-token","function-token","at-keyword-token","hash-token","string-token","bad-string-token","url-token","bad-url-token","delim-token","number-token","percentage-token","dimension-token","whitespace-token","CDO-token","CDC-token","colon-token","semicolon-token","comma-token","[-token","]-token","(-token",")-token","{-token","}-token","comment-token"];function ut(e=null,t){return e===null||e.length0?It(t.charCodeAt(0)):0,s=ut(e.lines,r),o=ut(e.columns,r),a=e.startLine,h=e.startColumn;for(let l=n;l{}){t=String(t||"");let n=t.length,s=ut(this.offsetAndType,t.length+1),o=ut(this.balance,t.length+1),a=0,h=0,l=0,i=-1;for(this.offsetAndType=null,this.balance=null,r(t,(c,f,k)=>{switch(c){default:o[a]=n;break;case h:{let S=l&M;for(l=o[S],h=l>>V,o[a]=S,o[S++]=a;S>V:0}lookupTypeNonSC(t){for(let r=this.tokenIndex;r>V;if(n!==13&&n!==25&&t--===0)return n}return 0}lookupOffset(t){return t+=this.tokenIndex,t>V;if(n!==13&&n!==25&&t--===0)return r-this.tokenIndex}return 0}lookupValue(t,r){return t+=this.tokenIndex,t0?t>V,this.tokenEnd=r&M):(this.tokenIndex=this.tokenCount,this.next())}next(){let t=this.tokenIndex+1;t>V,this.tokenEnd=t&M):(this.eof=!0,this.tokenIndex=this.tokenCount,this.tokenType=0,this.tokenStart=this.tokenEnd=this.source.length)}skipSC(){for(;this.tokenType===13||this.tokenType===25;)this.next()}skipUntilBalanced(t,r){let n=t,s,o;t:for(;n0?this.offsetAndType[n-1]&M:this.firstCharOffset,r(this.source.charCodeAt(o))){case 1:break t;case 2:n++;break t;default:this.balance[s]===n&&(n=s)}}this.skip(n-this.tokenIndex)}forEachToken(t){for(let r=0,n=this.firstCharOffset;r>V;n=a,t(h,s,a,r)}}dump(){let t=new Array(this.tokenCount);return this.forEachToken((r,n,s,o)=>{t[o]={idx:o,type:gt[r],chunk:this.source.substring(n,s),balance:this.balance[o]}}),t}};function Mt(e,t){function r(f){return f=e.length){ife,spec:()=>Ni});var Ei=43,wi=45,ue=(e,t)=>{if(e===9&&(e=t),typeof e=="string"){let r=e.charCodeAt(0);return r>127?32768:r<<8}return e},nr=[[1,1],[1,2],[1,7],[1,8],[1,"-"],[1,10],[1,11],[1,12],[1,15],[1,21],[3,1],[3,2],[3,7],[3,8],[3,"-"],[3,10],[3,11],[3,12],[3,15],[4,1],[4,2],[4,7],[4,8],[4,"-"],[4,10],[4,11],[4,12],[4,15],[12,1],[12,2],[12,7],[12,8],[12,"-"],[12,10],[12,11],[12,12],[12,15],["#",1],["#",2],["#",7],["#",8],["#","-"],["#",10],["#",11],["#",12],["#",15],["-",1],["-",2],["-",7],["-",8],["-","-"],["-",10],["-",11],["-",12],["-",15],[10,1],[10,2],[10,7],[10,8],[10,10],[10,11],[10,12],[10,"%"],[10,15],["@",1],["@",2],["@",7],["@",8],["@","-"],["@",15],[".",10],[".",11],[".",12],["+",10],["+",11],["+",12],["/","*"]],Ai=nr.concat([[1,4],[12,4],[4,4],[3,21],[3,5],[3,16],[11,11],[11,12],[11,2],[11,"-"],[22,1],[22,2],[22,11],[22,12],[22,4],[22,"-"]]);function ir(e){let t=new Set(e.map(([r,n])=>ue(r)<<16|ue(n)));return function(r,n,s){let o=ue(n,s),a=s.charCodeAt(0);return(a===wi&&n!==1&&n!==2&&n!==15||a===Ei?t.has(r<<16|a<<8):t.has(r<<16|o))&&this.emit(" ",13,!0),o}}var Ni=ir(nr),fe=ir(Ai);var Ii=92;function Di(e,t){if(typeof t=="function"){let r=null;e.children.forEach(n=>{r!==null&&t.call(this,r),this.node(n),r=n});return}e.children.forEach(this.node,this)}function Pi(e){Mt(e,(t,r,n)=>{this.token(t,e.slice(r,n))})}function sr(e){let t=new Map;for(let[r,n]of Object.entries(e.node))typeof(n.generate||n)=="function"&&t.set(r,n.generate||n);return function(r,n){let s="",o=0,a={node(l){if(t.has(l.type))t.get(l.type).call(h,l);else throw new Error("Unknown node type: "+l.type)},tokenBefore:fe,token(l,i){o=this.tokenBefore(o,l,i),this.emit(i,l,!1),l===9&&i.charCodeAt(0)===Ii&&this.emit(` +`,13,!0)},emit(l){s+=l},result(){return s}};n&&(typeof n.decorator=="function"&&(a=n.decorator(a)),n.sourceMap&&(a=rr(a)),n.mode in Vt&&(a.tokenBefore=Vt[n.mode]));let h={node:l=>a.node(l),children:Di,token:(l,i)=>a.token(l,i),tokenize:Pi};return a.node(r),a.result()}}var Se={};$t(Se,{AnPlusB:()=>ar,Atrule:()=>cr,AtrulePrelude:()=>lr,AttributeSelector:()=>fr,Block:()=>pr,Brackets:()=>mr,CDC:()=>dr,CDO:()=>xr,ClassSelector:()=>Sr,Combinator:()=>yr,Comment:()=>br,Condition:()=>Lr,Declaration:()=>Tr,DeclarationList:()=>vr,Dimension:()=>Er,Feature:()=>wr,FeatureFunction:()=>Ar,FeatureRange:()=>Nr,Function:()=>Ir,GeneralEnclosed:()=>Dr,Hash:()=>Pr,IdSelector:()=>_r,Identifier:()=>Rr,Layer:()=>Mr,LayerList:()=>Br,MediaQuery:()=>Ur,MediaQueryList:()=>Wr,NestingSelector:()=>Hr,Nth:()=>qr,Number:()=>Yr,Operator:()=>zr,Parentheses:()=>Kr,Percentage:()=>$r,PseudoClassSelector:()=>Jr,PseudoElementSelector:()=>tn,Ratio:()=>en,Raw:()=>nn,Rule:()=>sn,Scope:()=>on,Selector:()=>cn,SelectorList:()=>hn,String:()=>dn,StyleSheet:()=>xn,SupportsDeclaration:()=>kn,TypeSelector:()=>Cn,UnicodeRange:()=>yn,Url:()=>Ln,Value:()=>Tn,WhiteSpace:()=>vn});var Y=43,_=45,Ht=110,st=!0,Fi=!1;function Gt(e,t){let r=this.tokenStart+e,n=this.charCodeAt(r);for((n===Y||n===_)&&(t&&this.error("Number sign is not allowed"),r++);r0&&this.skip(e),t===0&&(r=this.charCodeAt(this.tokenStart),r!==Y&&r!==_&&this.error("Number sign is expected")),pt.call(this,t!==0),t===_?"-"+this.consume(10):this.consume(10)}function or(){let e=this.tokenStart,t=null,r=null;if(this.tokenType===10)pt.call(this,Fi),r=this.consume(10);else if(this.tokenType===1&&this.cmpChar(this.tokenStart,_))switch(t="-1",Z.call(this,1,Ht),this.tokenEnd-this.tokenStart){case 2:this.next(),r=pe.call(this);break;case 3:Z.call(this,2,_),this.next(),this.skipSC(),pt.call(this,st),r="-"+this.consume(10);break;default:Z.call(this,2,_),Gt.call(this,3,st),this.next(),r=this.substrToCursor(e+2)}else if(this.tokenType===1||this.isDelim(Y)&&this.lookupType(1)===1){let n=0;switch(t="1",this.isDelim(Y)&&(n=1,this.next()),Z.call(this,0,Ht),this.tokenEnd-this.tokenStart){case 1:this.next(),r=pe.call(this);break;case 2:Z.call(this,1,_),this.next(),this.skipSC(),pt.call(this,st),r="-"+this.consume(10);break;default:Z.call(this,1,_),Gt.call(this,2,st),this.next(),r=this.substrToCursor(e+n+1)}}else if(this.tokenType===12){let n=this.charCodeAt(this.tokenStart),s=n===Y||n===_,o=this.tokenStart+s;for(;o{t.type==="Declaration"&&this.token(17,";")})}function mr(e){this.token(9,"["),this.children(e),this.token(9,"]")}function dr(){this.token(15,"-->")}function xr(){this.token(14,"\n\n return {\n type: 'CDC',\n loc: this.getLocation(start, this.tokenStart)\n };\n}\n\nexport function generate() {\n this.token(CDC, '-->');\n}\n", "import { CDO } from '../../tokenizer/index.js';\n\nexport const name = 'CDO';\nexport const structure = [];\n\nexport function parse() {\n const start = this.tokenStart;\n\n this.eat(CDO); // \n child = this.CDC();\n break;\n\n // CSS Syntax Module Level 3\n // \u00A72.2 Error handling\n // At the \"top level\" of a stylesheet, an starts an at-rule.\n case AtKeyword:\n child = this.parseWithFallback(this.Atrule, consumeRaw);\n break;\n\n // Anything else starts a qualified rule ...\n default:\n child = this.parseWithFallback(this.Rule, consumeRaw);\n }\n\n children.push(child);\n }\n\n return {\n type: 'StyleSheet',\n loc: this.getLocation(start, this.tokenStart),\n children\n };\n}\n\nexport function generate(node) {\n this.children(node);\n}\n", "import {\n LeftParenthesis,\n RightParenthesis\n} from '../../tokenizer/index.js';\n\nexport const name = 'SupportsDeclaration';\nexport const structure = {\n declaration: 'Declaration'\n};\n\nexport function parse() {\n const start = this.tokenStart;\n\n this.eat(LeftParenthesis);\n this.skipSC();\n\n const declaration = this.Declaration();\n\n if (!this.eof) {\n this.eat(RightParenthesis);\n }\n\n return {\n type: 'SupportsDeclaration',\n loc: this.getLocation(start, this.tokenStart),\n declaration\n };\n}\n\nexport function generate(node) {\n this.token(LeftParenthesis, '(');\n this.node(node.declaration);\n this.token(RightParenthesis, ')');\n}\n", "import { Ident } from '../../tokenizer/index.js';\n\nconst ASTERISK = 0x002A; // U+002A ASTERISK (*)\nconst VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)\n\nfunction eatIdentifierOrAsterisk() {\n if (this.tokenType !== Ident &&\n this.isDelim(ASTERISK) === false) {\n this.error('Identifier or asterisk is expected');\n }\n\n this.next();\n}\n\nexport const name = 'TypeSelector';\nexport const structure = {\n name: String\n};\n\n// ident\n// ident|ident\n// ident|*\n// *\n// *|ident\n// *|*\n// |ident\n// |*\nexport function parse() {\n const start = this.tokenStart;\n\n if (this.isDelim(VERTICALLINE)) {\n this.next();\n eatIdentifierOrAsterisk.call(this);\n } else {\n eatIdentifierOrAsterisk.call(this);\n\n if (this.isDelim(VERTICALLINE)) {\n this.next();\n eatIdentifierOrAsterisk.call(this);\n }\n }\n\n return {\n type: 'TypeSelector',\n loc: this.getLocation(start, this.tokenStart),\n name: this.substrToCursor(start)\n };\n}\n\nexport function generate(node) {\n this.tokenize(node.name);\n}\n", "import {\n isHexDigit,\n Ident,\n Number,\n Dimension\n} from '../../tokenizer/index.js';\n\nconst PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)\nconst HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)\nconst QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)\n\nfunction eatHexSequence(offset, allowDash) {\n let len = 0;\n\n for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) {\n const code = this.charCodeAt(pos);\n\n if (code === HYPHENMINUS && allowDash && len !== 0) {\n eatHexSequence.call(this, offset + len + 1, false);\n return -1;\n }\n\n if (!isHexDigit(code)) {\n this.error(\n allowDash && len !== 0\n ? 'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected'\n : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),\n pos\n );\n }\n\n if (++len > 6) {\n this.error('Too many hex digits', pos);\n };\n }\n\n this.next();\n return len;\n}\n\nfunction eatQuestionMarkSequence(max) {\n let count = 0;\n\n while (this.isDelim(QUESTIONMARK)) {\n if (++count > max) {\n this.error('Too many question marks');\n }\n\n this.next();\n }\n}\n\nfunction startsWith(code) {\n if (this.charCodeAt(this.tokenStart) !== code) {\n this.error((code === PLUSSIGN ? 'Plus sign' : 'Hyphen minus') + ' is expected');\n }\n}\n\n// https://drafts.csswg.org/css-syntax/#urange\n// Informally, the production has three forms:\n// U+0001\n// Defines a range consisting of a single code point, in this case the code point \"1\".\n// U+0001-00ff\n// Defines a range of codepoints between the first and the second value, in this case\n// the range between \"1\" and \"ff\" (255 in decimal) inclusive.\n// U+00??\n// Defines a range of codepoints where the \"?\" characters range over all hex digits,\n// in this case defining the same as the value U+0000-00ff.\n// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat \"?\" as a hexadecimal digit).\n//\n// =\n// u '+' '?'* |\n// u '?'* |\n// u '?'* |\n// u |\n// u |\n// u '+' '?'+\nfunction scanUnicodeRange() {\n let hexLength = 0;\n\n switch (this.tokenType) {\n case Number:\n // u '?'*\n // u \n // u \n hexLength = eatHexSequence.call(this, 1, true);\n\n if (this.isDelim(QUESTIONMARK)) {\n eatQuestionMarkSequence.call(this, 6 - hexLength);\n break;\n }\n\n if (this.tokenType === Dimension ||\n this.tokenType === Number) {\n startsWith.call(this, HYPHENMINUS);\n eatHexSequence.call(this, 1, false);\n break;\n }\n\n break;\n\n case Dimension:\n // u '?'*\n hexLength = eatHexSequence.call(this, 1, true);\n\n if (hexLength > 0) {\n eatQuestionMarkSequence.call(this, 6 - hexLength);\n }\n\n break;\n\n default:\n // u '+' '?'*\n // u '+' '?'+\n this.eatDelim(PLUSSIGN);\n\n if (this.tokenType === Ident) {\n hexLength = eatHexSequence.call(this, 0, true);\n if (hexLength > 0) {\n eatQuestionMarkSequence.call(this, 6 - hexLength);\n }\n break;\n }\n\n if (this.isDelim(QUESTIONMARK)) {\n this.next();\n eatQuestionMarkSequence.call(this, 5);\n break;\n }\n\n this.error('Hex digit or question mark is expected');\n }\n}\n\nexport const name = 'UnicodeRange';\nexport const structure = {\n value: String\n};\n\nexport function parse() {\n const start = this.tokenStart;\n\n // U or u\n this.eatIdent('u');\n scanUnicodeRange.call(this);\n\n return {\n type: 'UnicodeRange',\n loc: this.getLocation(start, this.tokenStart),\n value: this.substrToCursor(start)\n };\n}\n\nexport function generate(node) {\n this.tokenize(node.value);\n}\n", "import {\n isHexDigit,\n isWhiteSpace,\n isValidEscape,\n consumeEscaped,\n decodeEscaped\n} from '../tokenizer/index.js';\n\nconst SPACE = 0x0020; // U+0020 SPACE\nconst REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\\)\nconst QUOTATION_MARK = 0x0022; // \"\nconst APOSTROPHE = 0x0027; // '\nconst LEFTPARENTHESIS = 0x0028; // U+0028 LEFT PARENTHESIS (()\nconst RIGHTPARENTHESIS = 0x0029; // U+0029 RIGHT PARENTHESIS ())\n\nexport function decode(str) {\n const len = str.length;\n let start = 4; // length of \"url(\"\n let end = str.charCodeAt(len - 1) === RIGHTPARENTHESIS ? len - 2 : len - 1;\n let decoded = '';\n\n while (start < end && isWhiteSpace(str.charCodeAt(start))) {\n start++;\n }\n\n while (start < end && isWhiteSpace(str.charCodeAt(end))) {\n end--;\n }\n\n for (let i = start; i <= end; i++) {\n let code = str.charCodeAt(i);\n\n if (code === REVERSE_SOLIDUS) {\n // special case at the ending\n if (i === end) {\n // if the next input code point is EOF, do nothing\n // otherwise include last left parenthesis as escaped\n if (i !== len - 1) {\n decoded = str.substr(i + 1);\n }\n break;\n }\n\n code = str.charCodeAt(++i);\n\n // consume escaped\n if (isValidEscape(REVERSE_SOLIDUS, code)) {\n const escapeStart = i - 1;\n const escapeEnd = consumeEscaped(str, escapeStart);\n\n i = escapeEnd - 1;\n decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));\n } else {\n // \\r\\n\n if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {\n i++;\n }\n }\n } else {\n decoded += str[i];\n }\n }\n\n return decoded;\n}\n\nexport function encode(str) {\n let encoded = '';\n let wsBeforeHexIsNeeded = false;\n\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n\n // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).\n if (code === 0x0000) {\n encoded += '\\uFFFD';\n continue;\n }\n\n // If the character is in the range [\\1-\\1f] (U+0001 to U+001F) or is U+007F,\n // the character escaped as code point.\n // Note: Do not compare with 0x0001 since 0x0000 is precessed before\n if (code <= 0x001f || code === 0x007F) {\n encoded += '\\\\' + code.toString(16);\n wsBeforeHexIsNeeded = true;\n continue;\n }\n\n if (code === SPACE ||\n code === REVERSE_SOLIDUS ||\n code === QUOTATION_MARK ||\n code === APOSTROPHE ||\n code === LEFTPARENTHESIS ||\n code === RIGHTPARENTHESIS) {\n encoded += '\\\\' + str.charAt(i);\n wsBeforeHexIsNeeded = false;\n } else {\n if (wsBeforeHexIsNeeded && isHexDigit(code)) {\n encoded += ' ';\n }\n\n encoded += str.charAt(i);\n wsBeforeHexIsNeeded = false;\n }\n }\n\n return 'url(' + encoded + ')';\n}\n", "import * as url from '../../utils/url.js';\nimport * as string from '../../utils/string.js';\nimport {\n Function as FunctionToken,\n String as StringToken,\n Url,\n RightParenthesis\n} from '../../tokenizer/index.js';\n\nexport const name = 'Url';\nexport const structure = {\n value: String\n};\n\n// | )\nexport function parse() {\n const start = this.tokenStart;\n let value;\n\n switch (this.tokenType) {\n case Url:\n value = url.decode(this.consume(Url));\n break;\n\n case FunctionToken:\n if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) {\n this.error('Function name must be `url`');\n }\n\n this.eat(FunctionToken);\n this.skipSC();\n value = string.decode(this.consume(StringToken));\n this.skipSC();\n if (!this.eof) {\n this.eat(RightParenthesis);\n }\n break;\n\n default:\n this.error('Url or Function is expected');\n }\n\n return {\n type: 'Url',\n loc: this.getLocation(start, this.tokenStart),\n value\n };\n}\n\nexport function generate(node) {\n this.token(Url, url.encode(node.value));\n}\n", "export const name = 'Value';\nexport const structure = {\n children: [[]]\n};\n\nexport function parse() {\n const start = this.tokenStart;\n const children = this.readSequence(this.scope.Value);\n\n return {\n type: 'Value',\n loc: this.getLocation(start, this.tokenStart),\n children\n };\n}\n\nexport function generate(node) {\n this.children(node);\n}\n", "import { WhiteSpace } from '../../tokenizer/index.js';\n\nconst SPACE = Object.freeze({\n type: 'WhiteSpace',\n loc: null,\n value: ' '\n});\n\nexport const name = 'WhiteSpace';\nexport const structure = {\n value: String\n};\n\nexport function parse() {\n this.eat(WhiteSpace);\n return SPACE;\n\n // return {\n // type: 'WhiteSpace',\n // loc: this.getLocation(this.tokenStart, this.tokenEnd),\n // value: this.consume(WHITESPACE)\n // };\n}\n\nexport function generate(node) {\n this.token(WhiteSpace, node.value);\n}\n", "import * as node from '../node/index-generate.js';\n\nexport default {\n node\n};\n", "import { createGenerator } from './create.js';\nimport config from '../syntax/config/generator.js';\n\nexport default createGenerator(config);\n", "//\n// list\n// \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500head \u2502\n// \u2502 \u2502 tail\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n// \u25BC \u25BC\n// item item item item\n// \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// null \u25C0\u2500\u2500\u253C\u2500prev \u2502\u25C0\u2500\u2500\u2500\u253C\u2500prev \u2502\u25C0\u2500\u2500\u2500\u253C\u2500prev \u2502\u25C0\u2500\u2500\u2500\u253C\u2500prev \u2502\n// \u2502 next\u2500\u253C\u2500\u2500\u2500\u25B6\u2502 next\u2500\u253C\u2500\u2500\u2500\u25B6\u2502 next\u2500\u253C\u2500\u2500\u2500\u25B6\u2502 next\u2500\u253C\u2500\u2500\u25B6 null\n// \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n// \u2502 data \u2502 \u2502 data \u2502 \u2502 data \u2502 \u2502 data \u2502\n// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n//\n\nlet releasedCursors = null;\n\nexport class List {\n static createItem(data) {\n return {\n prev: null,\n next: null,\n data\n };\n }\n\n constructor() {\n this.head = null;\n this.tail = null;\n this.cursor = null;\n }\n createItem(data) {\n return List.createItem(data);\n }\n\n // cursor helpers\n allocateCursor(prev, next) {\n let cursor;\n\n if (releasedCursors !== null) {\n cursor = releasedCursors;\n releasedCursors = releasedCursors.cursor;\n cursor.prev = prev;\n cursor.next = next;\n cursor.cursor = this.cursor;\n } else {\n cursor = {\n prev,\n next,\n cursor: this.cursor\n };\n }\n\n this.cursor = cursor;\n\n return cursor;\n }\n releaseCursor() {\n const { cursor } = this;\n\n this.cursor = cursor.cursor;\n cursor.prev = null;\n cursor.next = null;\n cursor.cursor = releasedCursors;\n releasedCursors = cursor;\n }\n updateCursors(prevOld, prevNew, nextOld, nextNew) {\n let { cursor } = this;\n\n while (cursor !== null) {\n if (cursor.prev === prevOld) {\n cursor.prev = prevNew;\n }\n\n if (cursor.next === nextOld) {\n cursor.next = nextNew;\n }\n\n cursor = cursor.cursor;\n }\n }\n *[Symbol.iterator]() {\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n yield cursor.data;\n }\n }\n\n // getters\n get size() {\n let size = 0;\n\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n size++;\n }\n\n return size;\n }\n get isEmpty() {\n return this.head === null;\n }\n get first() {\n return this.head && this.head.data;\n }\n get last() {\n return this.tail && this.tail.data;\n }\n\n // convertors\n fromArray(array) {\n let cursor = null;\n this.head = null;\n\n for (let data of array) {\n const item = List.createItem(data);\n\n if (cursor !== null) {\n cursor.next = item;\n } else {\n this.head = item;\n }\n\n item.prev = cursor;\n cursor = item;\n }\n\n this.tail = cursor;\n return this;\n }\n toArray() {\n return [...this];\n }\n toJSON() {\n return [...this];\n }\n\n // array-like methods\n forEach(fn, thisArg = this) {\n // push cursor\n const cursor = this.allocateCursor(null, this.head);\n\n while (cursor.next !== null) {\n const item = cursor.next;\n cursor.next = item.next;\n fn.call(thisArg, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n }\n forEachRight(fn, thisArg = this) {\n // push cursor\n const cursor = this.allocateCursor(this.tail, null);\n\n while (cursor.prev !== null) {\n const item = cursor.prev;\n cursor.prev = item.prev;\n fn.call(thisArg, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n }\n reduce(fn, initialValue, thisArg = this) {\n // push cursor\n let cursor = this.allocateCursor(null, this.head);\n let acc = initialValue;\n let item;\n\n while (cursor.next !== null) {\n item = cursor.next;\n cursor.next = item.next;\n\n acc = fn.call(thisArg, acc, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n\n return acc;\n }\n reduceRight(fn, initialValue, thisArg = this) {\n // push cursor\n let cursor = this.allocateCursor(this.tail, null);\n let acc = initialValue;\n let item;\n\n while (cursor.prev !== null) {\n item = cursor.prev;\n cursor.prev = item.prev;\n\n acc = fn.call(thisArg, acc, item.data, item, this);\n }\n\n // pop cursor\n this.releaseCursor();\n\n return acc;\n }\n some(fn, thisArg = this) {\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n if (fn.call(thisArg, cursor.data, cursor, this)) {\n return true;\n }\n }\n\n return false;\n }\n map(fn, thisArg = this) {\n const result = new List();\n\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n result.appendData(fn.call(thisArg, cursor.data, cursor, this));\n }\n\n return result;\n }\n filter(fn, thisArg = this) {\n const result = new List();\n\n for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n if (fn.call(thisArg, cursor.data, cursor, this)) {\n result.appendData(cursor.data);\n }\n }\n\n return result;\n }\n\n nextUntil(start, fn, thisArg = this) {\n if (start === null) {\n return;\n }\n\n // push cursor\n const cursor = this.allocateCursor(null, start);\n\n while (cursor.next !== null) {\n const item = cursor.next;\n cursor.next = item.next;\n if (fn.call(thisArg, item.data, item, this)) {\n break;\n }\n }\n\n // pop cursor\n this.releaseCursor();\n }\n prevUntil(start, fn, thisArg = this) {\n if (start === null) {\n return;\n }\n\n // push cursor\n const cursor = this.allocateCursor(start, null);\n\n while (cursor.prev !== null) {\n const item = cursor.prev;\n cursor.prev = item.prev;\n if (fn.call(thisArg, item.data, item, this)) {\n break;\n }\n }\n\n // pop cursor\n this.releaseCursor();\n }\n\n // mutation\n clear() {\n this.head = null;\n this.tail = null;\n }\n copy() {\n const result = new List();\n\n for (let data of this) {\n result.appendData(data);\n }\n\n return result;\n }\n prepend(item) {\n // head\n // ^\n // item\n this.updateCursors(null, item, this.head, item);\n\n // insert to the beginning of the list\n if (this.head !== null) {\n // new item <- first item\n this.head.prev = item;\n // new item -> first item\n item.next = this.head;\n } else {\n // if list has no head, then it also has no tail\n // in this case tail points to the new item\n this.tail = item;\n }\n\n // head always points to new item\n this.head = item;\n return this;\n }\n prependData(data) {\n return this.prepend(List.createItem(data));\n }\n append(item) {\n return this.insert(item);\n }\n appendData(data) {\n return this.insert(List.createItem(data));\n }\n insert(item, before = null) {\n if (before !== null) {\n // prev before\n // ^\n // item\n this.updateCursors(before.prev, item, before, item);\n\n if (before.prev === null) {\n // insert to the beginning of list\n if (this.head !== before) {\n throw new Error('before doesn\\'t belong to list');\n }\n // since head points to before therefore list doesn't empty\n // no need to check tail\n this.head = item;\n before.prev = item;\n item.next = before;\n this.updateCursors(null, item);\n } else {\n // insert between two items\n before.prev.next = item;\n item.prev = before.prev;\n before.prev = item;\n item.next = before;\n }\n } else {\n // tail\n // ^\n // item\n this.updateCursors(this.tail, item, null, item);\n\n // insert to the ending of the list\n if (this.tail !== null) {\n // last item -> new item\n this.tail.next = item;\n // last item <- new item\n item.prev = this.tail;\n } else {\n // if list has no tail, then it also has no head\n // in this case head points to new item\n this.head = item;\n }\n\n // tail always points to new item\n this.tail = item;\n }\n\n return this;\n }\n insertData(data, before) {\n return this.insert(List.createItem(data), before);\n }\n remove(item) {\n // item\n // ^\n // prev next\n this.updateCursors(item, item.prev, item, item.next);\n\n if (item.prev !== null) {\n item.prev.next = item.next;\n } else {\n if (this.head !== item) {\n throw new Error('item doesn\\'t belong to list');\n }\n\n this.head = item.next;\n }\n\n if (item.next !== null) {\n item.next.prev = item.prev;\n } else {\n if (this.tail !== item) {\n throw new Error('item doesn\\'t belong to list');\n }\n\n this.tail = item.prev;\n }\n\n item.prev = null;\n item.next = null;\n\n return item;\n }\n push(data) {\n this.insert(List.createItem(data));\n }\n pop() {\n return this.tail !== null ? this.remove(this.tail) : null;\n }\n unshift(data) {\n this.prepend(List.createItem(data));\n }\n shift() {\n return this.head !== null ? this.remove(this.head) : null;\n }\n prependList(list) {\n return this.insertList(list, this.head);\n }\n appendList(list) {\n return this.insertList(list);\n }\n insertList(list, before) {\n // ignore empty lists\n if (list.head === null) {\n return this;\n }\n\n if (before !== undefined && before !== null) {\n this.updateCursors(before.prev, list.tail, before, list.head);\n\n // insert in the middle of dist list\n if (before.prev !== null) {\n // before.prev <-> list.head\n before.prev.next = list.head;\n list.head.prev = before.prev;\n } else {\n this.head = list.head;\n }\n\n before.prev = list.tail;\n list.tail.next = before;\n } else {\n this.updateCursors(this.tail, list.tail, null, list.head);\n\n // insert to end of the list\n if (this.tail !== null) {\n // if destination list has a tail, then it also has a head,\n // but head doesn't change\n // dest tail -> source head\n this.tail.next = list.head;\n // dest tail <- source head\n list.head.prev = this.tail;\n } else {\n // if list has no a tail, then it also has no a head\n // in this case points head to new item\n this.head = list.head;\n }\n\n // tail always start point to new item\n this.tail = list.tail;\n }\n\n list.head = null;\n list.tail = null;\n return this;\n }\n replace(oldItem, newItemOrList) {\n if ('head' in newItemOrList) {\n this.insertList(newItemOrList, oldItem);\n } else {\n this.insert(newItemOrList, oldItem);\n }\n\n this.remove(oldItem);\n }\n}\n", "export function createCustomError(name, message) {\n // use Object.create(), because some VMs prevent setting line/column otherwise\n // (iOS Safari 10 even throws an exception)\n const error = Object.create(SyntaxError.prototype);\n const errorStack = new Error();\n\n return Object.assign(error, {\n name,\n message,\n get stack() {\n return (errorStack.stack || '').replace(/^(.+\\n){1,3}/, `${name}: ${message}\\n`);\n }\n });\n};\n", "import { createCustomError } from '../utils/create-custom-error.js';\n\nconst MAX_LINE_LENGTH = 100;\nconst OFFSET_CORRECTION = 60;\nconst TAB_REPLACEMENT = ' ';\n\nfunction sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) {\n function processLines(start, end) {\n return lines\n .slice(start, end)\n .map((line, idx) =>\n String(start + idx + 1).padStart(maxNumLength) + ' |' + line\n ).join('\\n');\n }\n\n const prelines = '\\n'.repeat(Math.max(baseLine - 1, 0));\n const precolumns = ' '.repeat(Math.max(baseColumn - 1, 0));\n const lines = (prelines + precolumns + source).split(/\\r\\n?|\\n|\\f/);\n const startLine = Math.max(1, line - extraLines) - 1;\n const endLine = Math.min(line + extraLines, lines.length + 1);\n const maxNumLength = Math.max(4, String(endLine).length) + 1;\n let cutLeft = 0;\n\n // column correction according to replaced tab before column\n column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\\t/g) || []).length;\n\n if (column > MAX_LINE_LENGTH) {\n cutLeft = column - OFFSET_CORRECTION + 3;\n column = OFFSET_CORRECTION - 2;\n }\n\n for (let i = startLine; i <= endLine; i++) {\n if (i >= 0 && i < lines.length) {\n lines[i] = lines[i].replace(/\\t/g, TAB_REPLACEMENT);\n lines[i] =\n (cutLeft > 0 && lines[i].length > cutLeft ? '\\u2026' : '') +\n lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +\n (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\\u2026' : '');\n }\n }\n\n return [\n processLines(startLine, line),\n new Array(column + maxNumLength + 2).join('-') + '^',\n processLines(line, endLine)\n ].filter(Boolean)\n .join('\\n')\n .replace(/^(\\s+\\d+\\s+\\|\\n)+/, '')\n .replace(/\\n(\\s+\\d+\\s+\\|)+$/, '');\n}\n\nexport function SyntaxError(message, source, offset, line, column, baseLine = 1, baseColumn = 1) {\n const error = Object.assign(createCustomError('SyntaxError', message), {\n source,\n offset,\n line,\n column,\n sourceFragment(extraLines) {\n return sourceFragment({ source, line, column, baseLine, baseColumn }, isNaN(extraLines) ? 0 : extraLines);\n },\n get formattedMessage() {\n return (\n `Parse error: ${message}\\n` +\n sourceFragment({ source, line, column, baseLine, baseColumn }, 2)\n );\n }\n });\n\n return error;\n}\n", "import { WhiteSpace, Comment } from '../tokenizer/index.js';\n\nexport function readSequence(recognizer) {\n const children = this.createList();\n let space = false;\n const context = {\n recognizer\n };\n\n while (!this.eof) {\n switch (this.tokenType) {\n case Comment:\n this.next();\n continue;\n\n case WhiteSpace:\n space = true;\n this.next();\n continue;\n }\n\n let child = recognizer.getNode.call(this, context);\n\n if (child === undefined) {\n break;\n }\n\n if (space) {\n if (recognizer.onWhiteSpace) {\n recognizer.onWhiteSpace.call(this, child, children, context);\n }\n space = false;\n }\n\n children.push(child);\n }\n\n if (space && recognizer.onWhiteSpace) {\n recognizer.onWhiteSpace.call(this, null, children, context);\n }\n\n return children;\n};\n", "import { List } from '../utils/List.js';\nimport { SyntaxError } from './SyntaxError.js';\nimport {\n tokenize,\n OffsetToLocation,\n TokenStream,\n tokenNames,\n\n consumeNumber,\n findWhiteSpaceStart,\n cmpChar,\n cmpStr,\n\n WhiteSpace,\n Comment,\n Ident,\n Function as FunctionToken,\n Url,\n Hash,\n Percentage,\n Number as NumberToken\n} from '../tokenizer/index.js';\nimport { readSequence } from './sequence.js';\n\nconst NOOP = () => {};\nconst EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)\nconst NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)\nconst SEMICOLON = 0x003B; // U+003B SEMICOLON (;)\nconst LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({)\nconst NULL = 0;\n\nfunction createParseContext(name) {\n return function() {\n return this[name]();\n };\n}\n\nfunction fetchParseValues(dict) {\n const result = Object.create(null);\n\n for (const name of Object.keys(dict)) {\n const item = dict[name];\n const fn = item.parse || item;\n\n if (fn) {\n result[name] = fn;\n }\n }\n\n return result;\n}\n\nfunction processConfig(config) {\n const parseConfig = {\n context: Object.create(null),\n features: Object.assign(Object.create(null), config.features),\n scope: Object.assign(Object.create(null), config.scope),\n atrule: fetchParseValues(config.atrule),\n pseudo: fetchParseValues(config.pseudo),\n node: fetchParseValues(config.node)\n };\n\n for (const [name, context] of Object.entries(config.parseContext)) {\n switch (typeof context) {\n case 'function':\n parseConfig.context[name] = context;\n break;\n\n case 'string':\n parseConfig.context[name] = createParseContext(context);\n break;\n }\n }\n\n return {\n config: parseConfig,\n ...parseConfig,\n ...parseConfig.node\n };\n}\n\nexport function createParser(config) {\n let source = '';\n let filename = '';\n let needPositions = false;\n let onParseError = NOOP;\n let onParseErrorThrow = false;\n\n const locationMap = new OffsetToLocation();\n const parser = Object.assign(new TokenStream(), processConfig(config || {}), {\n parseAtrulePrelude: true,\n parseRulePrelude: true,\n parseValue: true,\n parseCustomProperty: false,\n\n readSequence,\n\n consumeUntilBalanceEnd: () => 0,\n consumeUntilLeftCurlyBracket(code) {\n return code === LEFTCURLYBRACKET ? 1 : 0;\n },\n consumeUntilLeftCurlyBracketOrSemicolon(code) {\n return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0;\n },\n consumeUntilExclamationMarkOrSemicolon(code) {\n return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0;\n },\n consumeUntilSemicolonIncluded(code) {\n return code === SEMICOLON ? 2 : 0;\n },\n\n createList() {\n return new List();\n },\n createSingleNodeList(node) {\n return new List().appendData(node);\n },\n getFirstListNode(list) {\n return list && list.first;\n },\n getLastListNode(list) {\n return list && list.last;\n },\n\n parseWithFallback(consumer, fallback) {\n const startIndex = this.tokenIndex;\n\n try {\n return consumer.call(this);\n } catch (e) {\n if (onParseErrorThrow) {\n throw e;\n }\n\n this.skip(startIndex - this.tokenIndex);\n const fallbackNode = fallback.call(this);\n\n onParseErrorThrow = true;\n onParseError(e, fallbackNode);\n onParseErrorThrow = false;\n\n return fallbackNode;\n }\n },\n\n lookupNonWSType(offset) {\n let type;\n\n do {\n type = this.lookupType(offset++);\n if (type !== WhiteSpace && type !== Comment) {\n return type;\n }\n } while (type !== NULL);\n\n return NULL;\n },\n\n charCodeAt(offset) {\n return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;\n },\n substring(offsetStart, offsetEnd) {\n return source.substring(offsetStart, offsetEnd);\n },\n substrToCursor(start) {\n return this.source.substring(start, this.tokenStart);\n },\n\n cmpChar(offset, charCode) {\n return cmpChar(source, offset, charCode);\n },\n cmpStr(offsetStart, offsetEnd, str) {\n return cmpStr(source, offsetStart, offsetEnd, str);\n },\n\n consume(tokenType) {\n const start = this.tokenStart;\n\n this.eat(tokenType);\n\n return this.substrToCursor(start);\n },\n consumeFunctionName() {\n const name = source.substring(this.tokenStart, this.tokenEnd - 1);\n\n this.eat(FunctionToken);\n\n return name;\n },\n consumeNumber(type) {\n const number = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart));\n\n this.eat(type);\n\n return number;\n },\n\n eat(tokenType) {\n if (this.tokenType !== tokenType) {\n const tokenName = tokenNames[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase());\n let message = `${/[[\\](){}]/.test(tokenName) ? `\"${tokenName}\"` : tokenName} is expected`;\n let offset = this.tokenStart;\n\n // tweak message and offset\n switch (tokenType) {\n case Ident:\n // when identifier is expected but there is a function or url\n if (this.tokenType === FunctionToken || this.tokenType === Url) {\n offset = this.tokenEnd - 1;\n message = 'Identifier is expected but function found';\n } else {\n message = 'Identifier is expected';\n }\n break;\n\n case Hash:\n if (this.isDelim(NUMBERSIGN)) {\n this.next();\n offset++;\n message = 'Name is expected';\n }\n break;\n\n case Percentage:\n if (this.tokenType === NumberToken) {\n offset = this.tokenEnd;\n message = 'Percent sign is expected';\n }\n break;\n }\n\n this.error(message, offset);\n }\n\n this.next();\n },\n eatIdent(name) {\n if (this.tokenType !== Ident || this.lookupValue(0, name) === false) {\n this.error(`Identifier \"${name}\" is expected`);\n }\n\n this.next();\n },\n eatDelim(code) {\n if (!this.isDelim(code)) {\n this.error(`Delim \"${String.fromCharCode(code)}\" is expected`);\n }\n\n this.next();\n },\n\n getLocation(start, end) {\n if (needPositions) {\n return locationMap.getLocationRange(\n start,\n end,\n filename\n );\n }\n\n return null;\n },\n getLocationFromList(list) {\n if (needPositions) {\n const head = this.getFirstListNode(list);\n const tail = this.getLastListNode(list);\n return locationMap.getLocationRange(\n head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart,\n tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart,\n filename\n );\n }\n\n return null;\n },\n\n error(message, offset) {\n const location = typeof offset !== 'undefined' && offset < source.length\n ? locationMap.getLocation(offset)\n : this.eof\n ? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1))\n : locationMap.getLocation(this.tokenStart);\n\n throw new SyntaxError(\n message || 'Unexpected input',\n source,\n location.offset,\n location.line,\n location.column,\n locationMap.startLine,\n locationMap.startColumn\n );\n }\n });\n\n const parse = function(source_, options) {\n source = source_;\n options = options || {};\n\n parser.setSource(source, tokenize);\n locationMap.setSource(\n source,\n options.offset,\n options.line,\n options.column\n );\n\n filename = options.filename || '';\n needPositions = Boolean(options.positions);\n onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP;\n onParseErrorThrow = false;\n\n parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;\n parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;\n parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;\n parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;\n\n const { context = 'default', onComment } = options;\n\n if (context in parser.context === false) {\n throw new Error('Unknown context `' + context + '`');\n }\n\n if (typeof onComment === 'function') {\n parser.forEachToken((type, start, end) => {\n if (type === Comment) {\n const loc = parser.getLocation(start, end);\n const value = cmpStr(source, end - 2, end, '*/')\n ? source.slice(start + 2, end - 2)\n : source.slice(start + 2, end);\n\n onComment(value, loc);\n }\n });\n }\n\n const ast = parser.context[context].call(parser, options);\n\n if (!parser.eof) {\n parser.error();\n }\n\n return ast;\n };\n\n return Object.assign(parse, {\n SyntaxError,\n config: parser.config\n });\n};\n", "import {\n Delim,\n Ident,\n Dimension,\n Percentage,\n Number as NumberToken,\n Hash,\n Colon,\n LeftSquareBracket\n} from '../../tokenizer/index.js';\n\nconst NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)\nconst AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)\nconst ASTERISK = 0x002A; // U+002A ASTERISK (*)\nconst PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)\nconst SOLIDUS = 0x002F; // U+002F SOLIDUS (/)\nconst FULLSTOP = 0x002E; // U+002E FULL STOP (.)\nconst GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)\nconst VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)\nconst TILDE = 0x007E; // U+007E TILDE (~)\n\nfunction onWhiteSpace(next, children) {\n if (children.last !== null && children.last.type !== 'Combinator' &&\n next !== null && next.type !== 'Combinator') {\n children.push({ // FIXME: this.Combinator() should be used instead\n type: 'Combinator',\n loc: null,\n name: ' '\n });\n }\n}\n\nfunction getNode() {\n switch (this.tokenType) {\n case LeftSquareBracket:\n return this.AttributeSelector();\n\n case Hash:\n return this.IdSelector();\n\n case Colon:\n if (this.lookupType(1) === Colon) {\n return this.PseudoElementSelector();\n } else {\n return this.PseudoClassSelector();\n }\n\n case Ident:\n return this.TypeSelector();\n\n case NumberToken:\n case Percentage:\n return this.Percentage();\n\n case Dimension:\n // throws when .123ident\n if (this.charCodeAt(this.tokenStart) === FULLSTOP) {\n this.error('Identifier is expected', this.tokenStart + 1);\n }\n break;\n\n case Delim: {\n const code = this.charCodeAt(this.tokenStart);\n\n switch (code) {\n case PLUSSIGN:\n case GREATERTHANSIGN:\n case TILDE:\n case SOLIDUS: // /deep/\n return this.Combinator();\n\n case FULLSTOP:\n return this.ClassSelector();\n\n case ASTERISK:\n case VERTICALLINE:\n return this.TypeSelector();\n\n case NUMBERSIGN:\n return this.IdSelector();\n\n case AMPERSAND:\n return this.NestingSelector();\n }\n\n break;\n }\n }\n};\n\nexport default {\n onWhiteSpace,\n getNode\n};\n", "import { Comma, String as StringToken, Ident, RightParenthesis } from '../../tokenizer/index.js';\n\nexport function parseLanguageRangeList() {\n const children = this.createList();\n\n this.skipSC();\n\n loop: while (!this.eof) {\n switch (this.tokenType) {\n case Ident:\n children.push(this.Identifier());\n break;\n\n case StringToken:\n children.push(this.String());\n break;\n\n case Comma:\n children.push(this.Operator());\n break;\n\n case RightParenthesis:\n break loop;\n\n default:\n this.error('Identifier, string or comma is expected');\n }\n\n this.skipSC();\n }\n\n return children;\n}\n", "import { parseLanguageRangeList } from './lang.js';\n\nconst selectorList = {\n parse() {\n return this.createSingleNodeList(\n this.SelectorList()\n );\n }\n};\n\nconst selector = {\n parse() {\n return this.createSingleNodeList(\n this.Selector()\n );\n }\n};\n\nconst identList = {\n parse() {\n return this.createSingleNodeList(\n this.Identifier()\n );\n }\n};\n\nconst langList = {\n parse: parseLanguageRangeList\n};\n\nconst nth = {\n parse() {\n return this.createSingleNodeList(\n this.Nth()\n );\n }\n};\n\nexport default {\n 'dir': identList,\n 'has': selectorList,\n 'lang': langList,\n 'matches': selectorList,\n 'is': selectorList,\n '-moz-any': selectorList,\n '-webkit-any': selectorList,\n 'where': selectorList,\n 'not': selectorList,\n 'nth-child': nth,\n 'nth-last-child': nth,\n 'nth-last-of-type': nth,\n 'nth-of-type': nth,\n 'slotted': selector,\n 'host': selector,\n 'host-context': selector\n};\n", "export { parse as AnPlusB } from './AnPlusB.js';\nexport { parse as AttributeSelector } from './AttributeSelector.js';\nexport { parse as ClassSelector } from './ClassSelector.js';\nexport { parse as Combinator } from './Combinator.js';\nexport { parse as Identifier } from './Identifier.js';\nexport { parse as IdSelector } from './IdSelector.js';\nexport { parse as NestingSelector } from './NestingSelector.js';\nexport { parse as Nth } from './Nth.js';\nexport { parse as Operator } from './Operator.js';\nexport { parse as Percentage } from './Percentage.js';\nexport { parse as PseudoClassSelector } from './PseudoClassSelector.js';\nexport { parse as PseudoElementSelector } from './PseudoElementSelector.js';\nexport { parse as Raw } from './Raw.js';\nexport { parse as Selector } from './Selector.js';\nexport { parse as SelectorList } from './SelectorList.js';\nexport { parse as String } from './String.js';\nexport { parse as TypeSelector } from './TypeSelector.js';\n", "import { Selector } from '../scope/index.js';\nimport pseudo from '../pseudo/index.js';\nimport * as node from '../node/index-parse-selector.js';\n\nexport default {\n parseContext: {\n default: 'SelectorList',\n selectorList: 'SelectorList',\n selector: 'Selector'\n },\n scope: { Selector },\n atrule: {},\n pseudo,\n node\n};\n", "import { createParser } from './create.js';\nimport config from '../syntax/config/parser-selector.js';\n\nexport default createParser(config);\n", "const compare = (s1, s2) => {\n if (s1.a === s2.a) {\n if (s1.b === s2.b) {\n return s1.c - s2.c;\n }\n return s1.b - s2.b;\n }\n return s1.a - s2.a;\n};\n\nconst equals = (s1, s2) => {\n return compare(s1, s2) === 0;\n};\n\nconst greaterThan = (s1, s2) => {\n return compare(s1, s2) > 0;\n};\n\nconst lessThan = (s1, s2) => {\n return compare(s1, s2) < 0;\n};\n\nexport { compare, equals, greaterThan, lessThan };\n", "import { compare } from './compare.js';\n\nconst sort = (specificities, order = 'ASC') => {\n const sorted = specificities.sort(compare);\n\n if (order === 'DESC') {\n return sorted.reverse();\n }\n\n return sorted;\n};\n\nconst sortAsc = (...specificities) => {\n return sort(specificities, 'ASC');\n};\n\nconst sortDesc = (...specificities) => {\n return sort(specificities, 'DESC');\n};\n\nexport { sortAsc, sortDesc };\n", "import { sortAsc, sortDesc } from './sort.js';\n\nconst max = (...specificities) => {\n const sorted = sortDesc(...specificities);\n return sorted[0];\n};\n\nconst min = (...specificities) => {\n const sorted = sortAsc(...specificities);\n return sorted[0];\n};\n\nexport { max, min };\n", "import parse from 'css-tree/selector-parser';\nimport Specificity from '../index.js';\nimport { max } from './../util/index.js';\n\n/** @param {import('css-tree').Selector} selectorAST */\nconst calculateForAST = (selectorAST) => {\n // Quit while you're ahead\n if (!selectorAST || selectorAST.type !== 'Selector') {\n throw new TypeError(`Passed in source is not a Selector AST`);\n }\n\n // https://www.w3.org/TR/selectors-4/#specificity-rules\n let a = 0; /* ID Selectors */\n let b = 0; /* Class selectors, Attributes selectors, and Pseudo-classes */\n let c = 0; /* Type selectors and Pseudo-elements */\n\n selectorAST.children.forEach((child) => {\n switch (child.type) {\n case 'IdSelector':\n a += 1;\n break;\n\n case 'AttributeSelector':\n case 'ClassSelector':\n b += 1;\n break;\n\n case 'PseudoClassSelector':\n switch (child.name.toLowerCase()) {\n // \u201CThe specificity of a :where() pseudo-class is replaced by zero.\u201D\n case 'where':\n // Noop :)\n break;\n\n case '-webkit-any':\n case 'any':\n if (child.children?.first) {\n b += 1;\n }\n break;\n\n // \u201CThe specificity of an :is(), :not(), or :has() pseudo-class is replaced by the specificity of the most specific complex selector in its selector list argument.\u201C\n case '-moz-any':\n case 'is':\n case 'matches':\n case 'not':\n case 'has':\n if (child.children?.first) {\n // Calculate Specificity from nested SelectorList\n const max1 = max(...calculate(child.children.first));\n\n // Adjust orig specificity\n a += max1.a;\n b += max1.b;\n c += max1.c;\n }\n\n break;\n\n // \u201CThe specificity of an :nth-child() or :nth-last-child() selector is the specificity of the pseudo class itself (counting as one pseudo-class selector) plus the specificity of the most specific complex selector in its selector list argument\u201D\n case 'nth-child':\n case 'nth-last-child':\n b += 1;\n\n if (child.children?.first?.selector) {\n // Calculate Specificity from SelectorList\n const max2 = max(...calculate(child.children.first.selector));\n\n // Adjust orig specificity\n a += max2.a;\n b += max2.b;\n c += max2.c;\n }\n break;\n\n // \u201CThe specificity of :host is that of a pseudo-class. The specificity of :host() is that of a pseudo-class, plus the specificity of its argument.\u201D\n // \u201CThe specificity of :host-context() is that of a pseudo-class, plus the specificity of its argument.\u201D\n case 'host-context':\n case 'host':\n b += 1;\n\n if (child.children?.first?.children) {\n // Workaround to a css-tree bug in which it allows complex selectors instead of only compound selectors\n // We work around it by filtering out any Combinator and successive Selectors\n const childAST = { type: 'Selector', children: [] };\n let foundCombinator = false;\n child.children.first.children.forEach((entry) => {\n if (foundCombinator) return false;\n if (entry.type === 'Combinator') {\n foundCombinator = true;\n return false;\n }\n childAST.children.push(entry);\n });\n\n // Calculate Specificity from Selector\n const childSpecificity = calculate(childAST)[0];\n\n // Adjust orig specificity\n a += childSpecificity.a;\n b += childSpecificity.b;\n c += childSpecificity.c;\n }\n break;\n\n // Improper use of Pseudo-Class Selectors instead of a Pseudo-Element\n // @ref https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements#index\n case 'after':\n case 'before':\n case 'first-letter':\n case 'first-line':\n c += 1;\n break;\n\n default:\n b += 1;\n break;\n }\n break;\n\n case 'PseudoElementSelector':\n switch (child.name) {\n // \u201CThe specificity of ::slotted() is that of a pseudo-element, plus the specificity of its argument.\u201D\n case 'slotted':\n c += 1;\n\n if (child.children?.first?.children) {\n // Workaround to a css-tree bug in which it allows complex selectors instead of only compound selectors\n // We work around it by filtering out any Combinator and successive Selectors\n const childAST = { type: 'Selector', children: [] };\n let foundCombinator = false;\n child.children.first.children.forEach((entry) => {\n if (foundCombinator) return false;\n if (entry.type === 'Combinator') {\n foundCombinator = true;\n return false;\n }\n childAST.children.push(entry);\n });\n\n // Calculate Specificity from Selector\n const childSpecificity = calculate(childAST)[0];\n\n // Adjust orig specificity\n a += childSpecificity.a;\n b += childSpecificity.b;\n c += childSpecificity.c;\n }\n break;\n\n case 'view-transition-group':\n case 'view-transition-image-pair':\n case 'view-transition-old':\n case 'view-transition-new':\n // The specificity of a view-transition selector with a * argument is zero.\n if (child.children?.first?.value === '*') {\n break;\n }\n // The specificity of a view-transition selector with an argument is the same\n // as for other pseudo - elements, and is equivalent to a type selector.\n c += 1;\n break;\n\n default:\n c += 1;\n break;\n }\n break;\n\n case 'TypeSelector':\n // Omit namespace\n let typeSelector = child.name;\n if (typeSelector.includes('|')) {\n typeSelector = typeSelector.split('|')[1];\n }\n\n // \u201CIgnore the universal selector\u201D\n if (typeSelector !== '*') {\n c += 1;\n }\n break;\n\n default:\n // NOOP\n break;\n }\n });\n\n return new Specificity({ a, b, c }, selectorAST);\n};\n\nconst convertToAST = (source) => {\n // The passed in argument was a String.\n // ~> Let's try and parse to an AST\n if (typeof source === 'string' || source instanceof String) {\n try {\n return parse(source, {\n context: 'selectorList',\n });\n } catch (e) {\n throw new TypeError(`Could not convert passed in source '${source}' to SelectorList: ${e.message}`);\n }\n }\n\n // The passed in argument was an Object.\n // ~> Let's verify if it's a AST of the type Selector or SelectorList\n if (source instanceof Object) {\n if (source.type && ['Selector', 'SelectorList'].includes(source.type)) {\n return source;\n }\n\n // Manually parsing subtree when the child is of the type Raw, most likely due to https://github.com/csstree/csstree/issues/151\n if (source.type && source.type === 'Raw') {\n try {\n return parse(source.value, {\n context: 'selectorList',\n });\n } catch (e) {\n throw new TypeError(`Could not convert passed in source to SelectorList: ${e.message}`);\n }\n }\n\n throw new TypeError(`Passed in source is an Object but no AST / AST of the type Selector or SelectorList`);\n }\n\n throw new TypeError(`Passed in source is not a String nor an Object. I don't know what to do with it.`);\n};\n\n/**\n * @param {string} selector\n * @returns {Specificity[]}\n */\nconst calculate = (selector) => {\n // Quit while you're ahead\n if (!selector) {\n return [];\n }\n\n // Make sure we have a SelectorList AST\n // If not, an exception will be thrown\n const ast = convertToAST(selector);\n\n // Selector?\n if (ast.type === 'Selector') {\n return [calculateForAST(selector)];\n }\n\n // SelectorList?\n // ~> Calculate Specificity for each contained Selector\n if (ast.type === 'SelectorList') {\n const specificities = [];\n ast.children.forEach((childAST) => {\n const specificity = calculateForAST(childAST);\n specificities.push(specificity);\n });\n return specificities;\n }\n};\n\nexport { calculate, calculateForAST };\n", "import generate from 'css-tree/generator';\n\nimport { calculate, calculateForAST } from './core/index.js';\nimport { compare, equals, greaterThan, lessThan } from './util/compare.js';\nimport { min, max } from './util/filter.js';\nimport { sortAsc, sortDesc } from './util/sort.js';\n\nclass NotAllowedError extends Error {\n constructor() {\n super('Manipulating a Specificity instance is not allowed. Instead, create a new Specificity()');\n }\n}\n\nclass Specificity {\n constructor(value, selector = null) {\n this.value = value;\n this.selector = selector;\n }\n\n get a() {\n return this.value.a;\n }\n\n set a(val) {\n throw new NotAllowedError();\n }\n\n get b() {\n return this.value.b;\n }\n\n set b(val) {\n throw new NotAllowedError();\n }\n\n get c() {\n return this.value.c;\n }\n\n set c(val) {\n throw new NotAllowedError();\n }\n\n selectorString() {\n // this.selector already is a String\n if (typeof this.selector === 'string' || this.selector instanceof String) {\n return this.selector;\n }\n\n // this.selector is a Selector as parsed by CSSTree\n if (this.selector instanceof Object) {\n if (this.selector.type === 'Selector') {\n return generate(this.selector);\n }\n }\n\n // this.selector is something else \u2026\n return '';\n }\n\n toObject() {\n return this.value;\n }\n\n toArray() {\n return [this.value.a, this.value.b, this.value.c];\n }\n\n toString() {\n return `(${this.value.a},${this.value.b},${this.value.c})`;\n }\n\n toJSON() {\n return {\n selector: this.selectorString(),\n asObject: this.toObject(),\n asArray: this.toArray(),\n asString: this.toString(),\n };\n }\n\n isEqualTo(otherSpecificity) {\n return equals(this, otherSpecificity);\n }\n\n isGreaterThan(otherSpecificity) {\n return greaterThan(this, otherSpecificity);\n }\n\n isLessThan(otherSpecificity) {\n return lessThan(this, otherSpecificity);\n }\n\n static calculate(selector) {\n return calculate(selector);\n }\n\n static calculateForAST(selector) {\n return calculateForAST(selector);\n }\n\n static compare(s1, s2) {\n return compare(s1, s2);\n }\n\n static equals(s1, s2) {\n return equals(s1, s2);\n }\n\n static lessThan(s1, s2) {\n return lessThan(s1, s2);\n }\n\n static greaterThan(s1, s2) {\n return greaterThan(s1, s2);\n }\n\n static min(...specificities) {\n return min(...specificities);\n }\n\n static max(...specificities) {\n return max(...specificities);\n }\n\n static sortAsc(...specificities) {\n return sortAsc(...specificities);\n }\n\n static sortDesc(...specificities) {\n return sortDesc(...specificities);\n }\n}\n\nexport default Specificity;\n"], + "mappings": "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", + "names": [] +} diff --git a/node_modules/@bramus/specificity/index.d.ts b/node_modules/@bramus/specificity/index.d.ts new file mode 100644 index 0000000..95d477a --- /dev/null +++ b/node_modules/@bramus/specificity/index.d.ts @@ -0,0 +1,59 @@ +// Types & Classes +export type SpecificityArray = [number, number, number]; +export type SpecificityObject = { a: number; b: number; c: number }; + +export default class Specificity { + static calculate(selector: string | CSSTreeAST): Array; + static calculateForAST(selectorAST: CSSTreeAST): Specificity; + static compare(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): number; + static equals(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): boolean; + static lessThan(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): boolean; + static greaterThan(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): boolean; + static min(...specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject; + static max(...specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject; + static sortAsc(...specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject; + static sortDesc(...specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject; + constructor(value: SpecificityObject, selector?: any); + value: SpecificityObject; + selector: string | CSSTreeAST; + set a(arg: number); + get a(): number; + set b(arg: number); + get b(): number; + set c(arg: number); + get c(): number; + selectorString(): string; + toObject(): SpecificityObject; + toArray(): SpecificityArray; + toString(): string; + toJSON(): { + selector: string; + asObject: SpecificityObject; + asArray: SpecificityArray; + asString: string; + }; + isEqualTo(otherSpecificity: SpecificityInstanceOrObject): boolean; + isGreaterThan(otherSpecificity: SpecificityInstanceOrObject): boolean; + isLessThan(otherSpecificity: SpecificityInstanceOrObject): boolean; +} + +type SpecificityInstanceOrObject = Specificity | SpecificityObject; +type CSSTreeAST = Object; // @TODO: Define shape + +// CORE +export function calculate(selector: string | CSSTreeAST): Array; +export function calculateForAST(selectorAST: CSSTreeAST): Specificity; + +// UTIL: COMPARE +export function equals(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): boolean; +export function greaterThan(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): boolean; +export function lessThan(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): boolean; +export function compare(s1: SpecificityInstanceOrObject, s2: SpecificityInstanceOrObject): number; + +// UTIL: FILTER +export function min(specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject; +export function max(specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject; + +// UTIL: SORT +export function sortAsc(specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject[]; +export function sortDesc(specificities: SpecificityInstanceOrObject[]): SpecificityInstanceOrObject[]; diff --git a/node_modules/@bramus/specificity/package.json b/node_modules/@bramus/specificity/package.json new file mode 100644 index 0000000..1674a61 --- /dev/null +++ b/node_modules/@bramus/specificity/package.json @@ -0,0 +1,92 @@ +{ + "name": "@bramus/specificity", + "version": "2.4.2", + "description": "Calculate specificity of a CSS Selector", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "exports": { + ".": { + "browser": "./dist/index.js", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./core": { + "import": "./src/core/index.js" + }, + "./util": { + "import": "./src/util/index.js" + }, + "./compare": { + "import": "./src/util/compare.js" + }, + "./filter": { + "import": "./src/util/filter.js" + }, + "./sort": { + "import": "./src/util/sort.js" + } + }, + "unpkg": "./dist/index.js", + "jsdelivr": "./dist/index.js", + "files": [ + "bin", + "src", + "dist", + "index.d.ts" + ], + "types": "./index.d.ts", + "bin": { + "specificity": "./bin/cli.js" + }, + "scripts": { + "build-esm": "esbuild --bundle ./src/index.js --outfile=./dist/index.js --format=esm --sourcemap --minify", + "build-cjs": "esbuild --bundle ./src/index.js --outfile=./dist/index.cjs --format=cjs --sourcemap --minify", + "lint": "prettier --check '{src,test}/**/*.{ts,tsx,js,jsx}'", + "format": "prettier --write '{src,test}/**/*.{ts,tsx,js,jsx}'", + "build": "npm run build-esm && npm run build-cjs", + "prepack": "npm run prevent-dirty-tree && npm run test", + "prepublish": "npm run build", + "pretest": "npm run build", + "test": "mocha", + "prebenchmark": "npm run build", + "benchmark": "node ./benchmark/bench.cjs", + "beta-version-patch": "npm version $(semver $npm_package_version -i prerelease --preid beta)", + "beta-version-minor": "npm version $(semver $npm_package_version -i preminor --preid beta)", + "beta-version-major": "npm version $(semver $npm_package_version -i premajor --preid beta)", + "rc-version": "npm version $(semver $npm_package_version -i prerelease --preid rc)", + "final-release": "npm version $(semver $npm_package_version -i)", + "preversion": "npm run prevent-dirty-tree && npm run test", + "prevent-dirty-tree": "exit $(git status --porcelain | wc -l)" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bramus/specificity.git" + }, + "keywords": [ + "css", + "specificity" + ], + "author": { + "name": "Bramus Van Damme", + "email": "bramus@bram.us", + "twitter": "@bramus", + "web": "https://www.bram.us/" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/bramus/specificity/issues" + }, + "homepage": "https://github.com/bramus/specificity#readme", + "devDependencies": { + "benchmark": "^2.1.4", + "esbuild": "^0.25.0", + "microtime": "^3.1.1", + "mocha": "^11.1.0", + "prettier": "^3.5.1", + "semver": "^7.7.1" + }, + "dependencies": { + "css-tree": "^3.0.0" + } +} diff --git a/node_modules/@bramus/specificity/src/core/calculate.js b/node_modules/@bramus/specificity/src/core/calculate.js new file mode 100644 index 0000000..f05b1ae --- /dev/null +++ b/node_modules/@bramus/specificity/src/core/calculate.js @@ -0,0 +1,260 @@ +import parse from 'css-tree/selector-parser'; +import Specificity from '../index.js'; +import { max } from './../util/index.js'; + +/** @param {import('css-tree').Selector} selectorAST */ +const calculateForAST = (selectorAST) => { + // Quit while you're ahead + if (!selectorAST || selectorAST.type !== 'Selector') { + throw new TypeError(`Passed in source is not a Selector AST`); + } + + // https://www.w3.org/TR/selectors-4/#specificity-rules + let a = 0; /* ID Selectors */ + let b = 0; /* Class selectors, Attributes selectors, and Pseudo-classes */ + let c = 0; /* Type selectors and Pseudo-elements */ + + selectorAST.children.forEach((child) => { + switch (child.type) { + case 'IdSelector': + a += 1; + break; + + case 'AttributeSelector': + case 'ClassSelector': + b += 1; + break; + + case 'PseudoClassSelector': + switch (child.name.toLowerCase()) { + // “The specificity of a :where() pseudo-class is replaced by zero.” + case 'where': + // Noop :) + break; + + case '-webkit-any': + case 'any': + if (child.children?.first) { + b += 1; + } + break; + + // “The specificity of an :is(), :not(), or :has() pseudo-class is replaced by the specificity of the most specific complex selector in its selector list argument.“ + case '-moz-any': + case 'is': + case 'matches': + case 'not': + case 'has': + if (child.children?.first) { + // Calculate Specificity from nested SelectorList + const max1 = max(...calculate(child.children.first)); + + // Adjust orig specificity + a += max1.a; + b += max1.b; + c += max1.c; + } + + break; + + // “The specificity of an :nth-child() or :nth-last-child() selector is the specificity of the pseudo class itself (counting as one pseudo-class selector) plus the specificity of the most specific complex selector in its selector list argument” + case 'nth-child': + case 'nth-last-child': + b += 1; + + if (child.children?.first?.selector) { + // Calculate Specificity from SelectorList + const max2 = max(...calculate(child.children.first.selector)); + + // Adjust orig specificity + a += max2.a; + b += max2.b; + c += max2.c; + } + break; + + // “The specificity of :host is that of a pseudo-class. The specificity of :host() is that of a pseudo-class, plus the specificity of its argument.” + // “The specificity of :host-context() is that of a pseudo-class, plus the specificity of its argument.” + case 'host-context': + case 'host': + b += 1; + + if (child.children?.first?.children) { + // Workaround to a css-tree bug in which it allows complex selectors instead of only compound selectors + // We work around it by filtering out any Combinator and successive Selectors + const childAST = { type: 'Selector', children: [] }; + let foundCombinator = false; + child.children.first.children.forEach((entry) => { + if (foundCombinator) return false; + if (entry.type === 'Combinator') { + foundCombinator = true; + return false; + } + childAST.children.push(entry); + }); + + // Calculate Specificity from Selector + const childSpecificity = calculate(childAST)[0]; + + // Adjust orig specificity + a += childSpecificity.a; + b += childSpecificity.b; + c += childSpecificity.c; + } + break; + + // Improper use of Pseudo-Class Selectors instead of a Pseudo-Element + // @ref https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements#index + case 'after': + case 'before': + case 'first-letter': + case 'first-line': + c += 1; + break; + + default: + b += 1; + break; + } + break; + + case 'PseudoElementSelector': + switch (child.name) { + // “The specificity of ::slotted() is that of a pseudo-element, plus the specificity of its argument.” + case 'slotted': + c += 1; + + if (child.children?.first?.children) { + // Workaround to a css-tree bug in which it allows complex selectors instead of only compound selectors + // We work around it by filtering out any Combinator and successive Selectors + const childAST = { type: 'Selector', children: [] }; + let foundCombinator = false; + child.children.first.children.forEach((entry) => { + if (foundCombinator) return false; + if (entry.type === 'Combinator') { + foundCombinator = true; + return false; + } + childAST.children.push(entry); + }); + + // Calculate Specificity from Selector + const childSpecificity = calculate(childAST)[0]; + + // Adjust orig specificity + a += childSpecificity.a; + b += childSpecificity.b; + c += childSpecificity.c; + } + break; + + case 'view-transition-group': + case 'view-transition-image-pair': + case 'view-transition-old': + case 'view-transition-new': + // The specificity of a view-transition selector with a * argument is zero. + if (child.children?.first?.value === '*') { + break; + } + // The specificity of a view-transition selector with an argument is the same + // as for other pseudo - elements, and is equivalent to a type selector. + c += 1; + break; + + default: + c += 1; + break; + } + break; + + case 'TypeSelector': + // Omit namespace + let typeSelector = child.name; + if (typeSelector.includes('|')) { + typeSelector = typeSelector.split('|')[1]; + } + + // “Ignore the universal selector” + if (typeSelector !== '*') { + c += 1; + } + break; + + default: + // NOOP + break; + } + }); + + return new Specificity({ a, b, c }, selectorAST); +}; + +const convertToAST = (source) => { + // The passed in argument was a String. + // ~> Let's try and parse to an AST + if (typeof source === 'string' || source instanceof String) { + try { + return parse(source, { + context: 'selectorList', + }); + } catch (e) { + throw new TypeError(`Could not convert passed in source '${source}' to SelectorList: ${e.message}`); + } + } + + // The passed in argument was an Object. + // ~> Let's verify if it's a AST of the type Selector or SelectorList + if (source instanceof Object) { + if (source.type && ['Selector', 'SelectorList'].includes(source.type)) { + return source; + } + + // Manually parsing subtree when the child is of the type Raw, most likely due to https://github.com/csstree/csstree/issues/151 + if (source.type && source.type === 'Raw') { + try { + return parse(source.value, { + context: 'selectorList', + }); + } catch (e) { + throw new TypeError(`Could not convert passed in source to SelectorList: ${e.message}`); + } + } + + throw new TypeError(`Passed in source is an Object but no AST / AST of the type Selector or SelectorList`); + } + + throw new TypeError(`Passed in source is not a String nor an Object. I don't know what to do with it.`); +}; + +/** + * @param {string} selector + * @returns {Specificity[]} + */ +const calculate = (selector) => { + // Quit while you're ahead + if (!selector) { + return []; + } + + // Make sure we have a SelectorList AST + // If not, an exception will be thrown + const ast = convertToAST(selector); + + // Selector? + if (ast.type === 'Selector') { + return [calculateForAST(selector)]; + } + + // SelectorList? + // ~> Calculate Specificity for each contained Selector + if (ast.type === 'SelectorList') { + const specificities = []; + ast.children.forEach((childAST) => { + const specificity = calculateForAST(childAST); + specificities.push(specificity); + }); + return specificities; + } +}; + +export { calculate, calculateForAST }; diff --git a/node_modules/@bramus/specificity/src/core/index.js b/node_modules/@bramus/specificity/src/core/index.js new file mode 100644 index 0000000..0db60bf --- /dev/null +++ b/node_modules/@bramus/specificity/src/core/index.js @@ -0,0 +1 @@ +export { calculate, calculateForAST } from './calculate.js'; diff --git a/node_modules/@bramus/specificity/src/index.js b/node_modules/@bramus/specificity/src/index.js new file mode 100644 index 0000000..cfa1932 --- /dev/null +++ b/node_modules/@bramus/specificity/src/index.js @@ -0,0 +1,135 @@ +import generate from 'css-tree/generator'; + +import { calculate, calculateForAST } from './core/index.js'; +import { compare, equals, greaterThan, lessThan } from './util/compare.js'; +import { min, max } from './util/filter.js'; +import { sortAsc, sortDesc } from './util/sort.js'; + +class NotAllowedError extends Error { + constructor() { + super('Manipulating a Specificity instance is not allowed. Instead, create a new Specificity()'); + } +} + +class Specificity { + constructor(value, selector = null) { + this.value = value; + this.selector = selector; + } + + get a() { + return this.value.a; + } + + set a(val) { + throw new NotAllowedError(); + } + + get b() { + return this.value.b; + } + + set b(val) { + throw new NotAllowedError(); + } + + get c() { + return this.value.c; + } + + set c(val) { + throw new NotAllowedError(); + } + + selectorString() { + // this.selector already is a String + if (typeof this.selector === 'string' || this.selector instanceof String) { + return this.selector; + } + + // this.selector is a Selector as parsed by CSSTree + if (this.selector instanceof Object) { + if (this.selector.type === 'Selector') { + return generate(this.selector); + } + } + + // this.selector is something else … + return ''; + } + + toObject() { + return this.value; + } + + toArray() { + return [this.value.a, this.value.b, this.value.c]; + } + + toString() { + return `(${this.value.a},${this.value.b},${this.value.c})`; + } + + toJSON() { + return { + selector: this.selectorString(), + asObject: this.toObject(), + asArray: this.toArray(), + asString: this.toString(), + }; + } + + isEqualTo(otherSpecificity) { + return equals(this, otherSpecificity); + } + + isGreaterThan(otherSpecificity) { + return greaterThan(this, otherSpecificity); + } + + isLessThan(otherSpecificity) { + return lessThan(this, otherSpecificity); + } + + static calculate(selector) { + return calculate(selector); + } + + static calculateForAST(selector) { + return calculateForAST(selector); + } + + static compare(s1, s2) { + return compare(s1, s2); + } + + static equals(s1, s2) { + return equals(s1, s2); + } + + static lessThan(s1, s2) { + return lessThan(s1, s2); + } + + static greaterThan(s1, s2) { + return greaterThan(s1, s2); + } + + static min(...specificities) { + return min(...specificities); + } + + static max(...specificities) { + return max(...specificities); + } + + static sortAsc(...specificities) { + return sortAsc(...specificities); + } + + static sortDesc(...specificities) { + return sortDesc(...specificities); + } +} + +export default Specificity; diff --git a/node_modules/@bramus/specificity/src/util/compare.js b/node_modules/@bramus/specificity/src/util/compare.js new file mode 100644 index 0000000..4e2fcf9 --- /dev/null +++ b/node_modules/@bramus/specificity/src/util/compare.js @@ -0,0 +1,23 @@ +const compare = (s1, s2) => { + if (s1.a === s2.a) { + if (s1.b === s2.b) { + return s1.c - s2.c; + } + return s1.b - s2.b; + } + return s1.a - s2.a; +}; + +const equals = (s1, s2) => { + return compare(s1, s2) === 0; +}; + +const greaterThan = (s1, s2) => { + return compare(s1, s2) > 0; +}; + +const lessThan = (s1, s2) => { + return compare(s1, s2) < 0; +}; + +export { compare, equals, greaterThan, lessThan }; diff --git a/node_modules/@bramus/specificity/src/util/filter.js b/node_modules/@bramus/specificity/src/util/filter.js new file mode 100644 index 0000000..4cf500a --- /dev/null +++ b/node_modules/@bramus/specificity/src/util/filter.js @@ -0,0 +1,13 @@ +import { sortAsc, sortDesc } from './sort.js'; + +const max = (...specificities) => { + const sorted = sortDesc(...specificities); + return sorted[0]; +}; + +const min = (...specificities) => { + const sorted = sortAsc(...specificities); + return sorted[0]; +}; + +export { max, min }; diff --git a/node_modules/@bramus/specificity/src/util/index.js b/node_modules/@bramus/specificity/src/util/index.js new file mode 100644 index 0000000..160f341 --- /dev/null +++ b/node_modules/@bramus/specificity/src/util/index.js @@ -0,0 +1,3 @@ +export * from './compare.js'; +export * from './sort.js'; +export * from './filter.js'; diff --git a/node_modules/@bramus/specificity/src/util/sort.js b/node_modules/@bramus/specificity/src/util/sort.js new file mode 100644 index 0000000..9691c6e --- /dev/null +++ b/node_modules/@bramus/specificity/src/util/sort.js @@ -0,0 +1,21 @@ +import { compare } from './compare.js'; + +const sort = (specificities, order = 'ASC') => { + const sorted = specificities.sort(compare); + + if (order === 'DESC') { + return sorted.reverse(); + } + + return sorted; +}; + +const sortAsc = (...specificities) => { + return sort(specificities, 'ASC'); +}; + +const sortDesc = (...specificities) => { + return sort(specificities, 'DESC'); +}; + +export { sortAsc, sortDesc }; diff --git a/node_modules/@csstools/color-helpers/CHANGELOG.md b/node_modules/@csstools/color-helpers/CHANGELOG.md new file mode 100644 index 0000000..d99d4c8 --- /dev/null +++ b/node_modules/@csstools/color-helpers/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changes to Color Helpers + +### 6.0.2 + +_February 21, 2026_ + +- Updated: gamut mapping algorithm + +[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers/CHANGELOG.md) diff --git a/node_modules/@csstools/color-helpers/LICENSE.md b/node_modules/@csstools/color-helpers/LICENSE.md new file mode 100644 index 0000000..e8ae93b --- /dev/null +++ b/node_modules/@csstools/color-helpers/LICENSE.md @@ -0,0 +1,18 @@ +MIT No Attribution (MIT-0) + +Copyright © CSSTools Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@csstools/color-helpers/README.md b/node_modules/@csstools/color-helpers/README.md new file mode 100644 index 0000000..97528d0 --- /dev/null +++ b/node_modules/@csstools/color-helpers/README.md @@ -0,0 +1,32 @@ +# Color Helpers for CSS + +[npm version][npm-url] +[Build Status][cli-url] +[Discord][discord] + +## Usage + +Add [Color Helpers] to your project: + +```bash +npm install @csstools/color-helpers --save-dev +``` + +This package exists to join all the different color functions scattered among the Colors 4 and Colors 5 plugins we maintain such as: + +* [PostCSS Color Function] +* [PostCSS Lab Function] +* [PostCSS OKLab Function] + +## Copyright + +This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/tree/main/css-color-4. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + +[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test +[discord]: https://discord.gg/bUadyRwkJS +[npm-url]: https://www.npmjs.com/package/@csstools/color-helpers + +[Color Helpers]: https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers +[PostCSS Color Function]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-function +[PostCSS Lab Function]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-lab-functionw +[PostCSS OKLab Function]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-oklab-function diff --git a/node_modules/@csstools/color-helpers/dist/index.d.ts b/node_modules/@csstools/color-helpers/dist/index.d.ts new file mode 100644 index 0000000..2eb948c --- /dev/null +++ b/node_modules/@csstools/color-helpers/dist/index.d.ts @@ -0,0 +1,429 @@ +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function a98_RGB_to_XYZ_D50(x: Color): Color; + +export declare function clip(color: Color): Color; + +export declare type Color = [number, number, number]; + +/** + * WCAG 2.1 contrast ratio + */ +export declare function contrast_ratio_wcag_2_1(color1: Color, color2: Color): number; + +/** + * Convert an array of linear-light display-p3 RGB in the range 0.0-1.0 + * to gamma corrected form + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */ +export declare function gam_P3(RGB: Color): Color; + +/** + * Convert an array of linear-light sRGB values in the range 0.0-1.0 to gamma corrected form + * Extended transfer function: + * For negative values, linear portion extends on reflection + * of axis, then uses reflected pow below that + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://en.wikipedia.org/wiki/SRGB + */ +export declare function gam_sRGB(RGB: Color): Color; + +/** + * @param {Color} color [h, s, l] + * - Hue as degrees 0..360; + * - Saturation as number 0..100; + * - Lightness as number 0..100; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function HSL_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [h, w, b] + * - Hue as degrees 0..360; + * - Whiteness as number 0..100; + * - Blackness as number 0..100; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function HWB_to_XYZ_D50(x: Color): Color; + +export declare function inGamut(x: Color): boolean; + +/** + * @param {Color} color [l, a, b] + * - Lightness as number 0..100; + * - a as number -160..160; + * - b as number -160..160; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function Lab_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [l, c, h] + * - Lightness as number 0..100; + * - Chroma as number 0..230; + * - Hue as degrees 0..360; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function LCH_to_XYZ_D50(x: Color): Color; + +/** + * Convert an array of display-p3 RGB values in the range 0.0 - 1.0 + * to linear light (un-companded) form. + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */ +export declare function lin_P3(RGB: Color): Color; + +/** + * Convert an array of linear-light display-p3 values to CIE XYZ + * using D65 (no chromatic adaptation) + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + */ +export declare function lin_P3_to_XYZ(rgb: Color): Color; + +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function lin_P3_to_XYZ_D50(x: Color): Color; + +/** + * Convert an array of of sRGB values where in-gamut values are in the range + * [0 - 1] to linear light (un-companded) form. + * Extended transfer function: + * For negative values, linear portion is extended on reflection of axis, + * then reflected power function is used. + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://en.wikipedia.org/wiki/SRGB + */ +export declare function lin_sRGB(RGB: Color): Color; + +/** + * Convert an array of linear-light sRGB values to CIE XYZ + * using sRGB's own white, D65 (no chromatic adaptation) + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */ +export declare function lin_sRGB_to_XYZ(rgb: Color): Color; + +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function lin_sRGB_to_XYZ_D50(x: Color): Color; + +export declare function mapGamut(startOKLCH: Color, toDestination: (x: Color) => Color, fromDestination: (x: Color) => Color): Color; + +/** + * @license MIT https://github.com/facelessuser/coloraide/blob/main/LICENSE.md + */ +export declare function mapGamutRayTrace(startOKLCH: Color, toLinear: (x: Color) => Color, fromLinear: (x: Color) => Color): Color; + +export declare const namedColors: Record; + +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js + */ +export declare function OKLab_to_OKLCH(OKLab: Color): Color; + +/** + * Given OKLab, convert to XYZ relative to D65 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js + */ +export declare function OKLab_to_XYZ(OKLab: Color): Color; + +/** + * @param {Color} color [l, a, b] + * - Lightness as number 0..1; + * - a as number 0..0.5; + * - b as number 0..0.5; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function OKLab_to_XYZ_D50(x: Color): Color; + +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js + */ +export declare function OKLCH_to_OKLab(OKLCH: Color): Color; + +/** + * @param {Color} color [l, c, h] + * - Lightness as number 0..1; + * - Chroma as number 0..0.5; + * - Hue as degrees 0..360; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function OKLCH_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function P3_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function ProPhoto_RGB_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function rec_2020_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function sRGB_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} a98 sRGB [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + */ +export declare function XYZ_D50_to_a98_RGB(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} HSL [r, g, b] + * - Hue as degrees 0..360; + * - Saturation as number 0..100; + * - Lightness as number 0..100; + */ +export declare function XYZ_D50_to_HSL(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} HWB [r, g, b] + * - Hue as degrees 0..360; + * - Whiteness as number 0..100; + * - Blackness as number 0..100; + */ +export declare function XYZ_D50_to_HWB(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} Lab [r, g, b] + * - Lightness as number 0..100; + * - a as number -160..160; + * - b as number -160..160; + */ +export declare function XYZ_D50_to_Lab(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} LCH [r, g, b] + * - Lightness as number 0..100; + * - Chroma as number 0..230; + * - Hue as degrees 0..360; + */ +export declare function XYZ_D50_to_LCH(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} P3 [r, g, b] + * - R as number 0..1; + * - G as number 0..1; + * - B as number 0..1; + */ +export declare function XYZ_D50_to_lin_P3(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} linear sRGB [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + */ +export declare function XYZ_D50_to_lin_sRGB(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} OKLab [r, g, b] + * - Lightness as number 0..1; + * - a as number 0..0.5; + * - b as number 0..0.5; + */ +export declare function XYZ_D50_to_OKLab(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} OKLCH [r, g, b] + * - Lightness as number 0..1; + * - Chroma as number 0..0.5; + * - Hue as degrees 0..360; + */ +export declare function XYZ_D50_to_OKLCH(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} P3 [r, g, b] + * - R as number 0..1; + * - G as number 0..1; + * - B as number 0..1; + */ +export declare function XYZ_D50_to_P3(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} ProPhoto [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + */ +export declare function XYZ_D50_to_ProPhoto(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} rec 2020 [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + */ +export declare function XYZ_D50_to_rec_2020(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} sRGB [r, g, b] + * - Red as number 0..1; + * - Green as number 0..1; + * - Blue as number 0..1; + */ +export declare function XYZ_D50_to_sRGB(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function XYZ_D50_to_XYZ_D50(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} D65 XYZ [x, y, z] + */ +export declare function XYZ_D50_to_XYZ_D65(x: Color): Color; + +/** + * @param {Color} color [x, y, z] + * - X as number 0..1; + * - Y as number 0..1; + * - Z as number 0..1; + * @return {Color} D50 XYZ [x, y, z] + */ +export declare function XYZ_D65_to_XYZ_D50(x: Color): Color; + +/** + * Convert XYZ to linear-light P3 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */ +export declare function XYZ_to_lin_P3(XYZ: Color): Color; + +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */ +export declare function XYZ_to_lin_sRGB(XYZ: Color): Color; + +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * + * XYZ <-> LMS matrices recalculated for consistent reference white + * @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484 + */ +export declare function XYZ_to_OKLab(XYZ: Color): Color; + +export { } diff --git a/node_modules/@csstools/color-helpers/dist/index.mjs b/node_modules/@csstools/color-helpers/dist/index.mjs new file mode 100644 index 0000000..6e9f3e6 --- /dev/null +++ b/node_modules/@csstools/color-helpers/dist/index.mjs @@ -0,0 +1,263 @@ +function multiplyMatrices(t,n){return[t[0]*n[0]+t[1]*n[1]+t[2]*n[2],t[3]*n[0]+t[4]*n[1]+t[5]*n[2],t[6]*n[0]+t[7]*n[1]+t[8]*n[2]]}const t=[.955473421488075,-.02309845494876471,.06325924320057072,-.0283697093338637,1.0099953980813041,.021041441191917323,.012314014864481998,-.020507649298898964,1.330365926242124]; +/** + * Bradford chromatic adaptation from D50 to D65 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function D50_to_D65(n){return multiplyMatrices(t,n)}const n=[1.0479297925449969,.022946870601609652,-.05019226628920524,.02962780877005599,.9904344267538799,-.017073799063418826,-.009243040646204504,.015055191490298152,.7518742814281371]; +/** + * Bradford chromatic adaptation from D65 to D50 + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html + */function D65_to_D50(t){return multiplyMatrices(n,t)} +/** + * @param {number} hue - Hue as degrees 0..360 + * @param {number} sat - Saturation as percentage 0..100 + * @param {number} light - Lightness as percentage 0..100 + * @return {number[]} Array of sRGB components; in-gamut colors in range [0..1] + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hslToRgb.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hslToRgb.js + */function HSL_to_sRGB(t){let n=t[0]%360;const _=t[1]/100,o=t[2]/100;return n<0&&(n+=360),[HSL_to_sRGB_channel(0,n,_,o),HSL_to_sRGB_channel(8,n,_,o),HSL_to_sRGB_channel(4,n,_,o)]}function HSL_to_sRGB_channel(t,n,_,o){const e=(t+n/30)%12;return o-_*Math.min(o,1-o)*Math.max(-1,Math.min(e-3,9-e,1))} +/** + * @param {number} hue - Hue as degrees 0..360 + * @param {number} white - Whiteness as percentage 0..100 + * @param {number} black - Blackness as percentage 0..100 + * @return {number[]} Array of RGB components 0..1 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hwbToRgb.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hwbToRgb.js + */function HWB_to_sRGB(t){const n=t[0],_=t[1]/100,o=t[2]/100;if(_+o>=1){const t=_/(_+o);return[t,t,t]}const e=HSL_to_sRGB([n,100,50]),a=1-_-o;return[e[0]*a+_,e[1]*a+_,e[2]*a+_]} +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function LCH_to_Lab(t){const n=t[2]*Math.PI/180;return[t[0],t[1]*Math.cos(n),t[1]*Math.sin(n)]} +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function Lab_to_LCH(t){const n=Math.sqrt(Math.pow(t[1],2)+Math.pow(t[2],2));let _=180*Math.atan2(t[2],t[1])/Math.PI;return _<0&&(_+=360),n<=.0015&&(_=NaN),[t[0],n,_]}const _=[.3457/.3585,1,.2958/.3585]; +/** + * Convert Lab to D50-adapted XYZ + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + */function Lab_to_XYZ(t){const n=24389/27,o=216/24389,e=(t[0]+16)/116,a=t[1]/500+e,r=e-t[2]/200;return[(Math.pow(a,3)>o?Math.pow(a,3):(116*a-16)/n)*_[0],(t[0]>8?Math.pow((t[0]+16)/116,3):t[0]/n)*_[1],(Math.pow(r,3)>o?Math.pow(r,3):(116*r-16)/n)*_[2]]} +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js + */function OKLCH_to_OKLab(t){const n=t[2]*Math.PI/180;return[t[0],t[1]*Math.cos(n),t[1]*Math.sin(n)]} +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js + */function OKLab_to_OKLCH(t){const n=Math.sqrt(t[1]**2+t[2]**2);let _=180*Math.atan2(t[2],t[1])/Math.PI;return _<0&&(_+=360),n<=4e-6&&(_=NaN),[t[0],n,_]}const o=[1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],e=[1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092]; +/** + * Given OKLab, convert to XYZ relative to D65 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js + */ +function OKLab_to_XYZ(t){const n=multiplyMatrices(e,t);return multiplyMatrices(o,[n[0]**3,n[1]**3,n[2]**3])} +/** + * Assuming XYZ is relative to D50, convert to CIE Lab + * from CIE standard, which now defines these as a rational fraction + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function XYZ_to_Lab(t){const n=compute_f(t[0]/_[0]),o=compute_f(t[1]/_[1]);return[116*o-16,500*(n-o),200*(o-compute_f(t[2]/_[2]))]}const a=216/24389,r=24389/27;function compute_f(t){return t>a?Math.cbrt(t):(r*t+16)/116}const l=[.819022437996703,.3619062600528904,-.1288737815209879,.0329836539323885,.9292868615863434,.0361446663506424,.0481771893596242,.2642395317527308,.6335478284694309],i=[.210454268309314,.7936177747023054,-.0040720430116193,1.9779985324311684,-2.42859224204858,.450593709617411,.0259040424655478,.7827717124575296,-.8086757549230774]; +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * + * XYZ <-> LMS matrices recalculated for consistent reference white + * @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484 + */ +function XYZ_to_OKLab(t){const n=multiplyMatrices(l,t);return multiplyMatrices(i,[Math.cbrt(n[0]),Math.cbrt(n[1]),Math.cbrt(n[2])])}const c=[30757411/17917100,-6372589/17917100,-4539589/17917100,-.666684351832489,1.616481236634939,467509/29648200,792561/44930125,-1921689/44930125,.942103121235474]; +/** + * Convert XYZ to linear-light rec2020 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */const u=[446124/178915,-333277/357830,-72051/178915,-14852/17905,63121/35810,423/17905,11844/330415,-50337/660830,316169/330415]; +/** + * Convert XYZ to linear-light P3 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function XYZ_to_lin_P3(t){return multiplyMatrices(u,t)}const s=[1.3457868816471583,-.25557208737979464,-.05110186497554526,-.5446307051249019,1.5082477428451468,.02052744743642139,0,0,1.2119675456389452]; +/** + * Convert D50 XYZ to linear-light prophoto-rgb + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + */const h=[1829569/896150,-506331/896150,-308931/896150,-851781/878810,1648619/878810,36519/878810,16779/1248040,-147721/1248040,1266979/1248040]; +/** + * Convert XYZ to linear-light a98-rgb + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */const m=[12831/3959,-329/214,-1974/3959,-851781/878810,1648619/878810,36519/878810,705/12673,-2585/12673,705/667]; +/** + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function XYZ_to_lin_sRGB(t){return multiplyMatrices(m,t)} +/** + * Convert an array of linear-light rec2020 RGB in the range 0.0-1.0 + * to gamma corrected form ITU-R BT.2020-2 p.4 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function gam_2020_channel(t){const n=t<0?-1:1,_=Math.abs(t);return n*Math.pow(_,1/2.4)} +/** + * Convert an array of linear-light sRGB values in the range 0.0-1.0 to gamma corrected form + * Extended transfer function: + * For negative values, linear portion extends on reflection + * of axis, then uses reflected pow below that + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://en.wikipedia.org/wiki/SRGB + */function gam_sRGB(t){return[gam_sRGB_channel(t[0]),gam_sRGB_channel(t[1]),gam_sRGB_channel(t[2])]}function gam_sRGB_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>.0031308?n*(1.055*Math.pow(_,1/2.4)-.055):12.92*t} +/** + * Convert an array of linear-light display-p3 RGB in the range 0.0-1.0 + * to gamma corrected form + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function gam_P3(t){return gam_sRGB(t)} +/** + * Convert an array of linear-light prophoto-rgb in the range 0.0-1.0 + * to gamma corrected form. + * Transfer curve is gamma 1.8 with a small linear portion. + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */const D=1/512;function gam_ProPhoto_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>=D?n*Math.pow(_,1/1.8):16*t} +/** + * Convert an array of linear-light a98-rgb in the range 0.0-1.0 + * to gamma corrected form. Negative values are also now accepted + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function gam_a98rgb_channel(t){const n=t<0?-1:1,_=Math.abs(t);return n*Math.pow(_,256/563)} +/** + * Convert an array of rec2020 RGB values in the range 0.0 - 1.0 + * to linear light (un-companded) form. + * ITU-R BT.2020-2 p.4 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function lin_2020_channel(t){const n=t<0?-1:1,_=Math.abs(t);return n*Math.pow(_,2.4)}const b=[63426534/99577255,20160776/139408157,47086771/278816314,26158966/99577255,.677998071518871,8267143/139408157,0,19567812/697040785,1.0609850577107909]; +/** + * Convert an array of linear-light rec2020 values to CIE XYZ + * using D65 (no chromatic adaptation) + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + */ +/** + * Convert an array of of sRGB values where in-gamut values are in the range + * [0 - 1] to linear light (un-companded) form. + * Extended transfer function: + * For negative values, linear portion is extended on reflection of axis, + * then reflected power function is used. + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://en.wikipedia.org/wiki/SRGB + */ +function lin_sRGB(t){return[lin_sRGB_channel(t[0]),lin_sRGB_channel(t[1]),lin_sRGB_channel(t[2])]}function lin_sRGB_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _<=.04045?t/12.92:n*Math.pow((_+.055)/1.055,2.4)} +/** + * Convert an array of display-p3 RGB values in the range 0.0 - 1.0 + * to linear light (un-companded) form. + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function lin_P3(t){return lin_sRGB(t)}const g=[608311/1250200,189793/714400,198249/1000160,35783/156275,247089/357200,198249/2500400,0,32229/714400,5220557/5000800]; +/** + * Convert an array of linear-light display-p3 values to CIE XYZ + * using D65 (no chromatic adaptation) + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + */function lin_P3_to_XYZ(t){return multiplyMatrices(g,t)} +/** + * Convert an array of prophoto-rgb values where in-gamut Colors are in the + * range [0.0 - 1.0] to linear light (un-companded) form. Transfer curve is + * gamma 1.8 with a small linear portion. Extended transfer function + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */const X=16/512;function lin_ProPhoto_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _<=X?t/16:n*Math.pow(_,1.8)}const Y=[.7977666449006423,.13518129740053308,.0313477341283922,.2880748288194013,.711835234241873,8993693872564e-17,0,0,.8251046025104602]; +/** + * Convert an array of linear-light prophoto-rgb values to CIE D50 XYZ. + * Matrix cannot be expressed in rational form, but is calculated to 64 bit accuracy. + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see see https://github.com/w3c/csswg-drafts/issues/7675 + */function lin_a98rgb_channel(t){const n=t<0?-1:1,_=Math.abs(t);return n*Math.pow(_,563/256)}const Z=[573536/994567,263643/1420810,187206/994567,591459/1989134,6239551/9945670,374412/4972835,53769/1989134,351524/4972835,4929758/4972835]; +/** + * Convert an array of linear-light a98-rgb values to CIE XYZ + * http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + * has greater numerical precision than section 4.3.5.3 of + * https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf + * but the values below were calculated from first principles + * from the chromaticity coordinates of R G B W + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + * @see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/matrixmaker.html + */const f=[506752/1228815,87881/245763,12673/70218,87098/409605,175762/245763,12673/175545,7918/409605,87881/737289,1001167/1053270]; +/** + * Convert an array of linear-light sRGB values to CIE XYZ + * using sRGB's own white, D65 (no chromatic adaptation) + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */function lin_sRGB_to_XYZ(t){return multiplyMatrices(f,t)} +/** + * Convert an array of gamma-corrected sRGB values in the 0.0 to 1.0 range to HSL. + * + * @param {Color} RGB [r, g, b] + * - Red component 0..1 + * - Green component 0..1 + * - Blue component 0..1 + * @return {number[]} Array of HSL values: Hue as degrees 0..360, Saturation and Lightness as percentages 0..100 + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/utilities.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/better-rgbToHsl.js + */function sRGB_to_HSL(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o),r=(a+e)/2,l=e-a;let i=Number.NaN,c=0;if(0!==Math.round(1e5*l)){const t=Math.round(1e5*r);switch(c=0===t||1e5===t?0:(e-r)/Math.min(r,1-r),e){case n:i=(_-o)/l+(_=360&&(i-=360);return c<=1e-5&&(i=NaN),[i,100*c,100*r]}function sRGB_to_Hue(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o);let r=Number.NaN;const l=e-a;if(0!==l){switch(e){case n:r=(_-o)/l+(_=360&&(r-=360),r}function sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n}function HSL_to_XYZ_D50(t){let n=t;return n=HSL_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HSL(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n=sRGB_to_HSL(n),n}function HWB_to_XYZ_D50(t){let n=t;return n=HWB_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HWB(t){let n=t;n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n);const _=gam_sRGB(n),o=Math.min(_[0],_[1],_[2]),e=1-Math.max(_[0],_[1],_[2]);let a=sRGB_to_Hue(_);return o+e>=.99999&&(a=NaN),[a,100*o,100*e]}function Lab_to_XYZ_D50(t){let n=t;return n=Lab_to_XYZ(n),n}function XYZ_D50_to_Lab(t){let n=t;return n=XYZ_to_Lab(n),n}function LCH_to_XYZ_D50(t){let n=t;return n=LCH_to_Lab(n),n=Lab_to_XYZ(n),n}function XYZ_D50_to_LCH(t){let n=t;return n=XYZ_to_Lab(n),n=Lab_to_LCH(n),n}function OKLab_to_XYZ_D50(t){let n=t;return n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLab(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n}function OKLCH_to_XYZ_D50(t){let n=t;return n=OKLCH_to_OKLab(n),n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLCH(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n=OKLab_to_OKLCH(n),n}function lin_sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_lin_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n}function a98_RGB_to_XYZ_D50(t){let n=t; +/** + * Convert an array of a98-rgb values in the range 0.0 - 1.0 + * to linear light (un-companded) form. Negative values are also now accepted + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + */ +var _;return n=[lin_a98rgb_channel((_=n)[0]),lin_a98rgb_channel(_[1]),lin_a98rgb_channel(_[2])],n=multiplyMatrices(Z,n),n=D65_to_D50(n),n}function XYZ_D50_to_a98_RGB(t){let n=t;var _;return n=D50_to_D65(n),n=multiplyMatrices(h,n),n=[gam_a98rgb_channel((_=n)[0]),gam_a98rgb_channel(_[1]),gam_a98rgb_channel(_[2])],n}function P3_to_XYZ_D50(t){let n=t;return n=lin_P3(n),n=lin_P3_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_P3(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_P3(n),n=gam_P3(n),n}function lin_P3_to_XYZ_D50(t){let n=t;return n=lin_P3_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_lin_P3(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_P3(n),n}function rec_2020_to_XYZ_D50(t){let n=t;var _;return n=[lin_2020_channel((_=n)[0]),lin_2020_channel(_[1]),lin_2020_channel(_[2])],n=multiplyMatrices(b,n),n=D65_to_D50(n),n}function XYZ_D50_to_rec_2020(t){let n=t;var _;return n=D50_to_D65(n),n=multiplyMatrices(c,n),n=[gam_2020_channel((_=n)[0]),gam_2020_channel(_[1]),gam_2020_channel(_[2])],n}function ProPhoto_RGB_to_XYZ_D50(t){let n=t;var _;return n=[lin_ProPhoto_channel((_=n)[0]),lin_ProPhoto_channel(_[1]),lin_ProPhoto_channel(_[2])],n=multiplyMatrices(Y,n),n}function XYZ_D50_to_ProPhoto(t){let n=t;var _;return n=multiplyMatrices(s,n),n=[gam_ProPhoto_channel((_=n)[0]),gam_ProPhoto_channel(_[1]),gam_ProPhoto_channel(_[2])],n}function XYZ_D65_to_XYZ_D50(t){let n=t;return n=D65_to_D50(n),n}function XYZ_D50_to_XYZ_D65(t){let n=t;return n=D50_to_D65(n),n}function XYZ_D50_to_XYZ_D50(t){return t}function inGamut(t){return t[0]>=-1e-4&&t[0]<=1.0001&&t[1]>=-1e-4&&t[1]<=1.0001&&t[2]>=-1e-4&&t[2]<=1.0001}function clip(t){return[t[0]<0?0:t[0]>1?1:t[0],t[1]<0?0:t[1]>1?1:t[1],t[2]<0?0:t[2]>1?1:t[2]]} +/** + * @description Calculate deltaE OK which is the simple root sum of squares + * @param {number[]} reference - Array of OKLab values: L as 0..1, a and b as -1..1 + * @param {number[]} sample - Array of OKLab values: L as 0..1, a and b as -1..1 + * @return {number} How different a color sample is from reference + * + * @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/deltaEOK.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). + * @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/deltaEOK.js + */function deltaEOK(t,n){const[_,o,e]=t,[a,r,l]=n,i=_-a,c=o-r,u=e-l;return Math.sqrt(i**2+c**2+u**2)}const M=.02,p=1e-4;function mapGamut(t,n,_){const o=t;let e=clip(n(o)),a=deltaEOK(OKLCH_to_OKLab(_(e)),OKLCH_to_OKLab(o));if(ap;){const t=(r+l)/2;if(o[1]=t,i&&inGamut(n(o)))r=t;else if(e=clip(n(o)),a=deltaEOK(OKLCH_to_OKLab(_(e)),OKLCH_to_OKLab(o)),a0){const t=_(a);t[0]=o,t[2]=e,a=n(t)}const l=rayTraceBox(r,a);if(!l)break;a=l}return clip(a)}function rayTraceBox(t,n){let _=1/0,o=-1/0;const e=[0,0,0];for(let a=0;a<3;a++){const r=t[a],l=n[a]-r;e[a]=l;const i=0,c=1;if(Math.abs(l)>1e-15){const t=1/l,n=(i-r)*t,e=(c-r)*t;o=Math.max(Math.min(n,e),o),_=Math.min(Math.max(n,e),_)}else if(rc)return!1}return!(o>_||_<0)&&(o<0&&(o=_),!!isFinite(o)&&[t[0]+e[0]*o,t[1]+e[1]*o,t[2]+e[2]*o])}const d={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};function luminance(t){const[n,_,o]=t.map(t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*n+.7152*_+.0722*o}function contrast_ratio_wcag_2_1(t,n){const _=luminance(t),o=luminance(n);return(Math.max(_,o)+.05)/(Math.min(_,o)+.05)}export{HSL_to_XYZ_D50,HWB_to_XYZ_D50,LCH_to_XYZ_D50,Lab_to_XYZ_D50,OKLCH_to_OKLab,OKLCH_to_XYZ_D50,OKLab_to_OKLCH,OKLab_to_XYZ,OKLab_to_XYZ_D50,P3_to_XYZ_D50,ProPhoto_RGB_to_XYZ_D50,XYZ_D50_to_HSL,XYZ_D50_to_HWB,XYZ_D50_to_LCH,XYZ_D50_to_Lab,XYZ_D50_to_OKLCH,XYZ_D50_to_OKLab,XYZ_D50_to_P3,XYZ_D50_to_ProPhoto,XYZ_D50_to_XYZ_D50,XYZ_D50_to_XYZ_D65,XYZ_D50_to_a98_RGB,XYZ_D50_to_lin_P3,XYZ_D50_to_lin_sRGB,XYZ_D50_to_rec_2020,XYZ_D50_to_sRGB,XYZ_D65_to_XYZ_D50,XYZ_to_OKLab,XYZ_to_lin_P3,XYZ_to_lin_sRGB,a98_RGB_to_XYZ_D50,clip,contrast_ratio_wcag_2_1,gam_P3,gam_sRGB,inGamut,lin_P3,lin_P3_to_XYZ,lin_P3_to_XYZ_D50,lin_sRGB,lin_sRGB_to_XYZ,lin_sRGB_to_XYZ_D50,mapGamut,mapGamutRayTrace,d as namedColors,rec_2020_to_XYZ_D50,sRGB_to_XYZ_D50}; diff --git a/node_modules/@csstools/color-helpers/package.json b/node_modules/@csstools/color-helpers/package.json new file mode 100644 index 0000000..1774c01 --- /dev/null +++ b/node_modules/@csstools/color-helpers/package.json @@ -0,0 +1,55 @@ +{ + "name": "@csstools/color-helpers", + "description": "Color helpers to ease transformation between formats, gamut, etc", + "version": "6.0.2", + "contributors": [ + { + "name": "Antonio Laguna", + "email": "antonio@laguna.es", + "url": "https://antonio.laguna.es" + }, + { + "name": "Romain Menke", + "email": "romainmenke@gmail.com" + } + ], + "license": "MIT-0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=20.19.0" + }, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "files": [ + "CHANGELOG.md", + "LICENSE.md", + "README.md", + "dist" + ], + "scripts": {}, + "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/csstools/postcss-plugins.git", + "directory": "packages/color-helpers" + }, + "bugs": "https://github.com/csstools/postcss-plugins/issues", + "keywords": [ + "colors", + "css" + ] +} diff --git a/node_modules/@csstools/css-calc/CHANGELOG.md b/node_modules/@csstools/css-calc/CHANGELOG.md new file mode 100644 index 0000000..64dde47 --- /dev/null +++ b/node_modules/@csstools/css-calc/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changes to CSS Calc + +### 3.2.0 + +_April 12, 2026_ + +- Add support for `round(line-width, 1.2345px)` +- Add `devicePixelLength` option + +[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc/CHANGELOG.md) diff --git a/node_modules/@csstools/css-calc/LICENSE.md b/node_modules/@csstools/css-calc/LICENSE.md new file mode 100644 index 0000000..af5411f --- /dev/null +++ b/node_modules/@csstools/css-calc/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2022 Romain Menke, Antonio Laguna + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@csstools/css-calc/README.md b/node_modules/@csstools/css-calc/README.md new file mode 100644 index 0000000..1e20fae --- /dev/null +++ b/node_modules/@csstools/css-calc/README.md @@ -0,0 +1,132 @@ +# CSS Calc for CSS + +[npm version][npm-url] +[Build Status][cli-url] +[Discord][discord] + +Implemented from : https://drafts.csswg.org/css-values-4/ on 2023-02-17 + +## Usage + +Add [CSS calc] to your project: + +```bash +npm install @csstools/css-calc @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev +``` + +### With string values : + +```mjs +import { calc } from '@csstools/css-calc'; + +// '20' +console.log(calc('calc(10 * 2)')); +``` + +### With component values : + +```mjs +import { stringify, tokenizer } from '@csstools/css-tokenizer'; +import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms'; +import { calcFromComponentValues } from '@csstools/css-calc'; + +const t = tokenizer({ + css: 'calc(10 * 2)', +}); + +const tokens = []; + +{ + while (!t.endOfFile()) { + tokens.push(t.nextToken()); + } + + tokens.push(t.nextToken()); // EOF-token +} + +const result = parseCommaSeparatedListOfComponentValues(tokens, {}); + +// filter or mutate the component values + +const calcResult = calcFromComponentValues(result, { precision: 5, toCanonicalUnits: true }); + +// filter or mutate the component values even further + +const calcResultStr = calcResult.map((componentValues) => { + return componentValues.map((x) => stringify(...x.tokens())).join(''); +}).join(','); + +// '20' +console.log(calcResultStr); +``` + +### Options + +#### `precision` : + +The default precision is fairly high. +It aims to be high enough to make rounding unnoticeable in the browser. + +You can set it to a lower number to suit your needs. + +```mjs +import { calc } from '@csstools/css-calc'; + +// '0.3' +console.log(calc('calc(1 / 3)', { precision: 1 })); +// '0.33' +console.log(calc('calc(1 / 3)', { precision: 2 })); +``` + +#### `globals` : + +Pass global values as a map of key value pairs. + +> Example : Relative color syntax (`lch(from pink calc(l / 2) c h)`) exposes color channel information as ident tokens. +> By passing globals for `l`, `c` and `h` it is possible to solve nested `calc()`'s. + +```mjs +import { calc } from '@csstools/css-calc'; + +const globals = new Map([ + ['a', '10px'], + ['b', '2rem'], +]); + +// '20px' +console.log(calc('calc(a * 2)', { globals: globals })); +// '6rem' +console.log(calc('calc(b * 3)', { globals: globals })); +``` + +#### `toCanonicalUnits` : + +By default this package will try to preserve units. +The heuristic to do this is very simplistic. +We take the first unit we encounter and try to convert other dimensions to that unit. + +This better matches what users expect from a CSS dev tool. + +If you want to have outputs that are closes to CSS serialized values you can pass `toCanonicalUnits: true`. + +```mjs +import { calc } from '@csstools/css-calc'; + +// '20hz' +console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: true })); + +// '20hz' +console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: true })); + +// '0.02khz' !!! +console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: false })); + +// '20hz' +console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: false })); +``` + +[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test +[discord]: https://discord.gg/bUadyRwkJS +[npm-url]: https://www.npmjs.com/package/@csstools/css-calc + +[CSS calc]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc diff --git a/node_modules/@csstools/css-calc/dist/index.d.ts b/node_modules/@csstools/css-calc/dist/index.d.ts new file mode 100644 index 0000000..2c41cf8 --- /dev/null +++ b/node_modules/@csstools/css-calc/dist/index.d.ts @@ -0,0 +1,106 @@ +import { ComponentValue } from '@csstools/css-parser-algorithms'; +import type { TokenDimension } from '@csstools/css-tokenizer'; +import type { TokenNumber } from '@csstools/css-tokenizer'; +import type { TokenPercentage } from '@csstools/css-tokenizer'; + +export declare function calc(css: string, options?: conversionOptions): string; + +export declare function calcFromComponentValues(componentValuesList: Array>, options?: conversionOptions): Array>; + +export declare type conversionOptions = { + /** + * If a calc expression can not be solved the parse error might be reported through this callback. + * Not all cases are covered. Open an issue if you need specific errors reported. + * + * Values are recursively visited and at each nesting level an attempt is made to solve the expression. + * Errors can be reported multiple times as a result of this. + */ + onParseError?: (error: ParseError) => void; + /** + * Pass global values as a map of key value pairs. + */ + globals?: GlobalsWithStrings; + /** + * The default precision is fairly high. + * It aims to be high enough to make rounding unnoticeable in the browser. + * You can set it to a lower number to suite your needs. + */ + precision?: number; + /** + * The CSS pixel length of one device pixel. + * Used when rounding to `line-width` and similar features + */ + devicePixelLength?: number; + /** + * By default this package will try to preserve units. + * The heuristic to do this is very simplistic. + * We take the first unit we encounter and try to convert other dimensions to that unit. + * + * This better matches what users expect from a CSS dev tool. + * + * If you want to have outputs that are closes to CSS serialized values you can set `true`. + */ + toCanonicalUnits?: boolean; + /** + * Convert NaN, Infinity, ... into standard representable values. + */ + censorIntoStandardRepresentableValues?: boolean; + /** + * Some percentages resolve against other values and might be negative or positive depending on context. + * Raw percentages are more likely to be safe to simplify outside of a browser context + * + * @see https://drafts.csswg.org/css-values-4/#calc-simplification + */ + rawPercentages?: boolean; + /** + * The values used to generate random value cache keys. + */ + randomCaching?: { + /** + * The name of the property the random function is used in. + */ + propertyName: string; + /** + * N is the index of the random function among other random functions in the same property value. + */ + propertyN: number; + /** + * An element ID identifying the element the style is being applied to. + * When omitted any `random()` call will not be computed. + */ + elementID: string; + /** + * A document ID identifying the Document the styles are from. + * When omitted any `random()` call will not be computed. + */ + documentID: string; + }; +}; + +export declare type GlobalsWithStrings = Map; + +export declare const mathFunctionNames: Set; + +/** + * Any errors are reported through the `onParseError` callback. + */ +export declare class ParseError extends Error { + /** The index of the start character of the current token. */ + sourceStart: number; + /** The index of the end character of the current token. */ + sourceEnd: number; + constructor(message: string, sourceStart: number, sourceEnd: number); +} + +export declare const ParseErrorMessage: { + UnexpectedAdditionOfDimensionOrPercentageWithNumber: string; + UnexpectedSubtractionOfDimensionOrPercentageWithNumber: string; +}; + +export declare class ParseErrorWithComponentValues extends ParseError { + /** The associated component values. */ + componentValues: Array; + constructor(message: string, componentValues: Array); +} + +export { } diff --git a/node_modules/@csstools/css-calc/dist/index.mjs b/node_modules/@csstools/css-calc/dist/index.mjs new file mode 100644 index 0000000..ca4cb04 --- /dev/null +++ b/node_modules/@csstools/css-calc/dist/index.mjs @@ -0,0 +1 @@ +import{sourceIndices as e,TokenNode as n,isTokenNode as t,isWhitespaceNode as r,isCommentNode as a,isWhiteSpaceOrCommentNode as u,isSimpleBlockNode as i,isFunctionNode as o,FunctionNode as l,WhitespaceNode as c,parseCommaSeparatedListOfComponentValues as s,walk as v}from"@csstools/css-parser-algorithms";import{isTokenDimension as f,TokenType as m,NumberType as p,mutateUnit as d,isTokenNumber as C,isTokenPercentage as g,isTokenIdent as D,isTokenNumeric as h,isTokenOpenParen as N,isTokenDelim as B,isTokenComma as A,isToken as b,tokenizer as F,tokenize as w,stringify as E,isTokenColon as I,isTokenSemicolon as S}from"@csstools/css-tokenizer";class ParseError extends Error{sourceStart;sourceEnd;constructor(e,n,t){super(e),this.name="ParseError",this.sourceStart=n,this.sourceEnd=t}}class ParseErrorWithComponentValues extends ParseError{componentValues;constructor(n,t){super(n,...e(t)),this.componentValues=t}}const y={UnexpectedAdditionOfDimensionOrPercentageWithNumber:"Unexpected addition of a dimension or percentage with a number.",UnexpectedSubtractionOfDimensionOrPercentageWithNumber:"Unexpected subtraction of a dimension or percentage with a number."},M=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(M,e=>String.fromCharCode(e.charCodeAt(0)+32))}const x={cm:"px",in:"px",mm:"px",pc:"px",pt:"px",px:"px",q:"px",deg:"deg",grad:"deg",rad:"deg",turn:"deg",ms:"s",s:"s",hz:"hz",khz:"hz"},T=new Map([["cm",e=>e],["mm",e=>10*e],["q",e=>40*e],["in",e=>e/2.54],["pc",e=>e/2.54*6],["pt",e=>e/2.54*72],["px",e=>e/2.54*96]]),P=new Map([["deg",e=>e],["grad",e=>e/.9],["rad",e=>e/180*Math.PI],["turn",e=>e/360]]),k=new Map([["deg",e=>.9*e],["grad",e=>e],["rad",e=>.9*e/180*Math.PI],["turn",e=>.9*e/360]]),W=new Map([["hz",e=>e],["khz",e=>e/1e3]]),O=new Map([["cm",e=>2.54*e],["mm",e=>25.4*e],["q",e=>25.4*e*4],["in",e=>e],["pc",e=>6*e],["pt",e=>72*e],["px",e=>96*e]]),U=new Map([["hz",e=>1e3*e],["khz",e=>e]]),L=new Map([["cm",e=>e/10],["mm",e=>e],["q",e=>4*e],["in",e=>e/25.4],["pc",e=>e/25.4*6],["pt",e=>e/25.4*72],["px",e=>e/25.4*96]]),$=new Map([["ms",e=>e],["s",e=>e/1e3]]),V=new Map([["cm",e=>e/6*2.54],["mm",e=>e/6*25.4],["q",e=>e/6*25.4*4],["in",e=>e/6],["pc",e=>e],["pt",e=>e/6*72],["px",e=>e/6*96]]),Z=new Map([["cm",e=>e/72*2.54],["mm",e=>e/72*25.4],["q",e=>e/72*25.4*4],["in",e=>e/72],["pc",e=>e/72*6],["pt",e=>e],["px",e=>e/72*96]]),z=new Map([["cm",e=>e/96*2.54],["mm",e=>e/96*25.4],["q",e=>e/96*25.4*4],["in",e=>e/96],["pc",e=>e/96*6],["pt",e=>e/96*72],["px",e=>e]]),q=new Map([["cm",e=>e/4/10],["mm",e=>e/4],["q",e=>e],["in",e=>e/4/25.4],["pc",e=>e/4/25.4*6],["pt",e=>e/4/25.4*72],["px",e=>e/4/25.4*96]]),G=new Map([["deg",e=>180*e/Math.PI],["grad",e=>180*e/Math.PI/.9],["rad",e=>e],["turn",e=>180*e/Math.PI/360]]),R=new Map([["ms",e=>1e3*e],["s",e=>e]]),j=new Map([["deg",e=>360*e],["grad",e=>360*e/.9],["rad",e=>360*e/180*Math.PI],["turn",e=>e]]),Y=new Map([["cm",T],["mm",L],["q",q],["in",O],["pc",V],["pt",Z],["px",z],["ms",$],["s",R],["deg",P],["grad",k],["rad",G],["turn",j],["hz",W],["khz",U]]);function convertUnit(e,n){if(!f(e))return n;if(!f(n))return n;const t=toLowerCaseAZ(e[4].unit),r=toLowerCaseAZ(n[4].unit);if(t===r)return n;const a=Y.get(r);if(!a)return n;const u=a.get(t);if(!u)return n;const i=u(n[4].value),o=[m.Dimension,"",n[2],n[3],{...n[4],signCharacter:i<0?"-":void 0,type:Number.isInteger(i)?p.Integer:p.Number,value:i}];return d(o,e[4].unit),o}function toCanonicalUnit(e){if(!f(e))return e;const n=toLowerCaseAZ(e[4].unit),t=x[n];if(n===t)return e;const r=Y.get(n);if(!r)return e;const a=r.get(t);if(!a)return e;const u=a(e[4].value),i=[m.Dimension,"",e[2],e[3],{...e[4],signCharacter:u<0?"-":void 0,type:Number.isInteger(u)?p.Integer:p.Number,value:u}];return d(i,t),i}function addition(e,t){if(2!==e.length)return-1;const r=e[0].value;let a=e[1].value;if(C(r)&&C(a)){const e=r[4].value+a[4].value;return new n([m.Number,e.toString(),r[2],a[3],{value:e,type:r[4].type===p.Integer&&a[4].type===p.Integer?p.Integer:p.Number}])}if(g(r)&&g(a)){const e=r[4].value+a[4].value;return new n([m.Percentage,e.toString()+"%",r[2],a[3],{value:e}])}if(f(r)&&f(a)&&(a=convertUnit(r,a),toLowerCaseAZ(r[4].unit)===toLowerCaseAZ(a[4].unit))){const e=r[4].value+a[4].value;return new n([m.Dimension,e.toString()+r[4].unit,r[2],a[3],{value:e,type:r[4].type===p.Integer&&a[4].type===p.Integer?p.Integer:p.Number,unit:r[4].unit}])}return(C(r)&&(f(a)||g(a))||C(a)&&(f(r)||g(r)))&&t.onParseError?.(new ParseErrorWithComponentValues(y.UnexpectedAdditionOfDimensionOrPercentageWithNumber,e)),-1}function division(e){if(2!==e.length)return-1;const t=e[0].value,r=e[1].value;if(C(t)&&C(r)){const e=t[4].value/r[4].value;return new n([m.Number,e.toString(),t[2],r[3],{value:e,type:Number.isInteger(e)?p.Integer:p.Number}])}if(g(t)&&C(r)){const e=t[4].value/r[4].value;return new n([m.Percentage,e.toString()+"%",t[2],r[3],{value:e}])}if(f(t)&&C(r)){const e=t[4].value/r[4].value;return new n([m.Dimension,e.toString()+t[4].unit,t[2],r[3],{value:e,type:Number.isInteger(e)?p.Integer:p.Number,unit:t[4].unit}])}return-1}function isCalculation(e){return!!e&&"object"==typeof e&&"inputs"in e&&Array.isArray(e.inputs)&&"operation"in e}function solve(e,n){if(-1===e)return-1;const r=[];for(let a=0;aconvertUnit(a,e.value));if(!arrayOfSameNumeric(u))return-1;const i=u.map(e=>e[4].value),o=Math.hypot(...i);return resultToCalculation(e,a,o)}function solveMax(e,n,r){if(!n.every(t))return-1;const a=n[0].value;if(!h(a))return-1;if(!r.rawPercentages&&g(a))return-1;const u=n.map(e=>convertUnit(a,e.value));if(!arrayOfSameNumeric(u))return-1;const i=u.map(e=>e[4].value),o=Math.max(...i);return resultToCalculation(e,a,o)}function solveMin(e,n,r){if(!n.every(t))return-1;const a=n[0].value;if(!h(a))return-1;if(!r.rawPercentages&&g(a))return-1;const u=n.map(e=>convertUnit(a,e.value));if(!arrayOfSameNumeric(u))return-1;const i=u.map(e=>e[4].value),o=Math.min(...i);return resultToCalculation(e,a,o)}function solveMod(e,n,t){const r=n.value;if(!h(r))return-1;const a=convertUnit(r,t.value);if(!twoOfSameNumeric(r,a))return-1;let u;return u=0===a[4].value?Number.NaN:Number.isFinite(r[4].value)&&(Number.isFinite(a[4].value)||(a[4].value!==Number.POSITIVE_INFINITY||r[4].value!==Number.NEGATIVE_INFINITY&&!Object.is(0*r[4].value,-0))&&(a[4].value!==Number.NEGATIVE_INFINITY||r[4].value!==Number.POSITIVE_INFINITY&&!Object.is(0*r[4].value,0)))?Number.isFinite(a[4].value)?(r[4].value%a[4].value+a[4].value)%a[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solvePow(e,n,t){const r=n.value,a=t.value;if(!C(r))return-1;if(!twoOfSameNumeric(r,a))return-1;return numberToCalculation(e,Math.pow(r[4].value,a[4].value))}function solveRem(e,n,t){const r=n.value;if(!h(r))return-1;const a=convertUnit(r,t.value);if(!twoOfSameNumeric(r,a))return-1;let u;return u=0===a[4].value?Number.NaN:Number.isFinite(r[4].value)?Number.isFinite(a[4].value)?r[4].value%a[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function snapAsBorderWidth(e,n,t){if(!f(n))return-1;const r=t.devicePixelLength??1,a=[m.Dimension,`${r}px`,n[2],n[3],{value:r,type:p.Integer,unit:"px"}],u=convertUnit(a,n);if(!twoOfSameNumeric(u,a))return-1;if(u[4].value<0)return-1;if(Number.isInteger(u[4].value/r))return resultToCalculation(e,n,n[4].value);if(u[4].value>0&&u[4].valuer){const t=Math.floor(u[4].value/a[4].value)*a[4].value;return u[4].value=t,resultToCalculation(e,n,convertUnit(n,u)[4].value)}return resultToCalculation(e,n,n[4].value)}function solveRound(e,n,t,r,a){const u=t.value;if(!h(u))return-1;if("line-width"===n&&!f(u))return-1;if(!a.rawPercentages&&g(u))return-1;const i=convertUnit(u,r.value);if(!twoOfSameNumeric(u,i))return-1;let o;if(0===i[4].value)o=Number.NaN;else if(Number.isFinite(u[4].value)||Number.isFinite(i[4].value))if(!Number.isFinite(u[4].value)&&Number.isFinite(i[4].value))o=u[4].value;else if(Number.isFinite(u[4].value)&&!Number.isFinite(i[4].value))switch(n){case"down":o=u[4].value<0?-1/0:Object.is(-0,0*u[4].value)?-0:0;break;case"up":o=u[4].value>0?1/0:Object.is(0,0*u[4].value)?0:-0;break;default:o=Object.is(0,0*u[4].value)?0:-0}else switch(n){case"down":o=Math.floor(u[4].value/i[4].value)*i[4].value;break;case"up":o=Math.ceil(u[4].value/i[4].value)*i[4].value;break;case"to-zero":o=Math.trunc(u[4].value/i[4].value)*i[4].value;break;default:{let t=Math.floor(u[4].value/i[4].value)*i[4].value,r=Math.ceil(u[4].value/i[4].value)*i[4].value;if(t>r){const e=t;t=r,r=e}const l=Math.abs(u[4].value-t),c=Math.abs(u[4].value-r);if(o="line-width"===n&&u[4].value>0&&(0===r||0===t)?0!==r?r:t:l===c?r:l0?1/0:-1/0:Math.tan(u),numberToCalculation(e,u)}function subtraction(e,t){if(2!==e.length)return-1;const r=e[0].value;let a=e[1].value;if(C(r)&&C(a)){const e=r[4].value-a[4].value;return new n([m.Number,e.toString(),r[2],a[3],{value:e,type:r[4].type===p.Integer&&a[4].type===p.Integer?p.Integer:p.Number}])}if(g(r)&&g(a)){const e=r[4].value-a[4].value;return new n([m.Percentage,e.toString()+"%",r[2],a[3],{value:e}])}if(f(r)&&f(a)&&(a=convertUnit(r,a),toLowerCaseAZ(r[4].unit)===toLowerCaseAZ(a[4].unit))){const e=r[4].value-a[4].value;return new n([m.Dimension,e.toString()+r[4].unit,r[2],a[3],{value:e,type:r[4].type===p.Integer&&a[4].type===p.Integer?p.Integer:p.Number,unit:r[4].unit}])}return(C(r)&&(f(a)||g(a))||C(a)&&(f(r)||g(r)))&&t.onParseError?.(new ParseErrorWithComponentValues(y.UnexpectedSubtractionOfDimensionOrPercentageWithNumber,e)),-1}function solveLog(e,n){if(1===n.length){const r=n[0];if(!r||!t(r))return-1;const a=r.value;if(!C(a))return-1;return numberToCalculation(e,Math.log(a[4].value))}if(2===n.length){const r=n[0];if(!r||!t(r))return-1;const a=r.value;if(!C(a))return-1;const u=n[1];if(!u||!t(u))return-1;const i=u.value;if(!C(i))return-1;return numberToCalculation(e,Math.log(a[4].value)/Math.log(i[4].value))}return-1}const _=/^none$/i;function isNone(e){if(Array.isArray(e)){const n=e.filter(e=>!(r(e)&&a(e)));return 1===n.length&&isNone(n[0])}if(!t(e))return!1;const n=e.value;return!!D(n)&&_.test(n[4].value)}const H=String.fromCodePoint(0);function solveRandom(e,n,t,r,a,u){if(-1===n.fixed&&!u.randomCaching)return-1;u.randomCaching||(u.randomCaching={propertyName:"",propertyN:0,elementID:"",documentID:""}),u.randomCaching&&!u.randomCaching.propertyN&&(u.randomCaching.propertyN=0);const i=t.value;if(!h(i))return-1;const o=convertUnit(i,r.value);if(!twoOfSameNumeric(i,o))return-1;let l=null;if(a&&(l=convertUnit(i,a.value),!twoOfSameNumeric(i,l)))return-1;if(!Number.isFinite(i[4].value))return resultToCalculation(e,i,Number.NaN);if(!Number.isFinite(o[4].value))return resultToCalculation(e,i,Number.NaN);if(!Number.isFinite(o[4].value-i[4].value))return resultToCalculation(e,i,Number.NaN);if(l&&!Number.isFinite(l[4].value))return resultToCalculation(e,i,i[4].value);const c=-1===n.fixed?sfc32(crc32([n.dashedIdent?n.dashedIdent:`${u.randomCaching?.propertyName} ${u.randomCaching.propertyN++}`,n.elementShared?"":u.randomCaching.elementID,u.randomCaching.documentID].join(H))):()=>n.fixed;let s=i[4].value,v=o[4].value;if(s>v&&([s,v]=[v,s]),l&&(l[4].value<=0||Math.abs(s-v)/l[4].value>1e10)&&(l=null),l){const n=Math.max(l[4].value/1e3,1e-9),t=[s];let r=0;for(;;){r+=l[4].value;const e=s+r;if(!(e+nv)break}const a=c();return resultToCalculation(e,i,Number(t[Math.floor(t.length*a)].toFixed(5)))}const f=c();return resultToCalculation(e,i,Number((f*(v-s)+s).toFixed(5)))}function sfc32(e=.34944106645296036,n=.19228640875738723,t=.8784393832007205,r=.04850964319275053){return()=>{const a=((e|=0)+(n|=0)|0)+(r|=0)|0;return r=r+1|0,e=n^n>>>9,n=(t|=0)+(t<<3)|0,t=(t=t<<21|t>>>11)+a|0,(a>>>0)/4294967296}}function crc32(e){let n,t,r=0;r^=-1;for(let a=0,u=e.length;a>>8^n;return(-1^r)>>>0}const J=new Map([["abs",function abs(e,n,t){return singleNodeSolver(e,n,t,solveAbs)}],["acos",function acos(e,n,t){return singleNodeSolver(e,n,t,solveACos)}],["asin",function asin(e,n,t){return singleNodeSolver(e,n,t,solveASin)}],["atan",function atan(e,n,t){return singleNodeSolver(e,n,t,solveATan)}],["atan2",function atan2(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveATan2)}],["calc",calc$1],["clamp",function clamp(r,a,i){const o=resolveGlobalsAndConstants([...r.value.filter(e=>!u(e))],a),c=[],s=[],v=[];{let e=c;for(let n=0;n!u(e)),n,t);if(-1===r)return-1;const[a,i]=r,o=variadicArguments(e,i,n,t);if(-1===o)return-1;const[l,c,s]=o;if(!l||!c)return-1;return solveRandom(e,a,l,c,s,t)}],["rem",function rem(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveRem)}],["round",function round(e,r,a){const i=resolveGlobalsAndConstants([...e.value.filter(e=>!u(e))],r);let o="",l=!1;const c=[],s=[];{let e=c;for(let n=0;n!u(e))],n);if(1===a.length&&t(a[0]))return{inputs:[a[0]],operation:unary};let l=0;for(;l!u(e))],n),a=solve(calc$1(calcWrapper(e,r),n,t),t);return-1===a?-1:a}function twoCommaSeparatedNodesSolver(e,n,t,r){const a=twoCommaSeparatedArguments(e,n,t);if(-1===a)return-1;const[u,i]=a;return r(e,u,i,t)}function twoCommaSeparatedArguments(e,n,r){const a=resolveGlobalsAndConstants([...e.value.filter(e=>!u(e))],n),i=[],o=[];{let e=i;for(let n=0;n!u(e))],r),o=[];{const n=[];let u=[];for(let e=0;e1)return-1;u.fixed=Math.max(0,Math.min(o.value[4].value,1-1e-9));continue}if("auto"!==l)if(l.startsWith("--")){if(-1!==u.fixed||u.isAuto)return-1;u.dashedIdent=l}else;else{if(-1!==u.fixed||u.dashedIdent)return-1;u.isAuto=!0}}else{if(-1!==u.fixed)return-1;u.elementShared=!0}}return-1}function calcWrapper(e,n){return new l([m.Function,"calc(",e.name[2],e.name[3],{value:"calc"}],[m.CloseParen,")",e.endToken[2],e.endToken[3],void 0],n)}function maxWrapper(t,r,a){return new l([m.Function,"max(",t.name[2],t.name[3],{value:"max"}],[m.CloseParen,")",t.endToken[2],t.endToken[3],void 0],[r,new n([m.Comma,",",...e(r),void 0]),a])}function patchNaN(e){if(-1===e)return-1;if(o(e))return e;const t=e.value;return h(t)&&Number.isNaN(t[4].value)?C(t)?new l([m.Function,"calc(",t[2],t[3],{value:"calc"}],[m.CloseParen,")",t[2],t[3],void 0],[new n([m.Ident,"NaN",t[2],t[3],{value:"NaN"}])]):f(t)?new l([m.Function,"calc(",t[2],t[3],{value:"calc"}],[m.CloseParen,")",t[2],t[3],void 0],[new n([m.Ident,"NaN",t[2],t[3],{value:"NaN"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Delim,"*",t[2],t[3],{value:"*"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Dimension,"1"+t[4].unit,t[2],t[3],{value:1,type:p.Integer,unit:t[4].unit}])]):g(t)?new l([m.Function,"calc(",t[2],t[3],{value:"calc"}],[m.CloseParen,")",t[2],t[3],void 0],[new n([m.Ident,"NaN",t[2],t[3],{value:"NaN"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Delim,"*",t[2],t[3],{value:"*"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Percentage,"1%",t[2],t[3],{value:1}])]):-1:e}function patchInfinity(e){if(-1===e)return-1;if(o(e))return e;const t=e.value;if(!h(t))return e;if(Number.isFinite(t[4].value)||Number.isNaN(t[4].value))return e;let r="";return Number.NEGATIVE_INFINITY===t[4].value&&(r="-"),C(t)?new l([m.Function,"calc(",t[2],t[3],{value:"calc"}],[m.CloseParen,")",t[2],t[3],void 0],[new n([m.Ident,r+"infinity",t[2],t[3],{value:r+"infinity"}])]):f(t)?new l([m.Function,"calc(",t[2],t[3],{value:"calc"}],[m.CloseParen,")",t[2],t[3],void 0],[new n([m.Ident,r+"infinity",t[2],t[3],{value:r+"infinity"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Delim,"*",t[2],t[3],{value:"*"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Dimension,"1"+t[4].unit,t[2],t[3],{value:1,type:p.Integer,unit:t[4].unit}])]):new l([m.Function,"calc(",t[2],t[3],{value:"calc"}],[m.CloseParen,")",t[2],t[3],void 0],[new n([m.Ident,r+"infinity",t[2],t[3],{value:r+"infinity"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Delim,"*",t[2],t[3],{value:"*"}]),new c([[m.Whitespace," ",t[2],t[3],void 0]]),new n([m.Percentage,"1%",t[2],t[3],{value:1}])])}function patchMinusZero(e){if(-1===e)return-1;if(o(e))return e;const n=e.value;return h(n)&&Object.is(-0,n[4].value)?("-0"===n[1]||(g(n)?n[1]="-0%":f(n)?n[1]="-0"+n[4].unit:n[1]="-0"),e):e}function patchPrecision(e,n=13){if(-1===e)return-1;if(n<=0)return e;if(o(e))return e;const t=e.value;if(!h(t))return e;if(Number.isInteger(t[4].value))return e;const r=Number(t[4].value.toFixed(n)).toString();return C(t)?t[1]=r:g(t)?t[1]=r+"%":f(t)&&(t[1]=r+t[4].unit),e}function patchCanonicalUnit(e){return-1===e?-1:o(e)?e:f(e.value)?(e.value=toCanonicalUnit(e.value),e):e}function patchCalcResult(e,n){let t=e;return n?.toCanonicalUnits&&(t=patchCanonicalUnit(t)),t=patchPrecision(t,n?.precision),t=patchMinusZero(t),n?.censorIntoStandardRepresentableValues||(t=patchNaN(t),t=patchInfinity(t)),t}function tokenizeGlobals(e){const n=new Map;if(!e)return n;for(const[t,r]of e)if(b(r))n.set(t,r);else if("string"==typeof r){const e=F({css:r}),a=e.nextToken();if(e.nextToken(),!e.endOfFile())continue;if(!h(a))continue;n.set(t,a);continue}return n}function calc(e,n){return calcFromComponentValues(s(w({css:e}),{}),n).map(e=>e.map(e=>E(...e.tokens())).join("")).join(",")}function calcFromComponentValues(e,n){const t=tokenizeGlobals(n?.globals);return replaceComponentValues(e,e=>{if(!o(e))return;const r=J.get(e.getName().toLowerCase());if(!r)return;const a=patchCalcResult(solve(r(e,t,n??{}),n??{}),n);return-1!==a?a:void 0})}function replaceComponentValues(n,r){for(let a=0;a{if("number"!=typeof a)return;const i=r(n.node);if(!i)return;const o=[i],l=n.parent.value[a-1];t(l)&&B(l.value)&&("-"===l.value[4].value||"+"===l.value[4].value)&&o.splice(0,0,new c([[m.Whitespace," ",...e(n.node),void 0]]));const s=n.parent.value[a+1];!s||u(s)||t(s)&&(A(s.value)||I(s.value)||S(s.value)||B(s.value)&&"-"!==s.value[4].value&&"+"!==s.value[4].value)||o.push(new c([[m.Whitespace," ",...e(n.node),void 0]])),n.parent.value.splice(a,1,...o)})}return n}const Q=new Set(J.keys());export{ParseError,y as ParseErrorMessage,ParseErrorWithComponentValues,calc,calcFromComponentValues,Q as mathFunctionNames}; diff --git a/node_modules/@csstools/css-calc/package.json b/node_modules/@csstools/css-calc/package.json new file mode 100644 index 0000000..5c645d4 --- /dev/null +++ b/node_modules/@csstools/css-calc/package.json @@ -0,0 +1,59 @@ +{ + "name": "@csstools/css-calc", + "description": "Solve CSS math expressions", + "version": "3.2.0", + "contributors": [ + { + "name": "Antonio Laguna", + "email": "antonio@laguna.es", + "url": "https://antonio.laguna.es" + }, + { + "name": "Romain Menke", + "email": "romainmenke@gmail.com" + } + ], + "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=20.19.0" + }, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "files": [ + "CHANGELOG.md", + "LICENSE.md", + "README.md", + "dist" + ], + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "scripts": {}, + "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/csstools/postcss-plugins.git", + "directory": "packages/css-calc" + }, + "bugs": "https://github.com/csstools/postcss-plugins/issues", + "keywords": [ + "calc", + "css" + ] +} diff --git a/node_modules/@csstools/css-color-parser/CHANGELOG.md b/node_modules/@csstools/css-color-parser/CHANGELOG.md new file mode 100644 index 0000000..cf70fa1 --- /dev/null +++ b/node_modules/@csstools/css-color-parser/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changes to CSS Color Parser + +### 4.1.0 + +_April 12, 2026_ + +- Add support for analogous set in color interpolations +- Updated [`@csstools/css-calc`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc) to [`3.2.0`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc/CHANGELOG.md#320) (minor) + +[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser/CHANGELOG.md) diff --git a/node_modules/@csstools/css-color-parser/LICENSE.md b/node_modules/@csstools/css-color-parser/LICENSE.md new file mode 100644 index 0000000..af5411f --- /dev/null +++ b/node_modules/@csstools/css-color-parser/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2022 Romain Menke, Antonio Laguna + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@csstools/css-color-parser/README.md b/node_modules/@csstools/css-color-parser/README.md new file mode 100644 index 0000000..f886fc9 --- /dev/null +++ b/node_modules/@csstools/css-color-parser/README.md @@ -0,0 +1,37 @@ +# CSS Color Parser for CSS + +[npm version][npm-url] +[Build Status][cli-url] +[Discord][discord] + +## Usage + +Add [CSS Color Parser] to your project: + +```bash +npm install @csstools/css-color-parser @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev +``` + +```ts +import { color } from '@csstools/css-color-parser'; +import { isFunctionNode, parseComponentValue } from '@csstools/css-parser-algorithms'; +import { serializeRGB } from '@csstools/css-color-parser'; +import { tokenize } from '@csstools/css-tokenizer'; + +// color() expects a parsed component value. +const hwbComponentValue = parseComponentValue(tokenize({ css: 'hwb(10deg 10% 20%)' })); +const colorData = color(hwbComponentValue); +if (colorData) { + console.log(colorData); + + // serializeRGB() returns a component value. + const rgbComponentValue = serializeRGB(colorData); + console.log(rgbComponentValue.toString()); +} +``` + +[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test +[discord]: https://discord.gg/bUadyRwkJS +[npm-url]: https://www.npmjs.com/package/@csstools/css-color-parser + +[CSS Color Parser]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser diff --git a/node_modules/@csstools/css-color-parser/dist/index.d.ts b/node_modules/@csstools/css-color-parser/dist/index.d.ts new file mode 100644 index 0000000..e4b8600 --- /dev/null +++ b/node_modules/@csstools/css-color-parser/dist/index.d.ts @@ -0,0 +1,168 @@ +import type { Color } from '@csstools/color-helpers'; +import type { ComponentValue } from '@csstools/css-parser-algorithms'; +import { FunctionNode } from '@csstools/css-parser-algorithms'; + +/** + * Convert a color function to a `ColorData` object. + * + * @param {ComponentValue} colorNode - The color function to be converted. + * @returns {ColorData|false} The color function as a `ColorData` object or `false` if it could not be converted. + */ +export declare function color(colorNode: ComponentValue): ColorData | false; + +/** + * A color data object. + * It contains as much information as possible about the color and the original parsed syntax. + */ +export declare interface ColorData { + /** + * The color notation of the color data. + * + * We use "color notation" and not "color space" because these represent the original notation and not the actual color space. + * The actual color space is however always implied by the color notation. + */ + colorNotation: ColorNotation; + /** + * The color channels. + * This is always an array of three numbers + * but the channels can only be interpreted by looking at the color notation. + */ + channels: Color; + /** + * The alpha channel. + * This is either a number between `0` and `1` or a `ComponentValue` object. + * + * Since most computations are not dependent on the alpha channel, + * we allow things like `var(--some-alpha)` as an alpha channel value for most inputs. + */ + alpha: number | ComponentValue; + /** + * Information about the original syntax. + */ + syntaxFlags: Set; +} + +/** + * Check if a color data object fits the `display-p3` gamut. + * + * @param {ColorData} x - The color data to be checked. + * @returns {boolean} Whether the color data fits the `display-p3` gamut. + */ +export declare function colorDataFitsDisplayP3_Gamut(x: ColorData): boolean; + +/** + * Check if a color data object fits the `sRGB` gamut. + * + * @param {ColorData} x - The color data to be checked. + * @returns {boolean} Whether the color data fits the `sRGB` gamut. + */ +export declare function colorDataFitsRGB_Gamut(x: ColorData): boolean; + +export declare enum ColorNotation { + /** Adobe 1999, expressed through `color(a98-rgb 0 0 0)` */ + A98_RGB = "a98-rgb", + /** Display P3, expressed through `color(display-p3 0 0 0)` */ + Display_P3 = "display-p3", + /** Display P3, expressed through `color(display-p3-linear 0 0 0)` */ + Linear_Display_P3 = "display-p3-linear", + /** Hex, expressed through `#000` */ + HEX = "hex", + /** HSL, expressed through `hsl(0 0% 0%)` */ + HSL = "hsl", + /** HWB, expressed through `hwb(0 0% 0%)` */ + HWB = "hwb", + /** LCH, expressed through `lch(0 0% 0deg)` */ + LCH = "lch", + /** Lab, expressed through `lab(0 0 0)` */ + Lab = "lab", + /** Linear sRGB, expressed through `color(linear-srgb 0 0 0)` */ + Linear_sRGB = "srgb-linear", + /** Oklch, expressed through `oklch(0 0% 0deg)` */ + OKLCH = "oklch", + /** Oklab, expressed through `oklab(0 0 0)` */ + OKLab = "oklab", + /** ProPhoto RGB, expressed through `color(prophoto-rgb 0 0 0)` */ + ProPhoto_RGB = "prophoto-rgb", + /** RGB, expressed through `rgb(0 0 0)` */ + RGB = "rgb", + /** sRGB, expressed through `color(srgb 0 0 0)` */ + sRGB = "srgb", + /** Rec. 2020, expressed through `color(rec2020 0 0 0)` */ + Rec2020 = "rec2020", + /** XYZ, expressed through `color(xyz-d50 0 0 0)` */ + XYZ_D50 = "xyz-d50", + /** XYZ, expressed through `color(xyz-d65 0 0 0)` */ + XYZ_D65 = "xyz-d65" +} + +export declare function serializeHSL(color: ColorData, gamutMapping?: boolean): FunctionNode; + +/** + * Convert color data to component values in the OKLCH color space. + * The return value can be converted to a string by calling `toString()` on it. + * + * @param {ColorData} color - The color data to be serialized. + * @returns {FunctionNode} The serialized color data as a FunctionNode object. + */ +export declare function serializeOKLCH(color: ColorData): FunctionNode; + +/** + * Convert color data to component values in the display-p3 color space. + * The return value can be converted to a string by calling `toString()` on it. + * + * @param {ColorData} color - The color data to be serialized. + * @param {boolean} gamutMapping - Whether to perform gamut mapping, defaults to `true`. + * @returns {FunctionNode} The serialized color data as a FunctionNode object. + */ +export declare function serializeP3(color: ColorData, gamutMapping?: boolean): FunctionNode; + +/** + * Convert color data to component values in the srgb color space. + * The return value can be converted to a string by calling `toString()` on it. + * + * @param {ColorData} color - The color data to be serialized. + * @param {boolean} gamutMapping - Whether to perform gamut mapping, defaults to `true`. + * @returns {FunctionNode} The serialized color data as a FunctionNode object. + */ +export declare function serializeRGB(color: ColorData, gamutMapping?: boolean): FunctionNode; + +export declare enum SyntaxFlag { + /** Is a color keyword, e.g. `transparent`, `currentColor`, ... */ + ColorKeyword = "color-keyword", + /** Has an explicit alpha channel */ + HasAlpha = "has-alpha", + /** Has a channel with a dimension value, e.g. `50deg` */ + HasDimensionValues = "has-dimension-values", + /** Has a channel with the `none` keyword */ + HasNoneKeywords = "has-none-keywords", + /** Has a channel with a number value */ + HasNumberValues = "has-number-values", + /** Has an alpha channel with a percentage value */ + HasPercentageAlpha = "has-percentage-alpha", + /** Has a channel with a percentage value */ + HasPercentageValues = "has-percentage-values", + /** Has an alpha channel with a `var()` function value */ + HasVariableAlpha = "has-variable-alpha", + /** Is Hex notation */ + Hex = "hex", + /** Is legacy HSL, e.g. `hsl(50deg, 0%, 0%)` */ + LegacyHSL = "legacy-hsl", + /** Is legacy RGB, e.g. `rgb(0, 0, 0)` */ + LegacyRGB = "legacy-rgb", + /** Is a named color, e.g. `red`, `blue` */ + NamedColor = "named-color", + /** Is a relative color syntax, e.g. `rgb(from purple r g b)` */ + RelativeColorSyntax = "relative-color-syntax", + /** Is a mixed color, e.g. `color-mix(in oklch, red, blue)` */ + ColorMix = "color-mix", + /** Is a variadic mixed color, e.g. `color-mix(in oklch, red)` `color-mix(in oklch, red, blue, green)` */ + ColorMixVariadic = "color-mix-variadic", + /** Is a contrasting color, e.g. `contrast-color()` */ + ContrastColor = "contrast-color", + /** Is a relative alpha syntax `alpha(from red / 0.5)` */ + RelativeAlphaSyntax = "relative-alpha-syntax", + /** Is an experimental color syntax */ + Experimental = "experimental" +} + +export { } diff --git a/node_modules/@csstools/css-color-parser/dist/index.mjs b/node_modules/@csstools/css-color-parser/dist/index.mjs new file mode 100644 index 0000000..95a76b1 --- /dev/null +++ b/node_modules/@csstools/css-color-parser/dist/index.mjs @@ -0,0 +1 @@ +import{TokenType as e,NumberType as a,isTokenIdent as n,isTokenPercentage as r,isTokenNumber as o,isTokenDelim as l,isTokenNumeric as t,isTokenComma as s,isTokenDimension as u,isTokenHash as i}from"@csstools/css-tokenizer";import{XYZ_D50_to_XYZ_D65 as c,XYZ_D50_to_XYZ_D50 as h,XYZ_D50_to_OKLab as m,XYZ_D50_to_OKLCH as p,XYZ_D50_to_LCH as N,XYZ_D50_to_Lab as b,XYZ_D50_to_HWB as g,XYZ_D50_to_HSL as v,XYZ_D50_to_a98_RGB as f,XYZ_D50_to_ProPhoto as d,XYZ_D50_to_rec_2020 as y,XYZ_D50_to_lin_P3 as _,XYZ_D50_to_P3 as C,XYZ_D50_to_lin_sRGB as w,XYZ_D50_to_sRGB as x,XYZ_D65_to_XYZ_D50 as L,OKLCH_to_XYZ_D50 as H,LCH_to_XYZ_D50 as P,OKLab_to_XYZ_D50 as k,Lab_to_XYZ_D50 as S,HWB_to_XYZ_D50 as M,HSL_to_XYZ_D50 as D,ProPhoto_RGB_to_XYZ_D50 as F,a98_RGB_to_XYZ_D50 as z,rec_2020_to_XYZ_D50 as Z,lin_P3_to_XYZ_D50 as R,P3_to_XYZ_D50 as B,lin_sRGB_to_XYZ_D50 as V,sRGB_to_XYZ_D50 as T,namedColors as G,inGamut as A,clip as X,gam_sRGB as K,mapGamutRayTrace as Y,OKLCH_to_OKLab as I,OKLab_to_XYZ as O,XYZ_to_lin_sRGB as W,lin_sRGB_to_XYZ as E,XYZ_to_OKLab as U,OKLab_to_OKLCH as $,contrast_ratio_wcag_2_1 as j,gam_P3 as q,XYZ_to_lin_P3 as J,lin_P3_to_XYZ as Q}from"@csstools/color-helpers";import{isWhitespaceNode as ee,isCommentNode as ae,isTokenNode as ne,isFunctionNode as re,TokenNode as oe,isWhiteSpaceOrCommentNode as le,replaceComponentValues as te,FunctionNode as se,WhitespaceNode as ue}from"@csstools/css-parser-algorithms";import{mathFunctionNames as ie,calcFromComponentValues as ce}from"@csstools/css-calc";var he,me;function convertNaNToZero(e){return[Number.isNaN(e[0])?0:e[0],Number.isNaN(e[1])?0:e[1],Number.isNaN(e[2])?0:e[2]]}function colorData_to_XYZ_D50(e){switch(e.colorNotation){case he.HEX:case he.RGB:case he.sRGB:return{...e,colorNotation:he.XYZ_D50,channels:T(convertNaNToZero(e.channels))};case he.Linear_sRGB:return{...e,colorNotation:he.XYZ_D50,channels:V(convertNaNToZero(e.channels))};case he.Display_P3:return{...e,colorNotation:he.XYZ_D50,channels:B(convertNaNToZero(e.channels))};case he.Linear_Display_P3:return{...e,colorNotation:he.XYZ_D50,channels:R(convertNaNToZero(e.channels))};case he.Rec2020:return{...e,colorNotation:he.XYZ_D50,channels:Z(convertNaNToZero(e.channels))};case he.A98_RGB:return{...e,colorNotation:he.XYZ_D50,channels:z(convertNaNToZero(e.channels))};case he.ProPhoto_RGB:return{...e,colorNotation:he.XYZ_D50,channels:F(convertNaNToZero(e.channels))};case he.HSL:return{...e,colorNotation:he.XYZ_D50,channels:D(convertNaNToZero(e.channels))};case he.HWB:return{...e,colorNotation:he.XYZ_D50,channels:M(convertNaNToZero(e.channels))};case he.Lab:return{...e,colorNotation:he.XYZ_D50,channels:S(convertNaNToZero(e.channels))};case he.OKLab:return{...e,colorNotation:he.XYZ_D50,channels:k(convertNaNToZero(e.channels))};case he.LCH:return{...e,colorNotation:he.XYZ_D50,channels:P(convertNaNToZero(e.channels))};case he.OKLCH:return{...e,colorNotation:he.XYZ_D50,channels:H(convertNaNToZero(e.channels))};case he.XYZ_D50:return{...e,colorNotation:he.XYZ_D50,channels:h(convertNaNToZero(e.channels))};case he.XYZ_D65:return{...e,colorNotation:he.XYZ_D50,channels:L(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}!function(e){e.A98_RGB="a98-rgb",e.Display_P3="display-p3",e.Linear_Display_P3="display-p3-linear",e.HEX="hex",e.HSL="hsl",e.HWB="hwb",e.LCH="lch",e.Lab="lab",e.Linear_sRGB="srgb-linear",e.OKLCH="oklch",e.OKLab="oklab",e.ProPhoto_RGB="prophoto-rgb",e.RGB="rgb",e.sRGB="srgb",e.Rec2020="rec2020",e.XYZ_D50="xyz-d50",e.XYZ_D65="xyz-d65"}(he||(he={})),function(e){e.ColorKeyword="color-keyword",e.HasAlpha="has-alpha",e.HasDimensionValues="has-dimension-values",e.HasNoneKeywords="has-none-keywords",e.HasNumberValues="has-number-values",e.HasPercentageAlpha="has-percentage-alpha",e.HasPercentageValues="has-percentage-values",e.HasVariableAlpha="has-variable-alpha",e.Hex="hex",e.LegacyHSL="legacy-hsl",e.LegacyRGB="legacy-rgb",e.NamedColor="named-color",e.RelativeColorSyntax="relative-color-syntax",e.ColorMix="color-mix",e.ColorMixVariadic="color-mix-variadic",e.ContrastColor="contrast-color",e.RelativeAlphaSyntax="relative-alpha-syntax",e.Experimental="experimental"}(me||(me={}));const pe=new Set([he.A98_RGB,he.Display_P3,he.Linear_Display_P3,he.HEX,he.Linear_sRGB,he.ProPhoto_RGB,he.RGB,he.sRGB,he.Rec2020,he.XYZ_D50,he.XYZ_D65]);function colorDataTo(e,a){const n={...e};if(e.colorNotation!==a){const e=colorData_to_XYZ_D50(n);switch(a){case he.HEX:case he.RGB:n.colorNotation=he.RGB,n.channels=x(e.channels);break;case he.sRGB:n.colorNotation=he.sRGB,n.channels=x(e.channels);break;case he.Linear_sRGB:n.colorNotation=he.Linear_sRGB,n.channels=w(e.channels);break;case he.Display_P3:n.colorNotation=he.Display_P3,n.channels=C(e.channels);break;case he.Linear_Display_P3:n.colorNotation=he.Linear_Display_P3,n.channels=_(e.channels);break;case he.Rec2020:n.colorNotation=he.Rec2020,n.channels=y(e.channels);break;case he.ProPhoto_RGB:n.colorNotation=he.ProPhoto_RGB,n.channels=d(e.channels);break;case he.A98_RGB:n.colorNotation=he.A98_RGB,n.channels=f(e.channels);break;case he.HSL:n.colorNotation=he.HSL,n.channels=v(e.channels);break;case he.HWB:n.colorNotation=he.HWB,n.channels=g(e.channels);break;case he.Lab:n.colorNotation=he.Lab,n.channels=b(e.channels);break;case he.LCH:n.colorNotation=he.LCH,n.channels=N(e.channels);break;case he.OKLCH:n.colorNotation=he.OKLCH,n.channels=p(e.channels);break;case he.OKLab:n.colorNotation=he.OKLab,n.channels=m(e.channels);break;case he.XYZ_D50:n.colorNotation=he.XYZ_D50,n.channels=h(e.channels);break;case he.XYZ_D65:n.colorNotation=he.XYZ_D65,n.channels=c(e.channels);break;default:throw new Error("Unsupported color notation")}}else n.channels=convertNaNToZero(e.channels);if(a===e.colorNotation)n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);else if(pe.has(a)&&pe.has(e.colorNotation))n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);else switch(a){case he.HSL:switch(e.colorNotation){case he.HWB:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[2],[0,1],n.channels,[0],[1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[2,1,0],[]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;case he.HWB:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[2],[0,1]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;case he.Lab:case he.OKLab:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[2],[0,1]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;case he.LCH:case he.OKLCH:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[2,1,0],[]);break;case he.HWB:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[2],[0,1]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}return n.channels=convertPowerlessComponentsToMissingComponents(n.channels,a),n}function convertPowerlessComponentsToMissingComponents(e,a){const n=[...e];switch(a){case he.HSL:!Number.isNaN(n[1])&&reducePrecision(n[1],4)<=0&&(n[0]=Number.NaN);break;case he.HWB:Math.max(0,reducePrecision(n[1],4))+Math.max(0,reducePrecision(n[2],4))>=100&&(n[0]=Number.NaN);break;case he.LCH:!Number.isNaN(n[1])&&reducePrecision(n[1],4)<=0&&(n[2]=Number.NaN);break;case he.OKLCH:!Number.isNaN(n[1])&&reducePrecision(n[1],6)<=0&&(n[2]=Number.NaN)}return n}function convertPowerlessComponentsToZeroValuesForDisplay(e,a){const n=[...e];switch(a){case he.HSL:(reducePrecision(n[2])<=0||reducePrecision(n[2])>=100)&&(n[0]=Number.NaN,n[1]=Number.NaN),reducePrecision(n[1])<=0&&(n[0]=Number.NaN);break;case he.HWB:Math.max(0,reducePrecision(n[1]))+Math.max(0,reducePrecision(n[2]))>=100&&(n[0]=Number.NaN);break;case he.Lab:(reducePrecision(n[0])<=0||reducePrecision(n[0])>=100)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.LCH:reducePrecision(n[1])<=0&&(n[2]=Number.NaN),(reducePrecision(n[0])<=0||reducePrecision(n[0])>=100)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.OKLab:(reducePrecision(n[0])<=0||reducePrecision(n[0])>=1)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.OKLCH:reducePrecision(n[1])<=0&&(n[2]=Number.NaN),(reducePrecision(n[0])<=0||reducePrecision(n[0])>=1)&&(n[1]=Number.NaN,n[2]=Number.NaN)}return n}function carryForwardMissingComponents(e,a,n,r,o,l){if(a.length<3&&e.every(Number.isNaN))return[Number.NaN,Number.NaN,Number.NaN];const t=[...r];for(let n=0;nNumber.isNaN(e[a])))for(let e=0;ee<-1e-5||e>1.00001)}function colorDataFitsDisplayP3_Gamut(e){const a={...e,channels:[...e.channels]};a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);return!colorDataTo(a,he.Display_P3).channels.find(e=>e<-1e-5||e>1.00001)}function normalize(e,a,n,r){return Math.min(Math.max(e/a,n),r)}const Ne=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(Ne,e=>String.fromCharCode(e.charCodeAt(0)+32))}function normalize_Color_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}const be=new Set(["srgb","srgb-linear","display-p3","display-p3-linear","a98-rgb","prophoto-rgb","rec2020","xyz","xyz-d50","xyz-d65"]);function color$1(e,a){const r=[],s=[],u=[],i=[];let c,h,m=!1,p=!1;const N={colorNotation:he.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};let b=r;for(let o=0;o=0){u=i.value[4].value;continue}}return!1}if(!l)return!1;n.push({color:l,percentage:u}),l=!1,u=!1}}if(!l)return!1;n.push({color:l,percentage:u});let i=0,c=0;for(let e=0;e100)return!1;i+=a}else c++}const h=Math.max(0,100-i);i=0;for(let e=0;e100)for(let e=0;e=2;){const e=n.pop(),a=n.pop();if(!e||!a)return!1;const o=colorMixRectangularPair(r,e.color,e.percentage,a.color,a.percentage);if(!o)return!1;n.push({color:o,percentage:e.percentage+a.percentage})}const o=n[0]?.color;return!!o&&(a.colors.some(e=>e.color.syntaxFlags.has(me.Experimental))&&o.syntaxFlags.add(me.Experimental),"number"==typeof o.alpha&&(o.alpha=o.alpha*a.alphaMultiplier,2!==a.colors.length&&o.syntaxFlags.add(me.ColorMixVariadic),o))}function colorMixRectangularPair(e,a,n,r,o){const l=n/(n+o);let t=a.alpha;if("number"!=typeof t)return!1;let s=r.alpha;if("number"!=typeof s)return!1;t=Number.isNaN(t)?s:t,s=Number.isNaN(s)?t:s;const u=colorDataTo(a,e).channels,i=colorDataTo(r,e).channels;u[0]=fillInMissingComponent(u[0],i[0]),i[0]=fillInMissingComponent(i[0],u[0]),u[1]=fillInMissingComponent(u[1],i[1]),i[1]=fillInMissingComponent(i[1],u[1]),u[2]=fillInMissingComponent(u[2],i[2]),i[2]=fillInMissingComponent(i[2],u[2]),u[0]=premultiply(u[0],t),u[1]=premultiply(u[1],t),u[2]=premultiply(u[2],t),i[0]=premultiply(i[0],s),i[1]=premultiply(i[1],s),i[2]=premultiply(i[2],s);const c=interpolate(t,s,l);return{colorNotation:e,channels:[un_premultiply(interpolate(u[0],i[0],l),c),un_premultiply(interpolate(u[1],i[1],l),c),un_premultiply(interpolate(u[2],i[2],l),c)],alpha:c,syntaxFlags:new Set([me.ColorMix])}}function colorMixPolar(e,a,n){if(!n||!n.colors.length)return!1;const r=n.colors.slice();let o;switch(r.reverse(),e){case"hsl":o=he.HSL;break;case"hwb":o=he.HWB;break;case"lch":o=he.LCH;break;case"oklch":o=he.OKLCH;break;default:return!1}if(1===r.length){const e=colorDataTo(r[0].color,o);return e.colorNotation=o,e.syntaxFlags.add(me.ColorMixVariadic),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*n.alphaMultiplier,e)}for(;r.length>=2;){const e=r.pop(),n=r.pop();if(!e||!n)return!1;const l=colorMixPolarPair(o,a,e.color,e.percentage,n.color,n.percentage);if(!l)return!1;r.push({color:l,percentage:e.percentage+n.percentage})}const l=r[0]?.color;return!!l&&(n.colors.some(e=>e.color.syntaxFlags.has(me.Experimental))&&l.syntaxFlags.add(me.Experimental),"number"==typeof l.alpha&&(l.alpha=l.alpha*n.alphaMultiplier,2!==n.colors.length&&l.syntaxFlags.add(me.ColorMixVariadic),l))}function colorMixPolarPair(e,a,n,r,o,l){const t=r/(r+l);let s=0,u=0,i=0,c=0,h=0,m=0,p=n.alpha;if("number"!=typeof p)return!1;let N=o.alpha;if("number"!=typeof N)return!1;p=Number.isNaN(p)?N:p,N=Number.isNaN(N)?p:N;const b=colorDataTo(n,e).channels,g=colorDataTo(o,e).channels;switch(e){case he.HSL:case he.HWB:s=b[0],u=g[0],i=b[1],c=g[1],h=b[2],m=g[2];break;case he.LCH:case he.OKLCH:i=b[0],c=g[0],h=b[1],m=g[1],s=b[2],u=g[2]}s=fillInMissingComponent(s,u),Number.isNaN(s)&&(s=0),u=fillInMissingComponent(u,s),Number.isNaN(u)&&(u=0),i=fillInMissingComponent(i,c),c=fillInMissingComponent(c,i),h=fillInMissingComponent(h,m),m=fillInMissingComponent(m,h);const v=u-s;switch(a){case"shorter":v>180?s+=360:v<-180&&(u+=360);break;case"longer":-1800?s+=360:u+=360);break;case"increasing":v<0&&(u+=360);break;case"decreasing":v>0&&(s+=360);break;default:throw new Error("Unknown hue interpolation method")}i=premultiply(i,p),h=premultiply(h,p),c=premultiply(c,N),m=premultiply(m,N);let f=[0,0,0];const d=interpolate(p,N,t);switch(e){case he.HSL:case he.HWB:f=[interpolate(s,u,t),un_premultiply(interpolate(i,c,t),d),un_premultiply(interpolate(h,m,t),d)];break;case he.LCH:case he.OKLCH:f=[un_premultiply(interpolate(i,c,t),d),un_premultiply(interpolate(h,m,t),d),interpolate(s,u,t)]}return{colorNotation:e,channels:f,alpha:d,syntaxFlags:new Set([me.ColorMix])}}function fillInMissingComponent(e,a){return Number.isNaN(e)?a:e}function interpolate(e,a,n){return e*n+a*(1-n)}function premultiply(e,a){return Number.isNaN(a)?e:Number.isNaN(e)?Number.NaN:e*a}function un_premultiply(e,a){return 0===a||Number.isNaN(a)?e:Number.isNaN(e)?Number.NaN:e/a}function hex(e){const a=toLowerCaseAZ(e[4].value);if(a.match(/[^a-f0-9]/))return!1;const n={colorNotation:he.HEX,channels:[0,0,0],alpha:1,syntaxFlags:new Set([me.Hex])},r=a.length;if(3===r){const e=a[0],r=a[1],o=a[2];return n.channels=[parseInt(e+e,16)/255,parseInt(r+r,16)/255,parseInt(o+o,16)/255],n}if(6===r){const e=a[0]+a[1],r=a[2]+a[3],o=a[4]+a[5];return n.channels=[parseInt(e,16)/255,parseInt(r,16)/255,parseInt(o,16)/255],n}if(4===r){const e=a[0],r=a[1],o=a[2],l=a[3];return n.channels=[parseInt(e+e,16)/255,parseInt(r+r,16)/255,parseInt(o+o,16)/255],n.alpha=parseInt(l+l,16)/255,n.syntaxFlags.add(me.HasAlpha),n}if(8===r){const e=a[0]+a[1],r=a[2]+a[3],o=a[4]+a[5],l=a[6]+a[7];return n.channels=[parseInt(e,16)/255,parseInt(r,16)/255,parseInt(o,16)/255],n.alpha=parseInt(l,16)/255,n.syntaxFlags.add(me.HasAlpha),n}return!1}function normalizeHue(n){if(o(n))return n[4].value=n[4].value%360,n[1]=n[4].value.toString(),n;if(u(n)){let r=n[4].value;switch(toLowerCaseAZ(n[4].unit)){case"deg":break;case"rad":r=180*n[4].value/Math.PI;break;case"grad":r=.9*n[4].value;break;case"turn":r=360*n[4].value;break;default:return!1}return r%=360,[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_legacy_HSL_ChannelValues(n,l,t){if(0===l){const e=normalizeHue(n);return!1!==e&&(u(n)&&t.syntaxFlags.add(me.HasDimensionValues),e)}if(r(n)){3===l?t.syntaxFlags.add(me.HasPercentageAlpha):t.syntaxFlags.add(me.HasPercentageValues);let r=normalize(n[4].value,1,0,100);return 3===l&&(r=normalize(n[4].value,100,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}if(o(n)){if(3!==l)return!1;let r=normalize(n[4].value,1,0,100);return 3===l&&(r=normalize(n[4].value,1,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_modern_HSL_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(0===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3===t?s.syntaxFlags.add(me.HasPercentageAlpha):s.syntaxFlags.add(me.HasPercentageValues);let n=l[4].value;return 3===t?n=normalize(l[4].value,100,0,1):1===t&&(n=normalize(l[4].value,1,0,2147483647)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=l[4].value;return 3===t?n=normalize(l[4].value,1,0,1):1===t&&(n=normalize(l[4].value,1,0,2147483647)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function threeChannelLegacySyntax(e,a,n,r){const l=[],u=[],i=[],c=[],h={colorNotation:n,channels:[0,0,0],alpha:1,syntaxFlags:new Set(r)};let m=l;for(let a=0;ane(e)&&s(e.value))){const a=hslCommaSeparated(e);if(!1!==a)return a}{const n=hslSpaceSeparated(e,a);if(!1!==n)return n}return!1}function hslCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_HSL_ChannelValues,he.HSL,[me.LegacyHSL])}function hslSpaceSeparated(e,a){return threeChannelSpaceSeparated(e,normalize_modern_HSL_ChannelValues,he.HSL,[],a)}function normalize_HWB_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(0===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3===t?s.syntaxFlags.add(me.HasPercentageAlpha):s.syntaxFlags.add(me.HasPercentageValues);let n=l[4].value;return 3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=l[4].value;return 3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function normalize_Lab_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,1,0,100);return 1===t||2===t?n=normalize(l[4].value,.8,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,100);return 1===t||2===t?n=normalize(l[4].value,1,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function lab(e,a){return threeChannelSpaceSeparated(e,normalize_Lab_ChannelValues,he.Lab,[],a)}function normalize_LCH_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(2===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,1,0,100);return 1===t?n=normalize(l[4].value,100/150,0,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,100);return 1===t?n=normalize(l[4].value,1,0,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function lch(e,a){return threeChannelSpaceSeparated(e,normalize_LCH_ChannelValues,he.LCH,[],a)}const de=new Map;for(const[e,a]of Object.entries(G))de.set(e,a);function namedColor(e){const a=de.get(toLowerCaseAZ(e));return!!a&&{colorNotation:he.RGB,channels:[a[0]/255,a[1]/255,a[2]/255],alpha:1,syntaxFlags:new Set([me.ColorKeyword,me.NamedColor])}}function normalize_OKLab_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,0,1);return 1===t||2===t?n=normalize(l[4].value,250,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,1);return 1===t||2===t?n=normalize(l[4].value,1,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function oklab(e,a){return threeChannelSpaceSeparated(e,normalize_OKLab_ChannelValues,he.OKLab,[],a)}function normalize_OKLCH_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(2===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,0,1);return 1===t?n=normalize(l[4].value,250,0,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,1);return 1===t?n=normalize(l[4].value,1,0,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function oklch(e,a){return threeChannelSpaceSeparated(e,normalize_OKLCH_ChannelValues,he.OKLCH,[],a)}function normalize_legacy_sRGB_ChannelValues(n,l,t){if(r(n)){3===l?t.syntaxFlags.add(me.HasPercentageAlpha):t.syntaxFlags.add(me.HasPercentageValues);const r=normalize(n[4].value,100,0,1);return[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}if(o(n)){3!==l&&t.syntaxFlags.add(me.HasNumberValues);let r=normalize(n[4].value,255,0,1);return 3===l&&(r=normalize(n[4].value,1,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_modern_sRGB_ChannelValues(l,t,s){if(n(l)&&"none"===l[4].value.toLowerCase())return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,255,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function rgb(e,a){if(e.value.some(e=>ne(e)&&s(e.value))){const a=rgbCommaSeparated(e);if(!1!==a)return(!a.syntaxFlags.has(me.HasNumberValues)||!a.syntaxFlags.has(me.HasPercentageValues))&&a}else{const n=rgbSpaceSeparated(e,a);if(!1!==n)return n}return!1}function rgbCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_sRGB_ChannelValues,he.RGB,[me.LegacyRGB])}function rgbSpaceSeparated(e,a){return threeChannelSpaceSeparated(e,normalize_modern_sRGB_ChannelValues,he.RGB,[],a)}function XYZ_D50_to_sRGB_Gamut(e){const a=x(e);if(A(a))return X(a);let n=e;return n=p(n),n[0]<1e-6&&(n=[0,0,0]),n[0]>.999999&&(n=[1,0,0]),K(Y(n,oklch_to_lin_srgb,lin_srgb_to_oklch))}function oklch_to_lin_srgb(e){return e=I(e),e=O(e),W(e)}function lin_srgb_to_oklch(e){return e=E(e),e=U(e),$(e)}function contrastColor(e,a){let n=!1;for(let r=0;rl?[1,1,1]:[0,0,0],r}function alpha(e,a){let r,s,u=!1,i=!1,c=!1;const h={colorNotation:he.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};for(let m=0;m{if(ne(e)&&n(e.value)&&"alpha"===toLowerCaseAZ(e.value[4].value)&&r&&r.has("alpha"))return new oe(r.get("alpha"))});h.alpha=e[0][0],i=!0;continue}return!1}if(c)return!1;for(;ee(e.value[m+1])||ae(e.value[m+1]);)m++;if(m++,p=e.value[m],c=a(p),!1===c)return!1;r=normalizeRelativeColorDataChannels(c),s=noneToZeroInRelativeColorDataChannels(r),h.syntaxFlags=new Set(c.syntaxFlags),h.syntaxFlags.add(me.RelativeAlphaSyntax),h.channels=[...c.channels],h.colorNotation=c.colorNotation,h.alpha=c.alpha}}return!!r&&h}function XYZ_D50_to_P3_Gamut(e){const a=C(e);if(A(a))return X(a);let n=e;return n=p(n),n[0]<1e-6&&(n=[0,0,0]),n[0]>.999999&&(n=[1,0,0]),q(Y(n,oklch_to_lin_p3,lin_p3_to_oklch))}function oklch_to_lin_p3(e){return e=I(e),e=O(e),J(e)}function lin_p3_to_oklch(e){return e=Q(e),e=U(e),$(e)}function toPrecision(e,a=7){e=+e,a=+a;const n=(Math.floor(Math.abs(e))+"").length;if(a>n)return+e.toFixed(a-n);{const r=10**(n-a);return Math.round(e/r)*r}}function serializeWithAlpha(n,r,o,l){const t=[e.CloseParen,")",-1,-1,void 0];if("number"==typeof n.alpha){const s=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(s,4)?new se(r,t,l):new se(r,t,[...l,new ue([o]),new oe([e.Delim,"/",-1,-1,{value:"/"}]),new ue([o]),new oe([e.Number,toPrecision(s,4).toString(),-1,-1,{value:n.alpha,type:a.Integer}])])}return new se(r,t,[...l,new ue([o]),new oe([e.Delim,"/",-1,-1,{value:"/"}]),new ue([o]),n.alpha])}function serializeP3(n,r=!0){n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);let o=n.channels.map(e=>Number.isNaN(e)?0:e);r?o=XYZ_D50_to_P3_Gamut(colorData_to_XYZ_D50(n).channels):n.colorNotation!==he.Display_P3&&(o=C(colorData_to_XYZ_D50(n).channels));const l=r?Math.min(1,Math.max(0,toPrecision(o[0],6))):toPrecision(o[0],6),t=r?Math.min(1,Math.max(0,toPrecision(o[1],6))):toPrecision(o[1],6),s=r?Math.min(1,Math.max(0,toPrecision(o[2],6))):toPrecision(o[2],6),u=[e.Function,"color(",-1,-1,{value:"color"}],i=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(n,u,i,[new oe([e.Ident,"display-p3",-1,-1,{value:"display-p3"}]),new ue([i]),new oe([e.Number,l.toString(),-1,-1,{value:o[0],type:a.Number}]),new ue([i]),new oe([e.Number,t.toString(),-1,-1,{value:o[1],type:a.Number}]),new ue([i]),new oe([e.Number,s.toString(),-1,-1,{value:o[2],type:a.Number}])])}function serializeRGB(n,r=!0){let o;n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation),o=r?XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(n).channels):x(colorData_to_XYZ_D50(n).channels);const l=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[0])))),t=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[1])))),s=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[2])))),u=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],c=[e.Comma,",",-1,-1,void 0],h=[new oe([e.Number,l.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[0])),type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Number,t.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[1])),type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Number,s.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[2])),type:a.Integer}])];if("number"==typeof n.alpha){const r=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(r,4)?new se([e.Function,"rgb(",-1,-1,{value:"rgb"}],u,h):new se([e.Function,"rgba(",-1,-1,{value:"rgba"}],u,[...h,new oe(c),new ue([i]),new oe([e.Number,toPrecision(r,4).toString(),-1,-1,{value:n.alpha,type:a.Number}])])}return new se([e.Function,"rgba(",-1,-1,{value:"rgba"}],u,[...h,new oe(c),new ue([i]),n.alpha])}function serializeHSL(n,r=!0){let o;n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation),o=v(r?T(XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(n).channels)):colorData_to_XYZ_D50(n).channels),o=o.map(e=>Number.isNaN(e)?0:e);const l=Math.min(360,Math.max(0,Math.round(toPrecision(o[0])))),t=Math.min(100,Math.max(0,Math.round(toPrecision(o[1])))),s=Math.min(100,Math.max(0,Math.round(toPrecision(o[2])))),u=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],c=[e.Comma,",",-1,-1,void 0],h=[new oe([e.Number,l.toString(),-1,-1,{value:o[0],type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Percentage,t.toString()+"%",-1,-1,{value:o[1]}]),new oe(c),new ue([i]),new oe([e.Percentage,s.toString()+"%",-1,-1,{value:o[2]}])];if("number"==typeof n.alpha){const r=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(r,4)?new se([e.Function,"hsl(",-1,-1,{value:"hsl"}],u,h):new se([e.Function,"hsla(",-1,-1,{value:"hsla"}],u,[...h,new oe(c),new ue([i]),new oe([e.Number,toPrecision(r,4).toString(),-1,-1,{value:n.alpha,type:a.Number}])])}return new se([e.Function,"hsla(",-1,-1,{value:"hsla"}],u,[...h,new oe(c),new ue([i]),n.alpha])}function serializeOKLCH(n){n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);let r=n.channels.map(e=>Number.isNaN(e)?0:e);n.colorNotation!==he.OKLCH&&(r=p(colorData_to_XYZ_D50(n).channels));const o=toPrecision(r[0],6),l=toPrecision(r[1],6),t=toPrecision(r[2],6),s=[e.Function,"oklch(",-1,-1,{value:"oklch"}],u=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(n,s,u,[new oe([e.Number,o.toString(),-1,-1,{value:r[0],type:a.Number}]),new ue([u]),new oe([e.Number,l.toString(),-1,-1,{value:r[1],type:a.Number}]),new ue([u]),new oe([e.Number,t.toString(),-1,-1,{value:r[2],type:a.Number}])])}function color(e){if(re(e)){switch(toLowerCaseAZ(e.getName())){case"rgb":case"rgba":return rgb(e,color);case"hsl":case"hsla":return hsl(e,color);case"hwb":return a=color,threeChannelSpaceSeparated(e,normalize_HWB_ChannelValues,he.HWB,[],a);case"lab":return lab(e,color);case"lch":return lch(e,color);case"oklab":return oklab(e,color);case"oklch":return oklch(e,color);case"color":return color$1(e,color);case"color-mix":return colorMix(e,color);case"contrast-color":return contrastColor(e,color);case"alpha":return alpha(e,color)}}var a;if(ne(e)){if(i(e.value))return hex(e.value);if(n(e.value)){const a=namedColor(e.value[4].value);return!1!==a?a:"transparent"===toLowerCaseAZ(e.value[4].value)&&{colorNotation:he.RGB,channels:[0,0,0],alpha:0,syntaxFlags:new Set([me.ColorKeyword])}}}return!1}export{he as ColorNotation,me as SyntaxFlag,color,colorDataFitsDisplayP3_Gamut,colorDataFitsRGB_Gamut,serializeHSL,serializeOKLCH,serializeP3,serializeRGB}; diff --git a/node_modules/@csstools/css-color-parser/package.json b/node_modules/@csstools/css-color-parser/package.json new file mode 100644 index 0000000..37d8c55 --- /dev/null +++ b/node_modules/@csstools/css-color-parser/package.json @@ -0,0 +1,64 @@ +{ + "name": "@csstools/css-color-parser", + "description": "Parse CSS color values", + "version": "4.1.0", + "contributors": [ + { + "name": "Antonio Laguna", + "email": "antonio@laguna.es", + "url": "https://antonio.laguna.es" + }, + { + "name": "Romain Menke", + "email": "romainmenke@gmail.com" + } + ], + "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=20.19.0" + }, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "files": [ + "CHANGELOG.md", + "LICENSE.md", + "README.md", + "dist" + ], + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.2.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "scripts": {}, + "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/csstools/postcss-plugins.git", + "directory": "packages/css-color-parser" + }, + "bugs": "https://github.com/csstools/postcss-plugins/issues", + "keywords": [ + "color", + "css", + "parser" + ] +} diff --git a/node_modules/@csstools/css-parser-algorithms/CHANGELOG.md b/node_modules/@csstools/css-parser-algorithms/CHANGELOG.md new file mode 100644 index 0000000..5abd590 --- /dev/null +++ b/node_modules/@csstools/css-parser-algorithms/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changes to CSS Parser Algorithms + +### 4.0.0 + +_January 14, 2026_ + +- Updated: Support for Node `20.19.0` or later (major). +- Removed: `commonjs` API. In supported Node versions `require(esm)` will work without needing to make code changes. +- Updated [`@csstools/css-tokenizer`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer) to [`4.0.0`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer/CHANGELOG.md#400) (major) + +[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms/CHANGELOG.md) diff --git a/node_modules/@csstools/css-parser-algorithms/LICENSE.md b/node_modules/@csstools/css-parser-algorithms/LICENSE.md new file mode 100644 index 0000000..af5411f --- /dev/null +++ b/node_modules/@csstools/css-parser-algorithms/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2022 Romain Menke, Antonio Laguna + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@csstools/css-parser-algorithms/README.md b/node_modules/@csstools/css-parser-algorithms/README.md new file mode 100644 index 0000000..a51d668 --- /dev/null +++ b/node_modules/@csstools/css-parser-algorithms/README.md @@ -0,0 +1,119 @@ +# CSS Parser Algorithms for CSS + +[npm version][npm-url] +[Build Status][cli-url] +[Discord][discord] + +Implemented from : https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/ + +## API + +[Read the API docs](./docs/css-parser-algorithms.md) + +## Usage + +Add [CSS Parser Algorithms] to your project: + +```bash +npm install @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev +``` + +[CSS Parser Algorithms] only accepts tokenized CSS. +It must be used together with `@csstools/css-tokenizer`. + + +```js +import { tokenizer, TokenType } from '@csstools/css-tokenizer'; +import { parseComponentValue } from '@csstools/css-parser-algorithms'; + +const myCSS = `@media only screen and (min-width: 768rem) { + .foo { + content: 'Some content!' !important; + } +} +`; + +const t = tokenizer({ + css: myCSS, +}); + +const tokens = []; + +{ + while (!t.endOfFile()) { + tokens.push(t.nextToken()); + } + + tokens.push(t.nextToken()); // EOF-token +} + +const options = { + onParseError: ((err) => { + throw err; + }), +}; + +const result = parseComponentValue(tokens, options); + +console.log(result); +``` + +### Available functions + +- [`parseComponentValue`](https://www.w3.org/TR/css-syntax-3/#parse-component-value) +- [`parseListOfComponentValues`](https://www.w3.org/TR/css-syntax-3/#parse-list-of-component-values) +- [`parseCommaSeparatedListOfComponentValues`](https://www.w3.org/TR/css-syntax-3/#parse-comma-separated-list-of-component-values) + +### Utilities + +#### `gatherNodeAncestry` + +The AST does not expose the entire ancestry of each node. +The walker methods do provide access to the current parent, but also not the entire ancestry. + +To gather the entire ancestry for a a given sub tree of the AST you can use `gatherNodeAncestry`. +The result is a `Map` with the child nodes as keys and the parents as values. +This allows you to lookup any ancestor of any node. + +```js +import { parseComponentValue } from '@csstools/css-parser-algorithms'; + +const result = parseComponentValue(tokens, options); +const ancestry = gatherNodeAncestry(result); +``` + +### Options + +```ts +{ + onParseError?: (error: ParseError) => void +} +``` + +#### `onParseError` + +The parser algorithms are forgiving and won't stop when a parse error is encountered. +Parse errors also aren't tokens. + +To receive parsing error information you can set a callback. + +Parser errors will try to inform you about the point in the parsing logic the error happened. +This tells you the kind of error. + +## Goals and non-goals + +Things this package aims to be: +- specification compliant CSS parser +- a reliable low level package to be used in CSS sub-grammars + +What it is not: +- opinionated +- fast +- small +- a replacement for PostCSS (PostCSS is fast and also an ecosystem) + +[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test +[discord]: https://discord.gg/bUadyRwkJS +[npm-url]: https://www.npmjs.com/package/@csstools/css-parser-algorithms + +[CSS Parser Algorithms]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms diff --git a/node_modules/@csstools/css-parser-algorithms/dist/index.d.ts b/node_modules/@csstools/css-parser-algorithms/dist/index.d.ts new file mode 100644 index 0000000..c59d3dd --- /dev/null +++ b/node_modules/@csstools/css-parser-algorithms/dist/index.d.ts @@ -0,0 +1,604 @@ +/** + * Parse CSS following the {@link https://drafts.csswg.org/css-syntax/#parsing | CSS Syntax Level 3 specification}. + * + * @remarks + * The tokenizing and parsing tools provided by CSS Tools are designed to be low level and generic with strong ties to their respective specifications. + * + * Any analysis or mutation of CSS source code should be done with the least powerful tool that can accomplish the task. + * For many applications it is sufficient to work with tokens. + * For others you might need to use {@link https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms | @csstools/css-parser-algorithms} or a more specific parser. + * + * The implementation of the AST nodes is kept lightweight and simple. + * Do not expect magic methods, instead assume that arrays and class instances behave like any other JavaScript. + * + * @example + * Parse a string of CSS into a component value: + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseComponentValue } from '@csstools/css-parser-algorithms'; + * + * const myCSS = `calc(1px * 2)`; + * + * const componentValue = parseComponentValue(tokenize({ + * css: myCSS, + * })); + * + * console.log(componentValue); + * ``` + * + * @example + * Use the right algorithm for the job. + * + * Algorithms that can parse larger structures (comma-separated lists, ...) can also parse smaller structures. + * However, the opposite is not true. + * + * If your context allows a list of component values, use {@link parseListOfComponentValues}: + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseListOfComponentValues } from '@csstools/css-parser-algorithms'; + * + * parseListOfComponentValues(tokenize({ css: `10x 20px` })); + * ``` + * + * If your context allows a comma-separated list of component values, use {@link parseCommaSeparatedListOfComponentValues}: + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms'; + * + * parseCommaSeparatedListOfComponentValues(tokenize({ css: `20deg, 50%, 30%` })); + * ``` + * + * @example + * Use the stateful walkers to keep track of the context of a given component value. + * + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseComponentValue, isSimpleBlockNode } from '@csstools/css-parser-algorithms'; + * + * const myCSS = `calc(1px * (5 / 2))`; + * + * const componentValue = parseComponentValue(tokenize({ css: myCSS })); + * + * let state = { inSimpleBlock: false }; + * componentValue.walk((entry) => { + * if (isSimpleBlockNode(entry)) { + * entry.state.inSimpleBlock = true; + * return; + * } + * + * if (entry.state.inSimpleBlock) { + * console.log(entry.node.toString()); // `5`, ... + * } + * }, state); + * ``` + * + * @packageDocumentation + */ + +import type { CSSToken } from '@csstools/css-tokenizer'; +import { ParseError } from '@csstools/css-tokenizer'; +import type { TokenFunction } from '@csstools/css-tokenizer'; + +export declare class CommentNode { + /** + * The node type, always `ComponentValueType.Comment` + */ + type: ComponentValueType; + /** + * The comment token. + */ + value: CSSToken; + constructor(value: CSSToken); + /** + * Retrieve the tokens for the current comment. + * This is the inverse of parsing from a list of tokens. + */ + tokens(): Array; + /** + * Convert the current comment to a string. + * This is not a true serialization. + * It is purely a concatenation of the string representation of the tokens. + */ + toString(): string; + /** + * @internal + * + * A debug helper to convert the current object to a JSON representation. + * This is useful in asserts and to store large ASTs in files. + */ + toJSON(): Record; + /** + * @internal + */ + isCommentNode(): this is CommentNode; + /** + * @internal + */ + static isCommentNode(x: unknown): x is CommentNode; +} + +export declare type ComponentValue = FunctionNode | SimpleBlockNode | WhitespaceNode | CommentNode | TokenNode; + +export declare enum ComponentValueType { + Function = "function", + SimpleBlock = "simple-block", + Whitespace = "whitespace", + Comment = "comment", + Token = "token" +} + +export declare type ContainerNode = FunctionNode | SimpleBlockNode; + +export declare abstract class ContainerNodeBaseClass { + /** + * The contents of the `Function` or `Simple Block`. + * This is a list of component values. + */ + value: Array; + /** + * Retrieve the index of the given item in the current node. + * For most node types this will be trivially implemented as `this.value.indexOf(item)`. + */ + indexOf(item: ComponentValue): number | string; + /** + * Retrieve the item at the given index in the current node. + * For most node types this will be trivially implemented as `this.value[index]`. + */ + at(index: number | string): ComponentValue | undefined; + /** + * Iterates over each item in the `value` array of the current node. + * + * @param cb - The callback function to execute for each item. + * The function receives an object containing the current node (`node`), its parent (`parent`), + * and an optional `state` object. + * A second parameter is the index of the current node. + * The function can return `false` to stop the iteration. + * + * @param state - An optional state object that can be used to pass additional information to the callback function. + * The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration. + * + * @returns `false` if the iteration was halted, `undefined` otherwise. + */ + forEach, U extends ContainerNode>(this: U, cb: (entry: { + node: ComponentValue; + parent: ContainerNode; + state?: T; + }, index: number | string) => boolean | void, state?: T): false | undefined; + /** + * Walks the current node and all its children. + * + * @param cb - The callback function to execute for each item. + * The function receives an object containing the current node (`node`), its parent (`parent`), + * and an optional `state` object. + * A second parameter is the index of the current node. + * The function can return `false` to stop the iteration. + * + * @param state - An optional state object that can be used to pass additional information to the callback function. + * The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration. + * However changes are passed down to child node iterations. + * + * @returns `false` if the iteration was halted, `undefined` otherwise. + */ + walk, U extends ContainerNode>(this: U, cb: (entry: { + node: ComponentValue; + parent: ContainerNode; + state?: T; + }, index: number | string) => boolean | void, state?: T): false | undefined; +} + +/** + * Iterates over each item in a list of component values. + * + * @param cb - The callback function to execute for each item. + * The function receives an object containing the current node (`node`), its parent (`parent`), + * and an optional `state` object. + * A second parameter is the index of the current node. + * The function can return `false` to stop the iteration. + * + * @param state - An optional state object that can be used to pass additional information to the callback function. + * The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration. + * + * @returns `false` if the iteration was halted, `undefined` otherwise. + */ +export declare function forEach>(componentValues: Array, cb: (entry: { + node: ComponentValue; + parent: ContainerNode | { + value: Array; + }; + state?: T; +}, index: number | string) => boolean | void, state?: T): false | undefined; + +/** + * A function node. + * + * @example + * ```js + * const node = parseComponentValue(tokenize('calc(1 + 1)')); + * + * isFunctionNode(node); // true + * node.getName(); // 'calc' + * ``` + */ +export declare class FunctionNode extends ContainerNodeBaseClass { + /** + * The node type, always `ComponentValueType.Function` + */ + type: ComponentValueType; + /** + * The token for the name of the function. + */ + name: TokenFunction; + /** + * The token for the closing parenthesis of the function. + * If the function is unclosed, this will be an EOF token. + */ + endToken: CSSToken; + constructor(name: TokenFunction, endToken: CSSToken, value: Array); + /** + * Retrieve the name of the current function. + * This is the parsed and unescaped name of the function. + */ + getName(): string; + /** + * Normalize the current function: + * 1. if the "endToken" is EOF, replace with a ")-token" + */ + normalize(): void; + /** + * Retrieve the tokens for the current function. + * This is the inverse of parsing from a list of tokens. + */ + tokens(): Array; + /** + * Convert the current function to a string. + * This is not a true serialization. + * It is purely a concatenation of the string representation of the tokens. + */ + toString(): string; + /** + * @internal + * + * A debug helper to convert the current object to a JSON representation. + * This is useful in asserts and to store large ASTs in files. + */ + toJSON(): unknown; + /** + * @internal + */ + isFunctionNode(): this is FunctionNode; + /** + * @internal + */ + static isFunctionNode(x: unknown): x is FunctionNode; +} + +/** + * AST nodes do not have a `parent` property or method. + * This makes it harder to traverse the AST upwards. + * This function builds a `Map` that can be used to lookup ancestors of a node. + * + * @remarks + * There is no magic behind this or the map it returns. + * Mutating the AST will not update the map. + * + * Types are erased and any content of the map has type `unknown`. + * If someone knows a clever way to type this, please let us know. + * + * @example + * ```js + * const ancestry = gatherNodeAncestry(mediaQuery); + * mediaQuery.walk((entry) => { + * const node = entry.node; // directly exposed + * const parent = entry.parent; // directly exposed + * const grandParent: unknown = ancestry.get(parent); // lookup + * + * console.log('node', node); + * console.log('parent', parent); + * console.log('grandParent', grandParent); + * }); + * ``` + */ +export declare function gatherNodeAncestry(node: { + walk(cb: (entry: { + node: unknown; + parent: unknown; + }, index: number | string) => boolean | void): false | undefined; +}): Map; + +/** + * Check if the current object is a `CommentNode`. + * This is a type guard. + */ +export declare function isCommentNode(x: unknown): x is CommentNode; + +/** + * Check if the current object is a `FunctionNode`. + * This is a type guard. + */ +export declare function isFunctionNode(x: unknown): x is FunctionNode; + +/** + * Check if the current object is a `SimpleBlockNode`. + * This is a type guard. + */ +export declare function isSimpleBlockNode(x: unknown): x is SimpleBlockNode; + +/** + * Check if the current object is a `TokenNode`. + * This is a type guard. + */ +export declare function isTokenNode(x: unknown): x is TokenNode; + +/** + * Check if the current object is a `WhitespaceNode`. + * This is a type guard. + */ +export declare function isWhitespaceNode(x: unknown): x is WhitespaceNode; + +/** + * Check if the current object is a `WhiteSpaceNode` or a `CommentNode`. + * This is a type guard. + */ +export declare function isWhiteSpaceOrCommentNode(x: unknown): x is WhitespaceNode | CommentNode; + +/** + * Parse a comma-separated list of component values. + * + * @example + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms'; + * + * parseCommaSeparatedListOfComponentValues(tokenize({ css: `20deg, 50%, 30%` })); + * ``` + */ +export declare function parseCommaSeparatedListOfComponentValues(tokens: Array, options?: { + onParseError?: (error: ParseError) => void; +}): Array>; + +/** + * Parse a single component value. + * + * @example + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseComponentValue } from '@csstools/css-parser-algorithms'; + * + * parseComponentValue(tokenize({ css: `10px` })); + * parseComponentValue(tokenize({ css: `calc((10px + 1x) * 4)` })); + * ``` + */ +export declare function parseComponentValue(tokens: Array, options?: { + onParseError?: (error: ParseError) => void; +}): ComponentValue | undefined; + +/** + * Parse a list of component values. + * + * @example + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseListOfComponentValues } from '@csstools/css-parser-algorithms'; + * + * parseListOfComponentValues(tokenize({ css: `20deg 30%` })); + * ``` + */ +export declare function parseListOfComponentValues(tokens: Array, options?: { + onParseError?: (error: ParseError) => void; +}): Array; + +/** + * Replace specific component values in a list of component values. + * A helper for the most common and simplistic cases when mutating an AST. + */ +export declare function replaceComponentValues(componentValuesList: Array>, replaceWith: (componentValue: ComponentValue) => Array | ComponentValue | void): Array>; + +/** + * A simple block node. + * + * @example + * ```js + * const node = parseComponentValue(tokenize('[foo=bar]')); + * + * isSimpleBlockNode(node); // true + * node.startToken; // [TokenType.OpenSquare, '[', 0, 0, undefined] + * ``` + */ +export declare class SimpleBlockNode extends ContainerNodeBaseClass { + /** + * The node type, always `ComponentValueType.SimpleBlock` + */ + type: ComponentValueType; + /** + * The token for the opening token of the block. + */ + startToken: CSSToken; + /** + * The token for the closing token of the block. + * If the block is closed it will be the mirror variant of the `startToken`. + * If the block is unclosed, this will be an EOF token. + */ + endToken: CSSToken; + constructor(startToken: CSSToken, endToken: CSSToken, value: Array); + /** + * Normalize the current simple block + * 1. if the "endToken" is EOF, replace with the mirror token of the "startToken" + */ + normalize(): void; + /** + * Retrieve the tokens for the current simple block. + * This is the inverse of parsing from a list of tokens. + */ + tokens(): Array; + /** + * Convert the current simple block to a string. + * This is not a true serialization. + * It is purely a concatenation of the string representation of the tokens. + */ + toString(): string; + /** + * @internal + * + * A debug helper to convert the current object to a JSON representation. + * This is useful in asserts and to store large ASTs in files. + */ + toJSON(): unknown; + /** + * @internal + */ + isSimpleBlockNode(): this is SimpleBlockNode; + /** + * @internal + */ + static isSimpleBlockNode(x: unknown): x is SimpleBlockNode; +} + +/** + * Returns the start and end index of a node in the CSS source string. + */ +export declare function sourceIndices(x: { + tokens(): Array; +} | Array<{ + tokens(): Array; +}>): [number, number]; + +/** + * Concatenate the string representation of a collection of component values. + * This is not a proper serializer that will handle escaping and whitespace. + * It only produces valid CSS for token lists that are also valid. + */ +export declare function stringify(componentValueLists: Array>): string; + +export declare class TokenNode { + /** + * The node type, always `ComponentValueType.Token` + */ + type: ComponentValueType; + /** + * The token. + */ + value: CSSToken; + constructor(value: CSSToken); + /** + * This is the inverse of parsing from a list of tokens. + */ + tokens(): [CSSToken]; + /** + * Convert the current token to a string. + * This is not a true serialization. + * It is purely the string representation of token. + */ + toString(): string; + /** + * @internal + * + * A debug helper to convert the current object to a JSON representation. + * This is useful in asserts and to store large ASTs in files. + */ + toJSON(): Record; + /** + * @internal + */ + isTokenNode(): this is TokenNode; + /** + * @internal + */ + static isTokenNode(x: unknown): x is TokenNode; +} + +/** + * Walks each item in a list of component values all of their children. + * + * @param cb - The callback function to execute for each item. + * The function receives an object containing the current node (`node`), its parent (`parent`), + * and an optional `state` object. + * A second parameter is the index of the current node. + * The function can return `false` to stop the iteration. + * + * @param state - An optional state object that can be used to pass additional information to the callback function. + * The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration. + * However changes are passed down to child node iterations. + * + * @returns `false` if the iteration was halted, `undefined` otherwise. + * + * @example + * ```js + * import { tokenize } from '@csstools/css-tokenizer'; + * import { parseListOfComponentValues, isSimpleBlockNode } from '@csstools/css-parser-algorithms'; + * + * const myCSS = `calc(1px * (5 / 2)) 10px`; + * + * const componentValues = parseListOfComponentValues(tokenize({ css: myCSS })); + * + * let state = { inSimpleBlock: false }; + * walk(componentValues, (entry) => { + * if (isSimpleBlockNode(entry)) { + * entry.state.inSimpleBlock = true; + * return; + * } + * + * if (entry.state.inSimpleBlock) { + * console.log(entry.node.toString()); // `5`, ... + * } + * }, state); + * ``` + */ +export declare function walk>(componentValues: Array, cb: (entry: { + node: ComponentValue; + parent: ContainerNode | { + value: Array; + }; + state?: T; +}, index: number | string) => boolean | void, state?: T): false | undefined; + +/** + * Generate a function that finds the next element that should be visited when walking an AST. + * Rules : + * 1. the previous iteration is used as a reference, so any checks are relative to the start of the current iteration. + * 2. the next element always appears after the current index. + * 3. the next element always exists in the list. + * 4. replacing an element does not cause the replaced element to be visited. + * 5. removing an element does not cause elements to be skipped. + * 6. an element added later in the list will be visited. + */ +export declare function walkerIndexGenerator(initialList: Array): (list: Array, child: T, index: number) => number; + +export declare class WhitespaceNode { + /** + * The node type, always `ComponentValueType.WhiteSpace` + */ + type: ComponentValueType; + /** + * The list of consecutive whitespace tokens. + */ + value: Array; + constructor(value: Array); + /** + * Retrieve the tokens for the current whitespace. + * This is the inverse of parsing from a list of tokens. + */ + tokens(): Array; + /** + * Convert the current whitespace to a string. + * This is not a true serialization. + * It is purely a concatenation of the string representation of the tokens. + */ + toString(): string; + /** + * @internal + * + * A debug helper to convert the current object to a JSON representation. + * This is useful in asserts and to store large ASTs in files. + */ + toJSON(): Record; + /** + * @internal + */ + isWhitespaceNode(): this is WhitespaceNode; + /** + * @internal + */ + static isWhitespaceNode(x: unknown): x is WhitespaceNode; +} + +export { } diff --git a/node_modules/@csstools/css-parser-algorithms/dist/index.mjs b/node_modules/@csstools/css-parser-algorithms/dist/index.mjs new file mode 100644 index 0000000..ca4f76d --- /dev/null +++ b/node_modules/@csstools/css-parser-algorithms/dist/index.mjs @@ -0,0 +1 @@ +import{isTokenEOF as e,TokenType as n,isToken as t,stringify as o,mirrorVariant as s,isTokenOpenParen as i,isTokenOpenCurly as r,isTokenOpenSquare as a,isTokenFunction as c,isTokenWhitespace as u,isTokenComment as l,mirrorVariantType as d,ParseError as h,isTokenWhiteSpaceOrComment as p,isTokenCloseParen as m,isTokenComma as k}from"@csstools/css-tokenizer";var f;function walkerIndexGenerator(e){let n=e.slice();return(e,t,o)=>{let s=-1;for(let i=n.indexOf(t);i=e.length)?-1:(n=e.slice(),s)}}function consumeComponentValue(e,n){const t=n[0];if(i(t)||r(t)||a(t)){const t=consumeSimpleBlock(e,n);return{advance:t.advance,node:t.node}}if(c(t)){const t=consumeFunction(e,n);return{advance:t.advance,node:t.node}}if(u(t)){const t=consumeWhitespace(e,n);return{advance:t.advance,node:t.node}}if(l(t)){const t=consumeComment(e,n);return{advance:t.advance,node:t.node}}return{advance:1,node:new TokenNode(t)}}!function(e){e.Function="function",e.SimpleBlock="simple-block",e.Whitespace="whitespace",e.Comment="comment",e.Token="token"}(f||(f={}));class ContainerNodeBaseClass{value=[];indexOf(e){return this.value.indexOf(e)}at(e){if("number"==typeof e)return e<0&&(e=this.value.length+e),this.value[e]}forEach(e,n){if(0===this.value.length)return;const t=walkerIndexGenerator(this.value);let o=0;for(;o!1!==e(n,t)&&((!("walk"in n.node)||!this.value.includes(n.node)||!1!==n.node.walk(e,n.state))&&void 0),n)}}class FunctionNode extends ContainerNodeBaseClass{type=f.Function;name;endToken;constructor(e,n,t){super(),this.name=e,this.endToken=n,this.value=t}getName(){return this.name[4].value}normalize(){e(this.endToken)&&(this.endToken=[n.CloseParen,")",-1,-1,void 0])}tokens(){return e(this.endToken)?[this.name,...this.value.flatMap(e=>e.tokens())]:[this.name,...this.value.flatMap(e=>e.tokens()),this.endToken]}toString(){const e=this.value.map(e=>t(e)?o(e):e.toString()).join("");return o(this.name)+e+o(this.endToken)}toJSON(){return{type:this.type,name:this.getName(),tokens:this.tokens(),value:this.value.map(e=>e.toJSON())}}isFunctionNode(){return FunctionNode.isFunctionNode(this)}static isFunctionNode(e){return!!e&&(e instanceof FunctionNode&&e.type===f.Function)}}function consumeFunction(n,t){const o=[];let s=1;for(;;){const i=t[s];if(!i||e(i))return n.onParseError(new h("Unexpected EOF while consuming a function.",t[0][2],t[t.length-1][3],["5.4.9. Consume a function","Unexpected EOF"])),{advance:t.length,node:new FunctionNode(t[0],i,o)};if(m(i))return{advance:s+1,node:new FunctionNode(t[0],i,o)};if(p(i)){const e=consumeAllCommentsAndWhitespace(n,t.slice(s));s+=e.advance,o.push(...e.nodes);continue}const r=consumeComponentValue(n,t.slice(s));s+=r.advance,o.push(r.node)}}class SimpleBlockNode extends ContainerNodeBaseClass{type=f.SimpleBlock;startToken;endToken;constructor(e,n,t){super(),this.startToken=e,this.endToken=n,this.value=t}normalize(){if(e(this.endToken)){const e=s(this.startToken);e&&(this.endToken=e)}}tokens(){return e(this.endToken)?[this.startToken,...this.value.flatMap(e=>e.tokens())]:[this.startToken,...this.value.flatMap(e=>e.tokens()),this.endToken]}toString(){const e=this.value.map(e=>t(e)?o(e):e.toString()).join("");return o(this.startToken)+e+o(this.endToken)}toJSON(){return{type:this.type,startToken:this.startToken,tokens:this.tokens(),value:this.value.map(e=>e.toJSON())}}isSimpleBlockNode(){return SimpleBlockNode.isSimpleBlockNode(this)}static isSimpleBlockNode(e){return!!e&&(e instanceof SimpleBlockNode&&e.type===f.SimpleBlock)}}function consumeSimpleBlock(n,t){const o=d(t[0][0]);if(!o)throw new Error("Failed to parse, a mirror variant must exist for all block open tokens.");const s=[];let i=1;for(;;){const r=t[i];if(!r||e(r))return n.onParseError(new h("Unexpected EOF while consuming a simple block.",t[0][2],t[t.length-1][3],["5.4.8. Consume a simple block","Unexpected EOF"])),{advance:t.length,node:new SimpleBlockNode(t[0],r,s)};if(r[0]===o)return{advance:i+1,node:new SimpleBlockNode(t[0],r,s)};if(p(r)){const e=consumeAllCommentsAndWhitespace(n,t.slice(i));i+=e.advance,s.push(...e.nodes);continue}const a=consumeComponentValue(n,t.slice(i));i+=a.advance,s.push(a.node)}}class WhitespaceNode{type=f.Whitespace;value;constructor(e){this.value=e}tokens(){return this.value}toString(){return o(...this.value)}toJSON(){return{type:this.type,tokens:this.tokens()}}isWhitespaceNode(){return WhitespaceNode.isWhitespaceNode(this)}static isWhitespaceNode(e){return!!e&&(e instanceof WhitespaceNode&&e.type===f.Whitespace)}}function consumeWhitespace(e,n){let t=0;for(;;){const e=n[t];if(!u(e))return{advance:t,node:new WhitespaceNode(n.slice(0,t))};t++}}class CommentNode{type=f.Comment;value;constructor(e){this.value=e}tokens(){return[this.value]}toString(){return o(this.value)}toJSON(){return{type:this.type,tokens:this.tokens()}}isCommentNode(){return CommentNode.isCommentNode(this)}static isCommentNode(e){return!!e&&(e instanceof CommentNode&&e.type===f.Comment)}}function consumeComment(e,n){return{advance:1,node:new CommentNode(n[0])}}function consumeAllCommentsAndWhitespace(e,n){const t=[];let o=0;for(;;){if(u(n[o])){const e=consumeWhitespace(0,n.slice(o));o+=e.advance,t.push(e.node);continue}if(!l(n[o]))return{advance:o,nodes:t};t.push(new CommentNode(n[o])),o++}}class TokenNode{type=f.Token;value;constructor(e){this.value=e}tokens(){return[this.value]}toString(){return this.value[1]}toJSON(){return{type:this.type,tokens:this.tokens()}}isTokenNode(){return TokenNode.isTokenNode(this)}static isTokenNode(e){return!!e&&(e instanceof TokenNode&&e.type===f.Token)}}function parseComponentValue(t,o){const s={onParseError:o?.onParseError??(()=>{})},i=[...t];e(i[i.length-1])||i.push([n.EOF,"",i[i.length-1][2],i[i.length-1][3],void 0]);const r=consumeComponentValue(s,i);if(e(i[Math.min(r.advance,i.length-1)]))return r.node;s.onParseError(new h("Expected EOF after parsing a component value.",t[0][2],t[t.length-1][3],["5.3.9. Parse a component value","Expected EOF"]))}function parseListOfComponentValues(t,o){const s={onParseError:o?.onParseError??(()=>{})},i=[...t];e(i[i.length-1])&&i.push([n.EOF,"",i[i.length-1][2],i[i.length-1][3],void 0]);const r=[];let a=0;for(;;){if(!i[a]||e(i[a]))return r;const n=consumeComponentValue(s,i.slice(a));r.push(n.node),a+=n.advance}}function parseCommaSeparatedListOfComponentValues(t,o){const s={onParseError:o?.onParseError??(()=>{})},i=[...t];if(0===t.length)return[];e(i[i.length-1])&&i.push([n.EOF,"",i[i.length-1][2],i[i.length-1][3],void 0]);const r=[];let a=[],c=0;for(;;){if(!i[c]||e(i[c]))return a.length&&r.push(a),r;if(k(i[c])){r.push(a),a=[],c++;continue}const n=consumeComponentValue(s,t.slice(c));a.push(n.node),c+=n.advance}}function gatherNodeAncestry(e){const n=new Map;return e.walk(e=>{Array.isArray(e.node)?e.node.forEach(t=>{n.set(t,e.parent)}):n.set(e.node,e.parent)}),n}function forEach(e,n,t){if(0===e.length)return;const o=walkerIndexGenerator(e);let s=0;for(;s!1!==n(t,o)&&((!("walk"in t.node)||!e.includes(t.node)||!1!==t.node.walk(n,t.state))&&void 0),t)}function replaceComponentValues(e,n){for(let t=0;t{if("number"!=typeof t)return;const o=n(e.node);o&&(Array.isArray(o)?e.parent.value.splice(t,1,...o):e.parent.value.splice(t,1,o))})}return e}function stringify(e){return e.map(e=>e.map(e=>o(...e.tokens())).join("")).join(",")}function isSimpleBlockNode(e){return SimpleBlockNode.isSimpleBlockNode(e)}function isFunctionNode(e){return FunctionNode.isFunctionNode(e)}function isWhitespaceNode(e){return WhitespaceNode.isWhitespaceNode(e)}function isCommentNode(e){return CommentNode.isCommentNode(e)}function isWhiteSpaceOrCommentNode(e){return isWhitespaceNode(e)||isCommentNode(e)}function isTokenNode(e){return TokenNode.isTokenNode(e)}function sourceIndices(e){if(Array.isArray(e)){const n=e[0];if(!n)return[0,0];const t=e[e.length-1]||n;return[sourceIndices(n)[0],sourceIndices(t)[1]]}const n=e.tokens(),t=n[0],o=n[n.length-1];return t&&o?[t[2],o[3]]:[0,0]}export{CommentNode,f as ComponentValueType,ContainerNodeBaseClass,FunctionNode,SimpleBlockNode,TokenNode,WhitespaceNode,forEach,gatherNodeAncestry,isCommentNode,isFunctionNode,isSimpleBlockNode,isTokenNode,isWhiteSpaceOrCommentNode,isWhitespaceNode,parseCommaSeparatedListOfComponentValues,parseComponentValue,parseListOfComponentValues,replaceComponentValues,sourceIndices,stringify,walk,walkerIndexGenerator}; diff --git a/node_modules/@csstools/css-parser-algorithms/package.json b/node_modules/@csstools/css-parser-algorithms/package.json new file mode 100644 index 0000000..5734668 --- /dev/null +++ b/node_modules/@csstools/css-parser-algorithms/package.json @@ -0,0 +1,58 @@ +{ + "name": "@csstools/css-parser-algorithms", + "description": "Algorithms to help you parse CSS from an array of tokens.", + "version": "4.0.0", + "contributors": [ + { + "name": "Antonio Laguna", + "email": "antonio@laguna.es", + "url": "https://antonio.laguna.es" + }, + { + "name": "Romain Menke", + "email": "romainmenke@gmail.com" + } + ], + "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=20.19.0" + }, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "files": [ + "CHANGELOG.md", + "LICENSE.md", + "README.md", + "dist" + ], + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + }, + "scripts": {}, + "homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/csstools/postcss-plugins.git", + "directory": "packages/css-parser-algorithms" + }, + "bugs": "https://github.com/csstools/postcss-plugins/issues", + "keywords": [ + "css", + "parser" + ] +} diff --git a/node_modules/@csstools/css-syntax-patches-for-csstree/CHANGELOG.md b/node_modules/@csstools/css-syntax-patches-for-csstree/CHANGELOG.md new file mode 100644 index 0000000..d629ff4 --- /dev/null +++ b/node_modules/@csstools/css-syntax-patches-for-csstree/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changes to CSS Syntax Patches For CSSTree + +### 1.1.3 + +_April 12, 2026_ + +- Update `@webref/css` to [`v8.5.3`](https://github.com/w3c/webref/releases/tag/%40webref%2Fcss%408.5.3) + + +[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-syntax-patches-for-csstree/CHANGELOG.md) diff --git a/node_modules/@csstools/css-syntax-patches-for-csstree/LICENSE.md b/node_modules/@csstools/css-syntax-patches-for-csstree/LICENSE.md new file mode 100644 index 0000000..e8ae93b --- /dev/null +++ b/node_modules/@csstools/css-syntax-patches-for-csstree/LICENSE.md @@ -0,0 +1,18 @@ +MIT No Attribution (MIT-0) + +Copyright © CSSTools Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@csstools/css-syntax-patches-for-csstree/README.md b/node_modules/@csstools/css-syntax-patches-for-csstree/README.md new file mode 100644 index 0000000..00e214f --- /dev/null +++ b/node_modules/@csstools/css-syntax-patches-for-csstree/README.md @@ -0,0 +1,43 @@ +# CSS Syntax Patches For CSSTree for CSS + +[npm version][npm-url] +[Build Status][cli-url] + +Patch [csstree](https://github.com/csstree/csstree) syntax definitions with the latest data from CSS specifications. + +## Usage + +```bash +npm install @csstools/css-syntax-patches-for-csstree +``` + +```js +import { fork } from 'css-tree'; +import syntax_patches from '@csstools/css-syntax-patches-for-csstree' with { type: 'json' }; + +const forkedLexer = fork({ + atrules: syntax_patches.next.atrules, + properties: syntax_patches.next.properties, + types: syntax_patches.next.types, +}).lexer; +``` + +## `next` + +```js +import syntax_patches from '@csstools/css-syntax-patches-for-csstree' with { type: 'json' }; + +console.log(syntax_patches.next); +// ^^^^ +``` + +CSS specifications are often still in flux and various parts might change or disappear altogether. +Specifications also contains parts that haven't been implemented yet in a browser. +Only CSS that is widely adopted can be expected to be stable. + +The `next` grouping contains a combination of what is currently valid in browsers and the progress in various specifications. + +_In the future more groupings might be added._ + +[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test +[npm-url]: https://www.npmjs.com/package/@csstools/css-syntax-patches-for-csstree diff --git a/node_modules/@csstools/css-syntax-patches-for-csstree/dist/index.d.ts b/node_modules/@csstools/css-syntax-patches-for-csstree/dist/index.d.ts new file mode 100644 index 0000000..05d942a --- /dev/null +++ b/node_modules/@csstools/css-syntax-patches-for-csstree/dist/index.d.ts @@ -0,0 +1,5 @@ +export const next: { + atrules: Record }>, + properties: Record, + types: Record, +} diff --git a/node_modules/@csstools/css-syntax-patches-for-csstree/dist/index.json b/node_modules/@csstools/css-syntax-patches-for-csstree/dist/index.json new file mode 100644 index 0000000..79bc0cc --- /dev/null +++ b/node_modules/@csstools/css-syntax-patches-for-csstree/dist/index.json @@ -0,0 +1,752 @@ +{ + "next": { + "atrules": { + "color-profile": { + "descriptors": { + "components": "#", + "rendering-intent": "relative-colorimetric | absolute-colorimetric | perceptual | saturation", + "src": "" + } + }, + "font-face": { + "descriptors": { + "ascent-override": "[ normal | ]{1,2}", + "descent-override": "[ normal | ]{1,2}", + "font-language-override": "normal | ", + "font-named-instance": "auto | ", + "font-size": "auto | [ ]{1,2}", + "font-style": "auto | normal | italic | left | right | oblique [ {1,2} ]?", + "font-weight": "| auto", + "font-width": "auto | <'font-width'>{1,2}", + "line-gap-override": "[ normal | ]{1,2}", + "size-adjust": "", + "src": "", + "subscript-position-override": "[ normal | from-font | ]{1,2}", + "subscript-size-override": "[ normal | from-font | ]{1,2}", + "superscript-position-override": "[ normal | from-font | ]{1,2}", + "superscript-size-override": "[ normal | from-font | ]{1,2}", + "unicode-range": "#" + } + }, + "font-feature-values": { + "descriptors": { + "font-display": "auto | block | swap | fallback | optional" + } + }, + "function": { + "descriptors": { + "result": "?" + } + }, + "page": { + "descriptors": { + "page-margin-safety": "none | clamp | add" + } + } + }, + "properties": { + "align-self": "auto | ? [ normal | ] | stretch | | anchor-center", + "alignment-baseline": "auto | before-edge | text-before-edge | after-edge | text-after-edge | baseline | ", + "all": " | revert-rule", + "anchor-name": "none | #", + "anchor-scope": "none | all | #", + "animation-range-center": "[ normal | [ | ? ] ]#", + "appearance": "none | auto | base | base-select | | | base", + "background-blend-mode": "<'mix-blend-mode'>#", + "background-position-block": "[ center | [ [ start | end ]? ? ]! ]#", + "background-position-inline": "[ center | [ [ start | end ]? ? ]! ]#", + "background-repeat-block": "#", + "background-repeat-inline": "#", + "background-repeat-x": "#", + "background-repeat-y": "#", + "background-tbd": "#", + "baseline-shift": " | sub | super | top | center | bottom", + "block-ellipsis": "no-ellipsis | auto | ", + "block-step": "<'block-step-size'> || <'block-step-insert'> || <'block-step-align'> || <'block-step-round'>", + "block-step-align": "auto | center | start | end", + "block-step-insert": "margin-box | padding-box | content-box", + "block-step-round": "up | down | nearest", + "block-step-size": "none | ", + "bookmark-label": "", + "bookmark-level": "none | ", + "bookmark-state": "open | closed", + "border-block-clip": "<'border-top-clip'>", + "border-block-end": " || || ", + "border-block-end-clip": "none | [ | ]+", + "border-block-end-color": " | ", + "border-block-end-radius": "{1,2} [ / {1,2} ]?", + "border-block-end-style": "", + "border-block-end-width": "", + "border-block-start": " || || ", + "border-block-start-clip": "none | [ | ]+", + "border-block-start-color": " | ", + "border-block-start-radius": "{1,2} [ / {1,2} ]?", + "border-block-start-style": "", + "border-block-start-width": "", + "border-bottom-clip": "none | [ | ]+", + "border-bottom-color": " | ", + "border-bottom-left-radius": "", + "border-bottom-radius": "{1,2} [ / {1,2} ]?", + "border-bottom-right-radius": "", + "border-boundary": "none | parent | display", + "border-clip": "<'border-top-clip'>", + "border-color": "[ | ]{1,4}", + "border-end-end-radius": "", + "border-end-start-radius": "", + "border-inline-clip": "<'border-top-clip'>", + "border-inline-end": " || || ", + "border-inline-end-clip": "none | [ | ]+", + "border-inline-end-color": " | ", + "border-inline-end-radius": "{1,2} [ / {1,2} ]?", + "border-inline-end-style": "", + "border-inline-end-width": "", + "border-inline-start": " || || ", + "border-inline-start-clip": "none | [ | ]+", + "border-inline-start-color": " | ", + "border-inline-start-radius": "{1,2} [ / {1,2} ]?", + "border-inline-start-style": "", + "border-inline-start-width": "", + "border-left-clip": "none | [ | ]+", + "border-left-color": " | ", + "border-left-radius": "{1,2} [ / {1,2} ]?", + "border-limit": "all | [ sides | corners ] ? | [ top | right | bottom | left ] ", + "border-right-clip": "none | [ | ]+", + "border-right-color": " | ", + "border-right-radius": "{1,2} [ / {1,2} ]?", + "border-shape": "none | [ ? ]{1,2}", + "border-start-end-radius": "", + "border-start-start-radius": "", + "border-style": "<'border-top-style'>{1,4}", + "border-top-clip": "none | [ | ]+", + "border-top-color": " | ", + "border-top-left-radius": "", + "border-top-radius": "{1,2} [ / {1,2} ]?", + "border-top-right-radius": "", + "border-width": "<'border-top-width'>{1,4}", + "box-shadow": "#", + "box-shadow-blur": "#", + "box-shadow-color": "#", + "box-shadow-offset": "[ none | {1,2} ]#", + "box-shadow-position": "[ outset | inset ]#", + "box-shadow-spread": "#", + "box-snap": "none | block-start | block-end | center | baseline | last-baseline", + "caret-color": "auto | [ auto | ]?", + "clear": "| block-start | block-end | top | bottom | both-inline | both-block", + "clip": "rect( , , , ) | rect( ) | auto", + "color-adjust": "<'print-color-adjust'>", + "color-interpolation": "auto | sRGB | linearRGB", + "column-count": "auto | ", + "column-fill": "| balance-all", + "column-gap": "normal | | ", + "column-rule": " | ", + "column-rule-break": "none | normal | intersection", + "column-rule-color": " | ", + "column-rule-edge-inset": " [ ]?", + "column-rule-edge-inset-end": "", + "column-rule-edge-inset-start": "", + "column-rule-inset": "<'column-rule-edge-inset'> [ / <'column-rule-interior-inset'> ]?", + "column-rule-inset-end": "", + "column-rule-inset-start": "", + "column-rule-interior-inset": " [ ]?", + "column-rule-interior-inset-end": "", + "column-rule-interior-inset-start": "", + "column-rule-style": " | ", + "column-rule-visibility-items": "all | around | between | normal", + "column-rule-width": " | ", + "column-span": "| | auto", + "column-width": "auto | | min-content | max-content | fit-content( )", + "contain": "none | strict | content | [ [ size | inline-size ] || layout || style || paint ]", + "contain-intrinsic-block-size": "auto? [ none | ]", + "contain-intrinsic-height": "auto? [ none | ]", + "contain-intrinsic-inline-size": "auto? [ none | ]", + "contain-intrinsic-size": "[ auto? [ none | ] ]{1,2}", + "contain-intrinsic-width": "auto? [ none | ]", + "container-type": "normal | [ [ size | inline-size ] || scroll-state ]", + "content": "| ", + "continue": "auto | discard | collapse | -webkit-legacy | overflow | paginate | fragments", + "copy-into": "none | [ [ ] [, ]* ]?", + "corner": "<'border-radius'> || <'corner-shape'>", + "corner-block-end": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-block-end-shape": "<'corner-top-left-shape'>{1,2}", + "corner-block-start": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-block-start-shape": "<'corner-top-left-shape'>{1,2}", + "corner-bottom": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-bottom-left": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-bottom-right": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-bottom-shape": "<'corner-top-left-shape'>{1,2}", + "corner-end-end": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-end-start": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-inline-end": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-inline-end-shape": "<'corner-top-left-shape'>{1,2}", + "corner-inline-start": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-inline-start-shape": "<'corner-top-left-shape'>{1,2}", + "corner-left": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-left-shape": "<'corner-top-left-shape'>{1,2}", + "corner-right": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-right-shape": "<'corner-top-left-shape'>{1,2}", + "corner-shape": "<'corner-top-left-shape'>{1,4}", + "corner-start-end": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-start-start": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-top": "<'border-top-radius'> || <'corner-top-shape'>", + "corner-top-left": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-top-right": "<'border-top-left-radius'> || <'corner-top-left-shape'>", + "corner-top-shape": "<'corner-top-left-shape'>{1,2}", + "cursor": "[ , ]* ", + "cx": "", + "cy": "", + "display": "[ || ] | | | | | grid-lanes | inline-grid-lanes | ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container | | <-non-standard-display> || [ | math ]", + "dominant-baseline": "use-script | no-change | reset-size | text-after-edge | text-before-edge | auto | ", + "event-trigger": "none | [ <'event-trigger-name'> <'event-trigger-source'> ]#", + "event-trigger-name": "none | #", + "event-trigger-source": "[ none | + [ / + ]? ]#", + "fill-break": "bounding-box | slice | clone", + "fill-color": "", + "fill-image": "#", + "fill-opacity": "<'opacity'>", + "fill-origin": "match-parent | fill-box | stroke-box | content-box | padding-box | border-box", + "fill-position": "#", + "fill-repeat": "#", + "fill-size": "#", + "filter": "none | ", + "flex-grow": "", + "flex-shrink": "", + "float": "| block-start | block-end | snap-block | snap-block( , [ start | end | near ]? ) | snap-inline | snap-inline( , [ left | right | near ]? ) | top | bottom | footnote", + "float-defer": " | last | none", + "float-offset": "", + "float-reference": "inline | column | region | page", + "flow-from": " | none", + "flow-into": "none | [ element | content ]?", + "flow-tolerance": "normal | | infinite", + "font-size-adjust": "none | [ ex-height | cap-height | ch-width | ic-width | ic-height ]? [ from-font | ]", + "font-stretch": "normal | | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded", + "font-style": "normal | italic | left | right | oblique ?", + "font-synthesis-style": "auto | none | oblique-only", + "font-variant": "normal | none | [ [ || || || ] || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic( ) || historical-forms || styleset( # ) || character-variant( # ) || swash( ) || ornaments( ) || annotation( ) ] || [ || || || ordinal || slashed-zero ] || [ || || ruby ] || [ sub | super ] || [ text | emoji | unicode ] ]", + "font-variation-settings": "normal | [ ]#", + "footnote-display": "block | inline | compact", + "footnote-policy": "auto | line | block", + "frame-sizing": "auto | content-width | content-height | content-block-size | content-inline-size", + "glyph-orientation-vertical": "auto | 0deg | 90deg | 0 | 90", + "grid-column-gap": "normal | | ", + "grid-gap": "<'row-gap'> <'column-gap'>?", + "grid-row-gap": "normal | | ", + "height": "auto | | min-content | max-content | fit-content( ) | | | stretch | fit-content | contain | <-non-standard-size>", + "hyphenate-limit-last": "none | always | column | page | spread", + "hyphenate-limit-lines": "no-limit | ", + "hyphenate-limit-zone": "", + "image-animation": "normal | paused | stopped | running", + "image-orientation": "from-image | none | [ || flip ]", + "image-rendering": "auto | smooth | high-quality | pixelated | crisp-edges | <-non-standard-image-rendering>", + "initial-letter": "normal | | && [ drop | raise ]?", + "initial-letter-align": "[ border-box? [ alphabetic | ideographic | hanging | leading ]? ]!", + "initial-letter-wrap": "none | first | all | grid | ", + "inline-sizing": "normal | stretch", + "input-security": "auto | none", + "isolation": "", + "justify-self": "auto | ? [ normal | | left | right ] | stretch | | anchor-center", + "line-clamp": "none | [ || <'block-ellipsis'> ] -webkit-legacy?", + "line-fit-edge": "leading | ", + "line-grid": "match-parent | create", + "line-height": "normal | | ", + "line-height-step": "", + "line-padding": "", + "line-snap": "none | baseline | contain", + "link-parameters": "none | #", + "list-style": "<'list-style-position'> || <'list-style-image'> || <'list-style-type'>", + "margin-break": "auto | keep | discard", + "margin-trim": "none | [ block || inline ] | [ block-start || inline-start || block-end || inline-end ]", + "marker": "none | ", + "marker-end": "none | ", + "marker-mid": "none | ", + "marker-side": "match-self | match-parent", + "marker-start": "none | ", + "mask-border-slice": "[ | ]{1,4} fill?", + "max-height": "none | | min-content | max-content | fit-content( ) | | | stretch | fit-content | contain | <-non-standard-size>", + "max-lines": "none | ", + "max-width": "none | | min-content | max-content | fit-content( ) | | | stretch | fit-content | contain | <-non-standard-size>", + "min-height": "auto | | min-content | max-content | fit-content( ) | | | stretch | fit-content | contain | <-non-standard-size>", + "min-intrinsic-sizing": "legacy | zero-if-scroll || zero-if-extrinsic", + "min-width": "auto | | min-content | max-content | fit-content( ) | | | stretch | fit-content | contain | <-non-standard-size>", + "mix-blend-mode": " | plus-lighter", + "object-fit": "fill | none | [ contain | cover ] || scale-down", + "orphans": "", + "outline-color": "auto | <'border-top-color'>", + "overflow": "<'overflow-block'>{1,2} | <-non-standard-overflow>", + "overflow-block": "| <-non-standard-overflow>", + "overflow-clip-margin": " || ", + "overflow-clip-margin-block": " || ", + "overflow-clip-margin-block-end": " || ", + "overflow-clip-margin-block-start": " || ", + "overflow-clip-margin-bottom": " || ", + "overflow-clip-margin-inline": " || ", + "overflow-clip-margin-inline-end": " || ", + "overflow-clip-margin-inline-start": " || ", + "overflow-clip-margin-left": " || ", + "overflow-clip-margin-right": " || ", + "overflow-clip-margin-top": " || ", + "overflow-inline": "| <-non-standard-overflow>", + "overflow-x": "| <-non-standard-overflow>", + "overflow-y": "| <-non-standard-overflow>", + "pause-after": "