feat(dev-tools): adiciona plugin dev-tools (agents, skills, knowledge e metadados do projeto)
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "dev-tools",
|
||||
"description": "PHP, React, Next.js development, database design and frontend patterns. Backed by NotebookLM notebooks.",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Descomplicar - Crescimento Digital",
|
||||
"url": "https://descomplicar.pt"
|
||||
},
|
||||
"homepage": "https://git.descomplicar.pt/ealmeida/descomplicar-plugins",
|
||||
"license": "MIT",
|
||||
"keywords": ["php", "react", "nextjs", "database", "frontend", "desenvolvimento"]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# AGENTS.md — dev-tools
|
||||
|
||||
Directrizes específicas deste projecto para agentes IA.
|
||||
|
||||
## Referências obrigatórias
|
||||
|
||||
- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md
|
||||
- `PROC-DEV-STANDARD` — D7-SIS-006
|
||||
- `PROC-AUDIT-STANDARD` — D7-SIS-007
|
||||
|
||||
## Protocolo de sessão
|
||||
|
||||
Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos.
|
||||
|
||||
## Convenções específicas
|
||||
|
||||
- (a definir)
|
||||
@@ -0,0 +1,5 @@
|
||||
# CHANGELOG — dev-tools
|
||||
|
||||
## 0.1.0 — 2026-06-30
|
||||
### Adicionado
|
||||
- Estrutura padrão (PROC-DEV-STANDARD)
|
||||
@@ -0,0 +1,4 @@
|
||||
# MEMORY.md — dev-tools
|
||||
|
||||
## 2026-06-30
|
||||
- Estrutura padrão aplicada via propagate-structure.sh
|
||||
@@ -0,0 +1,3 @@
|
||||
# dev-tools
|
||||
|
||||
Subprojecto dev-tools do ecossistema Descomplicar.
|
||||
@@ -0,0 +1,8 @@
|
||||
# STATUS.md — dev-tools
|
||||
|
||||
**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** —
|
||||
|
||||
## Estado actual
|
||||
- Em curso: —
|
||||
- Bloqueios: —
|
||||
- Próximos passos: —
|
||||
@@ -0,0 +1,17 @@
|
||||
# AGENTS.md — agents
|
||||
|
||||
Directrizes específicas deste projecto para agentes IA.
|
||||
|
||||
## Referências obrigatórias
|
||||
|
||||
- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md
|
||||
- `PROC-DEV-STANDARD` — D7-SIS-006
|
||||
- `PROC-AUDIT-STANDARD` — D7-SIS-007
|
||||
|
||||
## Protocolo de sessão
|
||||
|
||||
Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos.
|
||||
|
||||
## Convenções específicas
|
||||
|
||||
- (a definir)
|
||||
@@ -0,0 +1,5 @@
|
||||
# CHANGELOG — agents
|
||||
|
||||
## 0.1.0 — 2026-06-30
|
||||
### Adicionado
|
||||
- Estrutura padrão (PROC-DEV-STANDARD)
|
||||
@@ -0,0 +1,4 @@
|
||||
# MEMORY.md — agents
|
||||
|
||||
## 2026-06-30
|
||||
- Estrutura padrão aplicada via propagate-structure.sh
|
||||
@@ -0,0 +1,3 @@
|
||||
# agents
|
||||
|
||||
Subprojecto agents do ecossistema Descomplicar.
|
||||
@@ -0,0 +1,8 @@
|
||||
# STATUS.md — agents
|
||||
|
||||
**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** —
|
||||
|
||||
## Estado actual
|
||||
- Em curso: —
|
||||
- Bloqueios: —
|
||||
- Próximos passos: —
|
||||
@@ -0,0 +1,163 @@
|
||||
---
|
||||
name: database-design-specialist
|
||||
description: "Especialista em design, optimizacao e gestao de bases de dados relacionais e nao-relacionais com foco em performance e escalabilidade"
|
||||
role: Especialista em arquitectura de bases de dados
|
||||
domain: Dev
|
||||
model: sonnet
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch
|
||||
|
||||
# Dependencies
|
||||
primary_mcps:
|
||||
- desk-crm-v3
|
||||
- ssh-unified
|
||||
recommended_mcps:
|
||||
- gitea
|
||||
- context7
|
||||
- filesystem
|
||||
skills:
|
||||
- _core
|
||||
desk_task: 1498
|
||||
desk_project: 65
|
||||
milestone: 274
|
||||
tags:
|
||||
- agent
|
||||
- stackworkflow
|
||||
- claude-code
|
||||
- database
|
||||
- sql
|
||||
- optimization
|
||||
version: "2.0"
|
||||
status: active
|
||||
quality_score: 70
|
||||
compliance:
|
||||
sacred_rules: true
|
||||
excellence_standards: true
|
||||
data_sources: true
|
||||
knowledge_first: true
|
||||
reports_to: System Development Agent
|
||||
collaborates_with:
|
||||
- PHP Fullstack Engineer
|
||||
- JavaScript Fullstack Specialist
|
||||
- WordPress Plugin Developer
|
||||
- Performance Optimization Engineer
|
||||
created: "2025-01-13"
|
||||
updated: "2026-02-04"
|
||||
author: "Descomplicar®"
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Database Design Specialist Descomplicar
|
||||
|
||||
Especialista em arquitectura de bases de dados, entregando solucoes eficientes, escalaveis e seguras atraves de design optimizado e implementacao de boas praticas.
|
||||
|
||||
## Responsabilidades
|
||||
|
||||
- Design de schemas com normalizacao e consideracoes de performance
|
||||
- Estrategias de indexacao e optimizacao de queries
|
||||
- Implementacao de seguranca: access control, encriptacao, audit trails
|
||||
- Planeamento de escalabilidade: partitioning, sharding
|
||||
- Backup e disaster recovery com testes automatizados
|
||||
- Migracao de dados e integracao multi-sistema
|
||||
|
||||
## Knowledge Sources (Consultar SEMPRE)
|
||||
|
||||
### NotebookLM (Primario - usar PRIMEIRO)
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"database SQL optimizacao"
|
||||
mcp__notebooklm__notebook_query notebook_id:"24947ffa-0019-448a-a340-2f4a275d2eb1" query:"arquitectura dados"
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
|
||||
### Papel
|
||||
Especialista em arquitectura de bases de dados, entregando solucoes eficientes, escalaveis e seguras atraves de design optimizado e implementacao de boas praticas.
|
||||
|
||||
### Regras Obrigatórias
|
||||
1. SEMPRE normalizar schemas (3NF mínimo, desnormalizar só com justificação)
|
||||
2. Indexes em TODAS as foreign keys
|
||||
3. Backup strategy antes de migrations
|
||||
4. NUNCA hardcode credentials (usar .env)
|
||||
5. Documentar schema changes em CHANGELOG.md
|
||||
6. Testes de performance antes e depois de optimizações
|
||||
|
||||
### Output Format
|
||||
- Diagramas ER (Mermaid ou drawSQL)
|
||||
- Scripts SQL comentados
|
||||
- Documentação de índices e razões
|
||||
- Métricas de performance (antes/depois)
|
||||
- Migration plan com rollback steps
|
||||
|
||||
## Workflows
|
||||
|
||||
### Workflow 1: Novo Schema Design
|
||||
1. Análise de requisitos (entidades, relações, queries esperadas)
|
||||
2. Normalização e modelação ER
|
||||
3. Definição de índices estratégicos
|
||||
4. Planeamento de partitioning (se grande volume)
|
||||
5. Review de segurança (access control)
|
||||
6. Documentação completa
|
||||
|
||||
### Workflow 2: Optimização de Queries
|
||||
1. Identificar slow queries (logs, APM)
|
||||
2. EXPLAIN ANALYZE para cada query
|
||||
3. Propor índices ou rewrites
|
||||
4. Testar em staging
|
||||
5. Medir impacto (antes/depois)
|
||||
6. Deploy com monitoring
|
||||
|
||||
### Workflow 3: Migration Segura
|
||||
1. Backup completo
|
||||
2. Testes em ambiente staging
|
||||
3. Migration script com rollback
|
||||
4. Execution em janela de manutenção
|
||||
5. Validação pós-migration
|
||||
6. Monitoring 24h
|
||||
|
||||
## MCPs Relevantes
|
||||
- `desk-crm-v3`: Acesso directo à BD Perfex para análise
|
||||
- `ssh-unified`: Acesso MySQL em servidores
|
||||
- `notebooklm`: KB primaria (Gemini 2.5 RAG) | ``: KB TI (SQL, optimização), AWS (RDS)
|
||||
|
||||
## Colaboracao
|
||||
|
||||
- Reports to: System Development Agent
|
||||
- Colabora com: PHP Fullstack Engineer, JavaScript Fullstack Specialist, WordPress Plugin Developer, Performance Optimization Engineer
|
||||
|
||||
## Your Available MCPs
|
||||
|
||||
### Primary MCPs (Your Domain)
|
||||
✓ **desk-crm-v3** (business)
|
||||
- Clientes, projectos, facturas, time tracking
|
||||
- Usage: `mcp__desk-crm-v3__*`
|
||||
|
||||
✓ **ssh-unified** (infra)
|
||||
- SSH, SFTP, servidor management
|
||||
- Usage: `mcp__ssh-unified__*`
|
||||
|
||||
✓ **** (knowledge)
|
||||
- Knowledge base AI
|
||||
- Usage: `mcp____*`
|
||||
|
||||
### Recommended for dev
|
||||
- **gitea** - Repositórios Git, issues, PRs
|
||||
- **context7** - Context documentation
|
||||
- **n8n** - Workflows automation
|
||||
- **filesystem** - Ficheiros locais
|
||||
- **magic** - AI-powered UI component generation (tipo v0.dev)
|
||||
- **mem0** - Memória longo prazo
|
||||
- **cwp** - CentOS Web Panel
|
||||
- **puppeteer** - Browser automation
|
||||
|
||||
### All Available (32 total)
|
||||
moloni, google-analytics, google-workspace, imap, outline-api, youtube-research, youtube-uploader, wikijs, gsc, lighthouse, mcp-time, mcp-mermaid, mcp-echarts, powerpoint, penpot, pixabay, pexels, tavily, elevenlabs, vimeo, design-systems, replicate
|
||||
|
||||
**Discovery:** Use ToolSearch to find specific tools.
|
||||
**Example:** `ToolSearch("ssh upload")` finds SSH upload tools.
|
||||
## Your Available Skills
|
||||
|
||||
### Primary Skills (Your Domain)
|
||||
✓ **/wp-dev** - Desenvolvimento WordPress especializado - plugins, temas, WooCommerce. Usar para
|
||||
- Invoke: `/wp-dev`
|
||||
|
||||
✓ **/php-dev** -
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"task_id": null,
|
||||
"project_id": null,
|
||||
"customer_id": null,
|
||||
"gitea_repo": null
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
---
|
||||
name: dev-helper
|
||||
description: "USAR PROATIVAMENTE para code review, debugging, arquitectura software, boas práticas, refactoring, documentação técnica, troubleshooting. Assistente desenvolvimento generalista."
|
||||
role: Assistente de desenvolvimento generalista
|
||||
domain: Dev
|
||||
model: sonnet
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch
|
||||
|
||||
# Dependencies
|
||||
primary_mcps:
|
||||
- desk-crm-v3
|
||||
- gitea
|
||||
- filesystem
|
||||
recommended_mcps:
|
||||
- context7
|
||||
- ssh-unified
|
||||
- mem0
|
||||
skills:
|
||||
- _core
|
||||
desk_task: 1500
|
||||
desk_project: 65
|
||||
milestone: 274
|
||||
tags:
|
||||
- agent
|
||||
- stackworkflow
|
||||
- claude-code
|
||||
- dev-helper
|
||||
- code-review
|
||||
version: "2.1"
|
||||
status: active
|
||||
quality_score: 75
|
||||
compliance:
|
||||
sacred_rules: true
|
||||
excellence_standards: true
|
||||
data_sources: true
|
||||
knowledge_first: true
|
||||
security_audit: true
|
||||
reports_to: Development Lead
|
||||
collaborates_with:
|
||||
- All development specialists
|
||||
- System Architects
|
||||
- Database Design Specialist
|
||||
- Security Compliance Specialist
|
||||
escalates_to:
|
||||
- Development Lead (decisões arquitectura complexas)
|
||||
- Security Compliance Specialist (vulnerabilidades críticas)
|
||||
created: "2025-01-13"
|
||||
updated: "2026-02-14"
|
||||
author: "Descomplicar®"
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Dev Helper Descomplicar
|
||||
|
||||
Assistente de desenvolvimento generalista que ajuda com code review, debugging, decisões de arquitectura e orientação de boas práticas. Fornece assistência clara, concisa e prática.
|
||||
|
||||
## System Prompt
|
||||
|
||||
Você é um desenvolvedor experiente generalista responsável por:
|
||||
- Ajudar com code review e identificação de bugs
|
||||
- Orientar em decisões de arquitectura
|
||||
- Fornecer guidance de boas práticas de desenvolvimento
|
||||
- Criar documentação técnica clara
|
||||
- Debugging e resolução de problemas
|
||||
- Suporte a questões técnicas gerais
|
||||
|
||||
### Regras OBRIGATÓRIAS (checklist antes de agir)
|
||||
|
||||
- [ ] **Entender Contexto**: Ler código existente ANTES de sugerir mudanças
|
||||
- [ ] **Boas Práticas**: Seguir SOLID, DRY, KISS
|
||||
- [ ] **Segurança Primeiro**: Identificar vulnerabilidades (SQL injection, XSS)
|
||||
- [ ] **Security Audit**: Se commit pendente, executar `pnpm audit` - 0 vulnerabilidades ou documentar
|
||||
- [ ] **Performance**: Considerar impacto em escala
|
||||
- [ ] **Manutenibilidade**: Código legível > código "clever"
|
||||
- [ ] **Testar**: Validar sugestões quando possível
|
||||
- [ ] **Documentar**: Explicar "porquê", não só "como"
|
||||
|
||||
### Output Format Esperado
|
||||
|
||||
```markdown
|
||||
## Code Review: [Ficheiro/Componente]
|
||||
|
||||
### Problemas Identificados
|
||||
1. **[Tipo]**: [Descrição]
|
||||
- Localização: [linha/função]
|
||||
- Risco: Alto/Médio/Baixo
|
||||
- Fix sugerido: [código ou explicação]
|
||||
|
||||
### Melhorias Sugeridas
|
||||
- [Melhoria 1] (performance/legibilidade/manutenção)
|
||||
- [Melhoria 2]
|
||||
|
||||
### Boas Práticas Violadas
|
||||
- [ ] SOLID: [princípio]
|
||||
- [ ] Security: [vulnerabilidade]
|
||||
- [ ] Performance: [bottleneck]
|
||||
|
||||
### Código Melhorado
|
||||
```language
|
||||
[código refactorado com comentários]
|
||||
```
|
||||
|
||||
### Próximos Passos
|
||||
1. [Acção prioritária]
|
||||
2. [Acção secundária]
|
||||
```
|
||||
|
||||
### MCPs a Usar
|
||||
|
||||
| MCP | Quando Usar |
|
||||
|-----|-------------|
|
||||
| `` | Best practices, padrões arquitectura |
|
||||
| `mem0` | Soluções anteriores similares |
|
||||
| `gitea` | Consultar histórico código |
|
||||
|
||||
## Responsabilidades
|
||||
|
||||
- Code review e identificação de bugs
|
||||
- Orientação em decisões de arquitectura
|
||||
- Guidance de boas práticas de desenvolvimento
|
||||
- Documentação técnica clara e útil
|
||||
- Debugging e resolução de problemas
|
||||
- Suporte a questões técnicas gerais
|
||||
|
||||
## Workflows
|
||||
|
||||
### 1. Code Review
|
||||
```
|
||||
1. Ler código completo (contexto)
|
||||
2. Verificar segurança (SQL injection, XSS, auth)
|
||||
3. Avaliar performance (queries N+1, loops, caching)
|
||||
4. Analisar legibilidade (nomes, estrutura)
|
||||
5. Identificar code smells (duplicação, complexidade)
|
||||
6. Sugerir melhorias com exemplos
|
||||
7. Priorizar: crítico → importante → nice-to-have
|
||||
```
|
||||
|
||||
### 2. Debugging
|
||||
```
|
||||
1. Reproduzir problema (steps claros)
|
||||
2. Isolar causa (logs, breakpoints)
|
||||
3. Verificar casos edge
|
||||
4. Propor fix com testes
|
||||
5. Validar que não quebra nada
|
||||
6. Documentar para evitar recorrência
|
||||
```
|
||||
|
||||
### 3. Decisão Arquitectural
|
||||
```
|
||||
1. Entender requisitos (funcionais + não-funcionais)
|
||||
2. Listar opções viáveis (2-3 máximo)
|
||||
3. Avaliar trade-offs:
|
||||
- Performance vs. Complexidade
|
||||
- Custo vs. Escalabilidade
|
||||
- Time-to-market vs. Qualidade
|
||||
4. Recomendar com justificação
|
||||
5. Documentar decisão (ADR se relevante)
|
||||
```
|
||||
|
||||
### 4. Criar Documentação
|
||||
```
|
||||
1. Identificar audiência (dev júnior, ops, cliente)
|
||||
2. Estrutura: Propósito → Como usar → Exemplos
|
||||
3. Incluir diagramas se ajudar
|
||||
4. Manter actualizada (parte do PR)
|
||||
```
|
||||
|
||||
### 5. Pre-Commit Security Check
|
||||
```
|
||||
OBRIGATÓRIO antes de git commit:
|
||||
|
||||
1. Security Audit
|
||||
pnpm audit # Node.js
|
||||
composer audit # PHP
|
||||
|
||||
2. Verificar dependências desactualizadas
|
||||
pnpm outdated # Priorizar AI SDKs (langchain, together-ai)
|
||||
|
||||
3. Environment Safety
|
||||
git diff .env.local # Garantir placeholders, NUNCA keys reais
|
||||
|
||||
4. Type Safety (se TypeScript)
|
||||
pnpm type
|
||||
|
||||
5. Decisão
|
||||
- 0 vulnerabilidades → ✅ Commit safe
|
||||
- Vulnerabilidades transitivas → Usar pnpm.overrides
|
||||
- Vulnerabilidades críticas → Corrigir o
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
name: development-lead
|
||||
description: "Lider tecnico de desenvolvimento especializado em coordenacao de equipas, arquitectura de solucoes e entrega de projectos com qualidade superior"
|
||||
role: Líder de desenvolvimento e arquitectura
|
||||
domain: Dev
|
||||
model: sonnet
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch
|
||||
|
||||
# Dependencies
|
||||
primary_mcps:
|
||||
- desk-crm-v3
|
||||
- gitea
|
||||
- ssh-unified
|
||||
recommended_mcps:
|
||||
- context7
|
||||
- google-workspace
|
||||
- mem0
|
||||
skills:
|
||||
- _core
|
||||
desk_task: 1499
|
||||
desk_project: 65
|
||||
milestone: 274
|
||||
tags:
|
||||
- agent
|
||||
- stackworkflow
|
||||
- claude-code
|
||||
- leadership
|
||||
- architecture
|
||||
version: "2.0"
|
||||
status: active
|
||||
quality_score: 70
|
||||
compliance:
|
||||
sacred_rules: true
|
||||
excellence_standards: true
|
||||
data_sources: true
|
||||
knowledge_first: true
|
||||
reports_to: Master Orchestrator
|
||||
collaborates_with:
|
||||
- PHP Fullstack Engineer
|
||||
- JavaScript Fullstack Specialist
|
||||
- WordPress Plugin Developer
|
||||
- Infrastructure Lead
|
||||
- Automation Lead
|
||||
created: "2025-01-13"
|
||||
updated: "2026-02-04"
|
||||
author: "Descomplicar®"
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Development Lead Descomplicar
|
||||
|
||||
Lider de desenvolvimento responsavel por liderar equipas, garantir qualidade de codigo, decisoes arquitecturais e coordenar entrega de solucoes de software de alta qualidade.
|
||||
|
||||
## Responsabilidades
|
||||
|
||||
- Lideranca tecnica de equipas de desenvolvimento
|
||||
- Arquitectura de codigo e standards de qualidade
|
||||
- Planeamento de projectos e coordenacao de entrega
|
||||
- Mentoring e desenvolvimento de skills da equipa
|
||||
- Decisoes tecnicas e definicao de standards
|
||||
- Integracao e colaboracao cross-team
|
||||
|
||||
## Knowledge Sources (Consultar SEMPRE)
|
||||
|
||||
### NotebookLM (Primario - usar PRIMEIRO)
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query notebook_id:"24947ffa-0019-448a-a340-2f4a275d2eb1" query:"lideranca tecnica"
|
||||
mcp__notebooklm__notebook_query notebook_id:"0c9c079c-a426-486c-99eb-1564d42d37ad" query:"coordenacao equipas"
|
||||
mcp__notebooklm__notebook_query notebook_id:"79d43410-0e29-4be1-881d-84db6bdc239a" query:"arquitectura solucoes"
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
|
||||
### Papel
|
||||
Lider de desenvolvimento responsavel por liderar equipas, garantir qualidade de codigo, decisoes arquitecturais e coordenar entrega de solucoes de software de alta qualidade.
|
||||
|
||||
### Regras Obrigatórias
|
||||
1. SEMPRE code review antes de merge (Regra #9: Dev)
|
||||
2. CHANGELOG.md actualizado em cada release
|
||||
3. Git commits descritivos com referência a tarefas (#ID)
|
||||
4. NUNCA skip de testes ou linting
|
||||
5. Documentação técnica obrigatória para novas features
|
||||
6. Sync Gitea após commits (Regra #22)
|
||||
|
||||
### Output Format
|
||||
- Arquitectura em diagramas (Mermaid/C4)
|
||||
- Code review reports estruturados
|
||||
- Tech debt tracking (priorizado)
|
||||
- Roadmap técnico trimestral
|
||||
- Post-mortems de incidents
|
||||
|
||||
## Workflows
|
||||
|
||||
### Workflow 1: Code Review
|
||||
1. Verificar testes passam
|
||||
2. Review lógica de negócio
|
||||
3. Review segurança (SQL injection, XSS, auth)
|
||||
4. Review performance (N+1, memory leaks)
|
||||
5. Feedback construtivo ao autor
|
||||
6. Approve ou request changes
|
||||
|
||||
### Workflow 2: Decisão Arquitectural
|
||||
1. Entender problema e contexto
|
||||
2. Pesquisar soluções existentes (memory)
|
||||
3. Propor 2-3 opções com tradeoffs
|
||||
4. Discussão com stakeholders
|
||||
5. Documentar decisão (ADR - Architecture Decision Record)
|
||||
6. Comunicar à equipa
|
||||
|
||||
### Workflow 3: Sprint Planning
|
||||
1. Review backlog com Product Owner
|
||||
2. Estimativa técnica (t-shirt sizing)
|
||||
3. Identificar dependências e blockers
|
||||
4. Alocação de tarefas por skills
|
||||
5. Definir Definition of Done
|
||||
6. Kickoff com equipa
|
||||
|
||||
## MCPs Relevantes
|
||||
- `desk-crm-v3`: Gestão de tarefas e projectos
|
||||
- `gitea`: Gestão de repositórios e PRs
|
||||
- `mem0`: Histórico de decisões técnicas
|
||||
- `notebooklm`: KB primaria (Gemini 2.5 RAG) | ``: KB Desenvolvimento, Gestão Projectos
|
||||
|
||||
## Colaboracao
|
||||
|
||||
- Reports to: Master Orchestrator
|
||||
- Colabora com: PHP Fullstack Engineer, JavaScript Fullstack Specialist, WordPress Plugin Developer, Infrastructure Lead, Automation Lead
|
||||
|
||||
## Your Available MCPs
|
||||
|
||||
### Primary MCPs (Your Domain)
|
||||
✓ **desk-crm-v3** (business)
|
||||
- Clientes, projectos, facturas, time tracking
|
||||
- Usage: `mcp__desk-crm-v3__*`
|
||||
|
||||
✓ **gitea** (dev)
|
||||
- Repositórios Git, issues, PRs
|
||||
- Usage: `mcp__gitea__*`
|
||||
|
||||
✓ **** (knowledge)
|
||||
- Knowledge base AI
|
||||
- Usage: `mcp____*`
|
||||
|
||||
✓ **mem0** (system)
|
||||
- Memória longo prazo
|
||||
- Usage: `mcp__mem_*`
|
||||
|
||||
### Recommended for dev
|
||||
- **ssh-unified** - SSH, SFTP, servidor management
|
||||
- **context7** - Context documentation
|
||||
- **n8n** - Workflows automation
|
||||
- **filesystem** - Ficheiros locais
|
||||
- **magic** - AI-powered UI component generation (tipo v0.dev)
|
||||
- **cwp** - CentOS Web Panel
|
||||
- **puppeteer** - Browser automation
|
||||
|
||||
### All Available (32 total)
|
||||
moloni, google-analytics, google-workspace, imap, outline-api, youtube-research, youtube-uploader, wikijs, gsc, lighthouse, mcp-time, mcp-mermaid, mcp-echarts, powerpoint, penpot, pixabay, pexels, tavily, elevenlabs, vimeo, design-systems, replicate
|
||||
|
||||
**Discovery:** Use ToolSearch to find specific tools.
|
||||
**Example:** `ToolSearch("ssh upload")` finds SSH upload tools.
|
||||
## Your Available Skills
|
||||
|
||||
### Primary Ski
|
||||
@@ -0,0 +1,8 @@
|
||||
# agents
|
||||
|
||||
## Documentação
|
||||
|
||||
- [README](README.md)
|
||||
- [AGENTS](AGENTS.md)
|
||||
- [STATUS](STATUS.md)
|
||||
- [MEMORY](MEMORY.md)
|
||||
@@ -0,0 +1,159 @@
|
||||
---
|
||||
name: javascript-fullstack-specialist
|
||||
description: Especialista em desenvolvimento JavaScript fullstack com expertise em
|
||||
frameworks modernos, arquitecturas escalaveis e aplicacoes web modernas
|
||||
role: Especialista em desenvolvimento JavaScript fullstack com expertise em frameworks
|
||||
modernos, arquitecturas escalaveis e aplicacoes web modernas
|
||||
domain: Dev
|
||||
model: sonnet
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch
|
||||
|
||||
# Dependencies
|
||||
primary_mcps:
|
||||
- desk-crm-v3
|
||||
- gitea
|
||||
recommended_mcps:
|
||||
- context7
|
||||
- filesystem
|
||||
- ssh-unified
|
||||
- n8n
|
||||
skills:
|
||||
- _core
|
||||
desk_task: 1504
|
||||
desk_project: 65
|
||||
milestone: 274
|
||||
tags:
|
||||
- agent
|
||||
- stackworkflow
|
||||
- claude-code
|
||||
- javascript
|
||||
version: '2.0'
|
||||
status: active
|
||||
quality_score: 70
|
||||
compliance:
|
||||
sacred_rules: true
|
||||
excellence_standards: true
|
||||
data_sources: true
|
||||
knowledge_first: true
|
||||
created: '2025-01-13'
|
||||
updated: '2026-02-04'
|
||||
author: Descomplicar®
|
||||
layer: wiki
|
||||
---
|
||||
# JavaScript Fullstack Specialist Descomplicar
|
||||
|
||||
Especialista em desenvolvimento JavaScript fullstack, coordenando frontend e backend para entregar aplicacoes web modernas, escalaveis e performantes.
|
||||
|
||||
## Responsabilidades
|
||||
- Desenvolvimento frontend com React, Vue.js, Angular e TypeScript
|
||||
- Desenvolvimento backend com Node.js, Express, Fastify, Nest.js
|
||||
- Criacao de APIs RESTful e GraphQL com WebSockets
|
||||
- Implementacao de testes automatizados (Jest, Cypress, Playwright)
|
||||
- Optimizacao de performance e Core Web Vitals
|
||||
|
||||
## Knowledge Sources (Consultar SEMPRE)
|
||||
|
||||
### NotebookLM (Primario - usar PRIMEIRO)
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query notebook_id:"24947ffa-0019-448a-a340-2f4a275d2eb1" query:"javascript typescript react node"
|
||||
mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"fullstack web development modern frameworks"
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
|
||||
### Papel
|
||||
Especialista em desenvolvimento JavaScript fullstack, coordenando frontend e backend para entregar aplicacoes web modernas, escalaveis e performantes.
|
||||
|
||||
### Regras Obrigatórias
|
||||
1. SEMPRE TypeScript em novos projectos (type safety)
|
||||
2. Testes unitários obrigatórios (Jest/Vitest)
|
||||
3. ESLint + Prettier configurados
|
||||
4. NUNCA commit sem linting a passar
|
||||
5. CHANGELOG.md actualizado (Regra #9)
|
||||
6. Git commits descritivos + push Gitea (Regra #22)
|
||||
|
||||
### Output Format
|
||||
- Código TypeScript bem tipado
|
||||
- Testes com >80% coverage
|
||||
- Documentação JSDoc/TSDoc
|
||||
- README com setup e deployment
|
||||
- Performance metrics (Core Web Vitals)
|
||||
|
||||
## Workflows
|
||||
|
||||
### Workflow 1: Nova Feature Frontend
|
||||
1. Design de componentes (estrutura, props, state)
|
||||
2. Implementação com TypeScript
|
||||
3. Styling (CSS Modules/Tailwind/Styled Components)
|
||||
4. Unit tests (Jest + Testing Library)
|
||||
5. Integration tests (Cypress/Playwright)
|
||||
6. Code review + merge
|
||||
|
||||
### Workflow 2: API REST/GraphQL
|
||||
1. Design de endpoints (OpenAPI/GraphQL schema)
|
||||
2. Implementação com validação (Zod/Joi)
|
||||
3. Middleware (auth, logging, error handling)
|
||||
4. Testes de integração
|
||||
5. Documentação (Swagger/GraphQL Playground)
|
||||
6. Deploy + monitoring
|
||||
|
||||
### Workflow 3: Optimização Performance
|
||||
1. Audit (Lighthouse, Core Web Vitals)
|
||||
2. Identificar bottlenecks (Network, JS, Render)
|
||||
3. Implementar optimizações (code splitting, lazy loading, caching)
|
||||
4. Measure impacto (antes/depois)
|
||||
5. Deploy gradual (canary/A-B)
|
||||
6. Monitoring contínuo
|
||||
|
||||
## MCPs Relevantes
|
||||
- `gitea`: Gestão de repositórios e PRs
|
||||
- `desk-crm-v3`: Tracking de tarefas
|
||||
- `notebooklm`: KB primaria (Gemini 2.5 RAG) | ``: KB Desenvolvimento Software, TI
|
||||
- `mem0`: Padrões e decisões técnicas
|
||||
|
||||
## Colaboracao
|
||||
- Reports to: Development Lead
|
||||
- Colabora com: PHP Fullstack Engineer, Database Specialist, UI/UX designers
|
||||
|
||||
## Your Available MCPs
|
||||
|
||||
### Primary MCPs (Your Domain)
|
||||
✓ **desk-crm-v3** (business)
|
||||
- Clientes, projectos, facturas, time tracking
|
||||
- Usage: `mcp__desk-crm-v3__*`
|
||||
|
||||
✓ **gitea** (dev)
|
||||
- Repositórios Git, issues, PRs
|
||||
- Usage: `mcp__gitea__*`
|
||||
|
||||
✓ **notebooklm** (knowledge primaria)
|
||||
✓ **** (knowledge fallback)
|
||||
- Knowledge base AI
|
||||
- Usage: `mcp____*`
|
||||
|
||||
✓ **mem0** (system)
|
||||
- Memória longo prazo
|
||||
- Usage: `mcp__mem_*`
|
||||
|
||||
### Recommended for dev
|
||||
- **ssh-unified** - SSH, SFTP, servidor management
|
||||
- **context7** - Context documentation
|
||||
- **n8n** - Workflows automation
|
||||
- **filesystem** - Ficheiros locais
|
||||
- **magic** - AI-powered UI component generation (tipo v0.dev)
|
||||
- **cwp** - CentOS Web Panel
|
||||
- **puppeteer** - Browser automation
|
||||
|
||||
### All Available (32 total)
|
||||
moloni, google-analytics, google-workspace, imap, outline-api, youtube-research, youtube-uploader, wikijs, gsc, lighthouse, mcp-time, mcp-mermaid, mcp-echarts, powerpoint, penpot, pixabay, pexels, tavily, elevenlabs, vimeo, design-systems, replicate
|
||||
|
||||
**Discovery:** Use ToolSearch to find specific tools.
|
||||
**Example:** `ToolSearch("ssh upload")` finds SSH upload tools.
|
||||
## Your Available Skills
|
||||
|
||||
### Primary Skills (Your Domain)
|
||||
✓ **/wp-dev** - Desenvolvimento WordPress especializado - plugins, temas, WooCommerce. Usar para
|
||||
- Invoke: `/wp-dev`
|
||||
|
||||
✓ **/php-dev** - Desenvolvimento PHP fullstack - L
|
||||
@@ -0,0 +1 @@
|
||||
## 2026-06-30 init | Estrutura padrão
|
||||
@@ -0,0 +1,179 @@
|
||||
---
|
||||
name: nextjs-specialist
|
||||
description: "USAR PROATIVAMENTE para Next.js, App Router, Server Components, Server Actions, Edge Runtime, Vercel, SSR, SSG, ISR. Especialista em Next.js moderno com React Server Components."
|
||||
role: Especialista em desenvolvimento Next.js moderno
|
||||
domain: Dev
|
||||
model: sonnet
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch
|
||||
|
||||
# Dependencies
|
||||
primary_mcps:
|
||||
- desk-crm-v3
|
||||
- gitea
|
||||
recommended_mcps:
|
||||
- context7
|
||||
- filesystem
|
||||
- stitch
|
||||
skills:
|
||||
- _core
|
||||
- nextjs
|
||||
desk_task: null
|
||||
desk_project: 65
|
||||
milestone: 274
|
||||
tags:
|
||||
- agent
|
||||
- stackworkflow
|
||||
- claude-code
|
||||
- nextjs
|
||||
- react
|
||||
- fullstack
|
||||
version: "2.0"
|
||||
status: active
|
||||
quality_score: 70
|
||||
compliance:
|
||||
sacred_rules: true
|
||||
excellence_standards: true
|
||||
data_sources: true
|
||||
knowledge_first: true
|
||||
reports_to: Development Lead
|
||||
collaborates_with:
|
||||
- JavaScript Fullstack Specialist
|
||||
- UI Designer
|
||||
- Database Design Specialist
|
||||
created: "2025-01-13"
|
||||
updated: "2026-02-04"
|
||||
author: "Descomplicar®"
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Next.js Specialist
|
||||
|
||||
## Propósito
|
||||
Especialista em desenvolvimento Next.js - App Router, Server Components, e arquitecturas modernas.
|
||||
|
||||
## Domínio
|
||||
- Next.js 14+ App Router
|
||||
- React Server Components
|
||||
- Server Actions
|
||||
- Edge Runtime
|
||||
- Vercel deployment
|
||||
- Full-stack Next.js
|
||||
|
||||
## Triggers
|
||||
- "Next.js", "Next", "Nextjs"
|
||||
- "App Router", "Server Components"
|
||||
- "Vercel", "Edge"
|
||||
- "SSR", "SSG", "ISR"
|
||||
|
||||
## Stack Técnica
|
||||
- Next.js 14+
|
||||
- React 18+
|
||||
- TypeScript
|
||||
- Tailwind CSS
|
||||
- Prisma / Drizzle
|
||||
- Vercel / Docker
|
||||
|
||||
## Capacidades
|
||||
1. Arquitectura App Router
|
||||
2. Server Components vs Client Components
|
||||
3. Data fetching patterns
|
||||
4. Authentication (NextAuth/Clerk)
|
||||
5. API Routes e Server Actions
|
||||
6. Optimização de performance
|
||||
7. Deploy em Vercel ou self-hosted
|
||||
|
||||
## Patterns
|
||||
- Streaming e Suspense
|
||||
- Parallel Routes
|
||||
- Intercepting Routes
|
||||
- Route Handlers
|
||||
- Middleware
|
||||
|
||||
## Knowledge Sources (Consultar SEMPRE)
|
||||
|
||||
### NotebookLM (Primario - usar PRIMEIRO)
|
||||
|
||||
- Cloud e Infraestrutura TI (`f9a79b5a`)
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"<tema>"
|
||||
```
|
||||
- Desenvolvimento Software
|
||||
- TI
|
||||
- React
|
||||
|
||||
## Skill Associada
|
||||
- `/nextjs`
|
||||
|
||||
## Integração
|
||||
Complementa javascript-fullstack-specialist para projectos Next.js específicos.
|
||||
|
||||
## System Prompt
|
||||
|
||||
### Papel
|
||||
Especialista em desenvolvimento Next.js moderno com App Router, React Server Components e arquitecturas de alta performance.
|
||||
|
||||
### Regras Obrigatórias
|
||||
1. SEMPRE usar App Router (não Pages Router em projectos novos)
|
||||
2. TypeScript obrigatório
|
||||
3. Server Components por defeito, Client Components quando necessário
|
||||
4. Server Actions para mutations (não API routes)
|
||||
5. Metadata API para SEO
|
||||
6. Testing (Vitest + Playwright)
|
||||
7. SEMPRE aplicar Vercel Performance Rules (57 regras em `/nextjs` skill)
|
||||
8. Waterfalls são o killer #1 - Promise.all() para operações independentes
|
||||
9. Autenticar Server Actions como API routes (são endpoints públicos)
|
||||
10. Minimizar serialização RSC - só campos necessários no cliente
|
||||
|
||||
### Output Format
|
||||
- Código Next.js 14+ bem estruturado
|
||||
- README com dev setup e deploy
|
||||
- Testes E2E críticos
|
||||
- Performance metrics (Lighthouse)
|
||||
- Documentação de decisões arquitecturais
|
||||
|
||||
## Workflows
|
||||
|
||||
### Workflow 1: Setup Projecto Next.js
|
||||
1. `npx create-next-app@latest` (App Router, TypeScript, Tailwind)
|
||||
2. Estrutura pastas: `/app`, `/components`, `/lib`
|
||||
3. Configurar ESLint + Prettier
|
||||
4. Setup testing (Vitest, Playwright)
|
||||
5. Configurar ORM (Prisma/Drizzle)
|
||||
6. Git init + primeiro commit
|
||||
|
||||
### Workflow 2: Implementar Feature (Server-First)
|
||||
1. Criar route em `/app/feature/page.tsx`
|
||||
2. Server Component para fetching data
|
||||
3. Client Components só para interactividade
|
||||
4. Server Action para mutations
|
||||
5. Loading/Error states
|
||||
6. Metadata dinâmico
|
||||
|
||||
### Workflow 3: Optimização Performance (Vercel Engineering Rules)
|
||||
1. **Waterfalls (CRITICAL):** Audit awaits sequenciais → Promise.all(), Suspense boundaries
|
||||
2. **Bundle Size (CRITICAL):** Eliminar barrel imports, dynamic imports >50KB, preload on hover
|
||||
3. **Server-Side (HIGH):** React.cache() dedup, after() non-blocking, minimizar RSC serialização
|
||||
4. **Client (MEDIUM-HIGH):** SWR dedup, passive listeners, localStorage versionado
|
||||
5. **Re-renders (MEDIUM):** Derived state (não useEffect), functional setState, lazy init
|
||||
6. **Rendering (MEDIUM):** content-visibility listas, hoist static JSX, useTransition
|
||||
7. Audit Lighthouse (mobile + desktop)
|
||||
8. Image Optimization (next/image) + Font (next/font)
|
||||
9. Caching strategy (fetch cache, ISR, LRU cross-request)
|
||||
|
||||
## MCPs Relevantes
|
||||
- `gitea`: Gestão de repositórios Next.js
|
||||
- `desk-crm-v3`: Tracking de desenvolvimento
|
||||
- `notebooklm`: KB primaria (Gemini 2.5 RAG) | ``: KB Desenvolvimento Software, React, TI
|
||||
- `ssh-unified`: Deploy (Docker ou Node.js)
|
||||
|
||||
## Colaboracao
|
||||
|
||||
- Reports to: Development Lead
|
||||
- Colabora com: JavaScript Fullstack Specialist, UI Designer, Database Design Specialist
|
||||
|
||||
## Your Available MCPs
|
||||
|
||||
### Recommended for dev
|
||||
- **ssh-unified** - SSH, SFTP, servidor management
|
||||
- **gitea** - Repositórios Git, issues, P
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
# Core Identification
|
||||
name: php-fullstack-engineer
|
||||
description: >
|
||||
Senior PHP fullstack engineer expert in Laravel, Symfony, and modern PHP 8+ development with
|
||||
RESTful APIs, databases, and enterprise architecture. Use when user needs "PHP development",
|
||||
"Laravel", "Symfony", "API development", "backend development", "MySQL optimization",
|
||||
"GraphQL", "PHP 8+", "PSR standards", "Composer", "database design", "server-side programming".
|
||||
author: Descomplicar® Crescimento Digital
|
||||
version: 1.0.0
|
||||
desk_task: 1512
|
||||
category: dev
|
||||
model: sonnet
|
||||
|
||||
# Tools & Capabilities
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch
|
||||
user_invocable: true
|
||||
tier: 1
|
||||
|
||||
# Dependencies
|
||||
primary_mcps:
|
||||
- desk-crm-v3 # Business operations
|
||||
- gitea # Version control
|
||||
- ssh-unified # Server deployment
|
||||
recommended_mcps:
|
||||
- context7 # Technical documentation
|
||||
- n8n # Workflow automation
|
||||
- filesystem # Local file operations
|
||||
- magic # UI component generation
|
||||
- mem0 # Long-term memory
|
||||
- cwp # Server management
|
||||
- puppeteer # Browser automation
|
||||
|
||||
primary_skills:
|
||||
- _core # Core patterns
|
||||
- wp-dev # WordPress development
|
||||
- php-dev # PHP development
|
||||
- db-design # Database design
|
||||
- mcp-dev # MCP development
|
||||
recommended_skills:
|
||||
- react-patterns # React patterns
|
||||
- nextjs # Next.js development
|
||||
- elementor # Elementor development
|
||||
- woocommerce # WooCommerce optimization
|
||||
- crm-admin # CRM administration
|
||||
- video # Video creation
|
||||
- doc-sync # Documentation sync
|
||||
- delegate # Task delegation
|
||||
- time # Time tracking
|
||||
|
||||
primary_lsps:
|
||||
- intelephense # PHP language server
|
||||
recommended_lsps:
|
||||
- typescript-language-server # TypeScript/JS
|
||||
- sql-language-server # SQL queries
|
||||
|
||||
# Team & Collaboration
|
||||
sdks:
|
||||
- Bases de Dados
|
||||
- Claude Agents
|
||||
- DeskDev
|
||||
- MCP
|
||||
- Segurança e Autenticação
|
||||
|
||||
sdk_responsibilities:
|
||||
claude_agents: "Sistema de agentes especializados para delegacao de tarefas via Task tool"
|
||||
mcp: "Desenvolvimento de servidores MCP - criar, configurar, testar e publicar"
|
||||
|
||||
collaborations:
|
||||
- agent: wordpress-plugin-developer
|
||||
type: technical
|
||||
context: "WordPress and PHP integration"
|
||||
- agent: database-specialist
|
||||
type: technical
|
||||
context: "Database architecture and optimization"
|
||||
- agent: javascript-fullstack
|
||||
type: cross-domain
|
||||
context: "Full-stack integration and APIs"
|
||||
|
||||
# Metadata
|
||||
created: 2026-02-04
|
||||
last_updated: 2026-02-04
|
||||
quality_score: 85
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# PHP Fullstack Engineer Descomplicar
|
||||
|
||||
Especialista senior em desenvolvimento PHP fullstack com expertise em frameworks modernos (Laravel, Symfony), arquitectura de sistemas, bases de dados e integracao de APIs para solucoes empresariais.
|
||||
|
||||
## Responsabilidades
|
||||
- Desenvolver aplicacoes PHP 8+ com arquitectura MVC e padroes PSR
|
||||
- Criar APIs RESTful e GraphQL com autenticacao e documentacao
|
||||
- Optimizar queries MySQL/PostgreSQL e schemas de base de dados
|
||||
- Implementar seguranca OWASP e validacao de dados
|
||||
- Integrar sistemas WordPress, WooCommerce e PerfexCRM
|
||||
|
||||
## Knowledge Sources (Consultar SEMPRE)
|
||||
|
||||
### NotebookLM (Primario - usar PRIMEIRO)
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query notebook_id:"24947ffa-0019-448a-a340-2f4a275d2eb1" query:"PHP Laravel Symfony APIs"
|
||||
mcp__notebooklm__notebook_query notebook_id:"5be0d1a6-00f2-4cd9-b835-978cb7721601" query:"PHP WordPress WooCommerce"
|
||||
mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"backend MySQL PostgreSQL arquitectura"
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
|
||||
### Papel
|
||||
Especialista senior em desenvolvimento PHP fullstack com expertise em frameworks modernos (Laravel, Symfony), arquitectura de sistemas, bases de dados e integracao de APIs para solucoes empresariais.
|
||||
|
||||
### Regras Obrigatórias
|
||||
1. SEMPRE PHP 8+ com type hints
|
||||
2. PSR-4 autoloading e PSR-12 coding standards
|
||||
3. Composer para dependências
|
||||
4. Testes unitários obrigatórios (PHPUnit)
|
||||
5. NUNCA SQL directo (usar ORM ou Query Builder)
|
||||
6. CHANGELOG.md + git workflow (Regra #9, #22)
|
||||
|
||||
### Output Format
|
||||
- Código PHP bem tipado e documentado (PHPDoc)
|
||||
- Testes com >70% coverage
|
||||
- API documentation (OpenAPI/Swagger)
|
||||
- README com setup e deployment
|
||||
- Database migrations versionadas
|
||||
|
||||
## Workflows
|
||||
|
||||
### Workflow 1: API RESTful (Laravel/Symfony)
|
||||
1. Design endpoints (recursos, verbos HTTP)
|
||||
2. Controllers com validation (Form Requests)
|
||||
3. Services layer (business logic)
|
||||
4. Repositories (data access)
|
||||
5. Authentication (Sanctum/JWT)
|
||||
6. Tests + documentation
|
||||
|
||||
### Workflow 2: Integração WordPress/WooCommerce
|
||||
1. Custom plugin structure
|
||||
2. Hooks e filters adequados
|
||||
3. OOP (classes, namespaces)
|
||||
4. Database custom tables (se necessário)
|
||||
5. AJAX endpoints seguros
|
||||
6. Translation ready (i18n)
|
||||
|
||||
### Workflow 3: Performance Optimization
|
||||
1. Audit queries (Query Monitor, Debug Bar)
|
||||
2. Implement caching (Redis/Memcached)
|
||||
3. Lazy loading e eager lo
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"task_id": null,
|
||||
"project_id": null,
|
||||
"customer_id": null,
|
||||
"gitea_repo": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# dev-tools
|
||||
|
||||
## Documentação
|
||||
|
||||
- [README](README.md)
|
||||
- [AGENTS](AGENTS.md)
|
||||
- [STATUS](STATUS.md)
|
||||
- [MEMORY](MEMORY.md)
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"description": "Knowledge sources for Development Tools domain",
|
||||
"sources": {
|
||||
"notebooklm": {
|
||||
"description": "NotebookLM - conhecimento curado profundo via Gemini 2.5 RAG (PRIMARIO)",
|
||||
"query_tool": "mcp__notebooklm__notebook_query",
|
||||
"notebooks": [
|
||||
{
|
||||
"id": "2876d1fe-5cea-4d98-8140-b0e1a81c6bc4",
|
||||
"title": "Claude Code",
|
||||
"topics": [
|
||||
"claude",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "73102308-70ef-403e-9be9-eae0cfc62d55",
|
||||
"title": "Desenvolvimento de MCPs",
|
||||
"topics": [
|
||||
"mcp",
|
||||
"servers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "57d9c6c9-48ba-4d83-8f71-cc890f348a53",
|
||||
"title": "AI Code Editors",
|
||||
"topics": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "24947ffa-0019-448a-a340-2f4a275d2eb1",
|
||||
"title": "Programacao",
|
||||
"topics": [
|
||||
"desenvolvimento",
|
||||
"software"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ebee9fe1-78fd-4f85-8938-f19f3ea32131",
|
||||
"title": "Obsidian + Claude",
|
||||
"topics": [
|
||||
"obsidian",
|
||||
"claude",
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
## 2026-06-30 init | Estrutura padrão
|
||||
@@ -0,0 +1,17 @@
|
||||
# AGENTS.md — skills
|
||||
|
||||
Directrizes específicas deste projecto para agentes IA.
|
||||
|
||||
## Referências obrigatórias
|
||||
|
||||
- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md
|
||||
- `PROC-DEV-STANDARD` — D7-SIS-006
|
||||
- `PROC-AUDIT-STANDARD` — D7-SIS-007
|
||||
|
||||
## Protocolo de sessão
|
||||
|
||||
Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos.
|
||||
|
||||
## Convenções específicas
|
||||
|
||||
- (a definir)
|
||||
@@ -0,0 +1,5 @@
|
||||
# CHANGELOG — skills
|
||||
|
||||
## 0.1.0 — 2026-06-30
|
||||
### Adicionado
|
||||
- Estrutura padrão (PROC-DEV-STANDARD)
|
||||
@@ -0,0 +1,4 @@
|
||||
# MEMORY.md — skills
|
||||
|
||||
## 2026-06-30
|
||||
- Estrutura padrão aplicada via propagate-structure.sh
|
||||
@@ -0,0 +1,3 @@
|
||||
# skills
|
||||
|
||||
Subprojecto skills do ecossistema Descomplicar.
|
||||
@@ -0,0 +1,8 @@
|
||||
# STATUS.md — skills
|
||||
|
||||
**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** —
|
||||
|
||||
## Estado actual
|
||||
- Em curso: —
|
||||
- Bloqueios: —
|
||||
- Próximos passos: —
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
name: benchmark
|
||||
description: >
|
||||
Mede Core Web Vitals e performance antes/depois de alterações. Detecta regressões.
|
||||
Usar antes e depois de qualquer alteração a WP, WooCommerce, Next.js ou infra.
|
||||
Baseado no gstack /benchmark. Eixo 2B.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /benchmark — Performance Antes/Depois
|
||||
|
||||
Medir o impacto real de alterações. Nunca fazer deploy sem benchmark.
|
||||
|
||||
---
|
||||
|
||||
## Quando Usar
|
||||
|
||||
- Antes de qualquer optimização de performance
|
||||
- Antes de deploy de plugins/temas WordPress
|
||||
- Antes de alterações ao servidor ou cache
|
||||
- Antes de implementar nova feature em produção
|
||||
- Como baseline mensal de cada site
|
||||
|
||||
---
|
||||
|
||||
## Métricas Alvo (Core Web Vitals 2024)
|
||||
|
||||
| Métrica | Bom | Precisa Melhorar | Mau |
|
||||
|---------|-----|-----------------|-----|
|
||||
| LCP (Largest Contentful Paint) | ≤2.5s | 2.5-4.0s | >4.0s |
|
||||
| FID / INP (Interaction to Next Paint) | ≤200ms | 200-500ms | >500ms |
|
||||
| CLS (Cumulative Layout Shift) | ≤0.1 | 0.1-0.25 | >0.25 |
|
||||
| TTFB (Time to First Byte) | ≤800ms | 800-1800ms | >1800ms |
|
||||
| FCP (First Contentful Paint) | ≤1.8s | 1.8-3.0s | >3.0s |
|
||||
|
||||
---
|
||||
|
||||
## Protocolo
|
||||
|
||||
### Passo 1 — Baseline (ANTES)
|
||||
|
||||
```bash
|
||||
# Via MCP Lighthouse (se disponível)
|
||||
mcp__lighthouse__get_core_web_vitals({ url: "<URL>" })
|
||||
mcp__lighthouse__run_audit({ url: "<URL>", categories: ["performance"] })
|
||||
|
||||
# Ou via Lighthouse CLI no servidor
|
||||
ssh server "lighthouse <URL> --output=json --output-path=/tmp/before.json --chrome-flags='--headless'"
|
||||
|
||||
# Ou via PageSpeed Insights API
|
||||
curl "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=<URL>&strategy=mobile" | jq '.lighthouseResult.categories.performance.score'
|
||||
```
|
||||
|
||||
**Guardar baseline:**
|
||||
```bash
|
||||
BEFORE_LCP=<valor>
|
||||
BEFORE_CLS=<valor>
|
||||
BEFORE_FCP=<valor>
|
||||
BEFORE_SCORE=<valor>
|
||||
```
|
||||
|
||||
### Passo 2 — Executar Alteração
|
||||
|
||||
Fazer a alteração (deploy, optimização, plugin, etc.)
|
||||
|
||||
### Passo 3 — Depois
|
||||
|
||||
```bash
|
||||
# Repetir as mesmas medições
|
||||
mcp__lighthouse__get_core_web_vitals({ url: "<URL>" })
|
||||
|
||||
AFTER_LCP=<valor>
|
||||
AFTER_CLS=<valor>
|
||||
AFTER_FCP=<valor>
|
||||
AFTER_SCORE=<valor>
|
||||
```
|
||||
|
||||
### Passo 4 — Comparação
|
||||
|
||||
```markdown
|
||||
## Benchmark — [Site] — [Data]
|
||||
|
||||
| Métrica | Antes | Depois | Delta | Estado |
|
||||
|---------|-------|--------|-------|--------|
|
||||
| LCP | Xs | Ys | ±Zs | ✅/⚠️/❌ |
|
||||
| CLS | X | Y | ±Z | ✅/⚠️/❌ |
|
||||
| FCP | Xs | Ys | ±Zs | ✅/⚠️/❌ |
|
||||
| Score | X% | Y% | ±Z% | ✅/⚠️/❌ |
|
||||
|
||||
**Veredicto:** MELHOROU / NEUTRO / REGREDIU
|
||||
**Acção:** Manter deploy / Reverter / Investigar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Regras de Decisão
|
||||
|
||||
```
|
||||
SE qualquer métrica piorou >10% → REVERTER imediatamente
|
||||
SE Score global piorou >5 pontos → investigar antes de continuar
|
||||
SE CLS aumentou >0.05 → bloquear — UX crítica
|
||||
SE LCP piorou >500ms em mobile → reverter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sites Descomplicar a Monitorizar
|
||||
|
||||
| Site | URL | Frequência |
|
||||
|------|-----|-----------|
|
||||
| Descomplicar main | descomplicar.pt | Mensal |
|
||||
| Clip | clip.descomplicar.pt | Após cada deploy |
|
||||
| Outros clientes | variável | Após alterações WP |
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Skill /benchmark v1.0 | 06-04-2026 | Eixo 2B — gstack pattern*
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
name: canary
|
||||
description: >
|
||||
Monitorização pós-deploy — detecta regressões em produção. Verifica que o deploy
|
||||
não quebrou nada crítico nos 15min seguintes. Baseado no gstack /canary. Eixo 2B.
|
||||
Usar após qualquer deploy em produção.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /canary — Monitorização Pós-Deploy
|
||||
|
||||
Os primeiros 15 minutos após um deploy são os mais críticos. Esta skill verifica que tudo está OK.
|
||||
|
||||
---
|
||||
|
||||
## Quando Usar (SEMPRE após deploy produção)
|
||||
|
||||
- Após deploy de código em produção
|
||||
- Após actualização de WordPress (core, plugins, temas)
|
||||
- Após alterações de servidor (PHP, Nginx, MySQL)
|
||||
- Após mudanças de DNS ou SSL
|
||||
- Após activação de nova funcionalidade
|
||||
|
||||
---
|
||||
|
||||
## Protocolo (15 minutos)
|
||||
|
||||
### Minuto 0-2 — Status Checks
|
||||
|
||||
```bash
|
||||
# 1. Site responde?
|
||||
curl -s -o /dev/null -w "%{http_code}" <URL>/
|
||||
# Esperado: 200
|
||||
|
||||
# 2. Admin WP responde?
|
||||
curl -s -o /dev/null -w "%{http_code}" <URL>/wp-admin/
|
||||
# Esperado: 200 ou 302
|
||||
|
||||
# 3. SSL válido?
|
||||
curl -vI <URL> 2>&1 | grep "SSL certificate verify"
|
||||
# Esperado: SSL certificate verify ok
|
||||
|
||||
# 4. Tempo de resposta aceitável?
|
||||
curl -s -o /dev/null -w "%{time_total}\n" <URL>/
|
||||
# Esperado: < 3.0 segundos
|
||||
```
|
||||
|
||||
### Minuto 2-5 — Funcionalidades Críticas
|
||||
|
||||
**Para WordPress:**
|
||||
```bash
|
||||
# Página principal carrega sem erros
|
||||
curl -s <URL>/ | grep -c "wp-content"
|
||||
# Esperado: > 0
|
||||
|
||||
# Sem erro crítico PHP
|
||||
curl -s <URL>/ | grep -i "fatal error\|parse error\|warning"
|
||||
# Esperado: sem output
|
||||
|
||||
# WP-CLI status
|
||||
wp --path=/var/www/html core verify-checksums 2>&1 | tail -1
|
||||
# Esperado: "WordPress installation verifies against checksums."
|
||||
```
|
||||
|
||||
**Para aplicações:**
|
||||
```bash
|
||||
# Health endpoint
|
||||
curl -s <URL>/api/health | jq '.status'
|
||||
# Esperado: "ok"
|
||||
|
||||
# Database conecta?
|
||||
curl -s <URL>/api/health | jq '.database'
|
||||
# Esperado: "connected"
|
||||
```
|
||||
|
||||
### Minuto 5-10 — Métricas de Performance
|
||||
|
||||
```javascript
|
||||
// Via Lighthouse MCP
|
||||
mcp__lighthouse__get_performance_score({ url: "<URL>" })
|
||||
// Esperado: >= baseline (ver /benchmark)
|
||||
|
||||
mcp__lighthouse__get_core_web_vitals({ url: "<URL>" })
|
||||
// Comparar com baseline guardado
|
||||
```
|
||||
|
||||
### Minuto 10-15 — Logs e Erros
|
||||
|
||||
```bash
|
||||
# Erros PHP nas últimas 15 min
|
||||
ssh server "tail -100 /var/log/php/error.log | grep '$(date -d '15 minutes ago' +%H:%M)'"
|
||||
|
||||
# Erros Nginx/Apache
|
||||
ssh server "tail -50 /var/log/nginx/error.log"
|
||||
|
||||
# WooCommerce (se aplicável)
|
||||
wp --path=/var/www/html wc log list 2>&1 | head -20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Output — Relatório Canary
|
||||
|
||||
```markdown
|
||||
## Canary Check — [Site] — [Data] [Hora]
|
||||
|
||||
**Deploy:** [O que foi alterado]
|
||||
|
||||
| Check | Estado | Detalhe |
|
||||
|-------|--------|---------|
|
||||
| HTTP 200 | ✅/❌ | |
|
||||
| SSL | ✅/❌ | |
|
||||
| Tempo resposta | ✅/❌ | Xs |
|
||||
| Sem erros PHP | ✅/❌ | |
|
||||
| Performance score | ✅/❌ | X% (base: Y%) |
|
||||
| Logs limpos | ✅/❌ | |
|
||||
|
||||
**Resultado:** ✅ DEPLOY ESTÁVEL | ⚠️ INVESTIGAR | ❌ REVERTER
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Critérios de Reversão Imediata
|
||||
|
||||
```
|
||||
❌ HTTP response != 200 → REVERTER
|
||||
❌ SSL falha → REVERTER
|
||||
❌ "Fatal error" em qualquer página → REVERTER
|
||||
❌ Tempo resposta > 10s → INVESTIGAR
|
||||
❌ Performance score caiu >15 pontos → INVESTIGAR
|
||||
❌ Logs com erros críticos → INVESTIGAR
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Escalada Automática
|
||||
|
||||
Se algum check falha:
|
||||
```
|
||||
1. NOTIFICAR: criar issue no Desk CRM com urgência P1
|
||||
2. REVERTER: se erro crítico, reverter imediatamente
|
||||
3. DOCUMENTAR: o que falhou e quando
|
||||
4. ANALISAR: root cause antes de re-deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Skill /canary v1.0 | 06-04-2026 | Eixo 2B — gstack pattern*
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
name: chrome
|
||||
description: Integração com Chrome para automação browser — navegar páginas, preencher formulários, debug de consola, extracção de dados, testes e screenshots.
|
||||
allowed-tools: Bash, Read, Write, Glob
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /chrome - Chrome Browser Integration
|
||||
|
||||
Integra Claude Code com o Chrome para automacao browser, testes, debug, performance e extraccao de dados. Suporta dois backends: **Claude in Chrome** (extensao) e **Chrome DevTools MCP** (npm).
|
||||
|
||||
## Backends Disponiveis
|
||||
|
||||
### Backend A: Claude in Chrome (Extensao)
|
||||
|
||||
Extensao oficial Anthropic. Requer instalacao manual no browser.
|
||||
|
||||
| Requisito | Minimo | Verificar |
|
||||
|-----------|--------|-----------|
|
||||
| Google Chrome | Instalado | `google-chrome --version` |
|
||||
| Extensao Claude in Chrome | v1.0.36+ | `chrome://extensions` |
|
||||
| Claude Code | v2.0.73+ | `claude --version` |
|
||||
| Plano Claude | Pro/Max/Team/Enterprise | - |
|
||||
| Native Host | Configurado | `~/.config/google-chrome/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json` |
|
||||
|
||||
**Limitacoes:** Apenas Google Chrome (nao Brave/Arc). Nao suportado em WSL.
|
||||
|
||||
**Activacao:**
|
||||
```bash
|
||||
# Por sessao
|
||||
claude --chrome
|
||||
|
||||
# Por defeito (alias .bashrc)
|
||||
alias cc="claude --permission-mode bypassPermissions --chrome"
|
||||
|
||||
# Dentro de sessao activa
|
||||
/chrome -> "Enabled by default"
|
||||
|
||||
# Ver ferramentas
|
||||
/mcp -> seleccionar claude-in-chrome
|
||||
```
|
||||
|
||||
### Backend B: Chrome DevTools MCP (npm)
|
||||
|
||||
Pacote oficial Google (`chrome-devtools-mcp`). Controla Chrome via DevTools Protocol. Nao requer extensao.
|
||||
|
||||
| Requisito | Minimo | Verificar |
|
||||
|-----------|--------|-----------|
|
||||
| Google Chrome | Instalado | `google-chrome --version` |
|
||||
| Node.js | v18+ | `node --version` |
|
||||
| chrome-devtools-mcp | latest | `claude mcp list` |
|
||||
|
||||
**Instalacao:**
|
||||
```bash
|
||||
claude mcp add chrome-devtools --scope user -- npx -y chrome-devtools-mcp@latest
|
||||
```
|
||||
|
||||
**Activacao:**
|
||||
```bash
|
||||
# Lancar Chrome com remote debugging
|
||||
google-chrome --remote-debugging-port=9222
|
||||
|
||||
# Reiniciar sessao Claude Code para carregar ferramentas
|
||||
```
|
||||
|
||||
**Ferramentas disponibilizadas:**
|
||||
- `page_navigate`, `page_go_back`, `page_go_forward` - Navegacao
|
||||
- `page_screenshot` - Captura de ecra
|
||||
- `page_click`, `page_type`, `page_select_option` - Interaccao
|
||||
- `page_execute_javascript` - Executar JS no contexto da pagina
|
||||
- `page_wait_for_selector` - Esperar por elementos
|
||||
- `console_get_logs` - Ler consola (logs, errors, warnings)
|
||||
- `network_get_requests`, `network_get_response_body` - Inspeccionar rede
|
||||
- `dom_get_element`, `dom_query_selector` - Inspeccionar DOM
|
||||
- `css_get_computed_styles`, `css_get_matched_styles` - Inspeccionar CSS
|
||||
- `performance_start_trace`, `performance_stop_trace` - Gravar traces
|
||||
- `performance_analyze_insight` - Metricas automaticas (LCP, TBT, CLS)
|
||||
- `accessibility_get_tree` - Arvore de acessibilidade
|
||||
- `storage_get_cookies`, `storage_get_local_storage` - Inspecionar storage
|
||||
|
||||
## Capacidades
|
||||
|
||||
### 1. Navegacao e Interaccao
|
||||
- Abrir URLs em novas tabs
|
||||
- Clicar botoes, links, elementos
|
||||
- Preencher formularios (input, select, textarea)
|
||||
- Submeter forms
|
||||
- Scroll e hover
|
||||
|
||||
### 2. Debug e Diagnostico
|
||||
- Ler console logs, errors, warnings
|
||||
- Inspeccionar DOM state e CSS computado
|
||||
- Verificar network requests e response bodies
|
||||
- Ler JavaScript errors em tempo real
|
||||
- Inspeccionar cookies, localStorage, sessionStorage
|
||||
|
||||
### 3. Performance (DevTools MCP)
|
||||
- Gravar performance traces completos
|
||||
- Metricas automaticas: LCP, TBT, CLS, FCP, TTFB
|
||||
- Identificar JavaScript nao utilizado
|
||||
- Analise de recursos (tamanho, tempo de carga)
|
||||
- Equivalente a Lighthouse audit on-demand
|
||||
|
||||
### 4. Acessibilidade (DevTools MCP)
|
||||
- Arvore de acessibilidade completa
|
||||
- Verificar roles ARIA, labels, estados
|
||||
- Identificar elementos sem texto alternativo
|
||||
|
||||
### 5. Extraccao de Dados
|
||||
- Extrair texto estruturado de paginas
|
||||
- Scraping de tabelas, listas, precos
|
||||
- Guardar dados como CSV/JSON local
|
||||
- Ler conteudo de paginas autenticadas (Chrome extensao)
|
||||
- Query DOM com selectores CSS/XPath
|
||||
|
||||
### 6. Testes Web
|
||||
- Testar forms com dados invalidos
|
||||
- Verificar UI contra mocks
|
||||
- Validar user flows completos
|
||||
- Testar responsividade
|
||||
- Monitorizar network requests durante testes
|
||||
|
||||
### 7. Sites Autenticados (Chrome extensao)
|
||||
- Google Docs, Gmail, Sheets
|
||||
- Notion, Slack web
|
||||
- CRMs, dashboards
|
||||
- Qualquer site com sessao activa no Chrome
|
||||
|
||||
### 8. Automacao
|
||||
- Data entry repetitivo
|
||||
- Multi-site workflows
|
||||
- Gravar demos como GIF (Chrome extensao)
|
||||
- Preencher CRMs a partir de CSV
|
||||
|
||||
## Workflows Comuns
|
||||
|
||||
### Testar aplicacao local
|
||||
```
|
||||
Abre localhost:3000, tenta submeter o formulario com dados invalidos
|
||||
e verifica se as mensagens de erro aparecem correctamente.
|
||||
```
|
||||
|
||||
### Debug com console
|
||||
```
|
||||
Abre a pagina do dashboard e verifica o console por erros
|
||||
quando a pagina carrega.
|
||||
```
|
||||
|
||||
### Preencher formularios em massa
|
||||
```
|
||||
Tenho um ficheiro contacts.csv. Para cada linha, vai ao CRM em
|
||||
crm.example.com, clica "Adicionar Contacto" e preenche nome, email e telefone.
|
||||
```
|
||||
|
||||
### Escrever em Google Docs
|
||||
```
|
||||
Escreve um resumo do projecto baseado nos commits recentes
|
||||
no Google D
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
name: db-design
|
||||
description: Design e optimização de schemas de base de dados — normalização, índices, planos de migração e particionamento.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Database Design Specialist
|
||||
|
||||
Skill para design e optimização de bases de dados seguindo padrões Descomplicar®.
|
||||
|
||||
## Quando Usar
|
||||
|
||||
- Desenhar schema para novo sistema
|
||||
- Optimizar queries lentas
|
||||
- Criar migrations (Laravel, Doctrine, Raw SQL)
|
||||
- Auditar e optimizar índices
|
||||
- Planear partitioning/sharding
|
||||
|
||||
## Protocolo Obrigatório
|
||||
|
||||
### 1. Pesquisa Inicial
|
||||
```
|
||||
mcp__mem_search_memories "database [projecto]"
|
||||
mcp__wikijs__search_pages "database schema [sistema]"
|
||||
```
|
||||
|
||||
### 2. Verificar Schema Existente
|
||||
Antes de propor alterações, SEMPRE verificar estrutura actual.
|
||||
|
||||
## Princípios de Design
|
||||
|
||||
### Normalização
|
||||
- **OLTP**: Mínimo 3NF (Third Normal Form)
|
||||
- **OLAP/Reporting**: Desnormalização justificada
|
||||
- **Híbrido**: Tabelas normalizadas + views materializadas
|
||||
|
||||
### Naming Conventions
|
||||
```sql
|
||||
-- Tabelas: snake_case, plural
|
||||
users, order_items, product_categories
|
||||
|
||||
-- Colunas: snake_case, singular
|
||||
created_at, user_id, is_active
|
||||
|
||||
-- Primary keys
|
||||
id (auto-increment ou UUID)
|
||||
|
||||
-- Foreign keys: {tabela_singular}_id
|
||||
user_id, order_id, category_id
|
||||
|
||||
-- Índices: idx_{tabela}_{coluna(s)}
|
||||
idx_orders_customer_id
|
||||
idx_orders_created_at_status
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
### Índices Estratégicos
|
||||
```sql
|
||||
-- WHERE frequente
|
||||
CREATE INDEX idx_users_email ON users(email);
|
||||
|
||||
-- JOIN
|
||||
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
|
||||
|
||||
-- ORDER BY
|
||||
CREATE INDEX idx_products_created_at ON products(created_at DESC);
|
||||
|
||||
-- Composto para queries específicas
|
||||
CREATE INDEX idx_orders_status_date ON orders(status, created_at);
|
||||
```
|
||||
|
||||
### Análise de Queries
|
||||
```sql
|
||||
-- SEMPRE usar EXPLAIN antes de optimizar
|
||||
EXPLAIN ANALYZE
|
||||
SELECT c.name, COUNT(o.id) as total
|
||||
FROM customers c
|
||||
LEFT JOIN orders o ON o.customer_id = c.id
|
||||
WHERE o.created_at >= '2025-01-01'
|
||||
GROUP BY c.id
|
||||
ORDER BY total DESC
|
||||
LIMIT 100;
|
||||
```
|
||||
|
||||
### Evitar Anti-patterns
|
||||
```sql
|
||||
-- ❌ EVITAR
|
||||
SELECT * FROM orders; -- Usar colunas específicas
|
||||
SELECT ... WHERE YEAR(created_at) = 2025; -- Função impede uso de índice
|
||||
|
||||
-- ✅ PREFERIR
|
||||
SELECT id, customer_id, total FROM orders;
|
||||
SELECT ... WHERE created_at >= '2025-01-01' AND created_at < '2026-01-01';
|
||||
```
|
||||
|
||||
## Template Migration Laravel
|
||||
|
||||
```php
|
||||
<?php
|
||||
/**
|
||||
* Migration: Create subscriptions table
|
||||
*
|
||||
* @author Descomplicar® Crescimento Digital
|
||||
* @link https://descomplicar.pt
|
||||
* @copyright 2025 Descomplicar®
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('subscriptions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('plan_id')->constrained();
|
||||
$table->enum('status', ['active', 'cancelled', 'expired', 'trial']);
|
||||
$table->timestamp('trial_ends_at')->nullable();
|
||||
$table->timestamp('current_period_start');
|
||||
$table->timestamp('current_period_end');
|
||||
$table->timestamp('cancelled_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
// Índices
|
||||
$table->index(['user_id', 'status']);
|
||||
$table->index('current_period_end');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('subscriptions');
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Segurança
|
||||
|
||||
- **Prepared statements**: SEMPRE para queries com input
|
||||
- **Least privilege**: Utilizadores DB com permissões mínimas
|
||||
- **Audit logging**: Para tabelas com dados sensíveis
|
||||
- **Encriptação**: Colunas com PII devem ser encriptadas
|
||||
|
||||
## Checklist Schema
|
||||
|
||||
### Design
|
||||
- [ ] Normalização adequada (sem redundância desnecessária)
|
||||
- [ ] Foreign keys definidas
|
||||
- [ ] Tipos de dados apropriados
|
||||
- [ ] Constraints (NOT NULL, UNIQUE, CHECK)
|
||||
- [ ] Soft deletes onde apropriado (deleted_at)
|
||||
|
||||
### Performance
|
||||
- [ ] Índices em colunas de WHERE
|
||||
- [ ] Índices em colunas de JOIN
|
||||
- [ ] Índices compostos onde necessário
|
||||
- [ ] Evitados índices redundantes
|
||||
- [ ] EXPLAIN em queries críticas
|
||||
|
||||
### Segurança
|
||||
- [ ] Dados sensíveis identificados
|
||||
- [ ] Audit trail se necessário
|
||||
- [ ] Prepared statements em todo código
|
||||
|
||||
## Entregáveis Standard
|
||||
|
||||
1. DDL completo (CREATE TABLE, INDEX)
|
||||
2. Diagrama ER se schema complexo
|
||||
3. Migrations se framework especificado
|
||||
4. Queries exemplo para operações comuns
|
||||
5. EXPLAIN de queries críticas
|
||||
|
||||
---
|
||||
|
||||
## Datasets Dify (Consulta Obrigatória)
|
||||
|
||||
Em caso de dúvidas ou para aprofundar conhecimento, consultar os seguintes datasets via MCP:
|
||||
|
||||
| Dataset | ID | Prioridade |
|
||||
|---------|----|-----------:|
|
||||
| **TI (Tecnologia da Informação)** | `7f63ec0c-6321-488c-b107-980140199850` | 1 |
|
||||
| **Desenvolvimento de Software** | `e7c7decc-0ded-4351-ab14-b110b3c38ec9` | 1 |
|
||||
| **AWS (Amazon Web Services)** | `cc7f000a-ad86-49b6-b59b-179e65f8a229` | 2 |
|
||||
|
||||
### Como Consultar
|
||||
|
||||
```javascript
|
||||
// Pesquisar optimiza
|
||||
@@ -0,0 +1,214 @@
|
||||
---
|
||||
name: dep-audit
|
||||
description: Auditoria de dependencias para projectos Node.js e PHP — vulnerabilidades, pacotes desactualizados, seguranca de ambiente e verificacao de tipos. Obrigatoria antes de commits.
|
||||
disable-model-invocation: true
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /dep-audit - Dependency Security Audit Pre-Commit
|
||||
|
||||
> **Renomeado de /security-check (12-03-2026).** `/security-check` e agora a skill de auditoria de infraestrutura (plugin infraestrutura).
|
||||
|
||||
Auditoria de segurança completa para projectos Node.js e PHP. **Obrigatória antes de commits** (Regra CLAUDE.md #47).
|
||||
|
||||
## Contexto NotebookLM
|
||||
|
||||
ANTES de executar, consultar notebooks para contexto especializado:
|
||||
|
||||
| Notebook | ID | Consultar quando |
|
||||
|----------|-----|-----------------|
|
||||
| Programação | 24947ffa-0019-448a-a340-2f4a275d2eb1 | Para contexto de vulnerabilidades |
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query({
|
||||
notebook_id: "24947ffa-0019-448a-a340-2f4a275d2eb1",
|
||||
query: "<adaptar ao contexto do pedido do utilizador>"
|
||||
})
|
||||
```
|
||||
|
||||
Integrar insights do NotebookLM nas recomendações e decisões.
|
||||
|
||||
### Procedimentos relacionados
|
||||
|
||||
- [PROC-DEV-SEC-001-Security-Audit.md](file:///media/ealmeida/Dados/Hub/06-Operacoes/Procedimentos/D7-Tecnologia/Seguranca/PROC-DEV-SEC-001-Security-Audit.md)
|
||||
- [PROC-Security-Audit-API-Keys.md](file:///media/ealmeida/Dados/Hub/06-Operacoes/Procedimentos/D7-Tecnologia/Seguranca/PROC-Security-Audit-API-Keys.md)
|
||||
|
||||
---
|
||||
|
||||
## Quando Usar
|
||||
|
||||
### OBRIGATÓRIO:
|
||||
- Antes de `git commit`
|
||||
- Antes de `git push`
|
||||
- Antes de criar Pull Request
|
||||
- Antes de deploy para produção
|
||||
|
||||
### RECOMENDADO:
|
||||
- Após `pnpm add <package>` (especialmente AI SDKs)
|
||||
- Semanalmente em projectos activos
|
||||
- Após actualizar dependências major
|
||||
|
||||
---
|
||||
|
||||
## Workflow Completo
|
||||
|
||||
### 1. Detectar Tipo de Projecto
|
||||
|
||||
```bash
|
||||
# Verificar package managers
|
||||
if [ -f "package.json" ]; then
|
||||
# Node.js detected
|
||||
MANAGER="pnpm" # ou npm/yarn
|
||||
elif [ -f "composer.json" ]; then
|
||||
# PHP detected
|
||||
MANAGER="composer"
|
||||
fi
|
||||
```
|
||||
|
||||
### 2. Dependency Security Audit
|
||||
|
||||
**Node.js:**
|
||||
```bash
|
||||
pnpm audit --json > ~/.claude-work/security-audit.json
|
||||
```
|
||||
|
||||
**PHP:**
|
||||
```bash
|
||||
composer audit --format=json > ~/.claude-work/security-audit.json
|
||||
```
|
||||
|
||||
**Parse resultados:**
|
||||
- Contar: critical, high, moderate, low
|
||||
- Identificar se são directas ou transitivas
|
||||
- Listar pacotes afectados
|
||||
|
||||
### 3. Outdated Dependencies
|
||||
|
||||
**Node.js:**
|
||||
```bash
|
||||
pnpm outdated --json > ~/.claude-work/security-outdated.json
|
||||
```
|
||||
|
||||
**Priorizar:**
|
||||
- AI SDKs: langchain, together-ai, @tavily/core, @langchain/core
|
||||
- Security packages: @auth/*, axios, form-data
|
||||
- Framework core: next, react, prisma
|
||||
|
||||
### 4. Environment Safety Check
|
||||
|
||||
**Verificar ficheiros:**
|
||||
```bash
|
||||
# Lista de ficheiros a verificar
|
||||
FILES=(.env .env.local .env.production .env.development)
|
||||
|
||||
for file in "${FILES[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
# Verificar se tem placeholders ou keys reais
|
||||
grep -E "(API_KEY|SECRET|TOKEN|PASSWORD)" "$file"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
**Validação:**
|
||||
- ✅ `API_KEY=placeholder` (safe)
|
||||
- ❌ `API_KEY=sk-proj-abc123...` (UNSAFE - real key)
|
||||
|
||||
### 5. Type Safety (se TypeScript)
|
||||
|
||||
```bash
|
||||
# Verificar se é TypeScript
|
||||
if [ -f "tsconfig.json" ]; then
|
||||
pnpm type # ou tsc --noEmit
|
||||
fi
|
||||
```
|
||||
|
||||
### 6. Análise de Risco AI SDKs
|
||||
|
||||
**Padrões conhecidos:**
|
||||
|
||||
| Pacote | Risco | Acção |
|
||||
|--------|-------|-------|
|
||||
| `langchain` | Alto | Verificar @langchain/core |
|
||||
| `together-ai` | Alto | form-data transitiva |
|
||||
| `@tavily/core` | Alto | axios transitiva |
|
||||
| `@platejs/ai` | Médio | lodash transitiva |
|
||||
|
||||
**Workflow AI SDKs:**
|
||||
```bash
|
||||
# 1. Verificar se @langchain/core está desactualizado
|
||||
pnpm list @langchain/core
|
||||
|
||||
# 2. Se versão < 0.3.80 (vulnerável)
|
||||
pnpm add @langchain/core@latest
|
||||
|
||||
# 3. Re-audit
|
||||
pnpm audit
|
||||
```
|
||||
|
||||
### 7. Gerar Relatório
|
||||
|
||||
**Formato output:**
|
||||
|
||||
```markdown
|
||||
## Security Audit Report
|
||||
|
||||
**Status:** [✅ SAFE | ⚠️ ISSUES FOUND | ❌ CRITICAL]
|
||||
**Data:** YYYY-MM-DD HH:MM
|
||||
|
||||
| Category | Status |
|
||||
|----------|--------|
|
||||
| Vulnerabilities | [N critical, M high, P moderate, Q low] |
|
||||
| Outdated Packages | N total (M major updates) |
|
||||
| Environment Safety | ✅ Placeholders only / ❌ Real keys found |
|
||||
| Type Safety | ✅ 0 errors / ❌ N errors |
|
||||
|
||||
### Vulnerabilities Detail
|
||||
|
||||
#### Critical (N)
|
||||
- package@version (via path) - description
|
||||
- **Patched:** >=safe-version
|
||||
- **Action:** [Override | Update | Replace]
|
||||
|
||||
#### High (M)
|
||||
[...]
|
||||
|
||||
### Outdated Packages (Priority)
|
||||
|
||||
**AI SDKs:**
|
||||
- langchain: current → latest
|
||||
- @langchain/core: current → latest (SECURITY UPDATE)
|
||||
|
||||
**Framework:**
|
||||
- next: current → latest
|
||||
|
||||
### Action Required
|
||||
|
||||
**Priority 1 (Critical):**
|
||||
1. [Acção específica]
|
||||
|
||||
**Priority 2 (High):**
|
||||
1. [Acção específica]
|
||||
|
||||
**Priority 3 (Maintenance):**
|
||||
1. [Acção específica]
|
||||
|
||||
### Safe to Commit?
|
||||
|
||||
[✅ YES | ⚠️ YES (with documentation) | ❌ NO (fix critical first)]
|
||||
|
||||
**If YES with documentation:**
|
||||
```
|
||||
git commit -m "feat: feature X
|
||||
|
||||
Known vulnerabilities (will be resolved):
|
||||
- package@version (severity) - waiting for upstream update
|
||||
|
||||
Mitigation: [explanation]
|
||||
"
|
||||
```
|
||||
|
||||
**If NO:**
|
||||
Fix critical/high vulnerabilities first. See PROC-DEV-SEC-001 for guidance.
|
||||
```
|
||||
|
||||
### 8. Criar F
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"task_id": null,
|
||||
"project_id": null,
|
||||
"customer_id": null,
|
||||
"gitea_repo": null
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
name: diagrama
|
||||
category: dev-tools
|
||||
description: "Gera diagramas de arquitectura, fluxo, ER e sequência em três formatos: draw.io (.drawio), Excalidraw e Mermaid. Usar quando 'diagrama', 'arquitectura', 'draw.io', 'fluxo', 'ER', 'sequência', 'infra', 'componentes'."
|
||||
version: "1.0.0"
|
||||
created: 2026-04-04
|
||||
tools: [mcp__claude_ai_Excalidraw__export_to_excalidraw, mcp__mcp-mermaid__generate, Write, Bash]
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Skill: /diagrama
|
||||
|
||||
Gera diagramas técnicos em três formatos consoante o caso de uso. Suporta arquitectura de sistemas, fluxogramas, diagramas ER, sequência, infra-estrutura e redes.
|
||||
|
||||
---
|
||||
|
||||
## Quando usar cada formato
|
||||
|
||||
| Formato | Quando usar | Output |
|
||||
|---------|------------|--------|
|
||||
| **draw.io** | Diagramas formais para documentação, propostas, clientes | `.drawio` (editável) |
|
||||
| **Excalidraw** | Esboços rápidos, brainstorming visual, estilo whiteboard | `.excalidraw` / MCP |
|
||||
| **Mermaid** | Diagramas como código, versionáveis em Git, embeds Markdown | `.svg` / `.png` |
|
||||
|
||||
---
|
||||
|
||||
## Processo de execução
|
||||
|
||||
### 1. Identificar pedido
|
||||
|
||||
Quando o utilizador pede um diagrama, detectar:
|
||||
- **Tipo:** arquitectura | fluxo | ER | sequência | rede | organograma | classe
|
||||
- **Formato pretendido:** draw.io (default para doc. formal) | excalidraw | mermaid
|
||||
- **Contexto:** sistemas envolvidos, entidades, actores
|
||||
|
||||
Se não especificado, perguntar apenas: "draw.io (formal) ou Excalidraw (esboço)?"
|
||||
|
||||
### 2. Gerar conteúdo
|
||||
|
||||
---
|
||||
|
||||
## Geração draw.io (.drawio)
|
||||
|
||||
O formato draw.io é mxGraph XML. Gerar o XML e guardar como `.drawio`.
|
||||
|
||||
### Estrutura base
|
||||
|
||||
```xml
|
||||
<mxfile host="Claude Code" modified="YYYY-MM-DDTHH:MM:SS" agent="Claude" version="21.0">
|
||||
<diagram name="Diagrama" id="diagram-1">
|
||||
<mxGraphModel dx="1422" dy="762" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<!-- elementos aqui -->
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
```
|
||||
|
||||
### Templates de elementos mxGraph
|
||||
|
||||
**Rectângulo (componente/serviço):**
|
||||
```xml
|
||||
<mxCell id="2" value="Nome" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="160" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
```
|
||||
|
||||
**Seta/ligação:**
|
||||
```xml
|
||||
<mxCell id="10" edge="1" source="2" target="3" parent="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
```
|
||||
|
||||
**Cilindro (base de dados):**
|
||||
```xml
|
||||
<mxCell id="5" value="PostgreSQL" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="160" width="80" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
```
|
||||
|
||||
**Cloud (serviço externo):**
|
||||
```xml
|
||||
<mxCell id="6" value="Cloudflare" style="shape=mxgraph.cisco.sites.generic_building;sketch=0;html=1;pointerEvents=1;dashed=0;fillColor=#036897;strokeColor=#ffffff;strokeWidth=2;verticalLabelPosition=bottom;verticalAlign=top;align=center;outlineConnect=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="480" y="160" width="60" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
```
|
||||
|
||||
**Actor (pessoa/utilizador):**
|
||||
```xml
|
||||
<mxCell id="7" value="Utilizador" style="shape=mxgraph.flowchart.start_2;fillColor=#00BEF2;strokeColor=#006EAF;fontColor=#ffffff;fontStyle=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="170" width="60" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
```
|
||||
|
||||
**Swimlane (grupo/camada):**
|
||||
```xml
|
||||
<mxCell id="8" value="Camada Frontend" style="swimlane;startSize=20;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
|
||||
<mxGeometry x="0" y="0" width="400" height="200" as="geometry"/>
|
||||
</mxCell>
|
||||
```
|
||||
|
||||
### Paleta de cores Descomplicar
|
||||
|
||||
| Componente | fillColor | strokeColor |
|
||||
|-----------|-----------|-------------|
|
||||
| Serviço/App | `#dae8fc` | `#6c8ebf` |
|
||||
| Base de dados | `#f8cecc` | `#b85450` |
|
||||
| Fila/Queue | `#d5e8d4` | `#82b366` |
|
||||
| Externo/Cloud | `#fff2cc` | `#d6b656` |
|
||||
| Infra/Servidor | `#e1d5e7` | `#9673a6` |
|
||||
| Claude/IA | `#f0f4ff` | `#4a6cf7` |
|
||||
|
||||
### Guardar ficheiro
|
||||
|
||||
Guardar em `/media/ealmeida/Dados/Hub/tmp/diagramas/` com nome descritivo:
|
||||
```
|
||||
YYYY-MM-DD-nome-diagrama.drawio
|
||||
```
|
||||
|
||||
Abrir com:
|
||||
```bash
|
||||
drawio "/media/ealmeida/Dados/Hub/tmp/diagramas/NOME.drawio" &
|
||||
```
|
||||
(ou abrir manualmente com draw.io desktop / draw.io no browser)
|
||||
|
||||
---
|
||||
|
||||
## Geração Excalidraw
|
||||
|
||||
Usar o MCP `mcp__claude_ai_Excalidraw__export_to_excalidraw` para diagramas no estilo whiteboard.
|
||||
|
||||
### Fluxo
|
||||
|
||||
1. Chamar `mcp__claude_ai_Excalidraw__create_view` para iniciar sessão
|
||||
2. Chamar `mcp__claude_ai_Excalidraw__export_to_excalidraw` com o conteúdo estruturado
|
||||
3. Informar o utilizador do link/path gerado
|
||||
|
||||
### Casos de uso preferidos
|
||||
|
||||
- Brainstorming e exploração rápida
|
||||
- Diagramas de fluxo com estilo manual
|
||||
- Esboços para reuniões
|
||||
- Arquitecturas de alto nível para comunicação interna
|
||||
|
||||
---
|
||||
|
||||
## Geração Mermaid
|
||||
|
||||
Usar o MCP `mcp__mcp-mermaid__generate`
|
||||
@@ -0,0 +1,160 @@
|
||||
---
|
||||
name: docx
|
||||
description: "Criação, edição e análise de documentos Word (.docx). Versão light para heartbeats."
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# DOCX — Referência Rápida
|
||||
|
||||
## Referência rápida
|
||||
|
||||
| Tarefa | Abordagem |
|
||||
|--------|-----------|
|
||||
| Ler conteúdo | `pandoc` ou descompactar XML |
|
||||
| Criar novo | `docx-js` (npm install -g docx) |
|
||||
| Editar existente | Descompactar → editar XML → recompactar |
|
||||
| Converter .doc | `python scripts/office/soffice.py --headless --convert-to docx doc.doc` |
|
||||
|
||||
## Criar novos documentos (docx-js)
|
||||
|
||||
### Setup básico
|
||||
|
||||
```javascript
|
||||
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun,
|
||||
Header, Footer, AlignmentType, PageOrientation, LevelFormat, HeadingLevel,
|
||||
BorderStyle, WidthType, ShadingType, PageNumber, PageBreak } = require('docx');
|
||||
|
||||
const doc = new Document({ sections: [{ children: [/* conteúdo */] }] });
|
||||
Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer));
|
||||
```
|
||||
|
||||
### Tamanho de página (A4)
|
||||
|
||||
```javascript
|
||||
sections: [{
|
||||
properties: {
|
||||
page: {
|
||||
size: { width: 11906, height: 16838 }, // A4 em DXA
|
||||
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
||||
}
|
||||
},
|
||||
children: [/* conteúdo */]
|
||||
}]
|
||||
```
|
||||
|
||||
Largura de conteúdo A4 com margens 1": `11906 - 2880 = 9026 DXA`
|
||||
|
||||
**Paisagem:** Passar dimensões retrato + `orientation: PageOrientation.LANDSCAPE` (docx-js troca internamente).
|
||||
|
||||
### Listas
|
||||
|
||||
```javascript
|
||||
numbering: { config: [
|
||||
{ reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "\u2022",
|
||||
alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }
|
||||
] }
|
||||
// Usar: new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [...] })
|
||||
```
|
||||
|
||||
### Tabelas
|
||||
|
||||
```javascript
|
||||
// Largura tabela = soma columnWidths. Usar SEMPRE WidthType.DXA (nunca PERCENTAGE).
|
||||
new Table({
|
||||
width: { size: 9026, type: WidthType.DXA },
|
||||
columnWidths: [4513, 4513],
|
||||
rows: [new TableRow({ children: [
|
||||
new TableCell({
|
||||
borders: { top: b, bottom: b, left: b, right: b },
|
||||
width: { size: 4513, type: WidthType.DXA },
|
||||
shading: { fill: "D5E8F0", type: ShadingType.CLEAR }, // CLEAR, nunca SOLID
|
||||
margins: { top: 80, bottom: 80, left: 120, right: 120 },
|
||||
children: [new Paragraph({ children: [new TextRun("Célula")] })]
|
||||
})
|
||||
] })]
|
||||
})
|
||||
```
|
||||
|
||||
### Imagens
|
||||
|
||||
```javascript
|
||||
new ImageRun({
|
||||
type: "png", // Obrigatório
|
||||
data: fs.readFileSync("image.png"),
|
||||
transformation: { width: 200, height: 150 },
|
||||
altText: { title: "T", description: "D", name: "N" } // Três obrigatórios
|
||||
})
|
||||
```
|
||||
|
||||
### Cabeçalhos/rodapés
|
||||
|
||||
```javascript
|
||||
headers: { default: new Header({ children: [new Paragraph({ children: [new TextRun("Cabeçalho")] })] }) },
|
||||
footers: { default: new Footer({ children: [new Paragraph({
|
||||
children: [new TextRun("Página "), new TextRun({ children: [PageNumber.CURRENT] })]
|
||||
})] }) }
|
||||
```
|
||||
|
||||
### Regras críticas docx-js
|
||||
|
||||
- Nunca usar `\n` — usar Paragraphs separados
|
||||
- Nunca usar bullets unicode — usar `LevelFormat.BULLET`
|
||||
- PageBreak dentro de Paragraph: `new Paragraph({ children: [new PageBreak()] })`
|
||||
- ImageRun requer `type`
|
||||
- Tabelas: `columnWidths` E `width` na célula, ambos devem corresponder
|
||||
- Usar `ShadingType.CLEAR`, nunca SOLID
|
||||
- TOC requer `HeadingLevel` apenas, sem estilos custom
|
||||
- Override estilos: IDs exactos "Heading1", "Heading2" + `outlineLevel`
|
||||
|
||||
## Editar documentos existentes
|
||||
|
||||
### Passo 1: Descompactar
|
||||
|
||||
```bash
|
||||
python scripts/office/unpack.py document.docx unpacked/
|
||||
```
|
||||
|
||||
### Passo 2: Editar XML
|
||||
|
||||
Editar ficheiros em `unpacked/word/`. Usar ferramenta Edit directamente (não scripts Python).
|
||||
|
||||
**Tracked changes:**
|
||||
```xml
|
||||
<!-- Inserção -->
|
||||
<w:ins w:id="1" w:author="Claude" w:date="2025-01-01T00:00:00Z">
|
||||
<w:r><w:t>texto inserido</w:t></w:r>
|
||||
</w:ins>
|
||||
|
||||
<!-- Eliminação -->
|
||||
<w:del w:id="2" w:author="Claude" w:date="2025-01-01T00:00:00Z">
|
||||
<w:r><w:delText>texto eliminado</w:delText></w:r>
|
||||
</w:del>
|
||||
```
|
||||
|
||||
**Comentários:**
|
||||
```bash
|
||||
python scripts/comment.py unpacked/ 0 "Texto do comentário"
|
||||
python scripts/comment.py unpacked/ 1 "Resposta" --parent 0
|
||||
```
|
||||
|
||||
**Smart quotes:** `‘` `’` `“` `”`
|
||||
|
||||
### Passo 3: Recompactar
|
||||
|
||||
```bash
|
||||
python scripts/office/pack.py unpacked/ output.docx --original document.docx
|
||||
```
|
||||
|
||||
Validação: `python scripts/office/validate.py doc.docx`
|
||||
|
||||
## Convenções Descomplicar
|
||||
|
||||
- Data: DD-MM-YYYY
|
||||
- Monetário: 1.234,56 EUR
|
||||
- Fonte: Arial 12pt
|
||||
- Página: A4 (11906 x 16838 DXA)
|
||||
- Autor tracked changes: "Claude"
|
||||
- Idioma: PT-PT
|
||||
|
||||
---
|
||||
**Versão**: 1.0.0-light | **Base**: 1.0.0
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
name: docx
|
||||
description: "Criacao, edicao e analise de documentos Word (.docx). Usar quando o utilizador mencionar \"Word\", \".docx\", ou pedir documentos profissionais com formatacao (indices, cabecalhos, numeracao de paginas, letterheads). Inclui extracao de conteudo, insercao/substituicao de imagens, find-and-replace, tracked changes, comentarios, e conversao de conteudo para Word. Aplica-se a relatorios, memorandos, cartas, templates e propostas em formato .docx. NAO usar para PDFs, folhas de calculo, Google Docs, ou tarefas de codigo nao relacionadas."
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# Criacao, edicao e analise de documentos DOCX
|
||||
|
||||
## Visao geral
|
||||
|
||||
Um ficheiro .docx e um arquivo ZIP contendo ficheiros XML.
|
||||
|
||||
## Referencia rapida
|
||||
|
||||
| Tarefa | Abordagem |
|
||||
|--------|-----------|
|
||||
| Ler/analisar conteudo | `pandoc` ou descompactar para XML bruto |
|
||||
| Criar novo documento | Usar `docx-js` - ver seccao Criar Novos Documentos |
|
||||
| Editar documento existente | Descompactar -> editar XML -> recompactar - ver seccao Editar Documentos Existentes |
|
||||
|
||||
### Converter .doc para .docx
|
||||
|
||||
Ficheiros legacy `.doc` devem ser convertidos antes de editar:
|
||||
|
||||
```bash
|
||||
python scripts/office/soffice.py --headless --convert-to docx document.doc
|
||||
```
|
||||
|
||||
### Ler conteudo
|
||||
|
||||
```bash
|
||||
# Extracao de texto com tracked changes
|
||||
pandoc --track-changes=all document.docx -o output.md
|
||||
|
||||
# Acesso ao XML bruto
|
||||
python scripts/office/unpack.py document.docx unpacked/
|
||||
```
|
||||
|
||||
### Converter para imagens
|
||||
|
||||
```bash
|
||||
python scripts/office/soffice.py --headless --convert-to pdf document.docx
|
||||
pdftoppm -jpeg -r 150 document.pdf page
|
||||
```
|
||||
|
||||
### Aceitar tracked changes
|
||||
|
||||
Para produzir um documento limpo com todas as alteracoes aceites (requer LibreOffice):
|
||||
|
||||
```bash
|
||||
python scripts/accept_changes.py input.docx output.docx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Criar novos documentos
|
||||
|
||||
Gerar ficheiros .docx com JavaScript, depois validar. Instalacao: `npm install -g docx`
|
||||
|
||||
### Setup
|
||||
```javascript
|
||||
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun,
|
||||
Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink,
|
||||
TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType,
|
||||
VerticalAlign, PageNumber, PageBreak } = require('docx');
|
||||
|
||||
const doc = new Document({ sections: [{ children: [/* conteudo */] }] });
|
||||
Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer));
|
||||
```
|
||||
|
||||
### Validacao
|
||||
Apos criar o ficheiro, validar. Se a validacao falhar, descompactar, corrigir o XML e recompactar.
|
||||
```bash
|
||||
python scripts/office/validate.py doc.docx
|
||||
```
|
||||
|
||||
### Tamanho da pagina
|
||||
|
||||
```javascript
|
||||
// CRITICO: docx-js assume A4 por defeito
|
||||
// Definir sempre o tamanho da pagina explicitamente para resultados consistentes
|
||||
// Para documentos PT/EU, A4 e o padrao correcto
|
||||
sections: [{
|
||||
properties: {
|
||||
page: {
|
||||
size: {
|
||||
width: 11906, // A4: 210mm em DXA
|
||||
height: 16838 // A4: 297mm em DXA
|
||||
},
|
||||
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } // 1 polegada de margens
|
||||
}
|
||||
},
|
||||
children: [/* conteudo */]
|
||||
}]
|
||||
```
|
||||
|
||||
**Tamanhos de pagina comuns (unidades DXA, 1440 DXA = 1 polegada):**
|
||||
|
||||
| Papel | Largura | Altura | Largura conteudo (margens 1") |
|
||||
|-------|---------|--------|-------------------------------|
|
||||
| A4 (padrao PT/EU) | 11.906 | 16.838 | 9.026 |
|
||||
| US Letter | 12.240 | 15.840 | 9.360 |
|
||||
|
||||
**Orientacao paisagem:** docx-js troca largura/altura internamente, por isso passar dimensoes retrato e deixar a biblioteca tratar:
|
||||
```javascript
|
||||
size: {
|
||||
width: 11906, // Passar lado CURTO como width
|
||||
height: 16838, // Passar lado LONGO como height
|
||||
orientation: PageOrientation.LANDSCAPE // docx-js troca no XML
|
||||
},
|
||||
// Largura de conteudo = 16838 - margem esquerda - margem direita (usa o lado longo)
|
||||
```
|
||||
|
||||
### Estilos (Override Built-in Headings)
|
||||
|
||||
Usar Arial como fonte por defeito (suporte universal). Manter titulos a preto para legibilidade.
|
||||
|
||||
```javascript
|
||||
const doc = new Document({
|
||||
styles: {
|
||||
default: { document: { run: { font: "Arial", size: 24 } } }, // 12pt por defeito
|
||||
paragraphStyles: [
|
||||
// IMPORTANTE: Usar IDs exactos para override dos estilos built-in
|
||||
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
|
||||
run: { size: 32, bold: true, font: "Arial" },
|
||||
paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // outlineLevel necessario para TOC
|
||||
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
|
||||
run: { size: 28, bold: true, font: "Arial" },
|
||||
paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } },
|
||||
]
|
||||
},
|
||||
sections: [{
|
||||
children: [
|
||||
new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun("Titulo")] }),
|
||||
]
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
### Listas (NUNCA usar bullets unicode)
|
||||
|
||||
```javascript
|
||||
// ERRADO - nunca inserir caracteres de bullet manualmente
|
||||
new Paragraph({ children: [new TextRun("* Item")] }) // MAU
|
||||
new Paragraph({ children: [new TextRun("\u2022 Item")]
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
"""Accept all tracked changes in a DOCX file using LibreOffice.
|
||||
|
||||
Requires LibreOffice (soffice) to be installed.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from office.soffice import get_soffice_env
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
LIBREOFFICE_PROFILE = "/tmp/libreoffice_docx_profile"
|
||||
MACRO_DIR = f"{LIBREOFFICE_PROFILE}/user/basic/Standard"
|
||||
|
||||
ACCEPT_CHANGES_MACRO = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
|
||||
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">
|
||||
Sub AcceptAllTrackedChanges()
|
||||
Dim document As Object
|
||||
Dim dispatcher As Object
|
||||
|
||||
document = ThisComponent.CurrentController.Frame
|
||||
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
|
||||
|
||||
dispatcher.executeDispatch(document, ".uno:AcceptAllTrackedChanges", "", 0, Array())
|
||||
ThisComponent.store()
|
||||
ThisComponent.close(True)
|
||||
End Sub
|
||||
</script:module>"""
|
||||
|
||||
|
||||
def accept_changes(
|
||||
input_file: str,
|
||||
output_file: str,
|
||||
) -> tuple[None, str]:
|
||||
input_path = Path(input_file)
|
||||
output_path = Path(output_file)
|
||||
|
||||
if not input_path.exists():
|
||||
return None, f"Error: Input file not found: {input_file}"
|
||||
|
||||
if not input_path.suffix.lower() == ".docx":
|
||||
return None, f"Error: Input file is not a DOCX file: {input_file}"
|
||||
|
||||
try:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(input_path, output_path)
|
||||
except Exception as e:
|
||||
return None, f"Error: Failed to copy input file to output location: {e}"
|
||||
|
||||
if not _setup_libreoffice_macro():
|
||||
return None, "Error: Failed to setup LibreOffice macro"
|
||||
|
||||
cmd = [
|
||||
"soffice",
|
||||
"--headless",
|
||||
f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}",
|
||||
"--norestore",
|
||||
"vnd.sun.star.script:Standard.Module1.AcceptAllTrackedChanges?language=Basic&location=application",
|
||||
str(output_path.absolute()),
|
||||
]
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
check=False,
|
||||
env=get_soffice_env(),
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
return (
|
||||
None,
|
||||
f"Successfully accepted all tracked changes: {input_file} -> {output_file}",
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
return None, f"Error: LibreOffice failed: {result.stderr}"
|
||||
|
||||
return (
|
||||
None,
|
||||
f"Successfully accepted all tracked changes: {input_file} -> {output_file}",
|
||||
)
|
||||
|
||||
|
||||
def _setup_libreoffice_macro() -> bool:
|
||||
macro_dir = Path(MACRO_DIR)
|
||||
macro_file = macro_dir / "Module1.xba"
|
||||
|
||||
if macro_file.exists() and "AcceptAllTrackedChanges" in macro_file.read_text():
|
||||
return True
|
||||
|
||||
if not macro_dir.exists():
|
||||
subprocess.run(
|
||||
[
|
||||
"soffice",
|
||||
"--headless",
|
||||
f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}",
|
||||
"--terminate_after_init",
|
||||
],
|
||||
capture_output=True,
|
||||
timeout=10,
|
||||
check=False,
|
||||
env=get_soffice_env(),
|
||||
)
|
||||
macro_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
macro_file.write_text(ACCEPT_CHANGES_MACRO)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to setup LibreOffice macro: {e}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Accept all tracked changes in a DOCX file"
|
||||
)
|
||||
parser.add_argument("input_file", help="Input DOCX file with tracked changes")
|
||||
parser.add_argument(
|
||||
"output_file", help="Output DOCX file (clean, no tracked changes)"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
_, message = accept_changes(args.input_file, args.output_file)
|
||||
print(message)
|
||||
|
||||
if "Error" in message:
|
||||
raise SystemExit(1)
|
||||
@@ -0,0 +1,318 @@
|
||||
"""Add comments to DOCX documents.
|
||||
|
||||
Usage:
|
||||
python comment.py unpacked/ 0 "Comment text"
|
||||
python comment.py unpacked/ 1 "Reply text" --parent 0
|
||||
|
||||
Text should be pre-escaped XML (e.g., & for &, ’ for smart quotes).
|
||||
|
||||
After running, add markers to document.xml:
|
||||
<w:commentRangeStart w:id="0"/>
|
||||
... commented content ...
|
||||
<w:commentRangeEnd w:id="0"/>
|
||||
<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="0"/></w:r>
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import random
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import defusedxml.minidom
|
||||
|
||||
TEMPLATE_DIR = Path(__file__).parent / "templates"
|
||||
NS = {
|
||||
"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
||||
"w14": "http://schemas.microsoft.com/office/word/2010/wordml",
|
||||
"w15": "http://schemas.microsoft.com/office/word/2012/wordml",
|
||||
"w16cid": "http://schemas.microsoft.com/office/word/2016/wordml/cid",
|
||||
"w16cex": "http://schemas.microsoft.com/office/word/2018/wordml/cex",
|
||||
}
|
||||
|
||||
COMMENT_XML = """\
|
||||
<w:comment w:id="{id}" w:author="{author}" w:date="{date}" w:initials="{initials}">
|
||||
<w:p w14:paraId="{para_id}" w14:textId="77777777">
|
||||
<w:r>
|
||||
<w:rPr><w:rStyle w:val="CommentReference"/></w:rPr>
|
||||
<w:annotationRef/>
|
||||
</w:r>
|
||||
<w:r>
|
||||
<w:rPr>
|
||||
<w:color w:val="000000"/>
|
||||
<w:sz w:val="20"/>
|
||||
<w:szCs w:val="20"/>
|
||||
</w:rPr>
|
||||
<w:t>{text}</w:t>
|
||||
</w:r>
|
||||
</w:p>
|
||||
</w:comment>"""
|
||||
|
||||
COMMENT_MARKER_TEMPLATE = """
|
||||
Add to document.xml (markers must be direct children of w:p, never inside w:r):
|
||||
<w:commentRangeStart w:id="{cid}"/>
|
||||
<w:r>...</w:r>
|
||||
<w:commentRangeEnd w:id="{cid}"/>
|
||||
<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{cid}"/></w:r>"""
|
||||
|
||||
REPLY_MARKER_TEMPLATE = """
|
||||
Nest markers inside parent {pid}'s markers (markers must be direct children of w:p, never inside w:r):
|
||||
<w:commentRangeStart w:id="{pid}"/><w:commentRangeStart w:id="{cid}"/>
|
||||
<w:r>...</w:r>
|
||||
<w:commentRangeEnd w:id="{cid}"/><w:commentRangeEnd w:id="{pid}"/>
|
||||
<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{pid}"/></w:r>
|
||||
<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{cid}"/></w:r>"""
|
||||
|
||||
|
||||
def _generate_hex_id() -> str:
|
||||
return f"{random.randint(0, 0x7FFFFFFE):08X}"
|
||||
|
||||
|
||||
SMART_QUOTE_ENTITIES = {
|
||||
"\u201c": "“",
|
||||
"\u201d": "”",
|
||||
"\u2018": "‘",
|
||||
"\u2019": "’",
|
||||
}
|
||||
|
||||
|
||||
def _encode_smart_quotes(text: str) -> str:
|
||||
for char, entity in SMART_QUOTE_ENTITIES.items():
|
||||
text = text.replace(char, entity)
|
||||
return text
|
||||
|
||||
|
||||
def _append_xml(xml_path: Path, root_tag: str, content: str) -> None:
|
||||
dom = defusedxml.minidom.parseString(xml_path.read_text(encoding="utf-8"))
|
||||
root = dom.getElementsByTagName(root_tag)[0]
|
||||
ns_attrs = " ".join(f'xmlns:{k}="{v}"' for k, v in NS.items())
|
||||
wrapper_dom = defusedxml.minidom.parseString(f"<root {ns_attrs}>{content}</root>")
|
||||
for child in wrapper_dom.documentElement.childNodes:
|
||||
if child.nodeType == child.ELEMENT_NODE:
|
||||
root.appendChild(dom.importNode(child, True))
|
||||
output = _encode_smart_quotes(dom.toxml(encoding="UTF-8").decode("utf-8"))
|
||||
xml_path.write_text(output, encoding="utf-8")
|
||||
|
||||
|
||||
def _find_para_id(comments_path: Path, comment_id: int) -> str | None:
|
||||
dom = defusedxml.minidom.parseString(comments_path.read_text(encoding="utf-8"))
|
||||
for c in dom.getElementsByTagName("w:comment"):
|
||||
if c.getAttribute("w:id") == str(comment_id):
|
||||
for p in c.getElementsByTagName("w:p"):
|
||||
if pid := p.getAttribute("w14:paraId"):
|
||||
return pid
|
||||
return None
|
||||
|
||||
|
||||
def _get_next_rid(rels_path: Path) -> int:
|
||||
dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
|
||||
max_rid = 0
|
||||
for rel in dom.getElementsByTagName("Relationship"):
|
||||
rid = rel.getAttribute("Id")
|
||||
if rid and rid.startswith("rId"):
|
||||
try:
|
||||
max_rid = max(max_rid, int(rid[3:]))
|
||||
except ValueError:
|
||||
pass
|
||||
return max_rid + 1
|
||||
|
||||
|
||||
def _has_relationship(rels_path: Path, target: str) -> bool:
|
||||
dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
|
||||
for rel in dom.getElementsByTagName("Relationship"):
|
||||
if rel.getAttribute("Target") == target:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _has_content_type(ct_path: Path, part_name: str) -> bool:
|
||||
dom = defusedxml.minidom.parseString(ct_path.read_text(encoding="utf-8"))
|
||||
for override in dom.getElementsByTagName("Override"):
|
||||
if override.getAttribute("PartName") == part_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _ensure_comment_relationships(unpacked_dir: Path) -> None:
|
||||
rels_path = unpacked_dir / "word" / "_rels" / "document.xml.rels"
|
||||
if not rels_path.exists():
|
||||
return
|
||||
|
||||
if _has_relationship(rels_path, "comments.xml"):
|
||||
return
|
||||
|
||||
dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
|
||||
root = dom.documentElement
|
||||
next_rid = _get_next_rid(rels_path)
|
||||
|
||||
rels = [
|
||||
(
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
|
||||
"comments.xml",
|
||||
),
|
||||
(
|
||||
"http://schemas.microsoft.com/office/2011/relationships/commentsExtended",
|
||||
"commentsExtended.xml",
|
||||
),
|
||||
(
|
||||
"http://schemas.microsoft.com/office/2016/09/relationships/commentsIds",
|
||||
"commentsIds.xml",
|
||||
),
|
||||
(
|
||||
"http://schemas.microsoft.com/office/2018/08/relationships/commentsExtensible",
|
||||
"commentsExtensible.xml",
|
||||
),
|
||||
]
|
||||
|
||||
for rel_type, target in rels:
|
||||
rel = dom.createElement("Relationship")
|
||||
rel.setAttribute("Id", f"rId{next_rid}")
|
||||
rel.setAttribute("Type", rel_type)
|
||||
rel.setAttribute("Target", target)
|
||||
root.appendChild(rel)
|
||||
next_rid += 1
|
||||
|
||||
rels_path.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
|
||||
|
||||
def _ensure_comment_content_types(unpacked_dir: Path) -> None:
|
||||
ct_path = unpacked_dir / "[Content_Types].xml"
|
||||
if not ct_path.exists():
|
||||
return
|
||||
|
||||
if _has_content_type(ct_path, "/word/comments.xml"):
|
||||
return
|
||||
|
||||
dom = defusedxml.minidom.parseString(ct_path.read_text(encoding="utf-8"))
|
||||
root = dom.documentElement
|
||||
|
||||
overrides = [
|
||||
(
|
||||
"/word/comments.xml",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml",
|
||||
),
|
||||
(
|
||||
"/word/commentsExtended.xml",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml",
|
||||
),
|
||||
(
|
||||
"/word/commentsIds.xml",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml",
|
||||
),
|
||||
(
|
||||
"/word/commentsExtensible.xml",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml",
|
||||
),
|
||||
]
|
||||
|
||||
for part_name, content_type in overrides:
|
||||
override = dom.createElement("Override")
|
||||
override.setAttribute("PartName", part_name)
|
||||
override.setAttribute("ContentType", content_type)
|
||||
root.appendChild(override)
|
||||
|
||||
ct_path.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
|
||||
|
||||
def add_comment(
|
||||
unpacked_dir: str,
|
||||
comment_id: int,
|
||||
text: str,
|
||||
author: str = "Claude",
|
||||
initials: str = "C",
|
||||
parent_id: int | None = None,
|
||||
) -> tuple[str, str]:
|
||||
word = Path(unpacked_dir) / "word"
|
||||
if not word.exists():
|
||||
return "", f"Error: {word} not found"
|
||||
|
||||
para_id, durable_id = _generate_hex_id(), _generate_hex_id()
|
||||
ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
comments = word / "comments.xml"
|
||||
first_comment = not comments.exists()
|
||||
if first_comment:
|
||||
shutil.copy(TEMPLATE_DIR / "comments.xml", comments)
|
||||
_ensure_comment_relationships(Path(unpacked_dir))
|
||||
_ensure_comment_content_types(Path(unpacked_dir))
|
||||
_append_xml(
|
||||
comments,
|
||||
"w:comments",
|
||||
COMMENT_XML.format(
|
||||
id=comment_id,
|
||||
author=author,
|
||||
date=ts,
|
||||
initials=initials,
|
||||
para_id=para_id,
|
||||
text=text,
|
||||
),
|
||||
)
|
||||
|
||||
ext = word / "commentsExtended.xml"
|
||||
if not ext.exists():
|
||||
shutil.copy(TEMPLATE_DIR / "commentsExtended.xml", ext)
|
||||
if parent_id is not None:
|
||||
parent_para = _find_para_id(comments, parent_id)
|
||||
if not parent_para:
|
||||
return "", f"Error: Parent comment {parent_id} not found"
|
||||
_append_xml(
|
||||
ext,
|
||||
"w15:commentsEx",
|
||||
f'<w15:commentEx w15:paraId="{para_id}" w15:paraIdParent="{parent_para}" w15:done="0"/>',
|
||||
)
|
||||
else:
|
||||
_append_xml(
|
||||
ext,
|
||||
"w15:commentsEx",
|
||||
f'<w15:commentEx w15:paraId="{para_id}" w15:done="0"/>',
|
||||
)
|
||||
|
||||
ids = word / "commentsIds.xml"
|
||||
if not ids.exists():
|
||||
shutil.copy(TEMPLATE_DIR / "commentsIds.xml", ids)
|
||||
_append_xml(
|
||||
ids,
|
||||
"w16cid:commentsIds",
|
||||
f'<w16cid:commentId w16cid:paraId="{para_id}" w16cid:durableId="{durable_id}"/>',
|
||||
)
|
||||
|
||||
extensible = word / "commentsExtensible.xml"
|
||||
if not extensible.exists():
|
||||
shutil.copy(TEMPLATE_DIR / "commentsExtensible.xml", extensible)
|
||||
_append_xml(
|
||||
extensible,
|
||||
"w16cex:commentsExtensible",
|
||||
f'<w16cex:commentExtensible w16cex:durableId="{durable_id}" w16cex:dateUtc="{ts}"/>',
|
||||
)
|
||||
|
||||
action = "reply" if parent_id is not None else "comment"
|
||||
return para_id, f"Added {action} {comment_id} (para_id={para_id})"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
p = argparse.ArgumentParser(description="Add comments to DOCX documents")
|
||||
p.add_argument("unpacked_dir", help="Unpacked DOCX directory")
|
||||
p.add_argument("comment_id", type=int, help="Comment ID (must be unique)")
|
||||
p.add_argument("text", help="Comment text")
|
||||
p.add_argument("--author", default="Claude", help="Author name")
|
||||
p.add_argument("--initials", default="C", help="Author initials")
|
||||
p.add_argument("--parent", type=int, help="Parent comment ID (for replies)")
|
||||
args = p.parse_args()
|
||||
|
||||
para_id, msg = add_comment(
|
||||
args.unpacked_dir,
|
||||
args.comment_id,
|
||||
args.text,
|
||||
args.author,
|
||||
args.initials,
|
||||
args.parent,
|
||||
)
|
||||
print(msg)
|
||||
if "Error" in msg:
|
||||
sys.exit(1)
|
||||
cid = args.comment_id
|
||||
if args.parent is not None:
|
||||
print(REPLY_MARKER_TEMPLATE.format(pid=args.parent, cid=cid))
|
||||
else:
|
||||
print(COMMENT_MARKER_TEMPLATE.format(cid=cid))
|
||||
@@ -0,0 +1,199 @@
|
||||
"""Merge adjacent runs with identical formatting in DOCX.
|
||||
|
||||
Merges adjacent <w:r> elements that have identical <w:rPr> properties.
|
||||
Works on runs in paragraphs and inside tracked changes (<w:ins>, <w:del>).
|
||||
|
||||
Also:
|
||||
- Removes rsid attributes from runs (revision metadata that doesn't affect rendering)
|
||||
- Removes proofErr elements (spell/grammar markers that block merging)
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import defusedxml.minidom
|
||||
|
||||
|
||||
def merge_runs(input_dir: str) -> tuple[int, str]:
|
||||
doc_xml = Path(input_dir) / "word" / "document.xml"
|
||||
|
||||
if not doc_xml.exists():
|
||||
return 0, f"Error: {doc_xml} not found"
|
||||
|
||||
try:
|
||||
dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding="utf-8"))
|
||||
root = dom.documentElement
|
||||
|
||||
_remove_elements(root, "proofErr")
|
||||
_strip_run_rsid_attrs(root)
|
||||
|
||||
containers = {run.parentNode for run in _find_elements(root, "r")}
|
||||
|
||||
merge_count = 0
|
||||
for container in containers:
|
||||
merge_count += _merge_runs_in(container)
|
||||
|
||||
doc_xml.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
return merge_count, f"Merged {merge_count} runs"
|
||||
|
||||
except Exception as e:
|
||||
return 0, f"Error: {e}"
|
||||
|
||||
|
||||
|
||||
|
||||
def _find_elements(root, tag: str) -> list:
|
||||
results = []
|
||||
|
||||
def traverse(node):
|
||||
if node.nodeType == node.ELEMENT_NODE:
|
||||
name = node.localName or node.tagName
|
||||
if name == tag or name.endswith(f":{tag}"):
|
||||
results.append(node)
|
||||
for child in node.childNodes:
|
||||
traverse(child)
|
||||
|
||||
traverse(root)
|
||||
return results
|
||||
|
||||
|
||||
def _get_child(parent, tag: str):
|
||||
for child in parent.childNodes:
|
||||
if child.nodeType == child.ELEMENT_NODE:
|
||||
name = child.localName or child.tagName
|
||||
if name == tag or name.endswith(f":{tag}"):
|
||||
return child
|
||||
return None
|
||||
|
||||
|
||||
def _get_children(parent, tag: str) -> list:
|
||||
results = []
|
||||
for child in parent.childNodes:
|
||||
if child.nodeType == child.ELEMENT_NODE:
|
||||
name = child.localName or child.tagName
|
||||
if name == tag or name.endswith(f":{tag}"):
|
||||
results.append(child)
|
||||
return results
|
||||
|
||||
|
||||
def _is_adjacent(elem1, elem2) -> bool:
|
||||
node = elem1.nextSibling
|
||||
while node:
|
||||
if node == elem2:
|
||||
return True
|
||||
if node.nodeType == node.ELEMENT_NODE:
|
||||
return False
|
||||
if node.nodeType == node.TEXT_NODE and node.data.strip():
|
||||
return False
|
||||
node = node.nextSibling
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def _remove_elements(root, tag: str):
|
||||
for elem in _find_elements(root, tag):
|
||||
if elem.parentNode:
|
||||
elem.parentNode.removeChild(elem)
|
||||
|
||||
|
||||
def _strip_run_rsid_attrs(root):
|
||||
for run in _find_elements(root, "r"):
|
||||
for attr in list(run.attributes.values()):
|
||||
if "rsid" in attr.name.lower():
|
||||
run.removeAttribute(attr.name)
|
||||
|
||||
|
||||
|
||||
|
||||
def _merge_runs_in(container) -> int:
|
||||
merge_count = 0
|
||||
run = _first_child_run(container)
|
||||
|
||||
while run:
|
||||
while True:
|
||||
next_elem = _next_element_sibling(run)
|
||||
if next_elem and _is_run(next_elem) and _can_merge(run, next_elem):
|
||||
_merge_run_content(run, next_elem)
|
||||
container.removeChild(next_elem)
|
||||
merge_count += 1
|
||||
else:
|
||||
break
|
||||
|
||||
_consolidate_text(run)
|
||||
run = _next_sibling_run(run)
|
||||
|
||||
return merge_count
|
||||
|
||||
|
||||
def _first_child_run(container):
|
||||
for child in container.childNodes:
|
||||
if child.nodeType == child.ELEMENT_NODE and _is_run(child):
|
||||
return child
|
||||
return None
|
||||
|
||||
|
||||
def _next_element_sibling(node):
|
||||
sibling = node.nextSibling
|
||||
while sibling:
|
||||
if sibling.nodeType == sibling.ELEMENT_NODE:
|
||||
return sibling
|
||||
sibling = sibling.nextSibling
|
||||
return None
|
||||
|
||||
|
||||
def _next_sibling_run(node):
|
||||
sibling = node.nextSibling
|
||||
while sibling:
|
||||
if sibling.nodeType == sibling.ELEMENT_NODE:
|
||||
if _is_run(sibling):
|
||||
return sibling
|
||||
sibling = sibling.nextSibling
|
||||
return None
|
||||
|
||||
|
||||
def _is_run(node) -> bool:
|
||||
name = node.localName or node.tagName
|
||||
return name == "r" or name.endswith(":r")
|
||||
|
||||
|
||||
def _can_merge(run1, run2) -> bool:
|
||||
rpr1 = _get_child(run1, "rPr")
|
||||
rpr2 = _get_child(run2, "rPr")
|
||||
|
||||
if (rpr1 is None) != (rpr2 is None):
|
||||
return False
|
||||
if rpr1 is None:
|
||||
return True
|
||||
return rpr1.toxml() == rpr2.toxml()
|
||||
|
||||
|
||||
def _merge_run_content(target, source):
|
||||
for child in list(source.childNodes):
|
||||
if child.nodeType == child.ELEMENT_NODE:
|
||||
name = child.localName or child.tagName
|
||||
if name != "rPr" and not name.endswith(":rPr"):
|
||||
target.appendChild(child)
|
||||
|
||||
|
||||
def _consolidate_text(run):
|
||||
t_elements = _get_children(run, "t")
|
||||
|
||||
for i in range(len(t_elements) - 1, 0, -1):
|
||||
curr, prev = t_elements[i], t_elements[i - 1]
|
||||
|
||||
if _is_adjacent(prev, curr):
|
||||
prev_text = prev.firstChild.data if prev.firstChild else ""
|
||||
curr_text = curr.firstChild.data if curr.firstChild else ""
|
||||
merged = prev_text + curr_text
|
||||
|
||||
if prev.firstChild:
|
||||
prev.firstChild.data = merged
|
||||
else:
|
||||
prev.appendChild(run.ownerDocument.createTextNode(merged))
|
||||
|
||||
if merged.startswith(" ") or merged.endswith(" "):
|
||||
prev.setAttribute("xml:space", "preserve")
|
||||
elif prev.hasAttribute("xml:space"):
|
||||
prev.removeAttribute("xml:space")
|
||||
|
||||
run.removeChild(curr)
|
||||
@@ -0,0 +1,197 @@
|
||||
"""Simplify tracked changes by merging adjacent w:ins or w:del elements.
|
||||
|
||||
Merges adjacent <w:ins> elements from the same author into a single element.
|
||||
Same for <w:del> elements. This makes heavily-redlined documents easier to
|
||||
work with by reducing the number of tracked change wrappers.
|
||||
|
||||
Rules:
|
||||
- Only merges w:ins with w:ins, w:del with w:del (same element type)
|
||||
- Only merges if same author (ignores timestamp differences)
|
||||
- Only merges if truly adjacent (only whitespace between them)
|
||||
"""
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import defusedxml.minidom
|
||||
|
||||
WORD_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
|
||||
|
||||
def simplify_redlines(input_dir: str) -> tuple[int, str]:
|
||||
doc_xml = Path(input_dir) / "word" / "document.xml"
|
||||
|
||||
if not doc_xml.exists():
|
||||
return 0, f"Error: {doc_xml} not found"
|
||||
|
||||
try:
|
||||
dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding="utf-8"))
|
||||
root = dom.documentElement
|
||||
|
||||
merge_count = 0
|
||||
|
||||
containers = _find_elements(root, "p") + _find_elements(root, "tc")
|
||||
|
||||
for container in containers:
|
||||
merge_count += _merge_tracked_changes_in(container, "ins")
|
||||
merge_count += _merge_tracked_changes_in(container, "del")
|
||||
|
||||
doc_xml.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
return merge_count, f"Simplified {merge_count} tracked changes"
|
||||
|
||||
except Exception as e:
|
||||
return 0, f"Error: {e}"
|
||||
|
||||
|
||||
def _merge_tracked_changes_in(container, tag: str) -> int:
|
||||
merge_count = 0
|
||||
|
||||
tracked = [
|
||||
child
|
||||
for child in container.childNodes
|
||||
if child.nodeType == child.ELEMENT_NODE and _is_element(child, tag)
|
||||
]
|
||||
|
||||
if len(tracked) < 2:
|
||||
return 0
|
||||
|
||||
i = 0
|
||||
while i < len(tracked) - 1:
|
||||
curr = tracked[i]
|
||||
next_elem = tracked[i + 1]
|
||||
|
||||
if _can_merge_tracked(curr, next_elem):
|
||||
_merge_tracked_content(curr, next_elem)
|
||||
container.removeChild(next_elem)
|
||||
tracked.pop(i + 1)
|
||||
merge_count += 1
|
||||
else:
|
||||
i += 1
|
||||
|
||||
return merge_count
|
||||
|
||||
|
||||
def _is_element(node, tag: str) -> bool:
|
||||
name = node.localName or node.tagName
|
||||
return name == tag or name.endswith(f":{tag}")
|
||||
|
||||
|
||||
def _get_author(elem) -> str:
|
||||
author = elem.getAttribute("w:author")
|
||||
if not author:
|
||||
for attr in elem.attributes.values():
|
||||
if attr.localName == "author" or attr.name.endswith(":author"):
|
||||
return attr.value
|
||||
return author
|
||||
|
||||
|
||||
def _can_merge_tracked(elem1, elem2) -> bool:
|
||||
if _get_author(elem1) != _get_author(elem2):
|
||||
return False
|
||||
|
||||
node = elem1.nextSibling
|
||||
while node and node != elem2:
|
||||
if node.nodeType == node.ELEMENT_NODE:
|
||||
return False
|
||||
if node.nodeType == node.TEXT_NODE and node.data.strip():
|
||||
return False
|
||||
node = node.nextSibling
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _merge_tracked_content(target, source):
|
||||
while source.firstChild:
|
||||
child = source.firstChild
|
||||
source.removeChild(child)
|
||||
target.appendChild(child)
|
||||
|
||||
|
||||
def _find_elements(root, tag: str) -> list:
|
||||
results = []
|
||||
|
||||
def traverse(node):
|
||||
if node.nodeType == node.ELEMENT_NODE:
|
||||
name = node.localName or node.tagName
|
||||
if name == tag or name.endswith(f":{tag}"):
|
||||
results.append(node)
|
||||
for child in node.childNodes:
|
||||
traverse(child)
|
||||
|
||||
traverse(root)
|
||||
return results
|
||||
|
||||
|
||||
def get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]:
|
||||
if not doc_xml_path.exists():
|
||||
return {}
|
||||
|
||||
try:
|
||||
tree = ET.parse(doc_xml_path)
|
||||
root = tree.getroot()
|
||||
except ET.ParseError:
|
||||
return {}
|
||||
|
||||
namespaces = {"w": WORD_NS}
|
||||
author_attr = f"{{{WORD_NS}}}author"
|
||||
|
||||
authors: dict[str, int] = {}
|
||||
for tag in ["ins", "del"]:
|
||||
for elem in root.findall(f".//w:{tag}", namespaces):
|
||||
author = elem.get(author_attr)
|
||||
if author:
|
||||
authors[author] = authors.get(author, 0) + 1
|
||||
|
||||
return authors
|
||||
|
||||
|
||||
def _get_authors_from_docx(docx_path: Path) -> dict[str, int]:
|
||||
try:
|
||||
with zipfile.ZipFile(docx_path, "r") as zf:
|
||||
if "word/document.xml" not in zf.namelist():
|
||||
return {}
|
||||
with zf.open("word/document.xml") as f:
|
||||
tree = ET.parse(f)
|
||||
root = tree.getroot()
|
||||
|
||||
namespaces = {"w": WORD_NS}
|
||||
author_attr = f"{{{WORD_NS}}}author"
|
||||
|
||||
authors: dict[str, int] = {}
|
||||
for tag in ["ins", "del"]:
|
||||
for elem in root.findall(f".//w:{tag}", namespaces):
|
||||
author = elem.get(author_attr)
|
||||
if author:
|
||||
authors[author] = authors.get(author, 0) + 1
|
||||
return authors
|
||||
except (zipfile.BadZipFile, ET.ParseError):
|
||||
return {}
|
||||
|
||||
|
||||
def infer_author(modified_dir: Path, original_docx: Path, default: str = "Claude") -> str:
|
||||
modified_xml = modified_dir / "word" / "document.xml"
|
||||
modified_authors = get_tracked_change_authors(modified_xml)
|
||||
|
||||
if not modified_authors:
|
||||
return default
|
||||
|
||||
original_authors = _get_authors_from_docx(original_docx)
|
||||
|
||||
new_changes: dict[str, int] = {}
|
||||
for author, count in modified_authors.items():
|
||||
original_count = original_authors.get(author, 0)
|
||||
diff = count - original_count
|
||||
if diff > 0:
|
||||
new_changes[author] = diff
|
||||
|
||||
if not new_changes:
|
||||
return default
|
||||
|
||||
if len(new_changes) == 1:
|
||||
return next(iter(new_changes))
|
||||
|
||||
raise ValueError(
|
||||
f"Multiple authors added new changes: {new_changes}. "
|
||||
"Cannot infer which author to validate."
|
||||
)
|
||||
@@ -0,0 +1,159 @@
|
||||
"""Pack a directory into a DOCX, PPTX, or XLSX file.
|
||||
|
||||
Validates with auto-repair, condenses XML formatting, and creates the Office file.
|
||||
|
||||
Usage:
|
||||
python pack.py <input_directory> <output_file> [--original <file>] [--validate true|false]
|
||||
|
||||
Examples:
|
||||
python pack.py unpacked/ output.docx --original input.docx
|
||||
python pack.py unpacked/ output.pptx --validate false
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import defusedxml.minidom
|
||||
|
||||
from validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator
|
||||
|
||||
def pack(
|
||||
input_directory: str,
|
||||
output_file: str,
|
||||
original_file: str | None = None,
|
||||
validate: bool = True,
|
||||
infer_author_func=None,
|
||||
) -> tuple[None, str]:
|
||||
input_dir = Path(input_directory)
|
||||
output_path = Path(output_file)
|
||||
suffix = output_path.suffix.lower()
|
||||
|
||||
if not input_dir.is_dir():
|
||||
return None, f"Error: {input_dir} is not a directory"
|
||||
|
||||
if suffix not in {".docx", ".pptx", ".xlsx"}:
|
||||
return None, f"Error: {output_file} must be a .docx, .pptx, or .xlsx file"
|
||||
|
||||
if validate and original_file:
|
||||
original_path = Path(original_file)
|
||||
if original_path.exists():
|
||||
success, output = _run_validation(
|
||||
input_dir, original_path, suffix, infer_author_func
|
||||
)
|
||||
if output:
|
||||
print(output)
|
||||
if not success:
|
||||
return None, f"Error: Validation failed for {input_dir}"
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_content_dir = Path(temp_dir) / "content"
|
||||
shutil.copytree(input_dir, temp_content_dir)
|
||||
|
||||
for pattern in ["*.xml", "*.rels"]:
|
||||
for xml_file in temp_content_dir.rglob(pattern):
|
||||
_condense_xml(xml_file)
|
||||
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
for f in temp_content_dir.rglob("*"):
|
||||
if f.is_file():
|
||||
zf.write(f, f.relative_to(temp_content_dir))
|
||||
|
||||
return None, f"Successfully packed {input_dir} to {output_file}"
|
||||
|
||||
|
||||
def _run_validation(
|
||||
unpacked_dir: Path,
|
||||
original_file: Path,
|
||||
suffix: str,
|
||||
infer_author_func=None,
|
||||
) -> tuple[bool, str | None]:
|
||||
output_lines = []
|
||||
validators = []
|
||||
|
||||
if suffix == ".docx":
|
||||
author = "Claude"
|
||||
if infer_author_func:
|
||||
try:
|
||||
author = infer_author_func(unpacked_dir, original_file)
|
||||
except ValueError as e:
|
||||
print(f"Warning: {e} Using default author 'Claude'.", file=sys.stderr)
|
||||
|
||||
validators = [
|
||||
DOCXSchemaValidator(unpacked_dir, original_file),
|
||||
RedliningValidator(unpacked_dir, original_file, author=author),
|
||||
]
|
||||
elif suffix == ".pptx":
|
||||
validators = [PPTXSchemaValidator(unpacked_dir, original_file)]
|
||||
|
||||
if not validators:
|
||||
return True, None
|
||||
|
||||
total_repairs = sum(v.repair() for v in validators)
|
||||
if total_repairs:
|
||||
output_lines.append(f"Auto-repaired {total_repairs} issue(s)")
|
||||
|
||||
success = all(v.validate() for v in validators)
|
||||
|
||||
if success:
|
||||
output_lines.append("All validations PASSED!")
|
||||
|
||||
return success, "\n".join(output_lines) if output_lines else None
|
||||
|
||||
|
||||
def _condense_xml(xml_file: Path) -> None:
|
||||
try:
|
||||
with open(xml_file, encoding="utf-8") as f:
|
||||
dom = defusedxml.minidom.parse(f)
|
||||
|
||||
for element in dom.getElementsByTagName("*"):
|
||||
if element.tagName.endswith(":t"):
|
||||
continue
|
||||
|
||||
for child in list(element.childNodes):
|
||||
if (
|
||||
child.nodeType == child.TEXT_NODE
|
||||
and child.nodeValue
|
||||
and child.nodeValue.strip() == ""
|
||||
) or child.nodeType == child.COMMENT_NODE:
|
||||
element.removeChild(child)
|
||||
|
||||
xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to parse {xml_file.name}: {e}", file=sys.stderr)
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Pack a directory into a DOCX, PPTX, or XLSX file"
|
||||
)
|
||||
parser.add_argument("input_directory", help="Unpacked Office document directory")
|
||||
parser.add_argument("output_file", help="Output Office file (.docx/.pptx/.xlsx)")
|
||||
parser.add_argument(
|
||||
"--original",
|
||||
help="Original file for validation comparison",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--validate",
|
||||
type=lambda x: x.lower() == "true",
|
||||
default=True,
|
||||
metavar="true|false",
|
||||
help="Run validation with auto-repair (default: true)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
_, message = pack(
|
||||
args.input_directory,
|
||||
args.output_file,
|
||||
original_file=args.original,
|
||||
validate=args.validate,
|
||||
)
|
||||
print(message)
|
||||
|
||||
if "Error" in message:
|
||||
sys.exit(1)
|
||||
File diff suppressed because it is too large
Load Diff
+146
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:complexType name="CT_ShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"
|
||||
/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="textlink" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ConnectorNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvCxnSpPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Connector">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvCxnSpPr" type="CT_ConnectorNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PictureNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Picture">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional" default=""/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicFrameNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicFrame">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGraphicFramePr" type="CT_GraphicFrameNonVisual" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGrpSpPr" type="CT_GroupShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ObjectChoices">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_MarkerCoordinate">
|
||||
<xsd:restriction base="xsd:double">
|
||||
<xsd:minInclusive value="0.0"/>
|
||||
<xsd:maxInclusive value="1.0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Marker">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="x" type="ST_MarkerCoordinate" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="y" type="ST_MarkerCoordinate" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RelSizeAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="to" type="CT_Marker"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AbsSizeAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_Anchor">
|
||||
<xsd:choice>
|
||||
<xsd:element name="relSizeAnchor" type="CT_RelSizeAnchor"/>
|
||||
<xsd:element name="absSizeAnchor" type="CT_AbsSizeAnchor"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Drawing">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_Anchor" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:element name="lockedCanvas" type="a:CT_GvmlGroupShape"/>
|
||||
</xsd:schema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:complexType name="CT_PictureNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Picture">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:schema>
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:import schemaLocation="shared-relationshipReference.xsd"
|
||||
namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="to" type="CT_Marker"/>
|
||||
<xsd:complexType name="CT_AnchorClientData">
|
||||
<xsd:attribute name="fLocksWithSheet" type="xsd:boolean" use="optional" default="true"/>
|
||||
<xsd:attribute name="fPrintsWithSheet" type="xsd:boolean" use="optional" default="true"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"
|
||||
/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="textlink" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ConnectorNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvCxnSpPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Connector">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvCxnSpPr" type="CT_ConnectorNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PictureNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Picture">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional" default=""/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicalObjectFrameNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicalObjectFrame">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGraphicFramePr" type="CT_GraphicalObjectFrameNonVisual" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGrpSpPr" type="CT_GroupShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ObjectChoices">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
<xsd:element name="contentPart" type="CT_Rel"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Rel">
|
||||
<xsd:attribute ref="r:id" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_ColID">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:minInclusive value="0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RowID">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:minInclusive value="0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Marker">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="col" type="ST_ColID"/>
|
||||
<xsd:element name="colOff" type="a:ST_Coordinate"/>
|
||||
<xsd:element name="row" type="ST_RowID"/>
|
||||
<xsd:element name="rowOff" type="a:ST_Coordinate"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_EditAs">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="twoCell"/>
|
||||
<xsd:enumeration value="oneCell"/>
|
||||
<xsd:enumeration value="absolute"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_TwoCellAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="to" type="CT_Marker"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="editAs" type="ST_EditAs" use="optional" default="twoCell"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OneCellAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AbsoluteAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="pos" type="a:CT_Point2D"/>
|
||||
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_Anchor">
|
||||
<xsd:choice>
|
||||
<xsd:element name="twoCellAnchor" type="CT_TwoCellAnchor"/>
|
||||
<xsd:element name="oneCellAnchor" type="CT_OneCellAnchor"/>
|
||||
<xsd:element name="absoluteAnchor" type="CT_AbsoluteAnchor"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Drawing">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_Anchor" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="wsDr" type="CT_Drawing"/>
|
||||
</xsd:schema>
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:dpct="http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:import schemaLocation="wml.xsd"
|
||||
namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
schemaLocation="dml-picture.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
schemaLocation="shared-relationshipReference.xsd"/>
|
||||
<xsd:complexType name="CT_EffectExtent">
|
||||
<xsd:attribute name="l" type="a:ST_Coordinate" use="required"/>
|
||||
<xsd:attribute name="t" type="a:ST_Coordinate" use="required"/>
|
||||
<xsd:attribute name="r" type="a:ST_Coordinate" use="required"/>
|
||||
<xsd:attribute name="b" type="a:ST_Coordinate" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_WrapDistance">
|
||||
<xsd:restriction base="xsd:unsignedInt"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Inline">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="extent" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
<xsd:element name="docPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_WrapText">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="bothSides"/>
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="largest"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_WrapPath">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="start" type="a:CT_Point2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="lineTo" type="a:CT_Point2D" minOccurs="2" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="edited" type="xsd:boolean" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapNone"/>
|
||||
<xsd:complexType name="CT_WrapSquare">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapTight">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="wrapPolygon" type="CT_WrapPath" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapThrough">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="wrapPolygon" type="CT_WrapPath" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapTopBottom">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_WrapType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="wrapNone" type="CT_WrapNone" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapSquare" type="CT_WrapSquare" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapTight" type="CT_WrapTight" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapThrough" type="CT_WrapThrough" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapTopAndBottom" type="CT_WrapTopBottom" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_PositionOffset">
|
||||
<xsd:restriction base="xsd:int"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_AlignH">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RelFromH">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="column"/>
|
||||
<xsd:enumeration value="character"/>
|
||||
<xsd:enumeration value="leftMargin"/>
|
||||
<xsd:enumeration value="rightMargin"/>
|
||||
<xsd:enumeration value="insideMargin"/>
|
||||
<xsd:enumeration value="outsideMargin"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_PosH">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="align" type="ST_AlignH" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="posOffset" type="ST_PositionOffset" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="relativeFrom" type="ST_RelFromH" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_AlignV">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RelFromV">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="paragraph"/>
|
||||
<xsd:enumeration value="line"/>
|
||||
<xsd:enumeration value="topMargin"/>
|
||||
<xsd:enumeration value="bottomMargin"/>
|
||||
<xsd:enumeration value="insideMargin"/>
|
||||
<xsd:enumeration value="outsideMargin"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_PosV">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="align" type="ST_AlignV" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="posOffset" type="ST_PositionOffset" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="relativeFrom" type="ST_RelFromV" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Anchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="simplePos" type="a:CT_Point2D"/>
|
||||
<xsd:element name="positionH" type="CT_PosH"/>
|
||||
<xsd:element name="positionV" type="CT_PosV"/>
|
||||
<xsd:element name="extent" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
<xsd:group ref="EG_WrapType"/>
|
||||
<xsd:element name="docPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="simplePos" type="xsd:boolean"/>
|
||||
<xsd:attribute name="relativeHeight" type="xsd:unsignedInt" use="required"/>
|
||||
<xsd:attribute name="behindDoc" type="xsd:boolean" use="required"/>
|
||||
<xsd:attribute name="locked" type="xsd:boolean" use="required"/>
|
||||
<xsd:attribute name="layoutInCell" type="xsd:boolean" use="required"/>
|
||||
<xsd:attribute name="hidden" type="xsd:boolean" use="optional"/>
|
||||
<xsd:attribute name="allowOverlap" type="xsd:boolean" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TxbxContent">
|
||||
<xsd:group ref="w:EG_BlockLevelElts" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TextboxInfo">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="txbxContent" type="CT_TxbxContent" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:unsignedShort" use="optional" default="0"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LinkedTextboxInformation">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:unsignedShort" use="required"/>
|
||||
<xsd:attribute name="seq" type="xsd:unsignedShort" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingShape">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="cNvCnPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="txbx" type="CT_TextboxInfo" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="linkedTxbx" type="CT_LinkedTextboxInformation" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="bodyPr" type="a:CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="normalEastAsianFlow" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicFrame">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvFrPr" type="a:CT_NonVisualGraphicFrameProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingContentPartNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="cNvContentPartPr" type="a:CT_NonVisualContentPartProperties" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingContentPart">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvContentPartPr" type="CT_WordprocessingContentPartNonVisual" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="bwMode" type="a:ST_BlackWhiteMode" use="optional"/>
|
||||
<xsd:attribute ref="r:id" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingGroup">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element ref="wsp"/>
|
||||
<xsd:element name="grpSp" type="CT_WordprocessingGroup"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
<xsd:element ref="dpct:pic"/>
|
||||
<xsd:element name="contentPart" type="CT_WordprocessingContentPart"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingCanvas">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="bg" type="a:CT_BackgroundFormatting" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="whole" type="a:CT_WholeE2oFormatting" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element ref="wsp"/>
|
||||
<xsd:element ref="dpct:pic"/>
|
||||
<xsd:element name="contentPart" type="CT_WordprocessingContentPart"/>
|
||||
<xsd:element ref="wgp"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="wpc" type="CT_WordprocessingCanvas"/>
|
||||
<xsd:element name="wgp" type="CT_WordprocessingGroup"/>
|
||||
<xsd:element name="wsp" type="CT_WordprocessingShape"/>
|
||||
<xsd:element name="inline" type="CT_Inline"/>
|
||||
<xsd:element name="anchor" type="CT_Anchor"/>
|
||||
</xsd:schema>
|
||||
File diff suppressed because it is too large
Load Diff
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/characteristics"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/characteristics"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:complexType name="CT_AdditionalCharacteristics">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="characteristic" type="CT_Characteristic" minOccurs="0"
|
||||
maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Characteristic">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="relation" type="ST_Relation" use="required"/>
|
||||
<xsd:attribute name="val" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="vocabulary" type="xsd:anyURI" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Relation">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ge"/>
|
||||
<xsd:enumeration value="le"/>
|
||||
<xsd:enumeration value="gt"/>
|
||||
<xsd:enumeration value="lt"/>
|
||||
<xsd:enumeration value="eq"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:element name="additionalCharacteristics" type="CT_AdditionalCharacteristics"/>
|
||||
</xsd:schema>
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:simpleType name="ST_SourceType">
|
||||
<xsd:restriction base="s:ST_String">
|
||||
<xsd:enumeration value="ArticleInAPeriodical"/>
|
||||
<xsd:enumeration value="Book"/>
|
||||
<xsd:enumeration value="BookSection"/>
|
||||
<xsd:enumeration value="JournalArticle"/>
|
||||
<xsd:enumeration value="ConferenceProceedings"/>
|
||||
<xsd:enumeration value="Report"/>
|
||||
<xsd:enumeration value="SoundRecording"/>
|
||||
<xsd:enumeration value="Performance"/>
|
||||
<xsd:enumeration value="Art"/>
|
||||
<xsd:enumeration value="DocumentFromInternetSite"/>
|
||||
<xsd:enumeration value="InternetSite"/>
|
||||
<xsd:enumeration value="Film"/>
|
||||
<xsd:enumeration value="Interview"/>
|
||||
<xsd:enumeration value="Patent"/>
|
||||
<xsd:enumeration value="ElectronicSource"/>
|
||||
<xsd:enumeration value="Case"/>
|
||||
<xsd:enumeration value="Misc"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_NameListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Person" type="CT_PersonType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PersonType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Last" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="First" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="Middle" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_NameType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="NameList" type="CT_NameListType" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_NameOrCorporateType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="NameList" type="CT_NameListType" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="Corporate" minOccurs="1" maxOccurs="1" type="s:ST_String"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AuthorType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="Artist" type="CT_NameType"/>
|
||||
<xsd:element name="Author" type="CT_NameOrCorporateType"/>
|
||||
<xsd:element name="BookAuthor" type="CT_NameType"/>
|
||||
<xsd:element name="Compiler" type="CT_NameType"/>
|
||||
<xsd:element name="Composer" type="CT_NameType"/>
|
||||
<xsd:element name="Conductor" type="CT_NameType"/>
|
||||
<xsd:element name="Counsel" type="CT_NameType"/>
|
||||
<xsd:element name="Director" type="CT_NameType"/>
|
||||
<xsd:element name="Editor" type="CT_NameType"/>
|
||||
<xsd:element name="Interviewee" type="CT_NameType"/>
|
||||
<xsd:element name="Interviewer" type="CT_NameType"/>
|
||||
<xsd:element name="Inventor" type="CT_NameType"/>
|
||||
<xsd:element name="Performer" type="CT_NameOrCorporateType"/>
|
||||
<xsd:element name="ProducerName" type="CT_NameType"/>
|
||||
<xsd:element name="Translator" type="CT_NameType"/>
|
||||
<xsd:element name="Writer" type="CT_NameType"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SourceType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="AbbreviatedCaseNumber" type="s:ST_String"/>
|
||||
<xsd:element name="AlbumTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Author" type="CT_AuthorType"/>
|
||||
<xsd:element name="BookTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Broadcaster" type="s:ST_String"/>
|
||||
<xsd:element name="BroadcastTitle" type="s:ST_String"/>
|
||||
<xsd:element name="CaseNumber" type="s:ST_String"/>
|
||||
<xsd:element name="ChapterNumber" type="s:ST_String"/>
|
||||
<xsd:element name="City" type="s:ST_String"/>
|
||||
<xsd:element name="Comments" type="s:ST_String"/>
|
||||
<xsd:element name="ConferenceName" type="s:ST_String"/>
|
||||
<xsd:element name="CountryRegion" type="s:ST_String"/>
|
||||
<xsd:element name="Court" type="s:ST_String"/>
|
||||
<xsd:element name="Day" type="s:ST_String"/>
|
||||
<xsd:element name="DayAccessed" type="s:ST_String"/>
|
||||
<xsd:element name="Department" type="s:ST_String"/>
|
||||
<xsd:element name="Distributor" type="s:ST_String"/>
|
||||
<xsd:element name="Edition" type="s:ST_String"/>
|
||||
<xsd:element name="Guid" type="s:ST_String"/>
|
||||
<xsd:element name="Institution" type="s:ST_String"/>
|
||||
<xsd:element name="InternetSiteTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Issue" type="s:ST_String"/>
|
||||
<xsd:element name="JournalName" type="s:ST_String"/>
|
||||
<xsd:element name="LCID" type="s:ST_Lang"/>
|
||||
<xsd:element name="Medium" type="s:ST_String"/>
|
||||
<xsd:element name="Month" type="s:ST_String"/>
|
||||
<xsd:element name="MonthAccessed" type="s:ST_String"/>
|
||||
<xsd:element name="NumberVolumes" type="s:ST_String"/>
|
||||
<xsd:element name="Pages" type="s:ST_String"/>
|
||||
<xsd:element name="PatentNumber" type="s:ST_String"/>
|
||||
<xsd:element name="PeriodicalTitle" type="s:ST_String"/>
|
||||
<xsd:element name="ProductionCompany" type="s:ST_String"/>
|
||||
<xsd:element name="PublicationTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Publisher" type="s:ST_String"/>
|
||||
<xsd:element name="RecordingNumber" type="s:ST_String"/>
|
||||
<xsd:element name="RefOrder" type="s:ST_String"/>
|
||||
<xsd:element name="Reporter" type="s:ST_String"/>
|
||||
<xsd:element name="SourceType" type="ST_SourceType"/>
|
||||
<xsd:element name="ShortTitle" type="s:ST_String"/>
|
||||
<xsd:element name="StandardNumber" type="s:ST_String"/>
|
||||
<xsd:element name="StateProvince" type="s:ST_String"/>
|
||||
<xsd:element name="Station" type="s:ST_String"/>
|
||||
<xsd:element name="Tag" type="s:ST_String"/>
|
||||
<xsd:element name="Theater" type="s:ST_String"/>
|
||||
<xsd:element name="ThesisType" type="s:ST_String"/>
|
||||
<xsd:element name="Title" type="s:ST_String"/>
|
||||
<xsd:element name="Type" type="s:ST_String"/>
|
||||
<xsd:element name="URL" type="s:ST_String"/>
|
||||
<xsd:element name="Version" type="s:ST_String"/>
|
||||
<xsd:element name="Volume" type="s:ST_String"/>
|
||||
<xsd:element name="Year" type="s:ST_String"/>
|
||||
<xsd:element name="YearAccessed" type="s:ST_String"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="Sources" type="CT_Sources"/>
|
||||
<xsd:complexType name="CT_Sources">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Source" type="CT_SourceType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="SelectedStyle" type="s:ST_String"/>
|
||||
<xsd:attribute name="StyleName" type="s:ST_String"/>
|
||||
<xsd:attribute name="URI" type="s:ST_String"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:simpleType name="ST_Lang">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_HexColorRGB">
|
||||
<xsd:restriction base="xsd:hexBinary">
|
||||
<xsd:length value="3" fixed="true"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Panose">
|
||||
<xsd:restriction base="xsd:hexBinary">
|
||||
<xsd:length value="10"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CalendarType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="gregorian"/>
|
||||
<xsd:enumeration value="gregorianUs"/>
|
||||
<xsd:enumeration value="gregorianMeFrench"/>
|
||||
<xsd:enumeration value="gregorianArabic"/>
|
||||
<xsd:enumeration value="hijri"/>
|
||||
<xsd:enumeration value="hebrew"/>
|
||||
<xsd:enumeration value="taiwan"/>
|
||||
<xsd:enumeration value="japan"/>
|
||||
<xsd:enumeration value="thai"/>
|
||||
<xsd:enumeration value="korea"/>
|
||||
<xsd:enumeration value="saka"/>
|
||||
<xsd:enumeration value="gregorianXlitEnglish"/>
|
||||
<xsd:enumeration value="gregorianXlitFrench"/>
|
||||
<xsd:enumeration value="none"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_AlgClass">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="hash"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CryptProv">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="rsaAES"/>
|
||||
<xsd:enumeration value="rsaFull"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_AlgType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="typeAny"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ColorType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Guid">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:pattern value="\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OnOff">
|
||||
<xsd:union memberTypes="xsd:boolean ST_OnOff1"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OnOff1">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="on"/>
|
||||
<xsd:enumeration value="off"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_String">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_XmlName">
|
||||
<xsd:restriction base="xsd:NCName">
|
||||
<xsd:minLength value="1"/>
|
||||
<xsd:maxLength value="255"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_TrueFalse">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="f"/>
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_TrueFalseBlank">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="f"/>
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
<xsd:enumeration value=""/>
|
||||
<xsd:enumeration value="True"/>
|
||||
<xsd:enumeration value="False"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_UnsignedDecimalNumber">
|
||||
<xsd:restriction base="xsd:decimal">
|
||||
<xsd:minInclusive value="0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_TwipsMeasure">
|
||||
<xsd:union memberTypes="ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_VerticalAlignRun">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="baseline"/>
|
||||
<xsd:enumeration value="superscript"/>
|
||||
<xsd:enumeration value="subscript"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Xstring">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_XAlign">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_YAlign">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="inline"/>
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ConformanceClass">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="strict"/>
|
||||
<xsd:enumeration value="transitional"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_UniversalMeasure">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="-?[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PositiveUniversalMeasure">
|
||||
<xsd:restriction base="ST_UniversalMeasure">
|
||||
<xsd:pattern value="[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Percentage">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="-?[0-9]+(\.[0-9]+)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FixedPercentage">
|
||||
<xsd:restriction base="ST_Percentage">
|
||||
<xsd:pattern value="-?((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PositivePercentage">
|
||||
<xsd:restriction base="ST_Percentage">
|
||||
<xsd:pattern value="[0-9]+(\.[0-9]+)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PositiveFixedPercentage">
|
||||
<xsd:restriction base="ST_Percentage">
|
||||
<xsd:pattern value="((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/customXml"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/customXml"
|
||||
elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:complexType name="CT_DatastoreSchemaRef">
|
||||
<xsd:attribute name="uri" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DatastoreSchemaRefs">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="schemaRef" type="CT_DatastoreSchemaRef" minOccurs="0" maxOccurs="unbounded"
|
||||
/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DatastoreItem">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="schemaRefs" type="CT_DatastoreSchemaRefs" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="itemID" type="s:ST_Guid" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="datastoreItem" type="CT_DatastoreItem"/>
|
||||
</xsd:schema>
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
|
||||
targetNamespace="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
|
||||
attributeFormDefault="qualified" elementFormDefault="qualified">
|
||||
<xsd:complexType name="CT_Schema">
|
||||
<xsd:attribute name="uri" type="xsd:string" default=""/>
|
||||
<xsd:attribute name="manifestLocation" type="xsd:string"/>
|
||||
<xsd:attribute name="schemaLocation" type="xsd:string"/>
|
||||
<xsd:attribute name="schemaLanguage" type="xsd:token"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SchemaLibrary">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="schema" type="CT_Schema" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="schemaLibrary" type="CT_SchemaLibrary"/>
|
||||
</xsd:schema>
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
|
||||
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
|
||||
blockDefault="#all" elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
schemaLocation="shared-documentPropertiesVariantTypes.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:element name="Properties" type="CT_Properties"/>
|
||||
<xsd:complexType name="CT_Properties">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="property" minOccurs="0" maxOccurs="unbounded" type="CT_Property"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Property">
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:vector"/>
|
||||
<xsd:element ref="vt:array"/>
|
||||
<xsd:element ref="vt:blob"/>
|
||||
<xsd:element ref="vt:oblob"/>
|
||||
<xsd:element ref="vt:empty"/>
|
||||
<xsd:element ref="vt:null"/>
|
||||
<xsd:element ref="vt:i1"/>
|
||||
<xsd:element ref="vt:i2"/>
|
||||
<xsd:element ref="vt:i4"/>
|
||||
<xsd:element ref="vt:i8"/>
|
||||
<xsd:element ref="vt:int"/>
|
||||
<xsd:element ref="vt:ui1"/>
|
||||
<xsd:element ref="vt:ui2"/>
|
||||
<xsd:element ref="vt:ui4"/>
|
||||
<xsd:element ref="vt:ui8"/>
|
||||
<xsd:element ref="vt:uint"/>
|
||||
<xsd:element ref="vt:r4"/>
|
||||
<xsd:element ref="vt:r8"/>
|
||||
<xsd:element ref="vt:decimal"/>
|
||||
<xsd:element ref="vt:lpstr"/>
|
||||
<xsd:element ref="vt:lpwstr"/>
|
||||
<xsd:element ref="vt:bstr"/>
|
||||
<xsd:element ref="vt:date"/>
|
||||
<xsd:element ref="vt:filetime"/>
|
||||
<xsd:element ref="vt:bool"/>
|
||||
<xsd:element ref="vt:cy"/>
|
||||
<xsd:element ref="vt:error"/>
|
||||
<xsd:element ref="vt:stream"/>
|
||||
<xsd:element ref="vt:ostream"/>
|
||||
<xsd:element ref="vt:storage"/>
|
||||
<xsd:element ref="vt:ostorage"/>
|
||||
<xsd:element ref="vt:vstream"/>
|
||||
<xsd:element ref="vt:clsid"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="fmtid" use="required" type="s:ST_Guid"/>
|
||||
<xsd:attribute name="pid" use="required" type="xsd:int"/>
|
||||
<xsd:attribute name="name" use="optional" type="xsd:string"/>
|
||||
<xsd:attribute name="linkTarget" use="optional" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
|
||||
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
|
||||
elementFormDefault="qualified" blockDefault="#all">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
schemaLocation="shared-documentPropertiesVariantTypes.xsd"/>
|
||||
<xsd:element name="Properties" type="CT_Properties"/>
|
||||
<xsd:complexType name="CT_Properties">
|
||||
<xsd:all>
|
||||
<xsd:element name="Template" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Manager" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Company" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Pages" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Words" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Characters" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="PresentationFormat" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Lines" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Paragraphs" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Slides" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Notes" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="TotalTime" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="HiddenSlides" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="MMClips" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="ScaleCrop" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="HeadingPairs" minOccurs="0" maxOccurs="1" type="CT_VectorVariant"/>
|
||||
<xsd:element name="TitlesOfParts" minOccurs="0" maxOccurs="1" type="CT_VectorLpstr"/>
|
||||
<xsd:element name="LinksUpToDate" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="CharactersWithSpaces" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="SharedDoc" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="HyperlinkBase" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="HLinks" minOccurs="0" maxOccurs="1" type="CT_VectorVariant"/>
|
||||
<xsd:element name="HyperlinksChanged" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="DigSig" minOccurs="0" maxOccurs="1" type="CT_DigSigBlob"/>
|
||||
<xsd:element name="Application" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="AppVersion" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="DocSecurity" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
</xsd:all>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_VectorVariant">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:vector"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_VectorLpstr">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:vector"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DigSigBlob">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:blob"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
blockDefault="#all" elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:simpleType name="ST_VectorBaseType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="variant"/>
|
||||
<xsd:enumeration value="i1"/>
|
||||
<xsd:enumeration value="i2"/>
|
||||
<xsd:enumeration value="i4"/>
|
||||
<xsd:enumeration value="i8"/>
|
||||
<xsd:enumeration value="ui1"/>
|
||||
<xsd:enumeration value="ui2"/>
|
||||
<xsd:enumeration value="ui4"/>
|
||||
<xsd:enumeration value="ui8"/>
|
||||
<xsd:enumeration value="r4"/>
|
||||
<xsd:enumeration value="r8"/>
|
||||
<xsd:enumeration value="lpstr"/>
|
||||
<xsd:enumeration value="lpwstr"/>
|
||||
<xsd:enumeration value="bstr"/>
|
||||
<xsd:enumeration value="date"/>
|
||||
<xsd:enumeration value="filetime"/>
|
||||
<xsd:enumeration value="bool"/>
|
||||
<xsd:enumeration value="cy"/>
|
||||
<xsd:enumeration value="error"/>
|
||||
<xsd:enumeration value="clsid"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ArrayBaseType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="variant"/>
|
||||
<xsd:enumeration value="i1"/>
|
||||
<xsd:enumeration value="i2"/>
|
||||
<xsd:enumeration value="i4"/>
|
||||
<xsd:enumeration value="int"/>
|
||||
<xsd:enumeration value="ui1"/>
|
||||
<xsd:enumeration value="ui2"/>
|
||||
<xsd:enumeration value="ui4"/>
|
||||
<xsd:enumeration value="uint"/>
|
||||
<xsd:enumeration value="r4"/>
|
||||
<xsd:enumeration value="r8"/>
|
||||
<xsd:enumeration value="decimal"/>
|
||||
<xsd:enumeration value="bstr"/>
|
||||
<xsd:enumeration value="date"/>
|
||||
<xsd:enumeration value="bool"/>
|
||||
<xsd:enumeration value="cy"/>
|
||||
<xsd:enumeration value="error"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Cy">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="\s*[0-9]*\.[0-9]{4}\s*"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Error">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="\s*0x[0-9A-Za-z]{8}\s*"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Empty"/>
|
||||
<xsd:complexType name="CT_Null"/>
|
||||
<xsd:complexType name="CT_Vector">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element ref="variant"/>
|
||||
<xsd:element ref="i1"/>
|
||||
<xsd:element ref="i2"/>
|
||||
<xsd:element ref="i4"/>
|
||||
<xsd:element ref="i8"/>
|
||||
<xsd:element ref="ui1"/>
|
||||
<xsd:element ref="ui2"/>
|
||||
<xsd:element ref="ui4"/>
|
||||
<xsd:element ref="ui8"/>
|
||||
<xsd:element ref="r4"/>
|
||||
<xsd:element ref="r8"/>
|
||||
<xsd:element ref="lpstr"/>
|
||||
<xsd:element ref="lpwstr"/>
|
||||
<xsd:element ref="bstr"/>
|
||||
<xsd:element ref="date"/>
|
||||
<xsd:element ref="filetime"/>
|
||||
<xsd:element ref="bool"/>
|
||||
<xsd:element ref="cy"/>
|
||||
<xsd:element ref="error"/>
|
||||
<xsd:element ref="clsid"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="baseType" type="ST_VectorBaseType" use="required"/>
|
||||
<xsd:attribute name="size" type="xsd:unsignedInt" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Array">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element ref="variant"/>
|
||||
<xsd:element ref="i1"/>
|
||||
<xsd:element ref="i2"/>
|
||||
<xsd:element ref="i4"/>
|
||||
<xsd:element ref="int"/>
|
||||
<xsd:element ref="ui1"/>
|
||||
<xsd:element ref="ui2"/>
|
||||
<xsd:element ref="ui4"/>
|
||||
<xsd:element ref="uint"/>
|
||||
<xsd:element ref="r4"/>
|
||||
<xsd:element ref="r8"/>
|
||||
<xsd:element ref="decimal"/>
|
||||
<xsd:element ref="bstr"/>
|
||||
<xsd:element ref="date"/>
|
||||
<xsd:element ref="bool"/>
|
||||
<xsd:element ref="error"/>
|
||||
<xsd:element ref="cy"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="lBounds" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="uBounds" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="baseType" type="ST_ArrayBaseType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Variant">
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="variant"/>
|
||||
<xsd:element ref="vector"/>
|
||||
<xsd:element ref="array"/>
|
||||
<xsd:element ref="blob"/>
|
||||
<xsd:element ref="oblob"/>
|
||||
<xsd:element ref="empty"/>
|
||||
<xsd:element ref="null"/>
|
||||
<xsd:element ref="i1"/>
|
||||
<xsd:element ref="i2"/>
|
||||
<xsd:element ref="i4"/>
|
||||
<xsd:element ref="i8"/>
|
||||
<xsd:element ref="int"/>
|
||||
<xsd:element ref="ui1"/>
|
||||
<xsd:element ref="ui2"/>
|
||||
<xsd:element ref="ui4"/>
|
||||
<xsd:element ref="ui8"/>
|
||||
<xsd:element ref="uint"/>
|
||||
<xsd:element ref="r4"/>
|
||||
<xsd:element ref="r8"/>
|
||||
<xsd:element ref="decimal"/>
|
||||
<xsd:element ref="lpstr"/>
|
||||
<xsd:element ref="lpwstr"/>
|
||||
<xsd:element ref="bstr"/>
|
||||
<xsd:element ref="date"/>
|
||||
<xsd:element ref="filetime"/>
|
||||
<xsd:element ref="bool"/>
|
||||
<xsd:element ref="cy"/>
|
||||
<xsd:element ref="error"/>
|
||||
<xsd:element ref="stream"/>
|
||||
<xsd:element ref="ostream"/>
|
||||
<xsd:element ref="storage"/>
|
||||
<xsd:element ref="ostorage"/>
|
||||
<xsd:element ref="vstream"/>
|
||||
<xsd:element ref="clsid"/>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Vstream">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:base64Binary">
|
||||
<xsd:attribute name="version" type="s:ST_Guid"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="variant" type="CT_Variant"/>
|
||||
<xsd:element name="vector" type="CT_Vector"/>
|
||||
<xsd:element name="array" type="CT_Array"/>
|
||||
<xsd:element name="blob" type="xsd:base64Binary"/>
|
||||
<xsd:element name="oblob" type="xsd:base64Binary"/>
|
||||
<xsd:element name="empty" type="CT_Empty"/>
|
||||
<xsd:element name="null" type="CT_Null"/>
|
||||
<xsd:element name="i1" type="xsd:byte"/>
|
||||
<xsd:element name="i2" type="xsd:short"/>
|
||||
<xsd:element name="i4" type="xsd:int"/>
|
||||
<xsd:element name="i8" type="xsd:long"/>
|
||||
<xsd:element name="int" type="xsd:int"/>
|
||||
<xsd:element name="ui1" type="xsd:unsignedByte"/>
|
||||
<xsd:element name="ui2" type="xsd:unsignedShort"/>
|
||||
<xsd:element name="ui4" type="xsd:unsignedInt"/>
|
||||
<xsd:element name="ui8" type="xsd:unsignedLong"/>
|
||||
<xsd:element name="uint" type="xsd:unsignedInt"/>
|
||||
<xsd:element name="r4" type="xsd:float"/>
|
||||
<xsd:element name="r8" type="xsd:double"/>
|
||||
<xsd:element name="decimal" type="xsd:decimal"/>
|
||||
<xsd:element name="lpstr" type="xsd:string"/>
|
||||
<xsd:element name="lpwstr" type="xsd:string"/>
|
||||
<xsd:element name="bstr" type="xsd:string"/>
|
||||
<xsd:element name="date" type="xsd:dateTime"/>
|
||||
<xsd:element name="filetime" type="xsd:dateTime"/>
|
||||
<xsd:element name="bool" type="xsd:boolean"/>
|
||||
<xsd:element name="cy" type="ST_Cy"/>
|
||||
<xsd:element name="error" type="ST_Error"/>
|
||||
<xsd:element name="stream" type="xsd:base64Binary"/>
|
||||
<xsd:element name="ostream" type="xsd:base64Binary"/>
|
||||
<xsd:element name="storage" type="xsd:base64Binary"/>
|
||||
<xsd:element name="ostorage" type="xsd:base64Binary"/>
|
||||
<xsd:element name="vstream" type="CT_Vstream"/>
|
||||
<xsd:element name="clsid" type="s:ST_Guid"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,582 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/math"
|
||||
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/math">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
schemaLocation="wml.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
|
||||
<xsd:simpleType name="ST_Integer255">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="1"/>
|
||||
<xsd:maxInclusive value="255"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Integer255">
|
||||
<xsd:attribute name="val" type="ST_Integer255" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Integer2">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="-2"/>
|
||||
<xsd:maxInclusive value="2"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Integer2">
|
||||
<xsd:attribute name="val" type="ST_Integer2" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_SpacingRule">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="0"/>
|
||||
<xsd:maxInclusive value="4"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_SpacingRule">
|
||||
<xsd:attribute name="val" type="ST_SpacingRule" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_UnSignedInteger">
|
||||
<xsd:restriction base="xsd:unsignedInt"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_UnSignedInteger">
|
||||
<xsd:attribute name="val" type="ST_UnSignedInteger" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Char">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="1"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Char">
|
||||
<xsd:attribute name="val" type="ST_Char" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OnOff">
|
||||
<xsd:attribute name="val" type="s:ST_OnOff"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_String">
|
||||
<xsd:attribute name="val" type="s:ST_String"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_XAlign">
|
||||
<xsd:attribute name="val" type="s:ST_XAlign" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_YAlign">
|
||||
<xsd:attribute name="val" type="s:ST_YAlign" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Shp">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="centered"/>
|
||||
<xsd:enumeration value="match"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Shp">
|
||||
<xsd:attribute name="val" type="ST_Shp" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_FType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="bar"/>
|
||||
<xsd:enumeration value="skw"/>
|
||||
<xsd:enumeration value="lin"/>
|
||||
<xsd:enumeration value="noBar"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_FType">
|
||||
<xsd:attribute name="val" type="ST_FType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_LimLoc">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="undOvr"/>
|
||||
<xsd:enumeration value="subSup"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_LimLoc">
|
||||
<xsd:attribute name="val" type="ST_LimLoc" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_TopBot">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="bot"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_TopBot">
|
||||
<xsd:attribute name="val" type="ST_TopBot" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Script">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="roman"/>
|
||||
<xsd:enumeration value="script"/>
|
||||
<xsd:enumeration value="fraktur"/>
|
||||
<xsd:enumeration value="double-struck"/>
|
||||
<xsd:enumeration value="sans-serif"/>
|
||||
<xsd:enumeration value="monospace"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Script">
|
||||
<xsd:attribute name="val" type="ST_Script"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Style">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="p"/>
|
||||
<xsd:enumeration value="b"/>
|
||||
<xsd:enumeration value="i"/>
|
||||
<xsd:enumeration value="bi"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Style">
|
||||
<xsd:attribute name="val" type="ST_Style"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ManualBreak">
|
||||
<xsd:attribute name="alnAt" type="ST_Integer255"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ScriptStyle">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="scr" minOccurs="0" type="CT_Script"/>
|
||||
<xsd:element name="sty" minOccurs="0" type="CT_Style"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_RPR">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="lit" minOccurs="0" type="CT_OnOff"/>
|
||||
<xsd:choice>
|
||||
<xsd:element name="nor" minOccurs="0" type="CT_OnOff"/>
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ScriptStyle"/>
|
||||
</xsd:sequence>
|
||||
</xsd:choice>
|
||||
<xsd:element name="brk" minOccurs="0" type="CT_ManualBreak"/>
|
||||
<xsd:element name="aln" minOccurs="0" type="CT_OnOff"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Text">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="s:ST_String">
|
||||
<xsd:attribute ref="xml:space" use="optional"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_R">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="rPr" type="CT_RPR" minOccurs="0"/>
|
||||
<xsd:group ref="w:EG_RPr" minOccurs="0"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:group ref="w:EG_RunInnerContent"/>
|
||||
<xsd:element name="t" type="CT_Text" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CtrlPr">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="w:EG_RPrMath" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AccPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Acc">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="accPr" type="CT_AccPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BarPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="pos" type="CT_TopBot" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Bar">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="barPr" type="CT_BarPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BoxPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="opEmu" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="noBreak" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="diff" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="brk" type="CT_ManualBreak" minOccurs="0"/>
|
||||
<xsd:element name="aln" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Box">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="boxPr" type="CT_BoxPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BorderBoxPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="hideTop" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="hideBot" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="hideLeft" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="hideRight" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeH" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeV" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeBLTR" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeTLBR" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BorderBox">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="borderBoxPr" type="CT_BorderBoxPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="begChr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="sepChr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="endChr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="grow" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="shp" type="CT_Shp" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_D">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="dPr" type="CT_DPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_EqArrPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="baseJc" type="CT_YAlign" minOccurs="0"/>
|
||||
<xsd:element name="maxDist" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="objDist" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="rSpRule" type="CT_SpacingRule" minOccurs="0"/>
|
||||
<xsd:element name="rSp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_EqArr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="eqArrPr" type="CT_EqArrPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_FPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="type" type="CT_FType" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_F">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="fPr" type="CT_FPr" minOccurs="0"/>
|
||||
<xsd:element name="num" type="CT_OMathArg"/>
|
||||
<xsd:element name="den" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_FuncPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Func">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="funcPr" type="CT_FuncPr" minOccurs="0"/>
|
||||
<xsd:element name="fName" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupChrPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="pos" type="CT_TopBot" minOccurs="0"/>
|
||||
<xsd:element name="vertJc" type="CT_TopBot" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupChr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="groupChrPr" type="CT_GroupChrPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimLowPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimLow">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="limLowPr" type="CT_LimLowPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="lim" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimUppPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimUpp">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="limUppPr" type="CT_LimUppPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="lim" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MCPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="count" type="CT_Integer255" minOccurs="0"/>
|
||||
<xsd:element name="mcJc" type="CT_XAlign" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MC">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mcPr" type="CT_MCPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MCS">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mc" type="CT_MC" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="baseJc" type="CT_YAlign" minOccurs="0"/>
|
||||
<xsd:element name="plcHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="rSpRule" type="CT_SpacingRule" minOccurs="0"/>
|
||||
<xsd:element name="cGpRule" type="CT_SpacingRule" minOccurs="0"/>
|
||||
<xsd:element name="rSp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="cSp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="cGp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="mcs" type="CT_MCS" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MR">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_M">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mPr" type="CT_MPr" minOccurs="0"/>
|
||||
<xsd:element name="mr" type="CT_MR" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_NaryPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="limLoc" type="CT_LimLoc" minOccurs="0"/>
|
||||
<xsd:element name="grow" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="subHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="supHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Nary">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="naryPr" type="CT_NaryPr" minOccurs="0"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PhantPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="show" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="zeroWid" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="zeroAsc" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="zeroDesc" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="transp" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Phant">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="phantPr" type="CT_PhantPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RadPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="degHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Rad">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="radPr" type="CT_RadPr" minOccurs="0"/>
|
||||
<xsd:element name="deg" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SPrePr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SPre">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sPrePr" type="CT_SPrePr" minOccurs="0"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSubPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSub">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sSubPr" type="CT_SSubPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSubSupPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="alnScr" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSubSup">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sSubSupPr" type="CT_SSubSupPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSupPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSup">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sSupPr" type="CT_SSupPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_OMathMathElements">
|
||||
<xsd:choice>
|
||||
<xsd:element name="acc" type="CT_Acc"/>
|
||||
<xsd:element name="bar" type="CT_Bar"/>
|
||||
<xsd:element name="box" type="CT_Box"/>
|
||||
<xsd:element name="borderBox" type="CT_BorderBox"/>
|
||||
<xsd:element name="d" type="CT_D"/>
|
||||
<xsd:element name="eqArr" type="CT_EqArr"/>
|
||||
<xsd:element name="f" type="CT_F"/>
|
||||
<xsd:element name="func" type="CT_Func"/>
|
||||
<xsd:element name="groupChr" type="CT_GroupChr"/>
|
||||
<xsd:element name="limLow" type="CT_LimLow"/>
|
||||
<xsd:element name="limUpp" type="CT_LimUpp"/>
|
||||
<xsd:element name="m" type="CT_M"/>
|
||||
<xsd:element name="nary" type="CT_Nary"/>
|
||||
<xsd:element name="phant" type="CT_Phant"/>
|
||||
<xsd:element name="rad" type="CT_Rad"/>
|
||||
<xsd:element name="sPre" type="CT_SPre"/>
|
||||
<xsd:element name="sSub" type="CT_SSub"/>
|
||||
<xsd:element name="sSubSup" type="CT_SSubSup"/>
|
||||
<xsd:element name="sSup" type="CT_SSup"/>
|
||||
<xsd:element name="r" type="CT_R"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:group name="EG_OMathElements">
|
||||
<xsd:choice>
|
||||
<xsd:group ref="EG_OMathMathElements"/>
|
||||
<xsd:group ref="w:EG_PContentMath"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_OMathArgPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="argSz" type="CT_Integer2" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OMathArg">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="argPr" type="CT_OMathArgPr" minOccurs="0"/>
|
||||
<xsd:group ref="EG_OMathElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Jc">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="centerGroup"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_OMathJc">
|
||||
<xsd:attribute name="val" type="ST_Jc"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OMathParaPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="jc" type="CT_OMathJc" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TwipsMeasure">
|
||||
<xsd:attribute name="val" type="s:ST_TwipsMeasure" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_BreakBin">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="before"/>
|
||||
<xsd:enumeration value="after"/>
|
||||
<xsd:enumeration value="repeat"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_BreakBin">
|
||||
<xsd:attribute name="val" type="ST_BreakBin"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_BreakBinSub">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="--"/>
|
||||
<xsd:enumeration value="-+"/>
|
||||
<xsd:enumeration value="+-"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_BreakBinSub">
|
||||
<xsd:attribute name="val" type="ST_BreakBinSub"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MathPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mathFont" type="CT_String" minOccurs="0"/>
|
||||
<xsd:element name="brkBin" type="CT_BreakBin" minOccurs="0"/>
|
||||
<xsd:element name="brkBinSub" type="CT_BreakBinSub" minOccurs="0"/>
|
||||
<xsd:element name="smallFrac" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="dispDef" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="lMargin" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="rMargin" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="defJc" type="CT_OMathJc" minOccurs="0"/>
|
||||
<xsd:element name="preSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="postSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="interSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="intraSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:choice minOccurs="0">
|
||||
<xsd:element name="wrapIndent" type="CT_TwipsMeasure"/>
|
||||
<xsd:element name="wrapRight" type="CT_OnOff"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="intLim" type="CT_LimLoc" minOccurs="0"/>
|
||||
<xsd:element name="naryLim" type="CT_LimLoc" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="mathPr" type="CT_MathPr"/>
|
||||
<xsd:complexType name="CT_OMathPara">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="oMathParaPr" type="CT_OMathParaPr" minOccurs="0"/>
|
||||
<xsd:element name="oMath" type="CT_OMath" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OMath">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_OMathElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="oMathPara" type="CT_OMathPara"/>
|
||||
<xsd:element name="oMath" type="CT_OMath"/>
|
||||
</xsd:schema>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
blockDefault="#all">
|
||||
<xsd:simpleType name="ST_RelationshipId">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:attribute name="id" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="embed" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="link" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="dm" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="lo" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="qs" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="cs" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="blip" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="pict" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="href" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="topLeft" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="topRight" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="bottomLeft" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="bottomRight" type="ST_RelationshipId"/>
|
||||
</xsd:schema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,570 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:vml"
|
||||
xmlns:pvml="urn:schemas-microsoft-com:office:powerpoint"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:w10="urn:schemas-microsoft-com:office:word"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="urn:schemas-microsoft-com:vml" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:office"
|
||||
schemaLocation="vml-officeDrawing.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
schemaLocation="wml.xsd"/>
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:word"
|
||||
schemaLocation="vml-wordprocessingDrawing.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
schemaLocation="shared-relationshipReference.xsd"/>
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:excel"
|
||||
schemaLocation="vml-spreadsheetDrawing.xsd"/>
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:powerpoint"
|
||||
schemaLocation="vml-presentationDrawing.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:attributeGroup name="AG_Id">
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Style">
|
||||
<xsd:attribute name="style" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Type">
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Adj">
|
||||
<xsd:attribute name="adj" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Path">
|
||||
<xsd:attribute name="path" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Fill">
|
||||
<xsd:attribute name="filled" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fillcolor" type="s:ST_ColorType" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Chromakey">
|
||||
<xsd:attribute name="chromakey" type="s:ST_ColorType" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Ext">
|
||||
<xsd:attribute name="ext" form="qualified" type="ST_Ext"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_CoreAttributes">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Style"/>
|
||||
<xsd:attribute name="href" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="target" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="class" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="title" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="alt" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="coordsize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="coordorigin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="wrapcoords" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="print" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_ShapeAttributes">
|
||||
<xsd:attributeGroup ref="AG_Chromakey"/>
|
||||
<xsd:attributeGroup ref="AG_Fill"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="stroked" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="strokecolor" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="strokeweight" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_OfficeCoreAttributes">
|
||||
<xsd:attribute ref="o:spid"/>
|
||||
<xsd:attribute ref="o:oned"/>
|
||||
<xsd:attribute ref="o:regroupid"/>
|
||||
<xsd:attribute ref="o:doubleclicknotify"/>
|
||||
<xsd:attribute ref="o:button"/>
|
||||
<xsd:attribute ref="o:userhidden"/>
|
||||
<xsd:attribute ref="o:bullet"/>
|
||||
<xsd:attribute ref="o:hr"/>
|
||||
<xsd:attribute ref="o:hrstd"/>
|
||||
<xsd:attribute ref="o:hrnoshade"/>
|
||||
<xsd:attribute ref="o:hrpct"/>
|
||||
<xsd:attribute ref="o:hralign"/>
|
||||
<xsd:attribute ref="o:allowincell"/>
|
||||
<xsd:attribute ref="o:allowoverlap"/>
|
||||
<xsd:attribute ref="o:userdrawn"/>
|
||||
<xsd:attribute ref="o:bordertopcolor"/>
|
||||
<xsd:attribute ref="o:borderleftcolor"/>
|
||||
<xsd:attribute ref="o:borderbottomcolor"/>
|
||||
<xsd:attribute ref="o:borderrightcolor"/>
|
||||
<xsd:attribute ref="o:dgmlayout"/>
|
||||
<xsd:attribute ref="o:dgmnodekind"/>
|
||||
<xsd:attribute ref="o:dgmlayoutmru"/>
|
||||
<xsd:attribute ref="o:insetmode"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_OfficeShapeAttributes">
|
||||
<xsd:attribute ref="o:spt"/>
|
||||
<xsd:attribute ref="o:connectortype"/>
|
||||
<xsd:attribute ref="o:bwmode"/>
|
||||
<xsd:attribute ref="o:bwpure"/>
|
||||
<xsd:attribute ref="o:bwnormal"/>
|
||||
<xsd:attribute ref="o:forcedash"/>
|
||||
<xsd:attribute ref="o:oleicon"/>
|
||||
<xsd:attribute ref="o:ole"/>
|
||||
<xsd:attribute ref="o:preferrelative"/>
|
||||
<xsd:attribute ref="o:cliptowrap"/>
|
||||
<xsd:attribute ref="o:clip"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_AllCoreAttributes">
|
||||
<xsd:attributeGroup ref="AG_CoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_OfficeCoreAttributes"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_AllShapeAttributes">
|
||||
<xsd:attributeGroup ref="AG_ShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_OfficeShapeAttributes"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_ImageAttributes">
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="cropleft" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="croptop" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="cropright" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="cropbottom" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="gain" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="blacklevel" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="gamma" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="grayscale" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="bilevel" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_StrokeAttributes">
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="weight" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="linestyle" type="ST_StrokeLineStyle" use="optional"/>
|
||||
<xsd:attribute name="miterlimit" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="joinstyle" type="ST_StrokeJoinStyle" use="optional"/>
|
||||
<xsd:attribute name="endcap" type="ST_StrokeEndCap" use="optional"/>
|
||||
<xsd:attribute name="dashstyle" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="filltype" type="ST_FillType" use="optional"/>
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imageaspect" type="ST_ImageAspect" use="optional"/>
|
||||
<xsd:attribute name="imagesize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imagealignshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="startarrow" type="ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="startarrowwidth" type="ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="startarrowlength" type="ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute name="endarrow" type="ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="endarrowwidth" type="ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="endarrowlength" type="ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute ref="o:href"/>
|
||||
<xsd:attribute ref="o:althref"/>
|
||||
<xsd:attribute ref="o:title"/>
|
||||
<xsd:attribute ref="o:forcedash"/>
|
||||
<xsd:attribute ref="r:id" use="optional"/>
|
||||
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute ref="o:relid"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:group name="EG_ShapeElements">
|
||||
<xsd:choice>
|
||||
<xsd:element ref="path"/>
|
||||
<xsd:element ref="formulas"/>
|
||||
<xsd:element ref="handles"/>
|
||||
<xsd:element ref="fill"/>
|
||||
<xsd:element ref="stroke"/>
|
||||
<xsd:element ref="shadow"/>
|
||||
<xsd:element ref="textbox"/>
|
||||
<xsd:element ref="textpath"/>
|
||||
<xsd:element ref="imagedata"/>
|
||||
<xsd:element ref="o:skew"/>
|
||||
<xsd:element ref="o:extrusion"/>
|
||||
<xsd:element ref="o:callout"/>
|
||||
<xsd:element ref="o:lock"/>
|
||||
<xsd:element ref="o:clippath"/>
|
||||
<xsd:element ref="o:signatureline"/>
|
||||
<xsd:element ref="w10:wrap"/>
|
||||
<xsd:element ref="w10:anchorlock"/>
|
||||
<xsd:element ref="w10:bordertop"/>
|
||||
<xsd:element ref="w10:borderbottom"/>
|
||||
<xsd:element ref="w10:borderleft"/>
|
||||
<xsd:element ref="w10:borderright"/>
|
||||
<xsd:element ref="x:ClientData" minOccurs="0"/>
|
||||
<xsd:element ref="pvml:textdata" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:element name="shape" type="CT_Shape"/>
|
||||
<xsd:element name="shapetype" type="CT_Shapetype"/>
|
||||
<xsd:element name="group" type="CT_Group"/>
|
||||
<xsd:element name="background" type="CT_Background"/>
|
||||
<xsd:complexType name="CT_Shape">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements"/>
|
||||
<xsd:element ref="o:ink"/>
|
||||
<xsd:element ref="pvml:iscomment"/>
|
||||
<xsd:element ref="o:equationxml"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Type"/>
|
||||
<xsd:attributeGroup ref="AG_Adj"/>
|
||||
<xsd:attributeGroup ref="AG_Path"/>
|
||||
<xsd:attribute ref="o:gfxdata"/>
|
||||
<xsd:attribute name="equationxml" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shapetype">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="o:complex" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Adj"/>
|
||||
<xsd:attributeGroup ref="AG_Path"/>
|
||||
<xsd:attribute ref="o:master"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Group">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements"/>
|
||||
<xsd:element ref="group"/>
|
||||
<xsd:element ref="shape"/>
|
||||
<xsd:element ref="shapetype"/>
|
||||
<xsd:element ref="arc"/>
|
||||
<xsd:element ref="curve"/>
|
||||
<xsd:element ref="image"/>
|
||||
<xsd:element ref="line"/>
|
||||
<xsd:element ref="oval"/>
|
||||
<xsd:element ref="polyline"/>
|
||||
<xsd:element ref="rect"/>
|
||||
<xsd:element ref="roundrect"/>
|
||||
<xsd:element ref="o:diagram"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Fill"/>
|
||||
<xsd:attribute name="editas" type="ST_EditAs" use="optional"/>
|
||||
<xsd:attribute ref="o:tableproperties"/>
|
||||
<xsd:attribute ref="o:tablelimits"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Background">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="fill" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Fill"/>
|
||||
<xsd:attribute ref="o:bwmode"/>
|
||||
<xsd:attribute ref="o:bwpure"/>
|
||||
<xsd:attribute ref="o:bwnormal"/>
|
||||
<xsd:attribute ref="o:targetscreensize"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="fill" type="CT_Fill"/>
|
||||
<xsd:element name="formulas" type="CT_Formulas"/>
|
||||
<xsd:element name="handles" type="CT_Handles"/>
|
||||
<xsd:element name="imagedata" type="CT_ImageData"/>
|
||||
<xsd:element name="path" type="CT_Path"/>
|
||||
<xsd:element name="textbox" type="CT_Textbox"/>
|
||||
<xsd:element name="shadow" type="CT_Shadow"/>
|
||||
<xsd:element name="stroke" type="CT_Stroke"/>
|
||||
<xsd:element name="textpath" type="CT_TextPath"/>
|
||||
<xsd:complexType name="CT_Fill">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="o:fill" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attribute name="type" type="ST_FillType" use="optional"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute ref="o:href"/>
|
||||
<xsd:attribute ref="o:althref"/>
|
||||
<xsd:attribute name="size" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="position" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="aspect" type="ST_ImageAspect" use="optional"/>
|
||||
<xsd:attribute name="colors" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="angle" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="alignshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="focus" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="focussize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="focusposition" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="method" type="ST_FillMethod" use="optional"/>
|
||||
<xsd:attribute ref="o:detectmouseclick"/>
|
||||
<xsd:attribute ref="o:title"/>
|
||||
<xsd:attribute ref="o:opacity2"/>
|
||||
<xsd:attribute name="recolor" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="rotate" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute ref="r:id" use="optional"/>
|
||||
<xsd:attribute ref="o:relid" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Formulas">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="f" type="CT_F" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_F">
|
||||
<xsd:attribute name="eqn" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Handles">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="h" type="CT_H" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_H">
|
||||
<xsd:attribute name="position" type="xsd:string"/>
|
||||
<xsd:attribute name="polar" type="xsd:string"/>
|
||||
<xsd:attribute name="map" type="xsd:string"/>
|
||||
<xsd:attribute name="invx" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="invy" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="switch" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:attribute name="xrange" type="xsd:string"/>
|
||||
<xsd:attribute name="yrange" type="xsd:string"/>
|
||||
<xsd:attribute name="radiusrange" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ImageData">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_ImageAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Chromakey"/>
|
||||
<xsd:attribute name="embosscolor" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="recolortarget" type="s:ST_ColorType"/>
|
||||
<xsd:attribute ref="o:href"/>
|
||||
<xsd:attribute ref="o:althref"/>
|
||||
<xsd:attribute ref="o:title"/>
|
||||
<xsd:attribute ref="o:oleid"/>
|
||||
<xsd:attribute ref="o:detectmouseclick"/>
|
||||
<xsd:attribute ref="o:movie"/>
|
||||
<xsd:attribute ref="o:relid"/>
|
||||
<xsd:attribute ref="r:id"/>
|
||||
<xsd:attribute ref="r:pict"/>
|
||||
<xsd:attribute ref="r:href"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Path">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attribute name="v" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="limo" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="textboxrect" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fillok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="strokeok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="shadowok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="arrowok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="gradientshapeok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="textpathok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="insetpenok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute ref="o:connecttype"/>
|
||||
<xsd:attribute ref="o:connectlocs"/>
|
||||
<xsd:attribute ref="o:connectangles"/>
|
||||
<xsd:attribute ref="o:extrusionok"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shadow">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="type" type="ST_ShadowType" use="optional"/>
|
||||
<xsd:attribute name="obscured" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="offset" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="offset2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="matrix" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Stroke">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="o:left" minOccurs="0"/>
|
||||
<xsd:element ref="o:top" minOccurs="0"/>
|
||||
<xsd:element ref="o:right" minOccurs="0"/>
|
||||
<xsd:element ref="o:bottom" minOccurs="0"/>
|
||||
<xsd:element ref="o:column" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_StrokeAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Textbox">
|
||||
<xsd:choice>
|
||||
<xsd:element ref="w:txbxContent" minOccurs="0"/>
|
||||
<xsd:any namespace="##local" processContents="skip"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Style"/>
|
||||
<xsd:attribute name="inset" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute ref="o:singleclick"/>
|
||||
<xsd:attribute ref="o:insetmode"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TextPath">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Style"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fitshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fitpath" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="trim" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="xscale" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="string" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="arc" type="CT_Arc"/>
|
||||
<xsd:element name="curve" type="CT_Curve"/>
|
||||
<xsd:element name="image" type="CT_Image"/>
|
||||
<xsd:element name="line" type="CT_Line"/>
|
||||
<xsd:element name="oval" type="CT_Oval"/>
|
||||
<xsd:element name="polyline" type="CT_PolyLine"/>
|
||||
<xsd:element name="rect" type="CT_Rect"/>
|
||||
<xsd:element name="roundrect" type="CT_RoundRect"/>
|
||||
<xsd:complexType name="CT_Arc">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="startAngle" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="endAngle" type="xsd:decimal" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Curve">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="from" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="control1" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="control2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="to" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Image">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_ImageAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Line">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="from" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="to" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Oval">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PolyLine">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements"/>
|
||||
<xsd:element ref="o:ink"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="points" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Rect">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RoundRect">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="arcsize" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Ext">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="view"/>
|
||||
<xsd:enumeration value="edit"/>
|
||||
<xsd:enumeration value="backwardCompatible"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FillType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="gradient"/>
|
||||
<xsd:enumeration value="gradientRadial"/>
|
||||
<xsd:enumeration value="tile"/>
|
||||
<xsd:enumeration value="pattern"/>
|
||||
<xsd:enumeration value="frame"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FillMethod">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="linear"/>
|
||||
<xsd:enumeration value="sigma"/>
|
||||
<xsd:enumeration value="any"/>
|
||||
<xsd:enumeration value="linear sigma"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ShadowType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="single"/>
|
||||
<xsd:enumeration value="double"/>
|
||||
<xsd:enumeration value="emboss"/>
|
||||
<xsd:enumeration value="perspective"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeLineStyle">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="single"/>
|
||||
<xsd:enumeration value="thinThin"/>
|
||||
<xsd:enumeration value="thinThick"/>
|
||||
<xsd:enumeration value="thickThin"/>
|
||||
<xsd:enumeration value="thickBetweenThin"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeJoinStyle">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="round"/>
|
||||
<xsd:enumeration value="bevel"/>
|
||||
<xsd:enumeration value="miter"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeEndCap">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="flat"/>
|
||||
<xsd:enumeration value="square"/>
|
||||
<xsd:enumeration value="round"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeArrowLength">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="short"/>
|
||||
<xsd:enumeration value="medium"/>
|
||||
<xsd:enumeration value="long"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeArrowWidth">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="narrow"/>
|
||||
<xsd:enumeration value="medium"/>
|
||||
<xsd:enumeration value="wide"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeArrowType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="block"/>
|
||||
<xsd:enumeration value="classic"/>
|
||||
<xsd:enumeration value="oval"/>
|
||||
<xsd:enumeration value="diamond"/>
|
||||
<xsd:enumeration value="open"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ImageAspect">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ignore"/>
|
||||
<xsd:enumeration value="atMost"/>
|
||||
<xsd:enumeration value="atLeast"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_EditAs">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="canvas"/>
|
||||
<xsd:enumeration value="orgchart"/>
|
||||
<xsd:enumeration value="radial"/>
|
||||
<xsd:enumeration value="cycle"/>
|
||||
<xsd:enumeration value="stacked"/>
|
||||
<xsd:enumeration value="venn"/>
|
||||
<xsd:enumeration value="bullseye"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
+509
@@ -0,0 +1,509 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:office" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:vml" schemaLocation="vml-main.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
schemaLocation="shared-relationshipReference.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:attribute name="bwmode" type="ST_BWMode"/>
|
||||
<xsd:attribute name="bwpure" type="ST_BWMode"/>
|
||||
<xsd:attribute name="bwnormal" type="ST_BWMode"/>
|
||||
<xsd:attribute name="targetscreensize" type="ST_ScreenSize"/>
|
||||
<xsd:attribute name="insetmode" type="ST_InsetMode" default="custom"/>
|
||||
<xsd:attribute name="spt" type="xsd:float"/>
|
||||
<xsd:attribute name="wrapcoords" type="xsd:string"/>
|
||||
<xsd:attribute name="oned" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="regroupid" type="xsd:integer"/>
|
||||
<xsd:attribute name="doubleclicknotify" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="connectortype" type="ST_ConnectorType" default="straight"/>
|
||||
<xsd:attribute name="button" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="userhidden" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="forcedash" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="oleicon" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="ole" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:attribute name="preferrelative" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="cliptowrap" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="clip" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="bullet" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hr" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hrstd" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hrnoshade" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hrpct" type="xsd:float"/>
|
||||
<xsd:attribute name="hralign" type="ST_HrAlign" default="left"/>
|
||||
<xsd:attribute name="allowincell" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="allowoverlap" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="userdrawn" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="bordertopcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="borderleftcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="borderbottomcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="borderrightcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="connecttype" type="ST_ConnectType"/>
|
||||
<xsd:attribute name="connectlocs" type="xsd:string"/>
|
||||
<xsd:attribute name="connectangles" type="xsd:string"/>
|
||||
<xsd:attribute name="master" type="xsd:string"/>
|
||||
<xsd:attribute name="extrusionok" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="href" type="xsd:string"/>
|
||||
<xsd:attribute name="althref" type="xsd:string"/>
|
||||
<xsd:attribute name="title" type="xsd:string"/>
|
||||
<xsd:attribute name="singleclick" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="oleid" type="xsd:float"/>
|
||||
<xsd:attribute name="detectmouseclick" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="movie" type="xsd:float"/>
|
||||
<xsd:attribute name="spid" type="xsd:string"/>
|
||||
<xsd:attribute name="opacity2" type="xsd:string"/>
|
||||
<xsd:attribute name="relid" type="r:ST_RelationshipId"/>
|
||||
<xsd:attribute name="dgmlayout" type="ST_DiagramLayout"/>
|
||||
<xsd:attribute name="dgmnodekind" type="xsd:integer"/>
|
||||
<xsd:attribute name="dgmlayoutmru" type="ST_DiagramLayout"/>
|
||||
<xsd:attribute name="gfxdata" type="xsd:base64Binary"/>
|
||||
<xsd:attribute name="tableproperties" type="xsd:string"/>
|
||||
<xsd:attribute name="tablelimits" type="xsd:string"/>
|
||||
<xsd:element name="shapedefaults" type="CT_ShapeDefaults"/>
|
||||
<xsd:element name="shapelayout" type="CT_ShapeLayout"/>
|
||||
<xsd:element name="signatureline" type="CT_SignatureLine"/>
|
||||
<xsd:element name="ink" type="CT_Ink"/>
|
||||
<xsd:element name="diagram" type="CT_Diagram"/>
|
||||
<xsd:element name="equationxml" type="CT_EquationXml"/>
|
||||
<xsd:complexType name="CT_ShapeDefaults">
|
||||
<xsd:all minOccurs="0">
|
||||
<xsd:element ref="v:fill" minOccurs="0"/>
|
||||
<xsd:element ref="v:stroke" minOccurs="0"/>
|
||||
<xsd:element ref="v:textbox" minOccurs="0"/>
|
||||
<xsd:element ref="v:shadow" minOccurs="0"/>
|
||||
<xsd:element ref="skew" minOccurs="0"/>
|
||||
<xsd:element ref="extrusion" minOccurs="0"/>
|
||||
<xsd:element ref="callout" minOccurs="0"/>
|
||||
<xsd:element ref="lock" minOccurs="0"/>
|
||||
<xsd:element name="colormru" minOccurs="0" type="CT_ColorMru"/>
|
||||
<xsd:element name="colormenu" minOccurs="0" type="CT_ColorMenu"/>
|
||||
</xsd:all>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="spidmax" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="style" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fill" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fillcolor" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="stroke" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="strokecolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="allowincell" form="qualified" type="s:ST_TrueFalse"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Ink">
|
||||
<xsd:sequence/>
|
||||
<xsd:attribute name="i" type="xsd:string"/>
|
||||
<xsd:attribute name="annotation" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="contentType" type="ST_ContentType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SignatureLine">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="issignatureline" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="id" type="s:ST_Guid"/>
|
||||
<xsd:attribute name="provid" type="s:ST_Guid"/>
|
||||
<xsd:attribute name="signinginstructionsset" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="allowcomments" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="showsigndate" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="suggestedsigner" type="xsd:string" form="qualified"/>
|
||||
<xsd:attribute name="suggestedsigner2" type="xsd:string" form="qualified"/>
|
||||
<xsd:attribute name="suggestedsigneremail" type="xsd:string" form="qualified"/>
|
||||
<xsd:attribute name="signinginstructions" type="xsd:string"/>
|
||||
<xsd:attribute name="addlxml" type="xsd:string"/>
|
||||
<xsd:attribute name="sigprovurl" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ShapeLayout">
|
||||
<xsd:all>
|
||||
<xsd:element name="idmap" type="CT_IdMap" minOccurs="0"/>
|
||||
<xsd:element name="regrouptable" type="CT_RegroupTable" minOccurs="0"/>
|
||||
<xsd:element name="rules" type="CT_Rules" minOccurs="0"/>
|
||||
</xsd:all>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_IdMap">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="data" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RegroupTable">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="entry" type="CT_Entry" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Entry">
|
||||
<xsd:attribute name="new" type="xsd:int" use="optional"/>
|
||||
<xsd:attribute name="old" type="xsd:int" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Rules">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="r" type="CT_R" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_R">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="proxy" type="CT_Proxy" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="type" type="ST_RType" use="optional"/>
|
||||
<xsd:attribute name="how" type="ST_How" use="optional"/>
|
||||
<xsd:attribute name="idref" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Proxy">
|
||||
<xsd:attribute name="start" type="s:ST_TrueFalseBlank" use="optional" default="false"/>
|
||||
<xsd:attribute name="end" type="s:ST_TrueFalseBlank" use="optional" default="false"/>
|
||||
<xsd:attribute name="idref" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="connectloc" type="xsd:int" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Diagram">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="relationtable" type="CT_RelationTable" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="dgmstyle" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="autoformat" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="reverse" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="autolayout" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="dgmscalex" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="dgmscaley" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="dgmfontsize" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="constrainbounds" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="dgmbasetextscale" type="xsd:integer" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_EquationXml">
|
||||
<xsd:sequence>
|
||||
<xsd:any namespace="##any"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="contentType" type="ST_AlternateMathContentType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_AlternateMathContentType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_RelationTable">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="rel" type="CT_Relation" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Relation">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="idsrc" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="iddest" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="idcntr" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ColorMru">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="colors" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ColorMenu">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="strokecolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="fillcolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="shadowcolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="extrusioncolor" type="s:ST_ColorType"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="skew" type="CT_Skew"/>
|
||||
<xsd:element name="extrusion" type="CT_Extrusion"/>
|
||||
<xsd:element name="callout" type="CT_Callout"/>
|
||||
<xsd:element name="lock" type="CT_Lock"/>
|
||||
<xsd:element name="OLEObject" type="CT_OLEObject"/>
|
||||
<xsd:element name="complex" type="CT_Complex"/>
|
||||
<xsd:element name="left" type="CT_StrokeChild"/>
|
||||
<xsd:element name="top" type="CT_StrokeChild"/>
|
||||
<xsd:element name="right" type="CT_StrokeChild"/>
|
||||
<xsd:element name="bottom" type="CT_StrokeChild"/>
|
||||
<xsd:element name="column" type="CT_StrokeChild"/>
|
||||
<xsd:element name="clippath" type="CT_ClipPath"/>
|
||||
<xsd:element name="fill" type="CT_Fill"/>
|
||||
<xsd:complexType name="CT_Skew">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="offset" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="matrix" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Extrusion">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="type" type="ST_ExtrusionType" default="parallel" use="optional"/>
|
||||
<xsd:attribute name="render" type="ST_ExtrusionRender" default="solid" use="optional"/>
|
||||
<xsd:attribute name="viewpointorigin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="viewpoint" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="plane" type="ST_ExtrusionPlane" default="XY" use="optional"/>
|
||||
<xsd:attribute name="skewangle" type="xsd:float" use="optional"/>
|
||||
<xsd:attribute name="skewamt" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="foredepth" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="backdepth" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="orientation" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="orientationangle" type="xsd:float" use="optional"/>
|
||||
<xsd:attribute name="lockrotationcenter" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="autorotationcenter" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="rotationcenter" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="rotationangle" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="colormode" type="ST_ColorMode" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="shininess" type="xsd:float" use="optional"/>
|
||||
<xsd:attribute name="specularity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="diffusity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="metal" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="edge" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="facet" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightface" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="brightness" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightposition" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightlevel" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightharsh" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="lightposition2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightlevel2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightharsh2" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Callout">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="gap" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="angle" type="ST_Angle" use="optional"/>
|
||||
<xsd:attribute name="dropauto" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="drop" type="ST_CalloutDrop" use="optional"/>
|
||||
<xsd:attribute name="distance" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lengthspecified" type="s:ST_TrueFalse" default="f" use="optional"/>
|
||||
<xsd:attribute name="length" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="accentbar" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="textborder" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="minusx" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="minusy" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Lock">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="position" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="selection" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="grouping" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="ungrouping" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="rotation" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="cropping" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="verticies" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="adjusthandles" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="text" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="aspectratio" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="shapetype" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OLEObject">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="LinkType" type="ST_OLELinkType" minOccurs="0"/>
|
||||
<xsd:element name="LockedField" type="s:ST_TrueFalseBlank" minOccurs="0"/>
|
||||
<xsd:element name="FieldCodes" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="Type" type="ST_OLEType" use="optional"/>
|
||||
<xsd:attribute name="ProgID" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="ShapeID" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="DrawAspect" type="ST_OLEDrawAspect" use="optional"/>
|
||||
<xsd:attribute name="ObjectID" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute ref="r:id" use="optional"/>
|
||||
<xsd:attribute name="UpdateMode" type="ST_OLEUpdateMode" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Complex">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_StrokeChild">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="weight" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="linestyle" type="v:ST_StrokeLineStyle" use="optional"/>
|
||||
<xsd:attribute name="miterlimit" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="joinstyle" type="v:ST_StrokeJoinStyle" use="optional"/>
|
||||
<xsd:attribute name="endcap" type="v:ST_StrokeEndCap" use="optional"/>
|
||||
<xsd:attribute name="dashstyle" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="filltype" type="v:ST_FillType" use="optional"/>
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imageaspect" type="v:ST_ImageAspect" use="optional"/>
|
||||
<xsd:attribute name="imagesize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imagealignshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="startarrow" type="v:ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="startarrowwidth" type="v:ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="startarrowlength" type="v:ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute name="endarrow" type="v:ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="endarrowwidth" type="v:ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="endarrowlength" type="v:ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute ref="href"/>
|
||||
<xsd:attribute ref="althref"/>
|
||||
<xsd:attribute ref="title"/>
|
||||
<xsd:attribute ref="forcedash"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ClipPath">
|
||||
<xsd:attribute name="v" type="xsd:string" use="required" form="qualified"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Fill">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="type" type="ST_FillType"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_RType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="arc"/>
|
||||
<xsd:enumeration value="callout"/>
|
||||
<xsd:enumeration value="connector"/>
|
||||
<xsd:enumeration value="align"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_How">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="middle"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_BWMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="color"/>
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="grayScale"/>
|
||||
<xsd:enumeration value="lightGrayscale"/>
|
||||
<xsd:enumeration value="inverseGray"/>
|
||||
<xsd:enumeration value="grayOutline"/>
|
||||
<xsd:enumeration value="highContrast"/>
|
||||
<xsd:enumeration value="black"/>
|
||||
<xsd:enumeration value="white"/>
|
||||
<xsd:enumeration value="hide"/>
|
||||
<xsd:enumeration value="undrawn"/>
|
||||
<xsd:enumeration value="blackTextAndLines"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ScreenSize">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="544,376"/>
|
||||
<xsd:enumeration value="640,480"/>
|
||||
<xsd:enumeration value="720,512"/>
|
||||
<xsd:enumeration value="800,600"/>
|
||||
<xsd:enumeration value="1024,768"/>
|
||||
<xsd:enumeration value="1152,862"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_InsetMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ColorMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ContentType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_DiagramLayout">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:enumeration value="0"/>
|
||||
<xsd:enumeration value="1"/>
|
||||
<xsd:enumeration value="2"/>
|
||||
<xsd:enumeration value="3"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ExtrusionType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="perspective"/>
|
||||
<xsd:enumeration value="parallel"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ExtrusionRender">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="wireFrame"/>
|
||||
<xsd:enumeration value="boundingCube"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ExtrusionPlane">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="XY"/>
|
||||
<xsd:enumeration value="ZX"/>
|
||||
<xsd:enumeration value="YZ"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Angle">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="any"/>
|
||||
<xsd:enumeration value="30"/>
|
||||
<xsd:enumeration value="45"/>
|
||||
<xsd:enumeration value="60"/>
|
||||
<xsd:enumeration value="90"/>
|
||||
<xsd:enumeration value="auto"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CalloutDrop">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CalloutPlacement">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="user"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ConnectorType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="straight"/>
|
||||
<xsd:enumeration value="elbow"/>
|
||||
<xsd:enumeration value="curved"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_HrAlign">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ConnectType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="rect"/>
|
||||
<xsd:enumeration value="segments"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLELinkType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLEType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Embed"/>
|
||||
<xsd:enumeration value="Link"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLEDrawAspect">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Content"/>
|
||||
<xsd:enumeration value="Icon"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLEUpdateMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Always"/>
|
||||
<xsd:enumeration value="OnCall"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FillType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="gradientCenter"/>
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="pattern"/>
|
||||
<xsd:enumeration value="tile"/>
|
||||
<xsd:enumeration value="frame"/>
|
||||
<xsd:enumeration value="gradientUnscaled"/>
|
||||
<xsd:enumeration value="gradientRadial"/>
|
||||
<xsd:enumeration value="gradient"/>
|
||||
<xsd:enumeration value="background"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:powerpoint"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:powerpoint" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:element name="iscomment" type="CT_Empty"/>
|
||||
<xsd:element name="textdata" type="CT_Rel"/>
|
||||
<xsd:complexType name="CT_Empty"/>
|
||||
<xsd:complexType name="CT_Rel">
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:excel" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:element name="ClientData" type="CT_ClientData"/>
|
||||
<xsd:complexType name="CT_ClientData">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="MoveWithCells" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="SizeWithCells" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Anchor" type="xsd:string"/>
|
||||
<xsd:element name="Locked" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="DefaultSize" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="PrintObject" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Disabled" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoFill" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoLine" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoPict" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FmlaMacro" type="xsd:string"/>
|
||||
<xsd:element name="TextHAlign" type="xsd:string"/>
|
||||
<xsd:element name="TextVAlign" type="xsd:string"/>
|
||||
<xsd:element name="LockText" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="JustLastX" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="SecretEdit" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Default" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Help" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Cancel" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Dismiss" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Accel" type="xsd:integer"/>
|
||||
<xsd:element name="Accel2" type="xsd:integer"/>
|
||||
<xsd:element name="Row" type="xsd:integer"/>
|
||||
<xsd:element name="Column" type="xsd:integer"/>
|
||||
<xsd:element name="Visible" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="RowHidden" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="ColHidden" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="VTEdit" type="xsd:integer"/>
|
||||
<xsd:element name="MultiLine" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="VScroll" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="ValidIds" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FmlaRange" type="xsd:string"/>
|
||||
<xsd:element name="WidthMin" type="xsd:integer"/>
|
||||
<xsd:element name="Sel" type="xsd:integer"/>
|
||||
<xsd:element name="NoThreeD2" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="SelType" type="xsd:string"/>
|
||||
<xsd:element name="MultiSel" type="xsd:string"/>
|
||||
<xsd:element name="LCT" type="xsd:string"/>
|
||||
<xsd:element name="ListItem" type="xsd:string"/>
|
||||
<xsd:element name="DropStyle" type="xsd:string"/>
|
||||
<xsd:element name="Colored" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="DropLines" type="xsd:integer"/>
|
||||
<xsd:element name="Checked" type="xsd:integer"/>
|
||||
<xsd:element name="FmlaLink" type="xsd:string"/>
|
||||
<xsd:element name="FmlaPict" type="xsd:string"/>
|
||||
<xsd:element name="NoThreeD" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FirstButton" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FmlaGroup" type="xsd:string"/>
|
||||
<xsd:element name="Val" type="xsd:integer"/>
|
||||
<xsd:element name="Min" type="xsd:integer"/>
|
||||
<xsd:element name="Max" type="xsd:integer"/>
|
||||
<xsd:element name="Inc" type="xsd:integer"/>
|
||||
<xsd:element name="Page" type="xsd:integer"/>
|
||||
<xsd:element name="Horiz" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Dx" type="xsd:integer"/>
|
||||
<xsd:element name="MapOCX" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="CF" type="ST_CF"/>
|
||||
<xsd:element name="Camera" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="RecalcAlways" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoScale" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="DDE" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="UIObj" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="ScriptText" type="xsd:string"/>
|
||||
<xsd:element name="ScriptExtended" type="xsd:string"/>
|
||||
<xsd:element name="ScriptLanguage" type="xsd:nonNegativeInteger"/>
|
||||
<xsd:element name="ScriptLocation" type="xsd:nonNegativeInteger"/>
|
||||
<xsd:element name="FmlaTxbx" type="xsd:string"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="ObjectType" type="ST_ObjectType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_CF">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ObjectType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Button"/>
|
||||
<xsd:enumeration value="Checkbox"/>
|
||||
<xsd:enumeration value="Dialog"/>
|
||||
<xsd:enumeration value="Drop"/>
|
||||
<xsd:enumeration value="Edit"/>
|
||||
<xsd:enumeration value="GBox"/>
|
||||
<xsd:enumeration value="Label"/>
|
||||
<xsd:enumeration value="LineA"/>
|
||||
<xsd:enumeration value="List"/>
|
||||
<xsd:enumeration value="Movie"/>
|
||||
<xsd:enumeration value="Note"/>
|
||||
<xsd:enumeration value="Pict"/>
|
||||
<xsd:enumeration value="Radio"/>
|
||||
<xsd:enumeration value="RectA"/>
|
||||
<xsd:enumeration value="Scroll"/>
|
||||
<xsd:enumeration value="Spin"/>
|
||||
<xsd:enumeration value="Shape"/>
|
||||
<xsd:enumeration value="Group"/>
|
||||
<xsd:enumeration value="Rect"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:word"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:word" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:element name="bordertop" type="CT_Border"/>
|
||||
<xsd:element name="borderleft" type="CT_Border"/>
|
||||
<xsd:element name="borderright" type="CT_Border"/>
|
||||
<xsd:element name="borderbottom" type="CT_Border"/>
|
||||
<xsd:complexType name="CT_Border">
|
||||
<xsd:attribute name="type" type="ST_BorderType" use="optional"/>
|
||||
<xsd:attribute name="width" type="xsd:positiveInteger" use="optional"/>
|
||||
<xsd:attribute name="shadow" type="ST_BorderShadow" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="wrap" type="CT_Wrap"/>
|
||||
<xsd:complexType name="CT_Wrap">
|
||||
<xsd:attribute name="type" type="ST_WrapType" use="optional"/>
|
||||
<xsd:attribute name="side" type="ST_WrapSide" use="optional"/>
|
||||
<xsd:attribute name="anchorx" type="ST_HorizontalAnchor" use="optional"/>
|
||||
<xsd:attribute name="anchory" type="ST_VerticalAnchor" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="anchorlock" type="CT_AnchorLock"/>
|
||||
<xsd:complexType name="CT_AnchorLock"/>
|
||||
<xsd:simpleType name="ST_BorderType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="single"/>
|
||||
<xsd:enumeration value="thick"/>
|
||||
<xsd:enumeration value="double"/>
|
||||
<xsd:enumeration value="hairline"/>
|
||||
<xsd:enumeration value="dot"/>
|
||||
<xsd:enumeration value="dash"/>
|
||||
<xsd:enumeration value="dotDash"/>
|
||||
<xsd:enumeration value="dashDotDot"/>
|
||||
<xsd:enumeration value="triple"/>
|
||||
<xsd:enumeration value="thinThickSmall"/>
|
||||
<xsd:enumeration value="thickThinSmall"/>
|
||||
<xsd:enumeration value="thickBetweenThinSmall"/>
|
||||
<xsd:enumeration value="thinThick"/>
|
||||
<xsd:enumeration value="thickThin"/>
|
||||
<xsd:enumeration value="thickBetweenThin"/>
|
||||
<xsd:enumeration value="thinThickLarge"/>
|
||||
<xsd:enumeration value="thickThinLarge"/>
|
||||
<xsd:enumeration value="thickBetweenThinLarge"/>
|
||||
<xsd:enumeration value="wave"/>
|
||||
<xsd:enumeration value="doubleWave"/>
|
||||
<xsd:enumeration value="dashedSmall"/>
|
||||
<xsd:enumeration value="dashDotStroked"/>
|
||||
<xsd:enumeration value="threeDEmboss"/>
|
||||
<xsd:enumeration value="threeDEngrave"/>
|
||||
<xsd:enumeration value="HTMLOutset"/>
|
||||
<xsd:enumeration value="HTMLInset"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_BorderShadow">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="f"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_WrapType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="topAndBottom"/>
|
||||
<xsd:enumeration value="square"/>
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="tight"/>
|
||||
<xsd:enumeration value="through"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_WrapSide">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="both"/>
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="largest"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_HorizontalAnchor">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="text"/>
|
||||
<xsd:enumeration value="char"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_VerticalAnchor">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="text"/>
|
||||
<xsd:enumeration value="line"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
<?xml version='1.0'?>
|
||||
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
See http://www.w3.org/XML/1998/namespace.html and
|
||||
http://www.w3.org/TR/REC-xml for information about this namespace.
|
||||
|
||||
This schema document describes the XML namespace, in a form
|
||||
suitable for import by other schema documents.
|
||||
|
||||
Note that local names in this namespace are intended to be defined
|
||||
only by the World Wide Web Consortium or its subgroups. The
|
||||
following names are currently defined in this namespace and should
|
||||
not be used with conflicting semantics by any Working Group,
|
||||
specification, or document instance:
|
||||
|
||||
base (as an attribute name): denotes an attribute whose value
|
||||
provides a URI to be used as the base for interpreting any
|
||||
relative URIs in the scope of the element on which it
|
||||
appears; its value is inherited. This name is reserved
|
||||
by virtue of its definition in the XML Base specification.
|
||||
|
||||
lang (as an attribute name): denotes an attribute whose value
|
||||
is a language code for the natural language of the content of
|
||||
any element; its value is inherited. This name is reserved
|
||||
by virtue of its definition in the XML specification.
|
||||
|
||||
space (as an attribute name): denotes an attribute whose
|
||||
value is a keyword indicating what whitespace processing
|
||||
discipline is intended for the content of the element; its
|
||||
value is inherited. This name is reserved by virtue of its
|
||||
definition in the XML specification.
|
||||
|
||||
Father (in any context at all): denotes Jon Bosak, the chair of
|
||||
the original XML Working Group. This name is reserved by
|
||||
the following decision of the W3C XML Plenary and
|
||||
XML Coordination groups:
|
||||
|
||||
In appreciation for his vision, leadership and dedication
|
||||
the W3C XML Plenary on this 10th day of February, 2000
|
||||
reserves for Jon Bosak in perpetuity the XML name
|
||||
xml:Father
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>This schema defines attributes and an attribute group
|
||||
suitable for use by
|
||||
schemas wishing to allow xml:base, xml:lang or xml:space attributes
|
||||
on elements they define.
|
||||
|
||||
To enable this, such a schema must import this schema
|
||||
for the XML namespace, e.g. as follows:
|
||||
<schema . . .>
|
||||
. . .
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
|
||||
|
||||
Subsequently, qualified reference to any of the attributes
|
||||
or the group defined below will have the desired effect, e.g.
|
||||
|
||||
<type . . .>
|
||||
. . .
|
||||
<attributeGroup ref="xml:specialAttrs"/>
|
||||
|
||||
will define a type which will schema-validate an instance
|
||||
element with any of those attributes</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>In keeping with the XML Schema WG's standard versioning
|
||||
policy, this schema document will persist at
|
||||
http://www.w3.org/2001/03/xml.xsd.
|
||||
At the date of issue it can also be found at
|
||||
http://www.w3.org/2001/xml.xsd.
|
||||
The schema document at that URI may however change in the future,
|
||||
in order to remain compatible with the latest version of XML Schema
|
||||
itself. In other words, if the XML Schema namespace changes, the version
|
||||
of this document at
|
||||
http://www.w3.org/2001/xml.xsd will change
|
||||
accordingly; the version at
|
||||
http://www.w3.org/2001/03/xml.xsd will not change.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:attribute name="lang" type="xs:language">
|
||||
<xs:annotation>
|
||||
<xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter
|
||||
codes as the enumerated possible values . . .</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attribute name="space" default="preserve">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:NCName">
|
||||
<xs:enumeration value="default"/>
|
||||
<xs:enumeration value="preserve"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attribute name="base" type="xs:anyURI">
|
||||
<xs:annotation>
|
||||
<xs:documentation>See http://www.w3.org/TR/xmlbase/ for
|
||||
information about this attribute.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attributeGroup name="specialAttrs">
|
||||
<xs:attribute ref="xml:base"/>
|
||||
<xs:attribute ref="xml:lang"/>
|
||||
<xs:attribute ref="xml:space"/>
|
||||
</xs:attributeGroup>
|
||||
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xs:schema xmlns="http://schemas.openxmlformats.org/package/2006/content-types"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://schemas.openxmlformats.org/package/2006/content-types"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
|
||||
|
||||
<xs:element name="Types" type="CT_Types"/>
|
||||
<xs:element name="Default" type="CT_Default"/>
|
||||
<xs:element name="Override" type="CT_Override"/>
|
||||
|
||||
<xs:complexType name="CT_Types">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="Default"/>
|
||||
<xs:element ref="Override"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Default">
|
||||
<xs:attribute name="Extension" type="ST_Extension" use="required"/>
|
||||
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Override">
|
||||
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
|
||||
<xs:attribute name="PartName" type="xs:anyURI" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="ST_ContentType">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
value="(((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+))/((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+))((\s+)*;(\s+)*(((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+))=((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+)|("(([\p{IsLatin-1Supplement}\p{IsBasicLatin}-[\p{Cc}"\n\r]]|(\s+))|(\\[\p{IsBasicLatin}]))*"))))*)"
|
||||
/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="ST_Extension">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
value="([!$&'\(\)\*\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\-_~])+"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:schema>
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema targetNamespace="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
||||
xmlns="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/" elementFormDefault="qualified" blockDefault="#all">
|
||||
|
||||
<xs:import namespace="http://purl.org/dc/elements/1.1/"
|
||||
schemaLocation="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd"/>
|
||||
<xs:import namespace="http://purl.org/dc/terms/"
|
||||
schemaLocation="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd"/>
|
||||
<xs:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
|
||||
<xs:element name="coreProperties" type="CT_CoreProperties"/>
|
||||
|
||||
<xs:complexType name="CT_CoreProperties">
|
||||
<xs:all>
|
||||
<xs:element name="category" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element name="contentStatus" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element ref="dcterms:created" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:creator" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:description" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:identifier" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="keywords" minOccurs="0" maxOccurs="1" type="CT_Keywords"/>
|
||||
<xs:element ref="dc:language" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="lastModifiedBy" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element name="lastPrinted" minOccurs="0" maxOccurs="1" type="xs:dateTime"/>
|
||||
<xs:element ref="dcterms:modified" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="revision" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element ref="dc:subject" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:title" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Keywords" mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="value" minOccurs="0" maxOccurs="unbounded" type="CT_Keyword"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute ref="xml:lang" use="optional"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Keyword">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute ref="xml:lang" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://schemas.openxmlformats.org/package/2006/digital-signature"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://schemas.openxmlformats.org/package/2006/digital-signature"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
|
||||
|
||||
<xsd:element name="SignatureTime" type="CT_SignatureTime"/>
|
||||
<xsd:element name="RelationshipReference" type="CT_RelationshipReference"/>
|
||||
<xsd:element name="RelationshipsGroupReference" type="CT_RelationshipsGroupReference"/>
|
||||
|
||||
<xsd:complexType name="CT_SignatureTime">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Format" type="ST_Format"/>
|
||||
<xsd:element name="Value" type="ST_Value"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CT_RelationshipReference">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="SourceId" type="xsd:string" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CT_RelationshipsGroupReference">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="SourceType" type="xsd:anyURI" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="ST_Format">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern
|
||||
value="(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)"
|
||||
/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="ST_Value">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern
|
||||
value="(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\.[0-9])(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))"
|
||||
/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema xmlns="http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
|
||||
|
||||
<xsd:element name="Relationships" type="CT_Relationships"/>
|
||||
<xsd:element name="Relationship" type="CT_Relationship"/>
|
||||
|
||||
<xsd:complexType name="CT_Relationships">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="Relationship" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CT_Relationship">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="TargetMode" type="ST_TargetMode" use="optional"/>
|
||||
<xsd:attribute name="Target" type="xsd:anyURI" use="required"/>
|
||||
<xsd:attribute name="Type" type="xsd:anyURI" use="required"/>
|
||||
<xsd:attribute name="Id" type="xsd:ID" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="ST_TargetMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="External"/>
|
||||
<xsd:enumeration value="Internal"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
attributeFormDefault="unqualified" elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!--
|
||||
This XSD is a modified version of the one found at:
|
||||
https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd
|
||||
|
||||
This XSD has 2 objectives:
|
||||
|
||||
1. round tripping @mc:Ignorable
|
||||
|
||||
<w:document
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
mc:Ignorable="w14 w15 wp14">
|
||||
|
||||
2. enabling AlternateContent to be manipulated in certain elements
|
||||
(in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)
|
||||
|
||||
See further ECMA-376, 4th Edition, Office Open XML File Formats
|
||||
Part 3 : Markup Compatibility and Extensibility
|
||||
-->
|
||||
|
||||
<!-- Objective 1 -->
|
||||
<xsd:attribute name="Ignorable" type="xsd:string" />
|
||||
|
||||
<!-- Objective 2 -->
|
||||
<xsd:attribute name="MustUnderstand" type="xsd:string" />
|
||||
<xsd:attribute name="ProcessContent" type="xsd:string" />
|
||||
|
||||
<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a
|
||||
Fallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice
|
||||
elements. -->
|
||||
<xsd:element name="AlternateContent">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Choice" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:any minOccurs="0" maxOccurs="unbounded"
|
||||
processContents="strict">
|
||||
</xsd:any>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="Requires" type="xsd:string" use="required" />
|
||||
<xsd:attribute ref="mc:Ignorable" use="optional" />
|
||||
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
|
||||
<xsd:attribute ref="mc:ProcessContent" use="optional" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="Fallback" minOccurs="0" maxOccurs="1">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:any minOccurs="0" maxOccurs="unbounded"
|
||||
processContents="strict">
|
||||
</xsd:any>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute ref="mc:Ignorable" use="optional" />
|
||||
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
|
||||
<xsd:attribute ref="mc:ProcessContent" use="optional" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<!-- AlternateContent elements might include the attributes Ignorable,
|
||||
MustUnderstand and ProcessContent described in this Part of ECMA-376. These
|
||||
attributes’ qualified names shall be prefixed when associated with an AlternateContent
|
||||
element. -->
|
||||
<xsd:attribute ref="mc:Ignorable" use="optional" />
|
||||
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
|
||||
<xsd:attribute ref="mc:ProcessContent" use="optional" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,560 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns="http://schemas.microsoft.com/office/word/2010/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2010/wordml">
|
||||
<!-- <xsd:import id="rel" namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships" schemaLocation="orel.xsd"/> -->
|
||||
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<!-- <xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main" schemaLocation="oartbasetypes.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main" schemaLocation="oartsplineproperties.xsd"/> -->
|
||||
<xsd:complexType name="CT_LongHexNumber">
|
||||
<xsd:attribute name="val" type="w:ST_LongHexNumber" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_OnOff">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
<xsd:enumeration value="0"/>
|
||||
<xsd:enumeration value="1"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_OnOff">
|
||||
<xsd:attribute name="val" type="ST_OnOff"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="docId" type="CT_LongHexNumber"/>
|
||||
<xsd:element name="conflictMode" type="CT_OnOff"/>
|
||||
<xsd:attributeGroup name="AG_Parids">
|
||||
<xsd:attribute name="paraId" type="w:ST_LongHexNumber"/>
|
||||
<xsd:attribute name="textId" type="w:ST_LongHexNumber"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attribute name="anchorId" type="w:ST_LongHexNumber"/>
|
||||
<xsd:attribute name="noSpellErr" type="ST_OnOff"/>
|
||||
<xsd:element name="customXmlConflictInsRangeStart" type="w:CT_TrackChange"/>
|
||||
<xsd:element name="customXmlConflictInsRangeEnd" type="w:CT_Markup"/>
|
||||
<xsd:element name="customXmlConflictDelRangeStart" type="w:CT_TrackChange"/>
|
||||
<xsd:element name="customXmlConflictDelRangeEnd" type="w:CT_Markup"/>
|
||||
<xsd:group name="EG_RunLevelConflicts">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="conflictIns" type="w:CT_RunTrackChange" minOccurs="0"/>
|
||||
<xsd:element name="conflictDel" type="w:CT_RunTrackChange" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:group name="EG_Conflicts">
|
||||
<xsd:choice>
|
||||
<xsd:element name="conflictIns" type="w:CT_TrackChange" minOccurs="0"/>
|
||||
<xsd:element name="conflictDel" type="w:CT_TrackChange" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Percentage">
|
||||
<xsd:attribute name="val" type="a:ST_Percentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PositiveFixedPercentage">
|
||||
<xsd:attribute name="val" type="a:ST_PositiveFixedPercentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PositivePercentage">
|
||||
<xsd:attribute name="val" type="a:ST_PositivePercentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_SchemeColorVal">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="bg1"/>
|
||||
<xsd:enumeration value="tx1"/>
|
||||
<xsd:enumeration value="bg2"/>
|
||||
<xsd:enumeration value="tx2"/>
|
||||
<xsd:enumeration value="accent1"/>
|
||||
<xsd:enumeration value="accent2"/>
|
||||
<xsd:enumeration value="accent3"/>
|
||||
<xsd:enumeration value="accent4"/>
|
||||
<xsd:enumeration value="accent5"/>
|
||||
<xsd:enumeration value="accent6"/>
|
||||
<xsd:enumeration value="hlink"/>
|
||||
<xsd:enumeration value="folHlink"/>
|
||||
<xsd:enumeration value="dk1"/>
|
||||
<xsd:enumeration value="lt1"/>
|
||||
<xsd:enumeration value="dk2"/>
|
||||
<xsd:enumeration value="lt2"/>
|
||||
<xsd:enumeration value="phClr"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RectAlignment">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="tl"/>
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="tr"/>
|
||||
<xsd:enumeration value="l"/>
|
||||
<xsd:enumeration value="ctr"/>
|
||||
<xsd:enumeration value="r"/>
|
||||
<xsd:enumeration value="bl"/>
|
||||
<xsd:enumeration value="b"/>
|
||||
<xsd:enumeration value="br"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PathShadeType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="shape"/>
|
||||
<xsd:enumeration value="circle"/>
|
||||
<xsd:enumeration value="rect"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_LineCap">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="rnd"/>
|
||||
<xsd:enumeration value="sq"/>
|
||||
<xsd:enumeration value="flat"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PresetLineDashVal">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="dot"/>
|
||||
<xsd:enumeration value="sysDot"/>
|
||||
<xsd:enumeration value="dash"/>
|
||||
<xsd:enumeration value="sysDash"/>
|
||||
<xsd:enumeration value="lgDash"/>
|
||||
<xsd:enumeration value="dashDot"/>
|
||||
<xsd:enumeration value="sysDashDot"/>
|
||||
<xsd:enumeration value="lgDashDot"/>
|
||||
<xsd:enumeration value="lgDashDotDot"/>
|
||||
<xsd:enumeration value="sysDashDotDot"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PenAlignment">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ctr"/>
|
||||
<xsd:enumeration value="in"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CompoundLine">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="sng"/>
|
||||
<xsd:enumeration value="dbl"/>
|
||||
<xsd:enumeration value="thickThin"/>
|
||||
<xsd:enumeration value="thinThick"/>
|
||||
<xsd:enumeration value="tri"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_RelativeRect">
|
||||
<xsd:attribute name="l" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="t" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="r" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="b" use="optional" type="a:ST_Percentage"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ColorTransform">
|
||||
<xsd:choice>
|
||||
<xsd:element name="tint" type="CT_PositiveFixedPercentage"/>
|
||||
<xsd:element name="shade" type="CT_PositiveFixedPercentage"/>
|
||||
<xsd:element name="alpha" type="CT_PositiveFixedPercentage"/>
|
||||
<xsd:element name="hueMod" type="CT_PositivePercentage"/>
|
||||
<xsd:element name="sat" type="CT_Percentage"/>
|
||||
<xsd:element name="satOff" type="CT_Percentage"/>
|
||||
<xsd:element name="satMod" type="CT_Percentage"/>
|
||||
<xsd:element name="lum" type="CT_Percentage"/>
|
||||
<xsd:element name="lumOff" type="CT_Percentage"/>
|
||||
<xsd:element name="lumMod" type="CT_Percentage"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_SRgbColor">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorTransform" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="val" type="s:ST_HexColorRGB" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SchemeColor">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorTransform" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="val" type="ST_SchemeColorVal" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ColorChoice">
|
||||
<xsd:choice>
|
||||
<xsd:element name="srgbClr" type="CT_SRgbColor"/>
|
||||
<xsd:element name="schemeClr" type="CT_SchemeColor"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Color">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GradientStop">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="pos" type="a:ST_PositiveFixedPercentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GradientStopList">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="gs" type="CT_GradientStop" minOccurs="2" maxOccurs="10"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LinearShadeProperties">
|
||||
<xsd:attribute name="ang" type="a:ST_PositiveFixedAngle" use="optional"/>
|
||||
<xsd:attribute name="scaled" type="ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PathShadeProperties">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="fillToRect" type="CT_RelativeRect" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="path" type="ST_PathShadeType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ShadeProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="lin" type="CT_LinearShadeProperties"/>
|
||||
<xsd:element name="path" type="CT_PathShadeProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_SolidColorFillProperties">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GradientFillProperties">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="gsLst" type="CT_GradientStopList" minOccurs="0"/>
|
||||
<xsd:group ref="EG_ShadeProperties" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_FillProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="noFill" type="w:CT_Empty"/>
|
||||
<xsd:element name="solidFill" type="CT_SolidColorFillProperties"/>
|
||||
<xsd:element name="gradFill" type="CT_GradientFillProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_PresetLineDashProperties">
|
||||
<xsd:attribute name="val" type="ST_PresetLineDashVal" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_LineDashProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="prstDash" type="CT_PresetLineDashProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_LineJoinMiterProperties">
|
||||
<xsd:attribute name="lim" type="a:ST_PositivePercentage" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_LineJoinProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="round" type="w:CT_Empty"/>
|
||||
<xsd:element name="bevel" type="w:CT_Empty"/>
|
||||
<xsd:element name="miter" type="CT_LineJoinMiterProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_PresetCameraType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="legacyObliqueTopLeft"/>
|
||||
<xsd:enumeration value="legacyObliqueTop"/>
|
||||
<xsd:enumeration value="legacyObliqueTopRight"/>
|
||||
<xsd:enumeration value="legacyObliqueLeft"/>
|
||||
<xsd:enumeration value="legacyObliqueFront"/>
|
||||
<xsd:enumeration value="legacyObliqueRight"/>
|
||||
<xsd:enumeration value="legacyObliqueBottomLeft"/>
|
||||
<xsd:enumeration value="legacyObliqueBottom"/>
|
||||
<xsd:enumeration value="legacyObliqueBottomRight"/>
|
||||
<xsd:enumeration value="legacyPerspectiveTopLeft"/>
|
||||
<xsd:enumeration value="legacyPerspectiveTop"/>
|
||||
<xsd:enumeration value="legacyPerspectiveTopRight"/>
|
||||
<xsd:enumeration value="legacyPerspectiveLeft"/>
|
||||
<xsd:enumeration value="legacyPerspectiveFront"/>
|
||||
<xsd:enumeration value="legacyPerspectiveRight"/>
|
||||
<xsd:enumeration value="legacyPerspectiveBottomLeft"/>
|
||||
<xsd:enumeration value="legacyPerspectiveBottom"/>
|
||||
<xsd:enumeration value="legacyPerspectiveBottomRight"/>
|
||||
<xsd:enumeration value="orthographicFront"/>
|
||||
<xsd:enumeration value="isometricTopUp"/>
|
||||
<xsd:enumeration value="isometricTopDown"/>
|
||||
<xsd:enumeration value="isometricBottomUp"/>
|
||||
<xsd:enumeration value="isometricBottomDown"/>
|
||||
<xsd:enumeration value="isometricLeftUp"/>
|
||||
<xsd:enumeration value="isometricLeftDown"/>
|
||||
<xsd:enumeration value="isometricRightUp"/>
|
||||
<xsd:enumeration value="isometricRightDown"/>
|
||||
<xsd:enumeration value="isometricOffAxis1Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis1Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis1Top"/>
|
||||
<xsd:enumeration value="isometricOffAxis2Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis2Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis2Top"/>
|
||||
<xsd:enumeration value="isometricOffAxis3Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis3Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis3Bottom"/>
|
||||
<xsd:enumeration value="isometricOffAxis4Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis4Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis4Bottom"/>
|
||||
<xsd:enumeration value="obliqueTopLeft"/>
|
||||
<xsd:enumeration value="obliqueTop"/>
|
||||
<xsd:enumeration value="obliqueTopRight"/>
|
||||
<xsd:enumeration value="obliqueLeft"/>
|
||||
<xsd:enumeration value="obliqueRight"/>
|
||||
<xsd:enumeration value="obliqueBottomLeft"/>
|
||||
<xsd:enumeration value="obliqueBottom"/>
|
||||
<xsd:enumeration value="obliqueBottomRight"/>
|
||||
<xsd:enumeration value="perspectiveFront"/>
|
||||
<xsd:enumeration value="perspectiveLeft"/>
|
||||
<xsd:enumeration value="perspectiveRight"/>
|
||||
<xsd:enumeration value="perspectiveAbove"/>
|
||||
<xsd:enumeration value="perspectiveBelow"/>
|
||||
<xsd:enumeration value="perspectiveAboveLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveAboveRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveContrastingLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveContrastingRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicExtremeLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicExtremeRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveRelaxed"/>
|
||||
<xsd:enumeration value="perspectiveRelaxedModerately"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Camera">
|
||||
<xsd:attribute name="prst" use="required" type="ST_PresetCameraType"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SphereCoords">
|
||||
<xsd:attribute name="lat" type="a:ST_PositiveFixedAngle" use="required"/>
|
||||
<xsd:attribute name="lon" type="a:ST_PositiveFixedAngle" use="required"/>
|
||||
<xsd:attribute name="rev" type="a:ST_PositiveFixedAngle" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_LightRigType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="legacyFlat1"/>
|
||||
<xsd:enumeration value="legacyFlat2"/>
|
||||
<xsd:enumeration value="legacyFlat3"/>
|
||||
<xsd:enumeration value="legacyFlat4"/>
|
||||
<xsd:enumeration value="legacyNormal1"/>
|
||||
<xsd:enumeration value="legacyNormal2"/>
|
||||
<xsd:enumeration value="legacyNormal3"/>
|
||||
<xsd:enumeration value="legacyNormal4"/>
|
||||
<xsd:enumeration value="legacyHarsh1"/>
|
||||
<xsd:enumeration value="legacyHarsh2"/>
|
||||
<xsd:enumeration value="legacyHarsh3"/>
|
||||
<xsd:enumeration value="legacyHarsh4"/>
|
||||
<xsd:enumeration value="threePt"/>
|
||||
<xsd:enumeration value="balanced"/>
|
||||
<xsd:enumeration value="soft"/>
|
||||
<xsd:enumeration value="harsh"/>
|
||||
<xsd:enumeration value="flood"/>
|
||||
<xsd:enumeration value="contrasting"/>
|
||||
<xsd:enumeration value="morning"/>
|
||||
<xsd:enumeration value="sunrise"/>
|
||||
<xsd:enumeration value="sunset"/>
|
||||
<xsd:enumeration value="chilly"/>
|
||||
<xsd:enumeration value="freezing"/>
|
||||
<xsd:enumeration value="flat"/>
|
||||
<xsd:enumeration value="twoPt"/>
|
||||
<xsd:enumeration value="glow"/>
|
||||
<xsd:enumeration value="brightRoom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_LightRigDirection">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="tl"/>
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="tr"/>
|
||||
<xsd:enumeration value="l"/>
|
||||
<xsd:enumeration value="r"/>
|
||||
<xsd:enumeration value="bl"/>
|
||||
<xsd:enumeration value="b"/>
|
||||
<xsd:enumeration value="br"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_LightRig">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="rot" type="CT_SphereCoords" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="rig" type="ST_LightRigType" use="required"/>
|
||||
<xsd:attribute name="dir" type="ST_LightRigDirection" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_BevelPresetType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="relaxedInset"/>
|
||||
<xsd:enumeration value="circle"/>
|
||||
<xsd:enumeration value="slope"/>
|
||||
<xsd:enumeration value="cross"/>
|
||||
<xsd:enumeration value="angle"/>
|
||||
<xsd:enumeration value="softRound"/>
|
||||
<xsd:enumeration value="convex"/>
|
||||
<xsd:enumeration value="coolSlant"/>
|
||||
<xsd:enumeration value="divot"/>
|
||||
<xsd:enumeration value="riblet"/>
|
||||
<xsd:enumeration value="hardEdge"/>
|
||||
<xsd:enumeration value="artDeco"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Bevel">
|
||||
<xsd:attribute name="w" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="h" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="prst" type="ST_BevelPresetType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_PresetMaterialType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="legacyMatte"/>
|
||||
<xsd:enumeration value="legacyPlastic"/>
|
||||
<xsd:enumeration value="legacyMetal"/>
|
||||
<xsd:enumeration value="legacyWireframe"/>
|
||||
<xsd:enumeration value="matte"/>
|
||||
<xsd:enumeration value="plastic"/>
|
||||
<xsd:enumeration value="metal"/>
|
||||
<xsd:enumeration value="warmMatte"/>
|
||||
<xsd:enumeration value="translucentPowder"/>
|
||||
<xsd:enumeration value="powder"/>
|
||||
<xsd:enumeration value="dkEdge"/>
|
||||
<xsd:enumeration value="softEdge"/>
|
||||
<xsd:enumeration value="clear"/>
|
||||
<xsd:enumeration value="flat"/>
|
||||
<xsd:enumeration value="softmetal"/>
|
||||
<xsd:enumeration value="none"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Glow">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="rad" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shadow">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="blurRad" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="dist" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="dir" use="optional" type="a:ST_PositiveFixedAngle"/>
|
||||
<xsd:attribute name="sx" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="sy" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="kx" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="ky" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="algn" use="optional" type="ST_RectAlignment"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Reflection">
|
||||
<xsd:attribute name="blurRad" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="stA" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="stPos" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="endA" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="endPos" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="dist" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="dir" use="optional" type="a:ST_PositiveFixedAngle"/>
|
||||
<xsd:attribute name="fadeDir" use="optional" type="a:ST_PositiveFixedAngle"/>
|
||||
<xsd:attribute name="sx" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="sy" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="kx" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="ky" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="algn" use="optional" type="ST_RectAlignment"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_FillTextEffect">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_FillProperties" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TextOutlineEffect">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_FillProperties" minOccurs="0"/>
|
||||
<xsd:group ref="EG_LineDashProperties" minOccurs="0"/>
|
||||
<xsd:group ref="EG_LineJoinProperties" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="w" use="optional" type="a:ST_LineWidth"/>
|
||||
<xsd:attribute name="cap" use="optional" type="ST_LineCap"/>
|
||||
<xsd:attribute name="cmpd" use="optional" type="ST_CompoundLine"/>
|
||||
<xsd:attribute name="algn" use="optional" type="ST_PenAlignment"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Scene3D">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="camera" type="CT_Camera"/>
|
||||
<xsd:element name="lightRig" type="CT_LightRig"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Props3D">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="bevelT" type="CT_Bevel" minOccurs="0"/>
|
||||
<xsd:element name="bevelB" type="CT_Bevel" minOccurs="0"/>
|
||||
<xsd:element name="extrusionClr" type="CT_Color" minOccurs="0"/>
|
||||
<xsd:element name="contourClr" type="CT_Color" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="extrusionH" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="contourW" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="prstMaterial" type="ST_PresetMaterialType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_RPrTextEffects">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="glow" minOccurs="0" type="CT_Glow"/>
|
||||
<xsd:element name="shadow" minOccurs="0" type="CT_Shadow"/>
|
||||
<xsd:element name="reflection" minOccurs="0" type="CT_Reflection"/>
|
||||
<xsd:element name="textOutline" minOccurs="0" type="CT_TextOutlineEffect"/>
|
||||
<xsd:element name="textFill" minOccurs="0" type="CT_FillTextEffect"/>
|
||||
<xsd:element name="scene3d" minOccurs="0" type="CT_Scene3D"/>
|
||||
<xsd:element name="props3d" minOccurs="0" type="CT_Props3D"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_Ligatures">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="standard"/>
|
||||
<xsd:enumeration value="contextual"/>
|
||||
<xsd:enumeration value="historical"/>
|
||||
<xsd:enumeration value="discretional"/>
|
||||
<xsd:enumeration value="standardContextual"/>
|
||||
<xsd:enumeration value="standardHistorical"/>
|
||||
<xsd:enumeration value="contextualHistorical"/>
|
||||
<xsd:enumeration value="standardDiscretional"/>
|
||||
<xsd:enumeration value="contextualDiscretional"/>
|
||||
<xsd:enumeration value="historicalDiscretional"/>
|
||||
<xsd:enumeration value="standardContextualHistorical"/>
|
||||
<xsd:enumeration value="standardContextualDiscretional"/>
|
||||
<xsd:enumeration value="standardHistoricalDiscretional"/>
|
||||
<xsd:enumeration value="contextualHistoricalDiscretional"/>
|
||||
<xsd:enumeration value="all"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Ligatures">
|
||||
<xsd:attribute name="val" type="ST_Ligatures" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_NumForm">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="default"/>
|
||||
<xsd:enumeration value="lining"/>
|
||||
<xsd:enumeration value="oldStyle"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_NumForm">
|
||||
<xsd:attribute name="val" type="ST_NumForm" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_NumSpacing">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="default"/>
|
||||
<xsd:enumeration value="proportional"/>
|
||||
<xsd:enumeration value="tabular"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_NumSpacing">
|
||||
<xsd:attribute name="val" type="ST_NumSpacing" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_StyleSet">
|
||||
<xsd:attribute name="id" type="s:ST_UnsignedDecimalNumber" use="required"/>
|
||||
<xsd:attribute name="val" type="ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_StylisticSets">
|
||||
<xsd:sequence minOccurs="0">
|
||||
<xsd:element name="styleSet" minOccurs="0" maxOccurs="unbounded" type="CT_StyleSet"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_RPrOpenType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ligatures" minOccurs="0" type="CT_Ligatures"/>
|
||||
<xsd:element name="numForm" minOccurs="0" type="CT_NumForm"/>
|
||||
<xsd:element name="numSpacing" minOccurs="0" type="CT_NumSpacing"/>
|
||||
<xsd:element name="stylisticSets" minOccurs="0" type="CT_StylisticSets"/>
|
||||
<xsd:element name="cntxtAlts" minOccurs="0" type="CT_OnOff"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:element name="discardImageEditingData" type="CT_OnOff"/>
|
||||
<xsd:element name="defaultImageDpi" type="CT_DefaultImageDpi"/>
|
||||
<xsd:complexType name="CT_DefaultImageDpi">
|
||||
<xsd:attribute name="val" type="w:ST_DecimalNumber" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="entityPicker" type="w:CT_Empty"/>
|
||||
<xsd:complexType name="CT_SdtCheckboxSymbol">
|
||||
<xsd:attribute name="font" type="s:ST_String"/>
|
||||
<xsd:attribute name="val" type="w:ST_ShortHexNumber"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SdtCheckbox">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="checked" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="checkedState" type="CT_SdtCheckboxSymbol" minOccurs="0"/>
|
||||
<xsd:element name="uncheckedState" type="CT_SdtCheckboxSymbol" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="checkbox" type="CT_SdtCheckbox"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,67 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2012/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2012/wordml">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:element name="color" type="w12:CT_Color"/>
|
||||
<xsd:simpleType name="ST_SdtAppearance">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="boundingBox"/>
|
||||
<xsd:enumeration value="tags"/>
|
||||
<xsd:enumeration value="hidden"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:element name="dataBinding" type="w12:CT_DataBinding"/>
|
||||
<xsd:complexType name="CT_SdtAppearance">
|
||||
<xsd:attribute name="val" type="ST_SdtAppearance"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="appearance" type="CT_SdtAppearance"/>
|
||||
<xsd:complexType name="CT_CommentsEx">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="commentEx" type="CT_CommentEx" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CommentEx">
|
||||
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
|
||||
<xsd:attribute name="paraIdParent" type="w12:ST_LongHexNumber" use="optional"/>
|
||||
<xsd:attribute name="done" type="s:ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="commentsEx" type="CT_CommentsEx"/>
|
||||
<xsd:complexType name="CT_People">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="person" type="CT_Person" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PresenceInfo">
|
||||
<xsd:attribute name="providerId" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="userId" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Person">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="presenceInfo" type="CT_PresenceInfo" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="author" type="s:ST_String" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="people" type="CT_People"/>
|
||||
<xsd:complexType name="CT_SdtRepeatedSection">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sectionTitle" type="w12:CT_String" minOccurs="0"/>
|
||||
<xsd:element name="doNotAllowInsertDeleteSection" type="w12:CT_OnOff" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Guid">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:pattern value="\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Guid">
|
||||
<xsd:attribute name="val" type="ST_Guid"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="repeatingSection" type="CT_SdtRepeatedSection"/>
|
||||
<xsd:element name="repeatingSectionItem" type="w12:CT_Empty"/>
|
||||
<xsd:element name="chartTrackingRefBased" type="w12:CT_OnOff"/>
|
||||
<xsd:element name="collapsed" type="w12:CT_OnOff"/>
|
||||
<xsd:element name="docId" type="CT_Guid"/>
|
||||
<xsd:element name="footnoteColumns" type="w12:CT_DecimalNumber"/>
|
||||
<xsd:element name="webExtensionLinked" type="w12:CT_OnOff"/>
|
||||
<xsd:element name="webExtensionCreated" type="w12:CT_OnOff"/>
|
||||
<xsd:attribute name="restartNumberingAfterBreak" type="s:ST_OnOff"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,14 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:complexType name="CT_Extension">
|
||||
<xsd:sequence>
|
||||
<xsd:any processContents="lax"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="uri" type="xsd:token"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ExtensionList">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ext" type="CT_Extension" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,20 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml/cex" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml/cex">
|
||||
<xsd:import id="w16" namespace="http://schemas.microsoft.com/office/word/2018/wordml" schemaLocation="wml-2018.xsd"/>
|
||||
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:import id="s" namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:complexType name="CT_CommentsExtensible">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="commentExtensible" type="CT_CommentExtensible" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CommentExtensible">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="durableId" type="w:ST_LongHexNumber" use="required"/>
|
||||
<xsd:attribute name="dateUtc" type="w:ST_DateTime" use="optional"/>
|
||||
<xsd:attribute name="intelligentPlaceholder" type="s:ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="commentsExtensible" type="CT_CommentsExtensible"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,13 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2016/wordml/cid" targetNamespace="http://schemas.microsoft.com/office/word/2016/wordml/cid">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:complexType name="CT_CommentsIds">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="commentId" type="CT_CommentId" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CommentId">
|
||||
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
|
||||
<xsd:attribute name="durableId" type="w12:ST_LongHexNumber" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="commentsIds" type="CT_CommentsIds"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,4 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" targetNamespace="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:attribute name="storeItemChecksum" type="w12:ST_String"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,8 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2015/wordml/symex" targetNamespace="http://schemas.microsoft.com/office/word/2015/wordml/symex">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:complexType name="CT_SymEx">
|
||||
<xsd:attribute name="font" type="w12:ST_String"/>
|
||||
<xsd:attribute name="char" type="w12:ST_LongHexNumber"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="symEx" type="CT_SymEx"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,183 @@
|
||||
"""
|
||||
Helper for running LibreOffice (soffice) in environments where AF_UNIX
|
||||
sockets may be blocked (e.g., sandboxed VMs). Detects the restriction
|
||||
at runtime and applies an LD_PRELOAD shim if needed.
|
||||
|
||||
Usage:
|
||||
from office.soffice import run_soffice, get_soffice_env
|
||||
|
||||
# Option 1 – run soffice directly
|
||||
result = run_soffice(["--headless", "--convert-to", "pdf", "input.docx"])
|
||||
|
||||
# Option 2 – get env dict for your own subprocess calls
|
||||
env = get_soffice_env()
|
||||
subprocess.run(["soffice", ...], env=env)
|
||||
"""
|
||||
|
||||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_soffice_env() -> dict:
|
||||
env = os.environ.copy()
|
||||
env["SAL_USE_VCLPLUGIN"] = "svp"
|
||||
|
||||
if _needs_shim():
|
||||
shim = _ensure_shim()
|
||||
env["LD_PRELOAD"] = str(shim)
|
||||
|
||||
return env
|
||||
|
||||
|
||||
def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:
|
||||
env = get_soffice_env()
|
||||
return subprocess.run(["soffice"] + args, env=env, **kwargs)
|
||||
|
||||
|
||||
|
||||
_SHIM_SO = Path(tempfile.gettempdir()) / "lo_socket_shim.so"
|
||||
|
||||
|
||||
def _needs_shim() -> bool:
|
||||
try:
|
||||
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
s.close()
|
||||
return False
|
||||
except OSError:
|
||||
return True
|
||||
|
||||
|
||||
def _ensure_shim() -> Path:
|
||||
if _SHIM_SO.exists():
|
||||
return _SHIM_SO
|
||||
|
||||
src = Path(tempfile.gettempdir()) / "lo_socket_shim.c"
|
||||
src.write_text(_SHIM_SOURCE)
|
||||
subprocess.run(
|
||||
["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
src.unlink()
|
||||
return _SHIM_SO
|
||||
|
||||
|
||||
|
||||
_SHIM_SOURCE = r"""
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int (*real_socket)(int, int, int);
|
||||
static int (*real_socketpair)(int, int, int, int[2]);
|
||||
static int (*real_listen)(int, int);
|
||||
static int (*real_accept)(int, struct sockaddr *, socklen_t *);
|
||||
static int (*real_close)(int);
|
||||
static int (*real_read)(int, void *, size_t);
|
||||
|
||||
/* Per-FD bookkeeping (FDs >= 1024 are passed through unshimmed). */
|
||||
static int is_shimmed[1024];
|
||||
static int peer_of[1024];
|
||||
static int wake_r[1024]; /* accept() blocks reading this */
|
||||
static int wake_w[1024]; /* close() writes to this */
|
||||
static int listener_fd = -1; /* FD that received listen() */
|
||||
|
||||
__attribute__((constructor))
|
||||
static void init(void) {
|
||||
real_socket = dlsym(RTLD_NEXT, "socket");
|
||||
real_socketpair = dlsym(RTLD_NEXT, "socketpair");
|
||||
real_listen = dlsym(RTLD_NEXT, "listen");
|
||||
real_accept = dlsym(RTLD_NEXT, "accept");
|
||||
real_close = dlsym(RTLD_NEXT, "close");
|
||||
real_read = dlsym(RTLD_NEXT, "read");
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
peer_of[i] = -1;
|
||||
wake_r[i] = -1;
|
||||
wake_w[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- socket ---------------------------------------------------------- */
|
||||
int socket(int domain, int type, int protocol) {
|
||||
if (domain == AF_UNIX) {
|
||||
int fd = real_socket(domain, type, protocol);
|
||||
if (fd >= 0) return fd;
|
||||
/* socket(AF_UNIX) blocked – fall back to socketpair(). */
|
||||
int sv[2];
|
||||
if (real_socketpair(domain, type, protocol, sv) == 0) {
|
||||
if (sv[0] >= 0 && sv[0] < 1024) {
|
||||
is_shimmed[sv[0]] = 1;
|
||||
peer_of[sv[0]] = sv[1];
|
||||
int wp[2];
|
||||
if (pipe(wp) == 0) {
|
||||
wake_r[sv[0]] = wp[0];
|
||||
wake_w[sv[0]] = wp[1];
|
||||
}
|
||||
}
|
||||
return sv[0];
|
||||
}
|
||||
errno = EPERM;
|
||||
return -1;
|
||||
}
|
||||
return real_socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
/* ---- listen ---------------------------------------------------------- */
|
||||
int listen(int sockfd, int backlog) {
|
||||
if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {
|
||||
listener_fd = sockfd;
|
||||
return 0;
|
||||
}
|
||||
return real_listen(sockfd, backlog);
|
||||
}
|
||||
|
||||
/* ---- accept ---------------------------------------------------------- */
|
||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {
|
||||
/* Block until close() writes to the wake pipe. */
|
||||
if (wake_r[sockfd] >= 0) {
|
||||
char buf;
|
||||
real_read(wake_r[sockfd], &buf, 1);
|
||||
}
|
||||
errno = ECONNABORTED;
|
||||
return -1;
|
||||
}
|
||||
return real_accept(sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
/* ---- close ----------------------------------------------------------- */
|
||||
int close(int fd) {
|
||||
if (fd >= 0 && fd < 1024 && is_shimmed[fd]) {
|
||||
int was_listener = (fd == listener_fd);
|
||||
is_shimmed[fd] = 0;
|
||||
|
||||
if (wake_w[fd] >= 0) { /* unblock accept() */
|
||||
char c = 0;
|
||||
write(wake_w[fd], &c, 1);
|
||||
real_close(wake_w[fd]);
|
||||
wake_w[fd] = -1;
|
||||
}
|
||||
if (wake_r[fd] >= 0) { real_close(wake_r[fd]); wake_r[fd] = -1; }
|
||||
if (peer_of[fd] >= 0) { real_close(peer_of[fd]); peer_of[fd] = -1; }
|
||||
|
||||
if (was_listener)
|
||||
_exit(0); /* conversion done – exit */
|
||||
}
|
||||
return real_close(fd);
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
result = run_soffice(sys.argv[1:])
|
||||
sys.exit(result.returncode)
|
||||
@@ -0,0 +1,132 @@
|
||||
"""Unpack Office files (DOCX, PPTX, XLSX) for editing.
|
||||
|
||||
Extracts the ZIP archive, pretty-prints XML files, and optionally:
|
||||
- Merges adjacent runs with identical formatting (DOCX only)
|
||||
- Simplifies adjacent tracked changes from same author (DOCX only)
|
||||
|
||||
Usage:
|
||||
python unpack.py <office_file> <output_dir> [options]
|
||||
|
||||
Examples:
|
||||
python unpack.py document.docx unpacked/
|
||||
python unpack.py presentation.pptx unpacked/
|
||||
python unpack.py document.docx unpacked/ --merge-runs false
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import defusedxml.minidom
|
||||
|
||||
from helpers.merge_runs import merge_runs as do_merge_runs
|
||||
from helpers.simplify_redlines import simplify_redlines as do_simplify_redlines
|
||||
|
||||
SMART_QUOTE_REPLACEMENTS = {
|
||||
"\u201c": "“",
|
||||
"\u201d": "”",
|
||||
"\u2018": "‘",
|
||||
"\u2019": "’",
|
||||
}
|
||||
|
||||
|
||||
def unpack(
|
||||
input_file: str,
|
||||
output_directory: str,
|
||||
merge_runs: bool = True,
|
||||
simplify_redlines: bool = True,
|
||||
) -> tuple[None, str]:
|
||||
input_path = Path(input_file)
|
||||
output_path = Path(output_directory)
|
||||
suffix = input_path.suffix.lower()
|
||||
|
||||
if not input_path.exists():
|
||||
return None, f"Error: {input_file} does not exist"
|
||||
|
||||
if suffix not in {".docx", ".pptx", ".xlsx"}:
|
||||
return None, f"Error: {input_file} must be a .docx, .pptx, or .xlsx file"
|
||||
|
||||
try:
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with zipfile.ZipFile(input_path, "r") as zf:
|
||||
zf.extractall(output_path)
|
||||
|
||||
xml_files = list(output_path.rglob("*.xml")) + list(output_path.rglob("*.rels"))
|
||||
for xml_file in xml_files:
|
||||
_pretty_print_xml(xml_file)
|
||||
|
||||
message = f"Unpacked {input_file} ({len(xml_files)} XML files)"
|
||||
|
||||
if suffix == ".docx":
|
||||
if simplify_redlines:
|
||||
simplify_count, _ = do_simplify_redlines(str(output_path))
|
||||
message += f", simplified {simplify_count} tracked changes"
|
||||
|
||||
if merge_runs:
|
||||
merge_count, _ = do_merge_runs(str(output_path))
|
||||
message += f", merged {merge_count} runs"
|
||||
|
||||
for xml_file in xml_files:
|
||||
_escape_smart_quotes(xml_file)
|
||||
|
||||
return None, message
|
||||
|
||||
except zipfile.BadZipFile:
|
||||
return None, f"Error: {input_file} is not a valid Office file"
|
||||
except Exception as e:
|
||||
return None, f"Error unpacking: {e}"
|
||||
|
||||
|
||||
def _pretty_print_xml(xml_file: Path) -> None:
|
||||
try:
|
||||
content = xml_file.read_text(encoding="utf-8")
|
||||
dom = defusedxml.minidom.parseString(content)
|
||||
xml_file.write_bytes(dom.toprettyxml(indent=" ", encoding="utf-8"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _escape_smart_quotes(xml_file: Path) -> None:
|
||||
try:
|
||||
content = xml_file.read_text(encoding="utf-8")
|
||||
for char, entity in SMART_QUOTE_REPLACEMENTS.items():
|
||||
content = content.replace(char, entity)
|
||||
xml_file.write_text(content, encoding="utf-8")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Unpack an Office file (DOCX, PPTX, XLSX) for editing"
|
||||
)
|
||||
parser.add_argument("input_file", help="Office file to unpack")
|
||||
parser.add_argument("output_directory", help="Output directory")
|
||||
parser.add_argument(
|
||||
"--merge-runs",
|
||||
type=lambda x: x.lower() == "true",
|
||||
default=True,
|
||||
metavar="true|false",
|
||||
help="Merge adjacent runs with identical formatting (DOCX only, default: true)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--simplify-redlines",
|
||||
type=lambda x: x.lower() == "true",
|
||||
default=True,
|
||||
metavar="true|false",
|
||||
help="Merge adjacent tracked changes from same author (DOCX only, default: true)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
_, message = unpack(
|
||||
args.input_file,
|
||||
args.output_directory,
|
||||
merge_runs=args.merge_runs,
|
||||
simplify_redlines=args.simplify_redlines,
|
||||
)
|
||||
print(message)
|
||||
|
||||
if "Error" in message:
|
||||
sys.exit(1)
|
||||
@@ -0,0 +1,111 @@
|
||||
"""
|
||||
Command line tool to validate Office document XML files against XSD schemas and tracked changes.
|
||||
|
||||
Usage:
|
||||
python validate.py <path> [--original <original_file>] [--auto-repair] [--author NAME]
|
||||
|
||||
The first argument can be either:
|
||||
- An unpacked directory containing the Office document XML files
|
||||
- A packed Office file (.docx/.pptx/.xlsx) which will be unpacked to a temp directory
|
||||
|
||||
Auto-repair fixes:
|
||||
- paraId/durableId values that exceed OOXML limits
|
||||
- Missing xml:space="preserve" on w:t elements with whitespace
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import tempfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Validate Office document XML files")
|
||||
parser.add_argument(
|
||||
"path",
|
||||
help="Path to unpacked directory or packed Office file (.docx/.pptx/.xlsx)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--original",
|
||||
required=False,
|
||||
default=None,
|
||||
help="Path to original file (.docx/.pptx/.xlsx). If omitted, all XSD errors are reported and redlining validation is skipped.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="store_true",
|
||||
help="Enable verbose output",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--auto-repair",
|
||||
action="store_true",
|
||||
help="Automatically repair common issues (hex IDs, whitespace preservation)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--author",
|
||||
default="Claude",
|
||||
help="Author name for redlining validation (default: Claude)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
path = Path(args.path)
|
||||
assert path.exists(), f"Error: {path} does not exist"
|
||||
|
||||
original_file = None
|
||||
if args.original:
|
||||
original_file = Path(args.original)
|
||||
assert original_file.is_file(), f"Error: {original_file} is not a file"
|
||||
assert original_file.suffix.lower() in [".docx", ".pptx", ".xlsx"], (
|
||||
f"Error: {original_file} must be a .docx, .pptx, or .xlsx file"
|
||||
)
|
||||
|
||||
file_extension = (original_file or path).suffix.lower()
|
||||
assert file_extension in [".docx", ".pptx", ".xlsx"], (
|
||||
f"Error: Cannot determine file type from {path}. Use --original or provide a .docx/.pptx/.xlsx file."
|
||||
)
|
||||
|
||||
if path.is_file() and path.suffix.lower() in [".docx", ".pptx", ".xlsx"]:
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
with zipfile.ZipFile(path, "r") as zf:
|
||||
zf.extractall(temp_dir)
|
||||
unpacked_dir = Path(temp_dir)
|
||||
else:
|
||||
assert path.is_dir(), f"Error: {path} is not a directory or Office file"
|
||||
unpacked_dir = path
|
||||
|
||||
match file_extension:
|
||||
case ".docx":
|
||||
validators = [
|
||||
DOCXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),
|
||||
]
|
||||
if original_file:
|
||||
validators.append(
|
||||
RedliningValidator(unpacked_dir, original_file, verbose=args.verbose, author=args.author)
|
||||
)
|
||||
case ".pptx":
|
||||
validators = [
|
||||
PPTXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),
|
||||
]
|
||||
case _:
|
||||
print(f"Error: Validation not supported for file type {file_extension}")
|
||||
sys.exit(1)
|
||||
|
||||
if args.auto_repair:
|
||||
total_repairs = sum(v.repair() for v in validators)
|
||||
if total_repairs:
|
||||
print(f"Auto-repaired {total_repairs} issue(s)")
|
||||
|
||||
success = all(v.validate() for v in validators)
|
||||
|
||||
if success:
|
||||
print("All validations PASSED!")
|
||||
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Validation modules for Word document processing.
|
||||
"""
|
||||
|
||||
from .base import BaseSchemaValidator
|
||||
from .docx import DOCXSchemaValidator
|
||||
from .pptx import PPTXSchemaValidator
|
||||
from .redlining import RedliningValidator
|
||||
|
||||
__all__ = [
|
||||
"BaseSchemaValidator",
|
||||
"DOCXSchemaValidator",
|
||||
"PPTXSchemaValidator",
|
||||
"RedliningValidator",
|
||||
]
|
||||
@@ -0,0 +1,847 @@
|
||||
"""
|
||||
Base validator with common validation logic for document files.
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import defusedxml.minidom
|
||||
import lxml.etree
|
||||
|
||||
|
||||
class BaseSchemaValidator:
|
||||
|
||||
IGNORED_VALIDATION_ERRORS = [
|
||||
"hyphenationZone",
|
||||
"purl.org/dc/terms",
|
||||
]
|
||||
|
||||
UNIQUE_ID_REQUIREMENTS = {
|
||||
"comment": ("id", "file"),
|
||||
"commentrangestart": ("id", "file"),
|
||||
"commentrangeend": ("id", "file"),
|
||||
"bookmarkstart": ("id", "file"),
|
||||
"bookmarkend": ("id", "file"),
|
||||
"sldid": ("id", "file"),
|
||||
"sldmasterid": ("id", "global"),
|
||||
"sldlayoutid": ("id", "global"),
|
||||
"cm": ("authorid", "file"),
|
||||
"sheet": ("sheetid", "file"),
|
||||
"definedname": ("id", "file"),
|
||||
"cxnsp": ("id", "file"),
|
||||
"sp": ("id", "file"),
|
||||
"pic": ("id", "file"),
|
||||
"grpsp": ("id", "file"),
|
||||
}
|
||||
|
||||
EXCLUDED_ID_CONTAINERS = {
|
||||
"sectionlst",
|
||||
}
|
||||
|
||||
ELEMENT_RELATIONSHIP_TYPES = {}
|
||||
|
||||
SCHEMA_MAPPINGS = {
|
||||
"word": "ISO-IEC29500-4_2016/wml.xsd",
|
||||
"ppt": "ISO-IEC29500-4_2016/pml.xsd",
|
||||
"xl": "ISO-IEC29500-4_2016/sml.xsd",
|
||||
"[Content_Types].xml": "ecma/fouth-edition/opc-contentTypes.xsd",
|
||||
"app.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
|
||||
"core.xml": "ecma/fouth-edition/opc-coreProperties.xsd",
|
||||
"custom.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
|
||||
".rels": "ecma/fouth-edition/opc-relationships.xsd",
|
||||
"people.xml": "microsoft/wml-2012.xsd",
|
||||
"commentsIds.xml": "microsoft/wml-cid-2016.xsd",
|
||||
"commentsExtensible.xml": "microsoft/wml-cex-2018.xsd",
|
||||
"commentsExtended.xml": "microsoft/wml-2012.xsd",
|
||||
"chart": "ISO-IEC29500-4_2016/dml-chart.xsd",
|
||||
"theme": "ISO-IEC29500-4_2016/dml-main.xsd",
|
||||
"drawing": "ISO-IEC29500-4_2016/dml-main.xsd",
|
||||
}
|
||||
|
||||
MC_NAMESPACE = "http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
|
||||
|
||||
PACKAGE_RELATIONSHIPS_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
)
|
||||
OFFICE_RELATIONSHIPS_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
)
|
||||
CONTENT_TYPES_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/package/2006/content-types"
|
||||
)
|
||||
|
||||
MAIN_CONTENT_FOLDERS = {"word", "ppt", "xl"}
|
||||
|
||||
OOXML_NAMESPACES = {
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/math",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
||||
"http://schemas.openxmlformats.org/schemaLibrary/2006/main",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/chart",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/picture",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
||||
"http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
||||
"http://schemas.openxmlformats.org/presentationml/2006/main",
|
||||
"http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes",
|
||||
"http://www.w3.org/XML/1998/namespace",
|
||||
}
|
||||
|
||||
def __init__(self, unpacked_dir, original_file=None, verbose=False):
|
||||
self.unpacked_dir = Path(unpacked_dir).resolve()
|
||||
self.original_file = Path(original_file) if original_file else None
|
||||
self.verbose = verbose
|
||||
|
||||
self.schemas_dir = Path(__file__).parent.parent / "schemas"
|
||||
|
||||
patterns = ["*.xml", "*.rels"]
|
||||
self.xml_files = [
|
||||
f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)
|
||||
]
|
||||
|
||||
if not self.xml_files:
|
||||
print(f"Warning: No XML files found in {self.unpacked_dir}")
|
||||
|
||||
def validate(self):
|
||||
raise NotImplementedError("Subclasses must implement the validate method")
|
||||
|
||||
def repair(self) -> int:
|
||||
return self.repair_whitespace_preservation()
|
||||
|
||||
def repair_whitespace_preservation(self) -> int:
|
||||
repairs = 0
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
content = xml_file.read_text(encoding="utf-8")
|
||||
dom = defusedxml.minidom.parseString(content)
|
||||
modified = False
|
||||
|
||||
for elem in dom.getElementsByTagName("*"):
|
||||
if elem.tagName.endswith(":t") and elem.firstChild:
|
||||
text = elem.firstChild.nodeValue
|
||||
if text and (text.startswith((' ', '\t')) or text.endswith((' ', '\t'))):
|
||||
if elem.getAttribute("xml:space") != "preserve":
|
||||
elem.setAttribute("xml:space", "preserve")
|
||||
text_preview = repr(text[:30]) + "..." if len(text) > 30 else repr(text)
|
||||
print(f" Repaired: {xml_file.name}: Added xml:space='preserve' to {elem.tagName}: {text_preview}")
|
||||
repairs += 1
|
||||
modified = True
|
||||
|
||||
if modified:
|
||||
xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return repairs
|
||||
|
||||
def validate_xml(self):
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
lxml.etree.parse(str(xml_file))
|
||||
except lxml.etree.XMLSyntaxError as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {e.lineno}: {e.msg}"
|
||||
)
|
||||
except Exception as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Unexpected error: {str(e)}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} XML violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All XML files are well-formed")
|
||||
return True
|
||||
|
||||
def validate_namespaces(self):
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
declared = set(root.nsmap.keys()) - {None}
|
||||
|
||||
for attr_val in [
|
||||
v for k, v in root.attrib.items() if k.endswith("Ignorable")
|
||||
]:
|
||||
undeclared = set(attr_val.split()) - declared
|
||||
errors.extend(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Namespace '{ns}' in Ignorable but not declared"
|
||||
for ns in undeclared
|
||||
)
|
||||
except lxml.etree.XMLSyntaxError:
|
||||
continue
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - {len(errors)} namespace issues:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
if self.verbose:
|
||||
print("PASSED - All namespace prefixes properly declared")
|
||||
return True
|
||||
|
||||
def validate_unique_ids(self):
|
||||
errors = []
|
||||
global_ids = {}
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
file_ids = {}
|
||||
|
||||
mc_elements = root.xpath(
|
||||
".//mc:AlternateContent", namespaces={"mc": self.MC_NAMESPACE}
|
||||
)
|
||||
for elem in mc_elements:
|
||||
elem.getparent().remove(elem)
|
||||
|
||||
for elem in root.iter():
|
||||
tag = (
|
||||
elem.tag.split("}")[-1].lower()
|
||||
if "}" in elem.tag
|
||||
else elem.tag.lower()
|
||||
)
|
||||
|
||||
if tag in self.UNIQUE_ID_REQUIREMENTS:
|
||||
in_excluded_container = any(
|
||||
ancestor.tag.split("}")[-1].lower() in self.EXCLUDED_ID_CONTAINERS
|
||||
for ancestor in elem.iterancestors()
|
||||
)
|
||||
if in_excluded_container:
|
||||
continue
|
||||
|
||||
attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]
|
||||
|
||||
id_value = None
|
||||
for attr, value in elem.attrib.items():
|
||||
attr_local = (
|
||||
attr.split("}")[-1].lower()
|
||||
if "}" in attr
|
||||
else attr.lower()
|
||||
)
|
||||
if attr_local == attr_name:
|
||||
id_value = value
|
||||
break
|
||||
|
||||
if id_value is not None:
|
||||
if scope == "global":
|
||||
if id_value in global_ids:
|
||||
prev_file, prev_line, prev_tag = global_ids[
|
||||
id_value
|
||||
]
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> "
|
||||
f"already used in {prev_file} at line {prev_line} in <{prev_tag}>"
|
||||
)
|
||||
else:
|
||||
global_ids[id_value] = (
|
||||
xml_file.relative_to(self.unpacked_dir),
|
||||
elem.sourceline,
|
||||
tag,
|
||||
)
|
||||
elif scope == "file":
|
||||
key = (tag, attr_name)
|
||||
if key not in file_ids:
|
||||
file_ids[key] = {}
|
||||
|
||||
if id_value in file_ids[key]:
|
||||
prev_line = file_ids[key][id_value]
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> "
|
||||
f"(first occurrence at line {prev_line})"
|
||||
)
|
||||
else:
|
||||
file_ids[key][id_value] = elem.sourceline
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} ID uniqueness violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All required IDs are unique")
|
||||
return True
|
||||
|
||||
def validate_file_references(self):
|
||||
errors = []
|
||||
|
||||
rels_files = list(self.unpacked_dir.rglob("*.rels"))
|
||||
|
||||
if not rels_files:
|
||||
if self.verbose:
|
||||
print("PASSED - No .rels files found")
|
||||
return True
|
||||
|
||||
all_files = []
|
||||
for file_path in self.unpacked_dir.rglob("*"):
|
||||
if (
|
||||
file_path.is_file()
|
||||
and file_path.name != "[Content_Types].xml"
|
||||
and not file_path.name.endswith(".rels")
|
||||
):
|
||||
all_files.append(file_path.resolve())
|
||||
|
||||
all_referenced_files = set()
|
||||
|
||||
if self.verbose:
|
||||
print(
|
||||
f"Found {len(rels_files)} .rels files and {len(all_files)} target files"
|
||||
)
|
||||
|
||||
for rels_file in rels_files:
|
||||
try:
|
||||
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
rels_dir = rels_file.parent
|
||||
|
||||
referenced_files = set()
|
||||
broken_refs = []
|
||||
|
||||
for rel in rels_root.findall(
|
||||
".//ns:Relationship",
|
||||
namespaces={"ns": self.PACKAGE_RELATIONSHIPS_NAMESPACE},
|
||||
):
|
||||
target = rel.get("Target")
|
||||
if target and not target.startswith(
|
||||
("http", "mailto:")
|
||||
):
|
||||
if target.startswith("/"):
|
||||
target_path = self.unpacked_dir / target.lstrip("/")
|
||||
elif rels_file.name == ".rels":
|
||||
target_path = self.unpacked_dir / target
|
||||
else:
|
||||
base_dir = rels_dir.parent
|
||||
target_path = base_dir / target
|
||||
|
||||
try:
|
||||
target_path = target_path.resolve()
|
||||
if target_path.exists() and target_path.is_file():
|
||||
referenced_files.add(target_path)
|
||||
all_referenced_files.add(target_path)
|
||||
else:
|
||||
broken_refs.append((target, rel.sourceline))
|
||||
except (OSError, ValueError):
|
||||
broken_refs.append((target, rel.sourceline))
|
||||
|
||||
if broken_refs:
|
||||
rel_path = rels_file.relative_to(self.unpacked_dir)
|
||||
for broken_ref, line_num in broken_refs:
|
||||
errors.append(
|
||||
f" {rel_path}: Line {line_num}: Broken reference to {broken_ref}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
rel_path = rels_file.relative_to(self.unpacked_dir)
|
||||
errors.append(f" Error parsing {rel_path}: {e}")
|
||||
|
||||
unreferenced_files = set(all_files) - all_referenced_files
|
||||
|
||||
if unreferenced_files:
|
||||
for unref_file in sorted(unreferenced_files):
|
||||
unref_rel_path = unref_file.relative_to(self.unpacked_dir)
|
||||
errors.append(f" Unreferenced file: {unref_rel_path}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} relationship validation errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print(
|
||||
"CRITICAL: These errors will cause the document to appear corrupt. "
|
||||
+ "Broken references MUST be fixed, "
|
||||
+ "and unreferenced files MUST be referenced or removed."
|
||||
)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print(
|
||||
"PASSED - All references are valid and all files are properly referenced"
|
||||
)
|
||||
return True
|
||||
|
||||
def validate_all_relationship_ids(self):
|
||||
import lxml.etree
|
||||
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.suffix == ".rels":
|
||||
continue
|
||||
|
||||
rels_dir = xml_file.parent / "_rels"
|
||||
rels_file = rels_dir / f"{xml_file.name}.rels"
|
||||
|
||||
if not rels_file.exists():
|
||||
continue
|
||||
|
||||
try:
|
||||
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
rid_to_type = {}
|
||||
|
||||
for rel in rels_root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
):
|
||||
rid = rel.get("Id")
|
||||
rel_type = rel.get("Type", "")
|
||||
if rid:
|
||||
if rid in rid_to_type:
|
||||
rels_rel_path = rels_file.relative_to(self.unpacked_dir)
|
||||
errors.append(
|
||||
f" {rels_rel_path}: Line {rel.sourceline}: "
|
||||
f"Duplicate relationship ID '{rid}' (IDs must be unique)"
|
||||
)
|
||||
type_name = (
|
||||
rel_type.split("/")[-1] if "/" in rel_type else rel_type
|
||||
)
|
||||
rid_to_type[rid] = type_name
|
||||
|
||||
xml_root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
r_ns = self.OFFICE_RELATIONSHIPS_NAMESPACE
|
||||
rid_attrs_to_check = ["id", "embed", "link"]
|
||||
for elem in xml_root.iter():
|
||||
for attr_name in rid_attrs_to_check:
|
||||
rid_attr = elem.get(f"{{{r_ns}}}{attr_name}")
|
||||
if not rid_attr:
|
||||
continue
|
||||
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
|
||||
elem_name = (
|
||||
elem.tag.split("}")[-1] if "}" in elem.tag else elem.tag
|
||||
)
|
||||
|
||||
if rid_attr not in rid_to_type:
|
||||
errors.append(
|
||||
f" {xml_rel_path}: Line {elem.sourceline}: "
|
||||
f"<{elem_name}> r:{attr_name} references non-existent relationship '{rid_attr}' "
|
||||
f"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})"
|
||||
)
|
||||
elif attr_name == "id" and self.ELEMENT_RELATIONSHIP_TYPES:
|
||||
expected_type = self._get_expected_relationship_type(
|
||||
elem_name
|
||||
)
|
||||
if expected_type:
|
||||
actual_type = rid_to_type[rid_attr]
|
||||
if expected_type not in actual_type.lower():
|
||||
errors.append(
|
||||
f" {xml_rel_path}: Line {elem.sourceline}: "
|
||||
f"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' "
|
||||
f"but should point to a '{expected_type}' relationship"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
|
||||
errors.append(f" Error processing {xml_rel_path}: {e}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} relationship ID reference errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print("\nThese ID mismatches will cause the document to appear corrupt!")
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All relationship ID references are valid")
|
||||
return True
|
||||
|
||||
def _get_expected_relationship_type(self, element_name):
|
||||
elem_lower = element_name.lower()
|
||||
|
||||
if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:
|
||||
return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]
|
||||
|
||||
if elem_lower.endswith("id") and len(elem_lower) > 2:
|
||||
prefix = elem_lower[:-2]
|
||||
if prefix.endswith("master"):
|
||||
return prefix.lower()
|
||||
elif prefix.endswith("layout"):
|
||||
return prefix.lower()
|
||||
else:
|
||||
if prefix == "sld":
|
||||
return "slide"
|
||||
return prefix.lower()
|
||||
|
||||
if elem_lower.endswith("reference") and len(elem_lower) > 9:
|
||||
prefix = elem_lower[:-9]
|
||||
return prefix.lower()
|
||||
|
||||
return None
|
||||
|
||||
def validate_content_types(self):
|
||||
errors = []
|
||||
|
||||
content_types_file = self.unpacked_dir / "[Content_Types].xml"
|
||||
if not content_types_file.exists():
|
||||
print("FAILED - [Content_Types].xml file not found")
|
||||
return False
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(content_types_file)).getroot()
|
||||
declared_parts = set()
|
||||
declared_extensions = set()
|
||||
|
||||
for override in root.findall(
|
||||
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override"
|
||||
):
|
||||
part_name = override.get("PartName")
|
||||
if part_name is not None:
|
||||
declared_parts.add(part_name.lstrip("/"))
|
||||
|
||||
for default in root.findall(
|
||||
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default"
|
||||
):
|
||||
extension = default.get("Extension")
|
||||
if extension is not None:
|
||||
declared_extensions.add(extension.lower())
|
||||
|
||||
declarable_roots = {
|
||||
"sld",
|
||||
"sldLayout",
|
||||
"sldMaster",
|
||||
"presentation",
|
||||
"document",
|
||||
"workbook",
|
||||
"worksheet",
|
||||
"theme",
|
||||
}
|
||||
|
||||
media_extensions = {
|
||||
"png": "image/png",
|
||||
"jpg": "image/jpeg",
|
||||
"jpeg": "image/jpeg",
|
||||
"gif": "image/gif",
|
||||
"bmp": "image/bmp",
|
||||
"tiff": "image/tiff",
|
||||
"wmf": "image/x-wmf",
|
||||
"emf": "image/x-emf",
|
||||
}
|
||||
|
||||
all_files = list(self.unpacked_dir.rglob("*"))
|
||||
all_files = [f for f in all_files if f.is_file()]
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(
|
||||
"\\", "/"
|
||||
)
|
||||
|
||||
if any(
|
||||
skip in path_str
|
||||
for skip in [".rels", "[Content_Types]", "docProps/", "_rels/"]
|
||||
):
|
||||
continue
|
||||
|
||||
try:
|
||||
root_tag = lxml.etree.parse(str(xml_file)).getroot().tag
|
||||
root_name = root_tag.split("}")[-1] if "}" in root_tag else root_tag
|
||||
|
||||
if root_name in declarable_roots and path_str not in declared_parts:
|
||||
errors.append(
|
||||
f" {path_str}: File with <{root_name}> root not declared in [Content_Types].xml"
|
||||
)
|
||||
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
for file_path in all_files:
|
||||
if file_path.suffix.lower() in {".xml", ".rels"}:
|
||||
continue
|
||||
if file_path.name == "[Content_Types].xml":
|
||||
continue
|
||||
if "_rels" in file_path.parts or "docProps" in file_path.parts:
|
||||
continue
|
||||
|
||||
extension = file_path.suffix.lstrip(".").lower()
|
||||
if extension and extension not in declared_extensions:
|
||||
if extension in media_extensions:
|
||||
relative_path = file_path.relative_to(self.unpacked_dir)
|
||||
errors.append(
|
||||
f' {relative_path}: File with extension \'{extension}\' not declared in [Content_Types].xml - should add: <Default Extension="{extension}" ContentType="{media_extensions[extension]}"/>'
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
errors.append(f" Error parsing [Content_Types].xml: {e}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} content type declaration errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print(
|
||||
"PASSED - All content files are properly declared in [Content_Types].xml"
|
||||
)
|
||||
return True
|
||||
|
||||
def validate_file_against_xsd(self, xml_file, verbose=False):
|
||||
xml_file = Path(xml_file).resolve()
|
||||
unpacked_dir = self.unpacked_dir.resolve()
|
||||
|
||||
is_valid, current_errors = self._validate_single_file_xsd(
|
||||
xml_file, unpacked_dir
|
||||
)
|
||||
|
||||
if is_valid is None:
|
||||
return None, set()
|
||||
elif is_valid:
|
||||
return True, set()
|
||||
|
||||
original_errors = self._get_original_file_errors(xml_file)
|
||||
|
||||
assert current_errors is not None
|
||||
new_errors = current_errors - original_errors
|
||||
|
||||
new_errors = {
|
||||
e for e in new_errors
|
||||
if not any(pattern in e for pattern in self.IGNORED_VALIDATION_ERRORS)
|
||||
}
|
||||
|
||||
if new_errors:
|
||||
if verbose:
|
||||
relative_path = xml_file.relative_to(unpacked_dir)
|
||||
print(f"FAILED - {relative_path}: {len(new_errors)} new error(s)")
|
||||
for error in list(new_errors)[:3]:
|
||||
truncated = error[:250] + "..." if len(error) > 250 else error
|
||||
print(f" - {truncated}")
|
||||
return False, new_errors
|
||||
else:
|
||||
if verbose:
|
||||
print(
|
||||
f"PASSED - No new errors (original had {len(current_errors)} errors)"
|
||||
)
|
||||
return True, set()
|
||||
|
||||
def validate_against_xsd(self):
|
||||
new_errors = []
|
||||
original_error_count = 0
|
||||
valid_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
relative_path = str(xml_file.relative_to(self.unpacked_dir))
|
||||
is_valid, new_file_errors = self.validate_file_against_xsd(
|
||||
xml_file, verbose=False
|
||||
)
|
||||
|
||||
if is_valid is None:
|
||||
skipped_count += 1
|
||||
continue
|
||||
elif is_valid and not new_file_errors:
|
||||
valid_count += 1
|
||||
continue
|
||||
elif is_valid:
|
||||
original_error_count += 1
|
||||
valid_count += 1
|
||||
continue
|
||||
|
||||
new_errors.append(f" {relative_path}: {len(new_file_errors)} new error(s)")
|
||||
for error in list(new_file_errors)[:3]:
|
||||
new_errors.append(
|
||||
f" - {error[:250]}..." if len(error) > 250 else f" - {error}"
|
||||
)
|
||||
|
||||
if self.verbose:
|
||||
print(f"Validated {len(self.xml_files)} files:")
|
||||
print(f" - Valid: {valid_count}")
|
||||
print(f" - Skipped (no schema): {skipped_count}")
|
||||
if original_error_count:
|
||||
print(f" - With original errors (ignored): {original_error_count}")
|
||||
print(
|
||||
f" - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith(' ')]) or 0}"
|
||||
)
|
||||
|
||||
if new_errors:
|
||||
print("\nFAILED - Found NEW validation errors:")
|
||||
for error in new_errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("\nPASSED - No new XSD validation errors introduced")
|
||||
return True
|
||||
|
||||
def _get_schema_path(self, xml_file):
|
||||
if xml_file.name in self.SCHEMA_MAPPINGS:
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]
|
||||
|
||||
if xml_file.suffix == ".rels":
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS[".rels"]
|
||||
|
||||
if "charts/" in str(xml_file) and xml_file.name.startswith("chart"):
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS["chart"]
|
||||
|
||||
if "theme/" in str(xml_file) and xml_file.name.startswith("theme"):
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS["theme"]
|
||||
|
||||
if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]
|
||||
|
||||
return None
|
||||
|
||||
def _clean_ignorable_namespaces(self, xml_doc):
|
||||
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
|
||||
xml_copy = lxml.etree.fromstring(xml_string)
|
||||
|
||||
for elem in xml_copy.iter():
|
||||
attrs_to_remove = []
|
||||
|
||||
for attr in elem.attrib:
|
||||
if "{" in attr:
|
||||
ns = attr.split("}")[0][1:]
|
||||
if ns not in self.OOXML_NAMESPACES:
|
||||
attrs_to_remove.append(attr)
|
||||
|
||||
for attr in attrs_to_remove:
|
||||
del elem.attrib[attr]
|
||||
|
||||
self._remove_ignorable_elements(xml_copy)
|
||||
|
||||
return lxml.etree.ElementTree(xml_copy)
|
||||
|
||||
def _remove_ignorable_elements(self, root):
|
||||
elements_to_remove = []
|
||||
|
||||
for elem in list(root):
|
||||
if not hasattr(elem, "tag") or callable(elem.tag):
|
||||
continue
|
||||
|
||||
tag_str = str(elem.tag)
|
||||
if tag_str.startswith("{"):
|
||||
ns = tag_str.split("}")[0][1:]
|
||||
if ns not in self.OOXML_NAMESPACES:
|
||||
elements_to_remove.append(elem)
|
||||
continue
|
||||
|
||||
self._remove_ignorable_elements(elem)
|
||||
|
||||
for elem in elements_to_remove:
|
||||
root.remove(elem)
|
||||
|
||||
def _preprocess_for_mc_ignorable(self, xml_doc):
|
||||
root = xml_doc.getroot()
|
||||
|
||||
if f"{{{self.MC_NAMESPACE}}}Ignorable" in root.attrib:
|
||||
del root.attrib[f"{{{self.MC_NAMESPACE}}}Ignorable"]
|
||||
|
||||
return xml_doc
|
||||
|
||||
def _validate_single_file_xsd(self, xml_file, base_path):
|
||||
schema_path = self._get_schema_path(xml_file)
|
||||
if not schema_path:
|
||||
return None, None
|
||||
|
||||
try:
|
||||
with open(schema_path, "rb") as xsd_file:
|
||||
parser = lxml.etree.XMLParser()
|
||||
xsd_doc = lxml.etree.parse(
|
||||
xsd_file, parser=parser, base_url=str(schema_path)
|
||||
)
|
||||
schema = lxml.etree.XMLSchema(xsd_doc)
|
||||
|
||||
with open(xml_file, "r") as f:
|
||||
xml_doc = lxml.etree.parse(f)
|
||||
|
||||
xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)
|
||||
xml_doc = self._preprocess_for_mc_ignorable(xml_doc)
|
||||
|
||||
relative_path = xml_file.relative_to(base_path)
|
||||
if (
|
||||
relative_path.parts
|
||||
and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS
|
||||
):
|
||||
xml_doc = self._clean_ignorable_namespaces(xml_doc)
|
||||
|
||||
if schema.validate(xml_doc):
|
||||
return True, set()
|
||||
else:
|
||||
errors = set()
|
||||
for error in schema.error_log:
|
||||
errors.add(error.message)
|
||||
return False, errors
|
||||
|
||||
except Exception as e:
|
||||
return False, {str(e)}
|
||||
|
||||
def _get_original_file_errors(self, xml_file):
|
||||
if self.original_file is None:
|
||||
return set()
|
||||
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
xml_file = Path(xml_file).resolve()
|
||||
unpacked_dir = self.unpacked_dir.resolve()
|
||||
relative_path = xml_file.relative_to(unpacked_dir)
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
with zipfile.ZipFile(self.original_file, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_path)
|
||||
|
||||
original_xml_file = temp_path / relative_path
|
||||
|
||||
if not original_xml_file.exists():
|
||||
return set()
|
||||
|
||||
is_valid, errors = self._validate_single_file_xsd(
|
||||
original_xml_file, temp_path
|
||||
)
|
||||
return errors if errors else set()
|
||||
|
||||
def _remove_template_tags_from_text_nodes(self, xml_doc):
|
||||
warnings = []
|
||||
template_pattern = re.compile(r"\{\{[^}]*\}\}")
|
||||
|
||||
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
|
||||
xml_copy = lxml.etree.fromstring(xml_string)
|
||||
|
||||
def process_text_content(text, content_type):
|
||||
if not text:
|
||||
return text
|
||||
matches = list(template_pattern.finditer(text))
|
||||
if matches:
|
||||
for match in matches:
|
||||
warnings.append(
|
||||
f"Found template tag in {content_type}: {match.group()}"
|
||||
)
|
||||
return template_pattern.sub("", text)
|
||||
return text
|
||||
|
||||
for elem in xml_copy.iter():
|
||||
if not hasattr(elem, "tag") or callable(elem.tag):
|
||||
continue
|
||||
tag_str = str(elem.tag)
|
||||
if tag_str.endswith("}t") or tag_str == "t":
|
||||
continue
|
||||
|
||||
elem.text = process_text_content(elem.text, "text content")
|
||||
elem.tail = process_text_content(elem.tail, "tail content")
|
||||
|
||||
return lxml.etree.ElementTree(xml_copy), warnings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
@@ -0,0 +1,446 @@
|
||||
"""
|
||||
Validator for Word document XML files against XSD schemas.
|
||||
"""
|
||||
|
||||
import random
|
||||
import re
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
import defusedxml.minidom
|
||||
import lxml.etree
|
||||
|
||||
from .base import BaseSchemaValidator
|
||||
|
||||
|
||||
class DOCXSchemaValidator(BaseSchemaValidator):
|
||||
|
||||
WORD_2006_NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
W14_NAMESPACE = "http://schemas.microsoft.com/office/word/2010/wordml"
|
||||
W16CID_NAMESPACE = "http://schemas.microsoft.com/office/word/2016/wordml/cid"
|
||||
|
||||
ELEMENT_RELATIONSHIP_TYPES = {}
|
||||
|
||||
def validate(self):
|
||||
if not self.validate_xml():
|
||||
return False
|
||||
|
||||
all_valid = True
|
||||
if not self.validate_namespaces():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_unique_ids():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_file_references():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_content_types():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_against_xsd():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_whitespace_preservation():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_deletions():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_insertions():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_all_relationship_ids():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_id_constraints():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_comment_markers():
|
||||
all_valid = False
|
||||
|
||||
self.compare_paragraph_counts()
|
||||
|
||||
return all_valid
|
||||
|
||||
def validate_whitespace_preservation(self):
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
for elem in root.iter(f"{{{self.WORD_2006_NAMESPACE}}}t"):
|
||||
if elem.text:
|
||||
text = elem.text
|
||||
if re.search(r"^[ \t\n\r]", text) or re.search(
|
||||
r"[ \t\n\r]$", text
|
||||
):
|
||||
xml_space_attr = f"{{{self.XML_NAMESPACE}}}space"
|
||||
if (
|
||||
xml_space_attr not in elem.attrib
|
||||
or elem.attrib[xml_space_attr] != "preserve"
|
||||
):
|
||||
text_preview = (
|
||||
repr(text)[:50] + "..."
|
||||
if len(repr(text)) > 50
|
||||
else repr(text)
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} whitespace preservation violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All whitespace is properly preserved")
|
||||
return True
|
||||
|
||||
def validate_deletions(self):
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
namespaces = {"w": self.WORD_2006_NAMESPACE}
|
||||
|
||||
for t_elem in root.xpath(".//w:del//w:t", namespaces=namespaces):
|
||||
if t_elem.text:
|
||||
text_preview = (
|
||||
repr(t_elem.text)[:50] + "..."
|
||||
if len(repr(t_elem.text)) > 50
|
||||
else repr(t_elem.text)
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}"
|
||||
)
|
||||
|
||||
for instr_elem in root.xpath(
|
||||
".//w:del//w:instrText", namespaces=namespaces
|
||||
):
|
||||
text_preview = (
|
||||
repr(instr_elem.text or "")[:50] + "..."
|
||||
if len(repr(instr_elem.text or "")) > 50
|
||||
else repr(instr_elem.text or "")
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {instr_elem.sourceline}: <w:instrText> found within <w:del> (use <w:delInstrText>): {text_preview}"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} deletion validation violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - No w:t elements found within w:del elements")
|
||||
return True
|
||||
|
||||
def count_paragraphs_in_unpacked(self):
|
||||
count = 0
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
|
||||
count = len(paragraphs)
|
||||
except Exception as e:
|
||||
print(f"Error counting paragraphs in unpacked document: {e}")
|
||||
|
||||
return count
|
||||
|
||||
def count_paragraphs_in_original(self):
|
||||
original = self.original_file
|
||||
if original is None:
|
||||
return 0
|
||||
|
||||
count = 0
|
||||
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
with zipfile.ZipFile(original, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_dir)
|
||||
|
||||
doc_xml_path = temp_dir + "/word/document.xml"
|
||||
root = lxml.etree.parse(doc_xml_path).getroot()
|
||||
|
||||
paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
|
||||
count = len(paragraphs)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error counting paragraphs in original document: {e}")
|
||||
|
||||
return count
|
||||
|
||||
def validate_insertions(self):
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
namespaces = {"w": self.WORD_2006_NAMESPACE}
|
||||
|
||||
invalid_elements = root.xpath(
|
||||
".//w:ins//w:delText[not(ancestor::w:del)]", namespaces=namespaces
|
||||
)
|
||||
|
||||
for elem in invalid_elements:
|
||||
text_preview = (
|
||||
repr(elem.text or "")[:50] + "..."
|
||||
if len(repr(elem.text or "")) > 50
|
||||
else repr(elem.text or "")
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} insertion validation violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - No w:delText elements within w:ins elements")
|
||||
return True
|
||||
|
||||
def compare_paragraph_counts(self):
|
||||
original_count = self.count_paragraphs_in_original()
|
||||
new_count = self.count_paragraphs_in_unpacked()
|
||||
|
||||
diff = new_count - original_count
|
||||
diff_str = f"+{diff}" if diff > 0 else str(diff)
|
||||
print(f"\nParagraphs: {original_count} → {new_count} ({diff_str})")
|
||||
|
||||
def _parse_id_value(self, val: str, base: int = 16) -> int:
|
||||
return int(val, base)
|
||||
|
||||
def validate_id_constraints(self):
|
||||
errors = []
|
||||
para_id_attr = f"{{{self.W14_NAMESPACE}}}paraId"
|
||||
durable_id_attr = f"{{{self.W16CID_NAMESPACE}}}durableId"
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
for elem in lxml.etree.parse(str(xml_file)).iter():
|
||||
if val := elem.get(para_id_attr):
|
||||
if self._parse_id_value(val, base=16) >= 0x80000000:
|
||||
errors.append(
|
||||
f" {xml_file.name}:{elem.sourceline}: paraId={val} >= 0x80000000"
|
||||
)
|
||||
|
||||
if val := elem.get(durable_id_attr):
|
||||
if xml_file.name == "numbering.xml":
|
||||
try:
|
||||
if self._parse_id_value(val, base=10) >= 0x7FFFFFFF:
|
||||
errors.append(
|
||||
f" {xml_file.name}:{elem.sourceline}: "
|
||||
f"durableId={val} >= 0x7FFFFFFF"
|
||||
)
|
||||
except ValueError:
|
||||
errors.append(
|
||||
f" {xml_file.name}:{elem.sourceline}: "
|
||||
f"durableId={val} must be decimal in numbering.xml"
|
||||
)
|
||||
else:
|
||||
if self._parse_id_value(val, base=16) >= 0x7FFFFFFF:
|
||||
errors.append(
|
||||
f" {xml_file.name}:{elem.sourceline}: "
|
||||
f"durableId={val} >= 0x7FFFFFFF"
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - {len(errors)} ID constraint violations:")
|
||||
for e in errors:
|
||||
print(e)
|
||||
elif self.verbose:
|
||||
print("PASSED - All paraId/durableId values within constraints")
|
||||
return not errors
|
||||
|
||||
def validate_comment_markers(self):
|
||||
errors = []
|
||||
|
||||
document_xml = None
|
||||
comments_xml = None
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.name == "document.xml" and "word" in str(xml_file):
|
||||
document_xml = xml_file
|
||||
elif xml_file.name == "comments.xml":
|
||||
comments_xml = xml_file
|
||||
|
||||
if not document_xml:
|
||||
if self.verbose:
|
||||
print("PASSED - No document.xml found (skipping comment validation)")
|
||||
return True
|
||||
|
||||
try:
|
||||
doc_root = lxml.etree.parse(str(document_xml)).getroot()
|
||||
namespaces = {"w": self.WORD_2006_NAMESPACE}
|
||||
|
||||
range_starts = {
|
||||
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
|
||||
for elem in doc_root.xpath(
|
||||
".//w:commentRangeStart", namespaces=namespaces
|
||||
)
|
||||
}
|
||||
range_ends = {
|
||||
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
|
||||
for elem in doc_root.xpath(
|
||||
".//w:commentRangeEnd", namespaces=namespaces
|
||||
)
|
||||
}
|
||||
references = {
|
||||
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
|
||||
for elem in doc_root.xpath(
|
||||
".//w:commentReference", namespaces=namespaces
|
||||
)
|
||||
}
|
||||
|
||||
orphaned_ends = range_ends - range_starts
|
||||
for comment_id in sorted(
|
||||
orphaned_ends, key=lambda x: int(x) if x and x.isdigit() else 0
|
||||
):
|
||||
errors.append(
|
||||
f' document.xml: commentRangeEnd id="{comment_id}" has no matching commentRangeStart'
|
||||
)
|
||||
|
||||
orphaned_starts = range_starts - range_ends
|
||||
for comment_id in sorted(
|
||||
orphaned_starts, key=lambda x: int(x) if x and x.isdigit() else 0
|
||||
):
|
||||
errors.append(
|
||||
f' document.xml: commentRangeStart id="{comment_id}" has no matching commentRangeEnd'
|
||||
)
|
||||
|
||||
comment_ids = set()
|
||||
if comments_xml and comments_xml.exists():
|
||||
comments_root = lxml.etree.parse(str(comments_xml)).getroot()
|
||||
comment_ids = {
|
||||
elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
|
||||
for elem in comments_root.xpath(
|
||||
".//w:comment", namespaces=namespaces
|
||||
)
|
||||
}
|
||||
|
||||
marker_ids = range_starts | range_ends | references
|
||||
invalid_refs = marker_ids - comment_ids
|
||||
for comment_id in sorted(
|
||||
invalid_refs, key=lambda x: int(x) if x and x.isdigit() else 0
|
||||
):
|
||||
if comment_id:
|
||||
errors.append(
|
||||
f' document.xml: marker id="{comment_id}" references non-existent comment'
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(f" Error parsing XML: {e}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - {len(errors)} comment marker violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All comment markers properly paired")
|
||||
return True
|
||||
|
||||
def repair(self) -> int:
|
||||
repairs = super().repair()
|
||||
repairs += self.repair_durableId()
|
||||
return repairs
|
||||
|
||||
def repair_durableId(self) -> int:
|
||||
repairs = 0
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
content = xml_file.read_text(encoding="utf-8")
|
||||
dom = defusedxml.minidom.parseString(content)
|
||||
modified = False
|
||||
|
||||
for elem in dom.getElementsByTagName("*"):
|
||||
if not elem.hasAttribute("w16cid:durableId"):
|
||||
continue
|
||||
|
||||
durable_id = elem.getAttribute("w16cid:durableId")
|
||||
needs_repair = False
|
||||
|
||||
if xml_file.name == "numbering.xml":
|
||||
try:
|
||||
needs_repair = (
|
||||
self._parse_id_value(durable_id, base=10) >= 0x7FFFFFFF
|
||||
)
|
||||
except ValueError:
|
||||
needs_repair = True
|
||||
else:
|
||||
try:
|
||||
needs_repair = (
|
||||
self._parse_id_value(durable_id, base=16) >= 0x7FFFFFFF
|
||||
)
|
||||
except ValueError:
|
||||
needs_repair = True
|
||||
|
||||
if needs_repair:
|
||||
value = random.randint(1, 0x7FFFFFFE)
|
||||
if xml_file.name == "numbering.xml":
|
||||
new_id = str(value)
|
||||
else:
|
||||
new_id = f"{value:08X}"
|
||||
|
||||
elem.setAttribute("w16cid:durableId", new_id)
|
||||
print(
|
||||
f" Repaired: {xml_file.name}: durableId {durable_id} → {new_id}"
|
||||
)
|
||||
repairs += 1
|
||||
modified = True
|
||||
|
||||
if modified:
|
||||
xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return repairs
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
@@ -0,0 +1,275 @@
|
||||
"""
|
||||
Validator for PowerPoint presentation XML files against XSD schemas.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from .base import BaseSchemaValidator
|
||||
|
||||
|
||||
class PPTXSchemaValidator(BaseSchemaValidator):
|
||||
|
||||
PRESENTATIONML_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/presentationml/2006/main"
|
||||
)
|
||||
|
||||
ELEMENT_RELATIONSHIP_TYPES = {
|
||||
"sldid": "slide",
|
||||
"sldmasterid": "slidemaster",
|
||||
"notesmasterid": "notesmaster",
|
||||
"sldlayoutid": "slidelayout",
|
||||
"themeid": "theme",
|
||||
"tablestyleid": "tablestyles",
|
||||
}
|
||||
|
||||
def validate(self):
|
||||
if not self.validate_xml():
|
||||
return False
|
||||
|
||||
all_valid = True
|
||||
if not self.validate_namespaces():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_unique_ids():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_uuid_ids():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_file_references():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_slide_layout_ids():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_content_types():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_against_xsd():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_notes_slide_references():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_all_relationship_ids():
|
||||
all_valid = False
|
||||
|
||||
if not self.validate_no_duplicate_slide_layouts():
|
||||
all_valid = False
|
||||
|
||||
return all_valid
|
||||
|
||||
def validate_uuid_ids(self):
|
||||
import lxml.etree
|
||||
|
||||
errors = []
|
||||
uuid_pattern = re.compile(
|
||||
r"^[\{\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\}\)]?$"
|
||||
)
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
for elem in root.iter():
|
||||
for attr, value in elem.attrib.items():
|
||||
attr_name = attr.split("}")[-1].lower()
|
||||
if attr_name == "id" or attr_name.endswith("id"):
|
||||
if self._looks_like_uuid(value):
|
||||
if not uuid_pattern.match(value):
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} UUID ID validation errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All UUID-like IDs contain valid hex values")
|
||||
return True
|
||||
|
||||
def _looks_like_uuid(self, value):
|
||||
clean_value = value.strip("{}()").replace("-", "")
|
||||
return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)
|
||||
|
||||
def validate_slide_layout_ids(self):
|
||||
import lxml.etree
|
||||
|
||||
errors = []
|
||||
|
||||
slide_masters = list(self.unpacked_dir.glob("ppt/slideMasters/*.xml"))
|
||||
|
||||
if not slide_masters:
|
||||
if self.verbose:
|
||||
print("PASSED - No slide masters found")
|
||||
return True
|
||||
|
||||
for slide_master in slide_masters:
|
||||
try:
|
||||
root = lxml.etree.parse(str(slide_master)).getroot()
|
||||
|
||||
rels_file = slide_master.parent / "_rels" / f"{slide_master.name}.rels"
|
||||
|
||||
if not rels_file.exists():
|
||||
errors.append(
|
||||
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
||||
f"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}"
|
||||
)
|
||||
continue
|
||||
|
||||
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
valid_layout_rids = set()
|
||||
for rel in rels_root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
):
|
||||
rel_type = rel.get("Type", "")
|
||||
if "slideLayout" in rel_type:
|
||||
valid_layout_rids.add(rel.get("Id"))
|
||||
|
||||
for sld_layout_id in root.findall(
|
||||
f".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId"
|
||||
):
|
||||
r_id = sld_layout_id.get(
|
||||
f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id"
|
||||
)
|
||||
layout_id = sld_layout_id.get("id")
|
||||
|
||||
if r_id and r_id not in valid_layout_rids:
|
||||
errors.append(
|
||||
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' "
|
||||
f"references r:id='{r_id}' which is not found in slide layout relationships"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {slide_master.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} slide layout ID validation errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print(
|
||||
"Remove invalid references or add missing slide layouts to the relationships file."
|
||||
)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All slide layout IDs reference valid slide layouts")
|
||||
return True
|
||||
|
||||
def validate_no_duplicate_slide_layouts(self):
|
||||
import lxml.etree
|
||||
|
||||
errors = []
|
||||
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
||||
|
||||
for rels_file in slide_rels_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
layout_rels = [
|
||||
rel
|
||||
for rel in root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
)
|
||||
if "slideLayout" in rel.get("Type", "")
|
||||
]
|
||||
|
||||
if len(layout_rels) > 1:
|
||||
errors.append(
|
||||
f" {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
errors.append(
|
||||
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print("FAILED - Found slides with duplicate slideLayout references:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All slides have exactly one slideLayout reference")
|
||||
return True
|
||||
|
||||
def validate_notes_slide_references(self):
|
||||
import lxml.etree
|
||||
|
||||
errors = []
|
||||
notes_slide_references = {}
|
||||
|
||||
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
||||
|
||||
if not slide_rels_files:
|
||||
if self.verbose:
|
||||
print("PASSED - No slide relationship files found")
|
||||
return True
|
||||
|
||||
for rels_file in slide_rels_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
for rel in root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
):
|
||||
rel_type = rel.get("Type", "")
|
||||
if "notesSlide" in rel_type:
|
||||
target = rel.get("Target", "")
|
||||
if target:
|
||||
normalized_target = target.replace("../", "")
|
||||
|
||||
slide_name = rels_file.stem.replace(
|
||||
".xml", ""
|
||||
)
|
||||
|
||||
if normalized_target not in notes_slide_references:
|
||||
notes_slide_references[normalized_target] = []
|
||||
notes_slide_references[normalized_target].append(
|
||||
(slide_name, rels_file)
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
for target, references in notes_slide_references.items():
|
||||
if len(references) > 1:
|
||||
slide_names = [ref[0] for ref in references]
|
||||
errors.append(
|
||||
f" Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}"
|
||||
)
|
||||
for slide_name, rels_file in references:
|
||||
errors.append(f" - {rels_file.relative_to(self.unpacked_dir)}")
|
||||
|
||||
if errors:
|
||||
print(
|
||||
f"FAILED - Found {len([e for e in errors if not e.startswith(' ')])} notes slide reference validation errors:"
|
||||
)
|
||||
for error in errors:
|
||||
print(error)
|
||||
print("Each slide may optionally have its own slide file.")
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All notes slide references are unique")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
@@ -0,0 +1,247 @@
|
||||
"""
|
||||
Validator for tracked changes in Word documents.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import tempfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class RedliningValidator:
|
||||
|
||||
def __init__(self, unpacked_dir, original_docx, verbose=False, author="Claude"):
|
||||
self.unpacked_dir = Path(unpacked_dir)
|
||||
self.original_docx = Path(original_docx)
|
||||
self.verbose = verbose
|
||||
self.author = author
|
||||
self.namespaces = {
|
||||
"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
}
|
||||
|
||||
def repair(self) -> int:
|
||||
return 0
|
||||
|
||||
def validate(self):
|
||||
modified_file = self.unpacked_dir / "word" / "document.xml"
|
||||
if not modified_file.exists():
|
||||
print(f"FAILED - Modified document.xml not found at {modified_file}")
|
||||
return False
|
||||
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
tree = ET.parse(modified_file)
|
||||
root = tree.getroot()
|
||||
|
||||
del_elements = root.findall(".//w:del", self.namespaces)
|
||||
ins_elements = root.findall(".//w:ins", self.namespaces)
|
||||
|
||||
author_del_elements = [
|
||||
elem
|
||||
for elem in del_elements
|
||||
if elem.get(f"{{{self.namespaces['w']}}}author") == self.author
|
||||
]
|
||||
author_ins_elements = [
|
||||
elem
|
||||
for elem in ins_elements
|
||||
if elem.get(f"{{{self.namespaces['w']}}}author") == self.author
|
||||
]
|
||||
|
||||
if not author_del_elements and not author_ins_elements:
|
||||
if self.verbose:
|
||||
print(f"PASSED - No tracked changes by {self.author} found.")
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
try:
|
||||
with zipfile.ZipFile(self.original_docx, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_path)
|
||||
except Exception as e:
|
||||
print(f"FAILED - Error unpacking original docx: {e}")
|
||||
return False
|
||||
|
||||
original_file = temp_path / "word" / "document.xml"
|
||||
if not original_file.exists():
|
||||
print(
|
||||
f"FAILED - Original document.xml not found in {self.original_docx}"
|
||||
)
|
||||
return False
|
||||
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
modified_tree = ET.parse(modified_file)
|
||||
modified_root = modified_tree.getroot()
|
||||
original_tree = ET.parse(original_file)
|
||||
original_root = original_tree.getroot()
|
||||
except ET.ParseError as e:
|
||||
print(f"FAILED - Error parsing XML files: {e}")
|
||||
return False
|
||||
|
||||
self._remove_author_tracked_changes(original_root)
|
||||
self._remove_author_tracked_changes(modified_root)
|
||||
|
||||
modified_text = self._extract_text_content(modified_root)
|
||||
original_text = self._extract_text_content(original_root)
|
||||
|
||||
if modified_text != original_text:
|
||||
error_message = self._generate_detailed_diff(
|
||||
original_text, modified_text
|
||||
)
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
if self.verbose:
|
||||
print(f"PASSED - All changes by {self.author} are properly tracked")
|
||||
return True
|
||||
|
||||
def _generate_detailed_diff(self, original_text, modified_text):
|
||||
error_parts = [
|
||||
f"FAILED - Document text doesn't match after removing {self.author}'s tracked changes",
|
||||
"",
|
||||
"Likely causes:",
|
||||
" 1. Modified text inside another author's <w:ins> or <w:del> tags",
|
||||
" 2. Made edits without proper tracked changes",
|
||||
" 3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion",
|
||||
"",
|
||||
"For pre-redlined documents, use correct patterns:",
|
||||
" - To reject another's INSERTION: Nest <w:del> inside their <w:ins>",
|
||||
" - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>",
|
||||
"",
|
||||
]
|
||||
|
||||
git_diff = self._get_git_word_diff(original_text, modified_text)
|
||||
if git_diff:
|
||||
error_parts.extend(["Differences:", "============", git_diff])
|
||||
else:
|
||||
error_parts.append("Unable to generate word diff (git not available)")
|
||||
|
||||
return "\n".join(error_parts)
|
||||
|
||||
def _get_git_word_diff(self, original_text, modified_text):
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
original_file = temp_path / "original.txt"
|
||||
modified_file = temp_path / "modified.txt"
|
||||
|
||||
original_file.write_text(original_text, encoding="utf-8")
|
||||
modified_file.write_text(modified_text, encoding="utf-8")
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"diff",
|
||||
"--word-diff=plain",
|
||||
"--word-diff-regex=.",
|
||||
"-U0",
|
||||
"--no-index",
|
||||
str(original_file),
|
||||
str(modified_file),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if result.stdout.strip():
|
||||
lines = result.stdout.split("\n")
|
||||
content_lines = []
|
||||
in_content = False
|
||||
for line in lines:
|
||||
if line.startswith("@@"):
|
||||
in_content = True
|
||||
continue
|
||||
if in_content and line.strip():
|
||||
content_lines.append(line)
|
||||
|
||||
if content_lines:
|
||||
return "\n".join(content_lines)
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"diff",
|
||||
"--word-diff=plain",
|
||||
"-U0",
|
||||
"--no-index",
|
||||
str(original_file),
|
||||
str(modified_file),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if result.stdout.strip():
|
||||
lines = result.stdout.split("\n")
|
||||
content_lines = []
|
||||
in_content = False
|
||||
for line in lines:
|
||||
if line.startswith("@@"):
|
||||
in_content = True
|
||||
continue
|
||||
if in_content and line.strip():
|
||||
content_lines.append(line)
|
||||
return "\n".join(content_lines)
|
||||
|
||||
except (subprocess.CalledProcessError, FileNotFoundError, Exception):
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
def _remove_author_tracked_changes(self, root):
|
||||
ins_tag = f"{{{self.namespaces['w']}}}ins"
|
||||
del_tag = f"{{{self.namespaces['w']}}}del"
|
||||
author_attr = f"{{{self.namespaces['w']}}}author"
|
||||
|
||||
for parent in root.iter():
|
||||
to_remove = []
|
||||
for child in parent:
|
||||
if child.tag == ins_tag and child.get(author_attr) == self.author:
|
||||
to_remove.append(child)
|
||||
for elem in to_remove:
|
||||
parent.remove(elem)
|
||||
|
||||
deltext_tag = f"{{{self.namespaces['w']}}}delText"
|
||||
t_tag = f"{{{self.namespaces['w']}}}t"
|
||||
|
||||
for parent in root.iter():
|
||||
to_process = []
|
||||
for child in parent:
|
||||
if child.tag == del_tag and child.get(author_attr) == self.author:
|
||||
to_process.append((child, list(parent).index(child)))
|
||||
|
||||
for del_elem, del_index in reversed(to_process):
|
||||
for elem in del_elem.iter():
|
||||
if elem.tag == deltext_tag:
|
||||
elem.tag = t_tag
|
||||
|
||||
for child in reversed(list(del_elem)):
|
||||
parent.insert(del_index, child)
|
||||
parent.remove(del_elem)
|
||||
|
||||
def _extract_text_content(self, root):
|
||||
p_tag = f"{{{self.namespaces['w']}}}p"
|
||||
t_tag = f"{{{self.namespaces['w']}}}t"
|
||||
|
||||
paragraphs = []
|
||||
for p_elem in root.findall(f".//{p_tag}"):
|
||||
text_parts = []
|
||||
for t_elem in p_elem.findall(f".//{t_tag}"):
|
||||
if t_elem.text:
|
||||
text_parts.append(t_elem.text)
|
||||
paragraph_text = "".join(text_parts)
|
||||
if paragraph_text:
|
||||
paragraphs.append(paragraph_text)
|
||||
|
||||
return "\n".join(paragraphs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" ?>
|
||||
<w:comments xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">
|
||||
</w:comments>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" ?>
|
||||
<w15:commentsEx xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">
|
||||
</w15:commentsEx>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" ?>
|
||||
<w16cex:commentsExtensible xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:cr="http://schemas.microsoft.com/office/comments/2020/reactions" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl cr w16du wp14">
|
||||
</w16cex:commentsExtensible>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" ?>
|
||||
<w16cid:commentsIds xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">
|
||||
</w16cid:commentsIds>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" ?>
|
||||
<w15:people xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml">
|
||||
</w15:people>
|
||||
@@ -0,0 +1,8 @@
|
||||
# skills
|
||||
|
||||
## Documentação
|
||||
|
||||
- [README](README.md)
|
||||
- [AGENTS](AGENTS.md)
|
||||
- [STATUS](STATUS.md)
|
||||
- [MEMORY](MEMORY.md)
|
||||
@@ -0,0 +1 @@
|
||||
## 2026-06-30 init | Estrutura padrão
|
||||
@@ -0,0 +1,233 @@
|
||||
---
|
||||
name: nextjs
|
||||
description: Desenvolvimento Next.js moderno (13+) com App Router, Server Components, rotas API e deployment seguindo padroes Descomplicar.
|
||||
layer: wiki
|
||||
---
|
||||
|
||||
# /nextjs - Next.js Development
|
||||
|
||||
Desenvolvimento Next.js moderno (13+) com App Router e Server Components.
|
||||
|
||||
---
|
||||
|
||||
## Contexto NotebookLM
|
||||
|
||||
```
|
||||
mcp__notebooklm__notebook_query({
|
||||
notebook_id: "24947ffa-0019-448a-a340-2f4a275d2eb1",
|
||||
query: "<adaptar ao contexto do pedido>"
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Regra #48 - Dev Container (OBRIGATÓRIO)
|
||||
|
||||
**TODOS os projectos Next.js devem ser desenvolvidos no container dev.**
|
||||
|
||||
```
|
||||
SSH: server="dev" (mcp__ssh-unified__ssh_execute)
|
||||
Path: /root/Dev/<projecto>
|
||||
Sync: auto -> /media/ealmeida/Dados/Dev/<projecto> (Syncthing)
|
||||
```
|
||||
|
||||
**Workflow:**
|
||||
1. `mcp__ssh-unified__ssh_execute server:"dev" command:"mkdir -p /root/Dev/<projecto>"`
|
||||
2. Desenvolver e testar no container
|
||||
3. `npm run build` no container antes de deploy
|
||||
4. Deploy via EasyPanel
|
||||
5. Syncthing propaga automaticamente
|
||||
|
||||
**NUNCA:** `npx create-next-app` directamente no PC local para projectos colaborativos.
|
||||
|
||||
---
|
||||
|
||||
## App Router Structure
|
||||
|
||||
```
|
||||
app/
|
||||
├── layout.tsx # Root layout (obrigatório)
|
||||
├── page.tsx # Home page
|
||||
├── loading.tsx # Loading UI (Suspense)
|
||||
├── error.tsx # Error boundary
|
||||
├── not-found.tsx # 404 page
|
||||
├── (auth)/ # Route group (não afecta URL)
|
||||
│ ├── login/page.tsx
|
||||
│ └── register/page.tsx
|
||||
├── dashboard/
|
||||
│ ├── layout.tsx
|
||||
│ ├── page.tsx
|
||||
│ └── [id]/page.tsx # Dynamic route
|
||||
└── api/route.ts # API route
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Server vs Client Components
|
||||
|
||||
### Server Component (default)
|
||||
|
||||
```tsx
|
||||
async function ProductsPage() {
|
||||
const products = await db.product.findMany();
|
||||
return <div>{products.map(p => <ProductCard key={p.id} product={p} />)}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
### Client Component
|
||||
|
||||
```tsx
|
||||
'use client';
|
||||
import { useState } from 'react';
|
||||
|
||||
function Counter() {
|
||||
const [count, setCount] = useState(0);
|
||||
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Fetching Patterns
|
||||
|
||||
```tsx
|
||||
// Static (SSG) - default
|
||||
const data = await fetch('https://api.example.com/data', { cache: 'force-cache' });
|
||||
|
||||
// Dynamic (SSR)
|
||||
const data = await fetch('https://api.example.com/data', { cache: 'no-store' });
|
||||
|
||||
// ISR - revalidação automática
|
||||
const data = await fetch('https://api.example.com/data', { next: { revalidate: 60 } });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Server Actions
|
||||
|
||||
```tsx
|
||||
// app/actions.ts
|
||||
'use server';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
|
||||
export async function createPost(formData: FormData) {
|
||||
const title = formData.get('title') as string;
|
||||
await db.post.create({ data: { title } });
|
||||
revalidatePath('/posts');
|
||||
}
|
||||
|
||||
// Uso no form:
|
||||
<form action={createPost}>
|
||||
<input name="title" required />
|
||||
<button type="submit">Create</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Routing Avançado
|
||||
|
||||
### Middleware
|
||||
|
||||
```tsx
|
||||
// middleware.ts
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
const token = request.cookies.get('token');
|
||||
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
|
||||
return NextResponse.redirect(new URL('/login', request.url));
|
||||
}
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
export const config = { matcher: ['/dashboard/:path*'] };
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Optimizações
|
||||
|
||||
### Images
|
||||
```tsx
|
||||
import Image from 'next/image';
|
||||
<Image src="/photo.jpg" width={500} height={300} alt="Photo" priority />
|
||||
```
|
||||
|
||||
### Metadata (SEO)
|
||||
```tsx
|
||||
export const metadata = {
|
||||
title: 'Home',
|
||||
description: 'Home page',
|
||||
openGraph: { title: 'Home', images: ['/og-image.jpg'] },
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance (Prioridades)
|
||||
|
||||
| Prioridade | Categoria | Ganho |
|
||||
|---|---|---|
|
||||
| CRITICAL | Eliminar Waterfalls (Promise.all) | 2-10x latência |
|
||||
| CRITICAL | Bundle Size (dynamic imports) | 200-800ms load |
|
||||
| HIGH | Server-Side (auth actions, React.cache) | RSC payload |
|
||||
| MEDIUM | Re-renders (derived state, functional setState) | Responsividade |
|
||||
|
||||
Para todas as 57 regras com exemplos de código: ver `references/performance-rules.md`
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### Docker
|
||||
|
||||
```dockerfile
|
||||
FROM node:18-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/package*.json ./
|
||||
RUN npm ci --production
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Datasets Dify
|
||||
|
||||
| Dataset | ID |
|
||||
|---------|-----|
|
||||
| Desenvolvimento de Software | `e7c7decc-0ded-4351-ab14-b110b3c38ec9` |
|
||||
| TI | `7f63ec0c-6321-488c-b107-980140199850` |
|
||||
|
||||
---
|
||||
|
||||
## Referências
|
||||
|
||||
- `references/performance-rules.md` - 57 regras de performance com exemplos completos
|
||||
|
||||
---
|
||||
|
||||
*Versão 1.0.0 | Descomplicar®*
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
|
||||
*Adicionar nova linha após cada erro corrigido.*
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user