Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
f91a301
Push the initial version of Substrate
AttilaMihaly Apr 23, 2026
54ddac8
Enhancements
AttilaMihaly Apr 23, 2026
f4ba5b8
Added init command
AttilaMihaly Apr 23, 2026
bf05258
Added init command
AttilaMihaly Apr 23, 2026
adfdfbc
Package management enhancements
AttilaMihaly Apr 23, 2026
dd5f25b
Package management enhancements
AttilaMihaly Apr 23, 2026
b582b8e
Package management enhancements.
AttilaMihaly Apr 23, 2026
10dbf74
Package management enhancements.
AttilaMihaly Apr 23, 2026
cf60adf
Added language package.
AttilaMihaly Apr 23, 2026
8b746c3
Added language package.
AttilaMihaly Apr 23, 2026
f15c9e3
Move substrate.json.
AttilaMihaly Apr 23, 2026
e499f11
Move substrate.json.
AttilaMihaly Apr 23, 2026
f0f1134
Allow any package name
AttilaMihaly Apr 23, 2026
bf849e5
Allow any package name
AttilaMihaly Apr 23, 2026
652ae92
Added context generator cli tool and updated language specs for effic…
AttilaMihaly Apr 23, 2026
ce5736e
Added context generator cli tool and updated language specs for effic…
AttilaMihaly Apr 23, 2026
218c2b1
Make contexts command work for root relative paths as well.
AttilaMihaly Apr 23, 2026
aedeffb
Make contexts command work for root relative paths as well.
AttilaMihaly Apr 23, 2026
55aeaef
Added no tree shaking option and stats command.
AttilaMihaly Apr 24, 2026
9257d44
Added no tree shaking option and stats command.
AttilaMihaly Apr 24, 2026
c40cb52
Enhancements
AttilaMihaly Apr 24, 2026
f9642b8
Enhancements
AttilaMihaly Apr 24, 2026
d003821
Added refactor command
AttilaMihaly Apr 24, 2026
11a31e8
Added refactor command
AttilaMihaly Apr 24, 2026
496e7d6
Fixed refactor command. Renamed type to datatype.
AttilaMihaly Apr 24, 2026
0e24e8d
Fixed refactor command. Renamed type to datatype.
AttilaMihaly Apr 24, 2026
3f2dc2a
Fix validate command
AttilaMihaly Apr 24, 2026
f3530a9
Fix validate command
AttilaMihaly Apr 24, 2026
6e6931e
added todo
AttilaMihaly Apr 24, 2026
25f6a56
added todo
AttilaMihaly Apr 24, 2026
1f6edf8
Refined vision and readme.
AttilaMihaly Apr 27, 2026
9f1903e
Refined vision and readme.
AttilaMihaly Apr 27, 2026
dff8bf7
Refine messaging
AttilaMihaly Apr 27, 2026
5b4523a
Refine messaging
AttilaMihaly Apr 27, 2026
6e30b26
Refined the role of engineers
AttilaMihaly Apr 27, 2026
d4213f2
Refined the role of engineers
AttilaMihaly Apr 27, 2026
96129e3
Updated docs
AttilaMihaly Apr 27, 2026
ed08064
Updated docs
AttilaMihaly Apr 27, 2026
472b9e2
Refine dataset.
AttilaMihaly Apr 27, 2026
868bb70
Refine dataset.
AttilaMihaly Apr 27, 2026
0ba66f9
Added horizontals
AttilaMihaly Apr 27, 2026
e6f9392
Added horizontals
AttilaMihaly Apr 27, 2026
84c6f64
Extracting FR 2052a into markdown for later translation to substrate.
AttilaMihaly May 1, 2026
77acf29
Exclude Obsidian files.
AttilaMihaly May 1, 2026
04f93b3
Support for building data processing solutions.
AttilaMihaly May 1, 2026
9be092d
Working on hierarchical dataset feature.
AttilaMihaly May 1, 2026
bcae72b
Extracted all of FR 2052a with LCR and NSFR instructions.
AttilaMihaly May 4, 2026
12689c3
Manually fixed data tables
AttilaMihaly May 4, 2026
2da959e
Moved the substrate.json down a level and updated tooling to support it.
AttilaMihaly May 4, 2026
b483762
Wipe out the design system
AttilaMihaly May 4, 2026
8133a24
Updated package name
AttilaMihaly May 4, 2026
c5a3b59
Refined dataset spec
AttilaMihaly May 8, 2026
89e01a0
Added initial version of migrate command.
AttilaMihaly May 8, 2026
3a4d479
Merge branch 'substrate' of https://github.com/AttilaMihaly/morphir i…
AttilaMihaly May 13, 2026
f7889dc
Moved incomplete features to the backlog.
AttilaMihaly May 13, 2026
0dff3dc
Moved migrate to the backlog
AttilaMihaly May 13, 2026
ad9b222
Refined deteset definition
AttilaMihaly May 13, 2026
158307c
Added missing attribute
AttilaMihaly May 13, 2026
cf6d0b9
Moved language description into language folder.
AttilaMihaly May 13, 2026
3d01ceb
Ship substrate CLI skill for Claude and GitHub Copilot via install
AttilaMihaly May 14, 2026
092e2ed
Added pipeline pattern.
AttilaMihaly May 14, 2026
d91d8a4
Added decision tree expression.
AttilaMihaly May 14, 2026
9c6dd5c
Added force flag to install command.
AttilaMihaly May 14, 2026
e2ba647
Added expression syntax.
AttilaMihaly May 15, 2026
1736a76
Added syntax for literals.
AttilaMihaly May 15, 2026
f02956e
Added variable.
AttilaMihaly May 15, 2026
d8cf4cf
Enhanced pipeline spec
AttilaMihaly May 15, 2026
c35ed90
Improved test cases handling.
AttilaMihaly May 15, 2026
38c896f
Fixed tests
AttilaMihaly May 15, 2026
d4925a7
Updated lock file name
AttilaMihaly May 15, 2026
64f6b27
Implement spec-implementation alignment (workstreams 1 & 2)
AttilaMihaly May 16, 2026
511e05d
Enhancements
AttilaMihaly May 16, 2026
a3828f9
Ignore everything claude
AttilaMihaly May 16, 2026
10260fc
Implement TypeScript horizontal and cut over expression evaluators (WS3)
AttilaMihaly May 16, 2026
c4d2b74
Fix warning
AttilaMihaly May 18, 2026
b0433b1
Added minimal dev UI
AttilaMihaly May 18, 2026
91d70d5
Cleaner web app structure
AttilaMihaly May 18, 2026
3ccef11
Find manifest instead of just running in the current or specified dir
AttilaMihaly May 18, 2026
4826366
Make sure every release is at least 7 days old.
AttilaMihaly May 18, 2026
e42ed36
Remove generated files.
AttilaMihaly May 18, 2026
429e547
Updated examples
AttilaMihaly May 18, 2026
a6036bb
New explanation approach.
AttilaMihaly May 18, 2026
4abb0da
Enhancements
AttilaMihaly May 18, 2026
67be4e9
Enhancements.
AttilaMihaly May 18, 2026
ff47b70
Text coverage.
AttilaMihaly May 18, 2026
54be455
Better coverage indicator.
AttilaMihaly May 19, 2026
c69c0b6
Split view
AttilaMihaly May 19, 2026
a3d94bb
Clean up generated files
AttilaMihaly May 19, 2026
979b9ab
Ignore generated files
AttilaMihaly May 19, 2026
cfa1110
Added scrolling
AttilaMihaly May 19, 2026
7c6848e
Updated wordmark
AttilaMihaly May 19, 2026
6863846
UI enhencements
AttilaMihaly May 19, 2026
7600d3f
Enhancements
AttilaMihaly May 19, 2026
e6faf4d
Proper AST and parsing for yaml.
AttilaMihaly May 19, 2026
8871c86
Handle lit prefix.
AttilaMihaly May 19, 2026
ee49925
Skill to do interpretation.
AttilaMihaly May 19, 2026
022a276
Better skills
AttilaMihaly May 19, 2026
ea99617
Enhancements
AttilaMihaly May 20, 2026
80d3b5c
Enhancements
AttilaMihaly May 27, 2026
e001a58
Added idea
AttilaMihaly May 27, 2026
8aed4bf
Introducing the catalog concept
AttilaMihaly May 31, 2026
0325296
Merge branch 'substrate' of https://github.com/AttilaMihaly/morphir i…
AttilaMihaly May 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Node, Bun, and Deno Related
package-lock.json
node_modules/

# IDE Related
Expand Down Expand Up @@ -74,3 +73,5 @@ website/.docusaurus/
# Added by cargo

/target

.claude/
8 changes: 8 additions & 0 deletions substrate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"package": {
"name": "language",
"kind": "library",
"version": "0.1.0",
"subdir": "substrate/specs/language"
}
}
10 changes: 10 additions & 0 deletions substrate/.agents/skills/grill-me/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: grill-me
description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".
---

Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.

Ask the questions one at a time.

If a question can be answered by exploring the codebase, explore the codebase instead.
47 changes: 47 additions & 0 deletions substrate/.agents/skills/grill-with-docs/ADR-FORMAT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# ADR Format

ADRs live in `docs/adr/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc.

Create the `docs/adr/` directory lazily — only when the first ADR is needed.

## Template

```md
# {Short title of the decision}

{1-3 sentences: what's the context, what did we decide, and why.}
```

That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why* — not in filling out sections.

## Optional sections

Only include these when they add genuine value. Most ADRs won't need them.

- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited
- **Considered Options** — only when the rejected alternatives are worth remembering
- **Consequences** — only when non-obvious downstream effects need to be called out

## Numbering

Scan `docs/adr/` for the highest existing number and increment by one.

## When to offer an ADR

All three of these must be true:

1. **Hard to reverse** — the cost of changing your mind later is meaningful
2. **Surprising without context** — a future reader will look at the code and wonder "why on earth did they do it this way?"
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons

If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing."

### What qualifies

- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
77 changes: 77 additions & 0 deletions substrate/.agents/skills/grill-with-docs/CONTEXT-FORMAT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CONTEXT.md Format

## Structure

```md
# {Context Name}

{One or two sentence description of what this context is and why it exists.}

## Language

**Order**:
{A concise description of the term}
_Avoid_: Purchase, transaction

**Invoice**:
A request for payment sent to a customer after delivery.
_Avoid_: Bill, payment request

**Customer**:
A person or organization that places orders.
_Avoid_: Client, buyer, account

## Relationships

- An **Order** produces one or more **Invoices**
- An **Invoice** belongs to exactly one **Customer**

## Example dialogue

> **Dev:** "When a **Customer** places an **Order**, do we create the **Invoice** immediately?"
> **Domain expert:** "No — an **Invoice** is only generated once a **Fulfillment** is confirmed."
## Flagged ambiguities

- "account" was used to mean both **Customer** and **User** — resolved: these are distinct concepts.
```

## Rules

- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others as aliases to avoid.
- **Flag conflicts explicitly.** If a term is used ambiguously, call it out in "Flagged ambiguities" with a clear resolution.
- **Keep definitions tight.** One sentence max. Define what it IS, not what it does.
- **Show relationships.** Use bold term names and express cardinality where obvious.
- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs.
- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine.
- **Write an example dialogue.** A conversation between a dev and a domain expert that demonstrates how the terms interact naturally and clarifies boundaries between related concepts.

## Single vs multi-context repos

**Single context (most repos):** One `CONTEXT.md` at the repo root.

**Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other:

```md
# Context Map

## Contexts

- [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders
- [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments
- [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping

## Relationships

- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
```

The skill infers which structure applies:

- If `CONTEXT-MAP.md` exists, read it to find contexts
- If only a root `CONTEXT.md` exists, single context
- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved

When multiple contexts exist, infer which one the current topic relates to. If unclear, ask.
88 changes: 88 additions & 0 deletions substrate/.agents/skills/grill-with-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
name: grill-with-docs
description: Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.
---

<what-to-do>

Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.

Ask the questions one at a time, waiting for feedback on each question before continuing.

If a question can be answered by exploring the codebase, explore the codebase instead.

</what-to-do>

<supporting-info>

## Domain awareness

During codebase exploration, also look for existing documentation:

### File structure

Most repos have a single context:

```
/
├── CONTEXT.md
├── docs/
│ └── adr/
│ ├── 0001-event-sourced-orders.md
│ └── 0002-postgres-for-write-model.md
└── src/
```

If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives:

```
/
├── CONTEXT-MAP.md
├── docs/
│ └── adr/ ← system-wide decisions
├── src/
│ ├── ordering/
│ │ ├── CONTEXT.md
│ │ └── docs/adr/ ← context-specific decisions
│ └── billing/
│ ├── CONTEXT.md
│ └── docs/adr/
```

Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed.

## During the session

### Challenge against the glossary

When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?"

### Sharpen fuzzy language

When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things."

### Discuss concrete scenarios

When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.

### Cross-reference with code

When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?"

### Update CONTEXT.md inline

When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md).

`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else.

### Offer ADRs sparingly

Only offer to create an ADR when all three are true:

1. **Hard to reverse** — the cost of changing your mind later is meaningful
2. **Surprising without context** — a future reader will wonder "why did they do it this way?"
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons

If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md).

</supporting-info>
11 changes: 11 additions & 0 deletions substrate/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules/
dist/
.claude/
.obsidian/
*.code-workspace
*.log
*.tsbuildinfo
assets/web/assets/
assets/web/index.html
examples/.github/
examples/substrate/
14 changes: 14 additions & 0 deletions substrate/.markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"config": {
// Heading levels should increment one at a time
"MD001": true,
// Line length: disabled (spec tables and links can be long)
"MD013": false,
// Allow duplicate headings in different sections (operations reuse names)
"MD024": false,
// Ordered list items should use incrementing numbers
"MD029": true,
// Inline HTML: disabled (none expected, but don't block on it)
"MD033": false
}
}
2 changes: 2 additions & 0 deletions substrate/.remarkignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
examples/broken.md
docs/src/content/
2 changes: 2 additions & 0 deletions substrate/.remarkrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
plugins:
- remark-validate-links
85 changes: 85 additions & 0 deletions substrate/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Important Instructions

- When presenting multiple options for the user to choose between (e.g. during grilling sessions, design discussions, or any enumerated choice), label them with latin letters or short descriptive tags — never Greek letters.
- When implementing a new feature or changing an existing one always update the `specs/` folder to reflect the requirements and design.
- **Minimum 7-day package age (transitive too).** Never add or upgrade an
npm dependency — direct *or transitive* — to a version published less
than seven days ago. Brand-new releases get yanked or get
supply-chain-compromised; the seven-day soak is our line of defence.
Workflow when adding/bumping a dep:
1. Before installing, check `npm view <pkg> time --json` for the
candidate version; pick an older patch or wait if it's too young.
2. After installing, run **`node scripts/check-ages-deep.mjs`** — it
walks every package in `node_modules/` and `web/node_modules/`
(730+ entries) and exits non-zero if anything is younger than 7 days.
This is the script that matters; it catches transitive deps that
direct-only audits miss (e.g. `rollup` arriving via `vite`).
3. If a direct dep's `^` / `~` range would resolve to a too-young
version, pin it to an exact version (no caret/tilde).
4. If a *transitive* dep is too young, pin it via the `overrides` field
in the relevant `package.json` (`web/package.json` for the SPA tree,
root `package.json` for the CLI tree). Document the rationale in a
`comment_overrides` sibling so the next person knows why and when to
revisit. Re-run the deep audit after `npm install`.

`scripts/check-ages.mjs` (direct-only) and
`scripts/check-range-risk.mjs` (latest-satisfying probe) exist as
faster sanity checks but **are not sufficient on their own**;
`check-ages-deep.mjs` is the source of truth.
- **Keep the bundled AI-assistant instructions in sync with the CLI.** Whenever you add, rename, remove, or change the behavior of a `substrate` command (especially the `refactor` subcommands), update *both* of these files in the same change so users who consume substrate via `substrate install` get an accurate skill:
- `assets/ai-instructions/claude/substrate-cli/SKILL.md` — the Claude skill.
- `assets/ai-instructions/copilot/substrate-cli.instructions.md` — the GitHub Copilot path-scoped instructions.
These are shipped with the npm package and copied into the consumer's project by `substrate init` and `substrate install`. If the spec under `specs/tools/cli/` changes but these files do not, the change is incomplete.

## Commands

```bash
npm run build # Build CLI (tsc → dist/) and web UI (vite → assets/web/)
npm run build:cli # CLI only
npm run build:web # Web UI only (Vite production build)
npm run dev:web # Live dev: substrate dev :5173 + Vite HMR on :5174
npm run web:install # Install web/ dependencies
npm run test # Run all tests (vitest)
npm run test:watch # Watch mode
npm run lint # Markdown lint + link validation
npm run lint:md # Markdown structure only
npm run lint:links # Internal link resolution only
```

Run a single test file:
```bash
npx vitest run test/stages/typecheck.test.ts
```

## Project Overview

This is **substrate**: an LLM-native executable specification language. The project is part of an umbrella
project called Morphir so it's sometimes referred to as **morphir-substrate**. The project lives under the
morphir repo, but it should treated as a standalne project.

### Specs (`specs/`)

The language specification itself lives in `specs/language/concepts/` and `specs/language/expressions/` as markdown files — they are both the source of truth and test input for the pipeline.

### Web UI (`web/`)

The `substrate dev` development UI is a Vite + React + TypeScript SPA
under `web/`. `vite build` emits a self-contained bundle into
`assets/web/`, which `src/commands/dev.ts` serves as static files in
production.

Layout and conventions (one folder per component, CSS modules, brand
tokens via `branding/tokens.css`) are documented in `web/README.md`.
Keep `web/src/types.ts` in sync with the JSON shapes served by
`src/commands/dev.ts`.

## Important Notes

- TypeScript strict mode, ES modules (`"type": "module"` in package.json)
- Tests live in `test/**/*.test.ts` with 10-second timeout (vitest)
- Compiled output goes to `dist/`; the CLI binary is `dist/cli.js`
- No AI co-authors in commits (see root `CLAUDE.md` at the parent repo level for EasyCLA requirements)
21 changes: 21 additions & 0 deletions substrate/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Attila Mihaly

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading
Loading