diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..60bd23e
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,12 @@
+# API Keys (Required to enable respective provider)
+ANTHROPIC_API_KEY="your_anthropic_api_key_here" # Required: Format: sk-ant-api03-...
+PERPLEXITY_API_KEY="your_perplexity_api_key_here" # Optional: Format: pplx-...
+OPENAI_API_KEY="your_openai_api_key_here" # Optional, for OpenAI models. Format: sk-proj-...
+GOOGLE_API_KEY="your_google_api_key_here" # Optional, for Google Gemini models.
+MISTRAL_API_KEY="your_mistral_key_here" # Optional, for Mistral AI models.
+XAI_API_KEY="YOUR_XAI_KEY_HERE" # Optional, for xAI AI models.
+GROQ_API_KEY="YOUR_GROQ_KEY_HERE" # Optional, for Groq models.
+OPENROUTER_API_KEY="YOUR_OPENROUTER_KEY_HERE" # Optional, for OpenRouter models.
+AZURE_OPENAI_API_KEY="your_azure_key_here" # Optional, for Azure OpenAI models (requires endpoint in .taskmaster/config.json).
+OLLAMA_API_KEY="your_ollama_api_key_here" # Optional: For remote Ollama servers that require authentication.
+GITHUB_API_KEY="your_github_api_key_here" # Optional: For GitHub import/export features. Format: ghp_... or github_pat_...
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4c8b8eb..d6a0845 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,27 @@
*.zip
.DS_Store
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+dev-debug.log
+# Dependency directories
+node_modules/
+# Environment variables
+.env
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+# OS specific
+
+# Task files
+# tasks.json
+# tasks/
diff --git a/.taskmaster/config.json b/.taskmaster/config.json
new file mode 100644
index 0000000..75c8952
--- /dev/null
+++ b/.taskmaster/config.json
@@ -0,0 +1,44 @@
+{
+ "models": {
+ "main": {
+ "provider": "anthropic",
+ "modelId": "claude-sonnet-4-20250514",
+ "maxTokens": 64000,
+ "temperature": 0.2
+ },
+ "research": {
+ "provider": "perplexity",
+ "modelId": "sonar",
+ "maxTokens": 8700,
+ "temperature": 0.1
+ },
+ "fallback": {
+ "provider": "anthropic",
+ "modelId": "claude-3-7-sonnet-20250219",
+ "maxTokens": 120000,
+ "temperature": 0.2
+ }
+ },
+ "global": {
+ "logLevel": "info",
+ "debug": false,
+ "defaultNumTasks": 10,
+ "defaultSubtasks": 5,
+ "defaultPriority": "medium",
+ "projectName": "Task Master",
+ "ollamaBaseURL": "http://localhost:11434/api",
+ "bedrockBaseURL": "https://bedrock.us-east-1.amazonaws.com",
+ "responseLanguage": "English",
+ "enableCodebaseAnalysis": true,
+ "enableProxy": false,
+ "anonymousTelemetry": true,
+ "userId": "1234567890"
+ },
+ "claudeCode": {},
+ "codexCli": {},
+ "grokCli": {
+ "timeout": 120000,
+ "workingDirectory": null,
+ "defaultModel": "grok-4-latest"
+ }
+}
\ No newline at end of file
diff --git a/.taskmaster/state.json b/.taskmaster/state.json
new file mode 100644
index 0000000..f3493fd
--- /dev/null
+++ b/.taskmaster/state.json
@@ -0,0 +1,6 @@
+{
+ "currentTag": "master",
+ "lastSwitched": "2026-04-24T15:47:33.139Z",
+ "branchTagMapping": {},
+ "migrationNoticeShown": false
+}
\ No newline at end of file
diff --git a/.taskmaster/tasks/tasks.json b/.taskmaster/tasks/tasks.json
new file mode 100644
index 0000000..05f9279
--- /dev/null
+++ b/.taskmaster/tasks/tasks.json
@@ -0,0 +1,35 @@
+{
+ "master": {
+ "tasks": [
+ {
+ "id": 1,
+ "title": "feat: search-mode split-view with PDF + page jump",
+ "description": "Render /kb/search results as a two-column split view: left column is the stack of ranked hit cards (kind, title, section, page label), right column is an iframe viewing the selected hit's PDF scrolled to page_number. Clicking any hit swaps the iframe. Text-only sources (law from Wikisource) fall back to a chunk/text panel with a Wikisource link so the right column never 404s.",
+ "status": "in-progress",
+ "priority": "high",
+ "details": "Before this change renderSearchResults produced plain vertical text cards — users got the chunk body and had to open the Wikisource link (or track down the PDF manually) to verify context. With 5 of 5 PDFs now carrying accurate page_number (shira-hermes e534709 + 1ca1cc0), the search UI can finally deep-link to the right page. Mirrors the ask-mode split view (v0.1.7 uncommitted).",
+ "testStrategy": "Search 'תקנה 37' → first hit should be a regulation/circular → right pane loads the PDF at page ~N where the section appears. Click a lower-ranked law hit → right pane swaps to a Wikisource link view. Search 'הגדרות' → hits span multiple sources → each click swaps iframe source.",
+ "subtasks": [],
+ "dependencies": [],
+ "createdAt": "2026-04-24T15:47:00Z"
+ },
+ {
+ "id": 2,
+ "title": "fix(kb/chunker): page_number propagation through split + packing (shira-hermes)",
+ "description": "Applied in shira-hermes commits e534709 + 1ca1cc0: (1) _split_oversized now re-derives page_number per piece from markers embedded in parent content + a virtual (offset 0, parent.page_number) anchor, (2) chunk_circular tracks absolute paragraph offsets in the original text so each packed sub-chunk reports its real starting page, (3) _as_dicts strips stray \\x00 bytes left behind when _split_oversized slices through a marker sentinel. Reference data: ספר הליקויים now 211 chunks × 210 pages (1-413) vs 209 × 1 before. Not work for this repo, but the search split-view in task #1 depends on it.",
+ "status": "done",
+ "priority": "high",
+ "details": "Lives in espocrm-extensions/shira-hermes. Logged here for traceability because task #1 can't demonstrate correct page jumps without it.",
+ "testStrategy": "Query DB: SELECT source_id, MIN/MAX(page_number), COUNT(DISTINCT page_number) FROM kb_chunk GROUP BY source_id — every PDF source should span multiple distinct pages.",
+ "subtasks": [],
+ "dependencies": [],
+ "createdAt": "2026-04-24T15:47:00Z"
+ }
+ ],
+ "metadata": {
+ "created": "2026-04-24T15:47:00Z",
+ "updated": "2026-04-24T15:47:00Z",
+ "description": "KnowledgeBase extension tasks"
+ }
+ }
+}
diff --git a/.taskmaster/templates/example_prd.txt b/.taskmaster/templates/example_prd.txt
new file mode 100644
index 0000000..194114d
--- /dev/null
+++ b/.taskmaster/templates/example_prd.txt
@@ -0,0 +1,47 @@
+
+# Overview
+[Provide a high-level overview of your product here. Explain what problem it solves, who it's for, and why it's valuable.]
+
+# Core Features
+[List and describe the main features of your product. For each feature, include:
+- What it does
+- Why it's important
+- How it works at a high level]
+
+# User Experience
+[Describe the user journey and experience. Include:
+- User personas
+- Key user flows
+- UI/UX considerations]
+
+
+# Technical Architecture
+[Outline the technical implementation details:
+- System components
+- Data models
+- APIs and integrations
+- Infrastructure requirements]
+
+# Development Roadmap
+[Break down the development process into phases:
+- MVP requirements
+- Future enhancements
+- Do not think about timelines whatsoever -- all that matters is scope and detailing exactly what needs to be build in each phase so it can later be cut up into tasks]
+
+# Logical Dependency Chain
+[Define the logical order of development:
+- Which features need to be built first (foundation)
+- Getting as quickly as possible to something usable/visible front end that works
+- Properly pacing and scoping each feature so it is atomic but can also be built upon and improved as development approaches]
+
+# Risks and Mitigations
+[Identify potential risks and how they'll be addressed:
+- Technical challenges
+- Figuring out the MVP that we can build upon
+- Resource constraints]
+
+# Appendix
+[Include any additional information:
+- Research findings
+- Technical specifications]
+
\ No newline at end of file
diff --git a/.taskmaster/templates/example_prd_rpg.txt b/.taskmaster/templates/example_prd_rpg.txt
new file mode 100644
index 0000000..5ad908f
--- /dev/null
+++ b/.taskmaster/templates/example_prd_rpg.txt
@@ -0,0 +1,511 @@
+
+# Repository Planning Graph (RPG) Method - PRD Template
+
+This template teaches you (AI or human) how to create structured, dependency-aware PRDs using the RPG methodology from Microsoft Research. The key insight: separate WHAT (functional) from HOW (structural), then connect them with explicit dependencies.
+
+## Core Principles
+
+1. **Dual-Semantics**: Think functional (capabilities) AND structural (code organization) separately, then map them
+2. **Explicit Dependencies**: Never assume - always state what depends on what
+3. **Topological Order**: Build foundation first, then layers on top
+4. **Progressive Refinement**: Start broad, refine iteratively
+
+## How to Use This Template
+
+- Follow the instructions in each `` block
+- Look at `` blocks to see good vs bad patterns
+- Fill in the content sections with your project details
+- The AI reading this will learn the RPG method by following along
+- Task Master will parse the resulting PRD into dependency-aware tasks
+
+## Recommended Tools for Creating PRDs
+
+When using this template to **create** a PRD (not parse it), use **code-context-aware AI assistants** for best results:
+
+**Why?** The AI needs to understand your existing codebase to make good architectural decisions about modules, dependencies, and integration points.
+
+**Recommended tools:**
+- **Claude Code** (claude-code CLI) - Best for structured reasoning and large contexts
+- **Cursor/Windsurf** - IDE integration with full codebase context
+- **Gemini CLI** (gemini-cli) - Massive context window for large codebases
+- **Codex/Grok CLI** - Strong code generation with context awareness
+
+**Note:** Once your PRD is created, `task-master parse-prd` works with any configured AI model - it just needs to read the PRD text itself, not your codebase.
+
+
+---
+
+
+
+Start with the problem, not the solution. Be specific about:
+- What pain point exists?
+- Who experiences it?
+- Why existing solutions don't work?
+- What success looks like (measurable outcomes)?
+
+Keep this section focused - don't jump into implementation details yet.
+
+
+## Problem Statement
+[Describe the core problem. Be concrete about user pain points.]
+
+## Target Users
+[Define personas, their workflows, and what they're trying to achieve.]
+
+## Success Metrics
+[Quantifiable outcomes. Examples: "80% task completion via autopilot", "< 5% manual intervention rate"]
+
+
+
+---
+
+
+
+Now think about CAPABILITIES (what the system DOES), not code structure yet.
+
+Step 1: Identify high-level capability domains
+- Think: "What major things does this system do?"
+- Examples: Data Management, Core Processing, Presentation Layer
+
+Step 2: For each capability, enumerate specific features
+- Use explore-exploit strategy:
+ * Exploit: What features are REQUIRED for core value?
+ * Explore: What features make this domain COMPLETE?
+
+Step 3: For each feature, define:
+- Description: What it does in one sentence
+- Inputs: What data/context it needs
+- Outputs: What it produces/returns
+- Behavior: Key logic or transformations
+
+
+Capability: Data Validation
+ Feature: Schema validation
+ - Description: Validate JSON payloads against defined schemas
+ - Inputs: JSON object, schema definition
+ - Outputs: Validation result (pass/fail) + error details
+ - Behavior: Iterate fields, check types, enforce constraints
+
+ Feature: Business rule validation
+ - Description: Apply domain-specific validation rules
+ - Inputs: Validated data object, rule set
+ - Outputs: Boolean + list of violated rules
+ - Behavior: Execute rules sequentially, short-circuit on failure
+
+
+
+Capability: validation.js
+ (Problem: This is a FILE, not a CAPABILITY. Mixing structure into functional thinking.)
+
+Capability: Validation
+ Feature: Make sure data is good
+ (Problem: Too vague. No inputs/outputs. Not actionable.)
+
+
+
+## Capability Tree
+
+### Capability: [Name]
+[Brief description of what this capability domain covers]
+
+#### Feature: [Name]
+- **Description**: [One sentence]
+- **Inputs**: [What it needs]
+- **Outputs**: [What it produces]
+- **Behavior**: [Key logic]
+
+#### Feature: [Name]
+- **Description**:
+- **Inputs**:
+- **Outputs**:
+- **Behavior**:
+
+### Capability: [Name]
+...
+
+
+
+---
+
+
+
+NOW think about code organization. Map capabilities to actual file/folder structure.
+
+Rules:
+1. Each capability maps to a module (folder or file)
+2. Features within a capability map to functions/classes
+3. Use clear module boundaries - each module has ONE responsibility
+4. Define what each module exports (public interface)
+
+The goal: Create a clear mapping between "what it does" (functional) and "where it lives" (structural).
+
+
+Capability: Data Validation
+ → Maps to: src/validation/
+ ├── schema-validator.js (Schema validation feature)
+ ├── rule-validator.js (Business rule validation feature)
+ └── index.js (Public exports)
+
+Exports:
+ - validateSchema(data, schema)
+ - validateRules(data, rules)
+
+
+
+Capability: Data Validation
+ → Maps to: src/utils.js
+ (Problem: "utils" is not a clear module boundary. Where do I find validation logic?)
+
+Capability: Data Validation
+ → Maps to: src/validation/everything.js
+ (Problem: One giant file. Features should map to separate files for maintainability.)
+
+
+
+## Repository Structure
+
+```
+project-root/
+├── src/
+│ ├── [module-name]/ # Maps to: [Capability Name]
+│ │ ├── [file].js # Maps to: [Feature Name]
+│ │ └── index.js # Public exports
+│ └── [module-name]/
+├── tests/
+└── docs/
+```
+
+## Module Definitions
+
+### Module: [Name]
+- **Maps to capability**: [Capability from functional decomposition]
+- **Responsibility**: [Single clear purpose]
+- **File structure**:
+ ```
+ module-name/
+ ├── feature1.js
+ ├── feature2.js
+ └── index.js
+ ```
+- **Exports**:
+ - `functionName()` - [what it does]
+ - `ClassName` - [what it does]
+
+
+
+---
+
+
+
+This is THE CRITICAL SECTION for Task Master parsing.
+
+Define explicit dependencies between modules. This creates the topological order for task execution.
+
+Rules:
+1. List modules in dependency order (foundation first)
+2. For each module, state what it depends on
+3. Foundation modules should have NO dependencies
+4. Every non-foundation module should depend on at least one other module
+5. Think: "What must EXIST before I can build this module?"
+
+
+Foundation Layer (no dependencies):
+ - error-handling: No dependencies
+ - config-manager: No dependencies
+ - base-types: No dependencies
+
+Data Layer:
+ - schema-validator: Depends on [base-types, error-handling]
+ - data-ingestion: Depends on [schema-validator, config-manager]
+
+Core Layer:
+ - algorithm-engine: Depends on [base-types, error-handling]
+ - pipeline-orchestrator: Depends on [algorithm-engine, data-ingestion]
+
+
+
+- validation: Depends on API
+- API: Depends on validation
+(Problem: Circular dependency. This will cause build/runtime issues.)
+
+- user-auth: Depends on everything
+(Problem: Too many dependencies. Should be more focused.)
+
+
+
+## Dependency Chain
+
+### Foundation Layer (Phase 0)
+No dependencies - these are built first.
+
+- **[Module Name]**: [What it provides]
+- **[Module Name]**: [What it provides]
+
+### [Layer Name] (Phase 1)
+- **[Module Name]**: Depends on [[module-from-phase-0], [module-from-phase-0]]
+- **[Module Name]**: Depends on [[module-from-phase-0]]
+
+### [Layer Name] (Phase 2)
+- **[Module Name]**: Depends on [[module-from-phase-1], [module-from-foundation]]
+
+[Continue building up layers...]
+
+
+
+---
+
+
+
+Turn the dependency graph into concrete development phases.
+
+Each phase should:
+1. Have clear entry criteria (what must exist before starting)
+2. Contain tasks that can be parallelized (no inter-dependencies within phase)
+3. Have clear exit criteria (how do we know phase is complete?)
+4. Build toward something USABLE (not just infrastructure)
+
+Phase ordering follows topological sort of dependency graph.
+
+
+Phase 0: Foundation
+ Entry: Clean repository
+ Tasks:
+ - Implement error handling utilities
+ - Create base type definitions
+ - Setup configuration system
+ Exit: Other modules can import foundation without errors
+
+Phase 1: Data Layer
+ Entry: Phase 0 complete
+ Tasks:
+ - Implement schema validator (uses: base types, error handling)
+ - Build data ingestion pipeline (uses: validator, config)
+ Exit: End-to-end data flow from input to validated output
+
+
+
+Phase 1: Build Everything
+ Tasks:
+ - API
+ - Database
+ - UI
+ - Tests
+ (Problem: No clear focus. Too broad. Dependencies not considered.)
+
+
+
+## Development Phases
+
+### Phase 0: [Foundation Name]
+**Goal**: [What foundational capability this establishes]
+
+**Entry Criteria**: [What must be true before starting]
+
+**Tasks**:
+- [ ] [Task name] (depends on: [none or list])
+ - Acceptance criteria: [How we know it's done]
+ - Test strategy: [What tests prove it works]
+
+- [ ] [Task name] (depends on: [none or list])
+
+**Exit Criteria**: [Observable outcome that proves phase complete]
+
+**Delivers**: [What can users/developers do after this phase?]
+
+---
+
+### Phase 1: [Layer Name]
+**Goal**:
+
+**Entry Criteria**: Phase 0 complete
+
+**Tasks**:
+- [ ] [Task name] (depends on: [[tasks-from-phase-0]])
+- [ ] [Task name] (depends on: [[tasks-from-phase-0]])
+
+**Exit Criteria**:
+
+**Delivers**:
+
+---
+
+[Continue with more phases...]
+
+
+
+---
+
+
+
+Define how testing will be integrated throughout development (TDD approach).
+
+Specify:
+1. Test pyramid ratios (unit vs integration vs e2e)
+2. Coverage requirements
+3. Critical test scenarios
+4. Test generation guidelines for Surgical Test Generator
+
+This section guides the AI when generating tests during the RED phase of TDD.
+
+
+Critical Test Scenarios for Data Validation module:
+ - Happy path: Valid data passes all checks
+ - Edge cases: Empty strings, null values, boundary numbers
+ - Error cases: Invalid types, missing required fields
+ - Integration: Validator works with ingestion pipeline
+
+
+
+## Test Pyramid
+
+```
+ /\
+ /E2E\ ← [X]% (End-to-end, slow, comprehensive)
+ /------\
+ /Integration\ ← [Y]% (Module interactions)
+ /------------\
+ / Unit Tests \ ← [Z]% (Fast, isolated, deterministic)
+ /----------------\
+```
+
+## Coverage Requirements
+- Line coverage: [X]% minimum
+- Branch coverage: [X]% minimum
+- Function coverage: [X]% minimum
+- Statement coverage: [X]% minimum
+
+## Critical Test Scenarios
+
+### [Module/Feature Name]
+**Happy path**:
+- [Scenario description]
+- Expected: [What should happen]
+
+**Edge cases**:
+- [Scenario description]
+- Expected: [What should happen]
+
+**Error cases**:
+- [Scenario description]
+- Expected: [How system handles failure]
+
+**Integration points**:
+- [What interactions to test]
+- Expected: [End-to-end behavior]
+
+## Test Generation Guidelines
+[Specific instructions for Surgical Test Generator about what to focus on, what patterns to follow, project-specific test conventions]
+
+
+
+---
+
+
+
+Describe technical architecture, data models, and key design decisions.
+
+Keep this section AFTER functional/structural decomposition - implementation details come after understanding structure.
+
+
+## System Components
+[Major architectural pieces and their responsibilities]
+
+## Data Models
+[Core data structures, schemas, database design]
+
+## Technology Stack
+[Languages, frameworks, key libraries]
+
+**Decision: [Technology/Pattern]**
+- **Rationale**: [Why chosen]
+- **Trade-offs**: [What we're giving up]
+- **Alternatives considered**: [What else we looked at]
+
+
+
+---
+
+
+
+Identify risks that could derail development and how to mitigate them.
+
+Categories:
+- Technical risks (complexity, unknowns)
+- Dependency risks (blocking issues)
+- Scope risks (creep, underestimation)
+
+
+## Technical Risks
+**Risk**: [Description]
+- **Impact**: [High/Medium/Low - effect on project]
+- **Likelihood**: [High/Medium/Low]
+- **Mitigation**: [How to address]
+- **Fallback**: [Plan B if mitigation fails]
+
+## Dependency Risks
+[External dependencies, blocking issues]
+
+## Scope Risks
+[Scope creep, underestimation, unclear requirements]
+
+
+
+---
+
+
+## References
+[Papers, documentation, similar systems]
+
+## Glossary
+[Domain-specific terms]
+
+## Open Questions
+[Things to resolve during development]
+
+
+---
+
+
+# How Task Master Uses This PRD
+
+When you run `task-master parse-prd .txt`, the parser:
+
+1. **Extracts capabilities** → Main tasks
+ - Each `### Capability:` becomes a top-level task
+
+2. **Extracts features** → Subtasks
+ - Each `#### Feature:` becomes a subtask under its capability
+
+3. **Parses dependencies** → Task dependencies
+ - `Depends on: [X, Y]` sets task.dependencies = ["X", "Y"]
+
+4. **Orders by phases** → Task priorities
+ - Phase 0 tasks = highest priority
+ - Phase N tasks = lower priority, properly sequenced
+
+5. **Uses test strategy** → Test generation context
+ - Feeds test scenarios to Surgical Test Generator during implementation
+
+**Result**: A dependency-aware task graph that can be executed in topological order.
+
+## Why RPG Structure Matters
+
+Traditional flat PRDs lead to:
+- ❌ Unclear task dependencies
+- ❌ Arbitrary task ordering
+- ❌ Circular dependencies discovered late
+- ❌ Poorly scoped tasks
+
+RPG-structured PRDs provide:
+- ✅ Explicit dependency chains
+- ✅ Topological execution order
+- ✅ Clear module boundaries
+- ✅ Validated task graph before implementation
+
+## Tips for Best Results
+
+1. **Spend time on dependency graph** - This is the most valuable section for Task Master
+2. **Keep features atomic** - Each feature should be independently testable
+3. **Progressive refinement** - Start broad, use `task-master expand` to break down complex tasks
+4. **Use research mode** - `task-master parse-prd --research` leverages AI for better task generation
+
diff --git a/files/client/custom/modules/knowledge-base/src/views/kb/index.js b/files/client/custom/modules/knowledge-base/src/views/kb/index.js
index f5e15f0..613c8e2 100644
--- a/files/client/custom/modules/knowledge-base/src/views/kb/index.js
+++ b/files/client/custom/modules/knowledge-base/src/views/kb/index.js
@@ -113,7 +113,7 @@ define('modules/knowledge-base/views/kb/index', ['view'], function (Dep) {
}, {timeout: 240000}).then(res => {
this.stopAskProgress();
this.setLoading(false);
- this.renderAskAnswer(res.text || '');
+ this.renderAskAnswer(res.text || '', res.sources || []);
}).catch(err => {
this.stopAskProgress();
this.setLoading(false);
@@ -172,50 +172,252 @@ define('modules/knowledge-base/views/kb/index', ['view'], function (Dep) {
return;
}
const kindHe = {law: 'חוק', regulation: 'תקנה', circular: 'חוזר'};
- const rows = hits.map(h => {
+ const self = this;
+
+ const isPdfBacked = h => h && (h.kind === 'regulation' || h.kind === 'circular');
+
+ // Left column: stacked hit cards. Click → preview on the right.
+ const bodyStyle =
+ 'direction:rtl;unicode-bidi:plaintext;white-space:pre-wrap;' +
+ 'font-family:"Segoe UI",Arial,sans-serif;line-height:1.6;text-align:right;' +
+ 'max-height:14em;overflow:hidden;';
+ const listHtml = hits.map((h, i) => {
const kind = kindHe[h.kind] || h.kind;
const ident = h.identifier ? ' ' + this.escape(h.identifier) : '';
const path = h.heading_path || h.section_ref || '';
const pub = h.published_at ? ' · פורסם ' + h.published_at : '';
- // Content is rendered inside a white-space:pre-wrap block —
- // no need to convert \n to ; that would double-break.
- const content = this.escape(h.content || '');
- const srcLink = h.source_url
- ? `מקור`
- : '';
- const bodyStyle =
- 'direction:rtl;unicode-bidi:plaintext;white-space:pre-wrap;' +
- 'font-family:"Segoe UI",Arial,sans-serif;line-height:1.7;text-align:right;';
+ const pageLabel = (isPdfBacked(h) && h.page_number)
+ ? ` · עמ׳ ${h.page_number}` : '';
+ const activeClass = i === 0 ? 'panel-primary' : 'panel-default';
return `
-