class WompumGrid { constructor(element) { this.gridElement = element; this.gridSize = { columns: parseInt(element.dataset.columns) || 7, rows: parseInt(element.dataset.rows) || 5 }; // Set grid template columns based on data attribute or default this.gridElement.style.gridTemplateColumns = `repeat(${this.gridSize.columns}, 1fr)`; // Initialize color calculator this.colorCalculator = new ColorCalculator(); // Generate sigil from text content if provided const text = element.dataset.text || ''; this.sigil = Sigil.generate(text); this.gridElement.dataset.sigil = JSON.stringify(this.sigil); } // Get sigil digit for a cell based on its position getSigilDigit(position) { if (!this.sigil || !this.sigil.length) return 0; return this.sigil[position % this.sigil.length]; } // Get influences from adjacent cells getInfluences(column, row) { const influences = []; // Check adjacent cells (up, down, left, right) const adjacentPositions = [ [column, row - 1], // up [column, row + 1], // down [column - 1, row], // left [column + 1, row] // right ]; for (const [adjCol, adjRow] of adjacentPositions) { if (adjCol >= 0 && adjCol < this.gridSize.columns && adjRow >= 0 && adjRow < this.gridSize.rows) { const cell = this.gridElement.querySelector( `[data-column="${adjCol}"][data-row="${adjRow}"]` ); if (cell && cell.dataset.sigilDigit) { influences.push(parseInt(cell.dataset.sigilDigit)); } } } return influences; } // Create basic grid cells createGrid() { const totalCells = this.gridSize.columns * this.gridSize.rows; for (let i = 0; i < totalCells; i++) { const cell = document.createElement('div'); const column = i % this.gridSize.columns; const row = Math.floor(i / this.gridSize.columns); cell.className = 'wompum-cell'; cell.setAttribute('data-cell-index', i); cell.setAttribute('data-column', column); cell.setAttribute('data-row', row); // Set sigil digit based on cell position const sigilDigit = this.getSigilDigit(i); cell.setAttribute('data-sigil-digit', sigilDigit); this.gridElement.appendChild(cell); } } applyMetadataDesign() { const cells = this.gridElement.querySelectorAll('.wompum-cell'); cells.forEach(cell => { const column = parseInt(cell.dataset.column); const row = parseInt(cell.dataset.row); const sigilDigit = parseInt(cell.dataset.sigilDigit); // Get influences from adjacent cells const influences = this.getInfluences(column, row); // Calculate and apply color const color = this.colorCalculator.getColor(sigilDigit, influences); cell.style.backgroundColor = color; }); } init() { if (!this.gridElement) return; this.createGrid(); this.applyMetadataDesign(); } } class ArticleGrid extends WompumGrid { constructor(element, metadata) { super(element); this.metadata = metadata; // Generate sigils for each metadata component this.sigils = { narrator: Sigil.generate(metadata.narrator), subject: Sigil.generate(metadata.subject), facilitator: Sigil.generate(metadata.facilitator) }; // Store sigils as data attributes Object.entries(this.sigils).forEach(([key, value]) => { this.gridElement.dataset[`${key}Sigil`] = JSON.stringify(value); }); } getSigilDigit(position, section) { const sigil = this.sigils[section]; if (!sigil || !sigil.length) return 0; return sigil[position % sigil.length]; } createGrid() { const totalCells = this.gridSize.columns * this.gridSize.rows; const narratorColumns = 2; const facilitatorColumns = 2; for (let i = 0; i < totalCells; i++) { const cell = document.createElement('div'); const column = i % this.gridSize.columns; const row = Math.floor(i / this.gridSize.columns); // Determine section based on column position let section; if (column < narratorColumns) section = 'narrator'; else if (column >= this.gridSize.columns - facilitatorColumns) section = 'facilitator'; else section = 'subject'; cell.className = 'wompum-cell'; cell.setAttribute('data-cell-index', i); cell.setAttribute('data-section', section); cell.setAttribute('data-column', column); cell.setAttribute('data-row', row); // Set sigil digit based on section and position const sigilDigit = this.getSigilDigit(row, section); cell.setAttribute('data-sigil-digit', sigilDigit); this.gridElement.appendChild(cell); } } } // Initialize grids document.addEventListener('DOMContentLoaded', () => { // Initialize basic grids document.querySelectorAll('.wompum-grid').forEach(element => { const grid = new WompumGrid(element); grid.init(); }); // Initialize article grids document.querySelectorAll('.wompum-article-grid').forEach(element => { let metadata = {}; try { metadata = JSON.parse(element.dataset.metadata || '{}'); } catch (e) { console.error('Error parsing metadata for article grid:', e); } const grid = new ArticleGrid(element, metadata); grid.init(); }); });