snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-16 05:09:45 +05:00
commit bcf6ef63ad
7118 changed files with 1236854 additions and 0 deletions

94
docs/API_STABILITY.md Normal file
View File

@@ -0,0 +1,94 @@
# API Stability Policy
This document defines how Univer treats public APIs, experimental APIs, internal APIs, deprecations, and breaking changes.
Univer is currently pre-1.0, so the project can still make breaking changes when they are needed for architecture, correctness, or long-term maintainability. Even in pre-1.0 releases, the project should make API risk visible before users depend on it.
## Stability Levels
### Stable
Stable APIs are intended for application and plugin developers.
An API is stable when it is exported from a public package entry point and is documented in the generated API reference, package README, guide, or examples without an experimental warning.
Examples include:
- Public package entry points such as `@univerjs/core`, `@univerjs/sheets`, and `@univerjs/presets`.
- Documented Facade APIs such as workbook, worksheet, range, formula, and document APIs.
- Public plugin classes, configuration types, commands, and service interfaces documented for extension authors.
Stable APIs should not be removed or changed incompatibly without a deprecation path.
### Experimental
Experimental APIs are usable, but their behavior, names, parameters, or package location may change.
An API is experimental when any of the following is true:
- It is documented as experimental, alpha, beta, preview, or under active development.
- It belongs to a product surface that is explicitly marked as under active development.
- It is exposed for early integration feedback before the project has committed to its final shape.
Experimental APIs should include a short note in docs or JSDoc that explains the instability. Breaking changes to experimental APIs should still be called out in release notes when they affect users.
### Internal
Internal APIs are implementation details and are not covered by compatibility guarantees.
An API should be treated as internal when it is:
- Not documented for application or plugin authors.
- Located under implementation folders such as controllers, render controllers, models, views, utilities, or test helpers without a public export contract.
- Exported only to support package composition inside the monorepo.
- Marked `@internal`, `@private`, or described as implementation-only.
Avoid depending on internal APIs in user applications. If an internal API is needed for real integrations, open an issue or discussion so it can be promoted to a public API intentionally.
### Deprecated
Deprecated APIs are still available for compatibility, but users should migrate away from them.
When deprecating an API:
1. Mark it with `@deprecated` in JSDoc and link to the replacement when one exists.
2. Log a deprecation warning through `ILogService` when runtime usage can be detected without excessive noise.
3. Add migration guidance in the relevant guide, README, or release notes when the API is broadly used.
Deprecated stable APIs should remain available until the next major release unless the API is unsafe, broken, or impossible to preserve. In pre-1.0 releases, removals may happen in a minor release, but they should be documented as breaking changes.
## Breaking Changes
A change is breaking when it requires users to modify application code, plugin code, build configuration, package versions, persisted data assumptions, or runtime integration behavior.
Breaking changes should be documented in the changelog or release notes with:
- The affected package or feature area.
- What changed.
- Why the change was necessary.
- The migration path or replacement API.
Pull requests that introduce breaking changes should include a `BREAKING CHANGE:` section in the PR description.
## Package Version Alignment
Keep the `@univerjs/*` SDK packages that participate in the same coordinated Univer release line on the same version. Independently released packages, including `@univerjs/icons` and `@univerjs/icons-svg`, follow the compatible versions declared by package manifests rather than the SDK version. If an application uses Univer Pro packages, keep `@univerjs-pro/*` aligned with the matching coordinated Univer release line.
Mixing versions within a coordinated SDK release line can bypass compatibility checks and produce runtime failures, especially around plugin registration, Facade API composition, locales, commands, and shared data models.
## Public API Checklist
Before exposing a new public API, confirm that:
- The API has a clear owner package and entry point.
- The name follows the repository naming convention.
- The API works in the intended runtime: browser, Node.js, worker, or shared.
- Facade APIs are registered by the correct package or preset.
- The API has tests for expected behavior and at least one usage example or reference entry.
- Experimental status is explicitly documented if the design is not final.
## User Expectations
Users can rely on documented stable APIs as the preferred integration surface. Users should expect experimental APIs to evolve and internal APIs to change without notice.
If the documentation and package exports disagree, treat the documentation as the intended public contract and report the mismatch.

View File

@@ -0,0 +1,51 @@
# How to Contribute to Facade API
Facade API is an API layer of all other packages of Univer and it helps users to use Univer easily. For a detailed introduction of Facade API, please visit [Facade API](https://docs.univer.ai/en-US/guides/sheets/getting-started/facade).
Facade API is consists of multi classes such as `FUniver`, `FWorkbook` and `FRange` etc. You can refer to Google's [AppScripts](https://developers.google.com/apps-script/reference/spreadsheet) to design Facade API.
Please use JSDoc to document your code. For example:
```typescript
export class FWorkbook {
/**
* Get the active sheet of the workbook.
* @returns The active sheet of the workbook
*/
getActiveSheet(): FWorksheet | null {
// ...
}
/**
* Create a new worksheet and returns a handle to it.
* @param name Name of the new sheet
* @param rows How may rows would the new sheet have
* @param column How many columns would the new sheet have
* @returns The new created sheet
*/
create(name: string, rows: number, column: number): FWorksheet {
// ...
}
}
```
## Synchronous API Priority
- For asynchronous APIs, consider the following: Can a synchronous sub-API be extracted, separating logic such as secondary confirmation.
- For APIs that must be asynchronous, indicate this in the method name, such as `addCommentAsync`.
## Chaining Principle
APIs must adhere to the chaining principle:
- APIs with `modify` semantics should return `this`.
- APIs with `create` semantics should return the created instance.
- APIs with `delete` semantics should return `true/false`.
## Easy to Get
All APIs/constants/enums should be accessible from the `univerAPI` variable.
## Documentation
It is strongly suggested to add documentation for your code alongside the current [Sheets Facade guide](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/getting-started/facade.mdx). Please refer to the [documentation repository](https://github.com/dream-num/documentation) for more guidance.

48
docs/FIX_MEMORY_LEAK.md Normal file
View File

@@ -0,0 +1,48 @@
# How to Fix Memory Leak
## How to Investigate Memory Leak
Start the workbench and select the smallest route that reproduces the leak from the navigation bar:
```shell
pnpm dev
```
Take a baseline heap snapshot in Chrome DevTools, exercise the behavior, then dispose the mounted instance from the Console:
```javascript
window.univer?.dispose();
delete window.univer;
delete window.univerAPI;
document.querySelector('#app')?.replaceChildren();
```
Force garbage collection and take another snapshot. Reload the page between runs so each measurement starts from a fresh fixture.
## Frequent Reasons for Memory Leak
### Forget to call dispose subscriptions
For example: dream-num/univer@6423ff8/packages/sheets-drawing-ui/src/controllers/sheet-drawing-update.controller.ts#L244
**HOW TO FIX**: Please remember to dispose subscriptions.
### Get current unit in singleton modules
It is very common to cause memory leak if you get the current unit in singleton modules and subscribe to it. Singleton modules are defined as modules that are registered in the Univer root injector instead of injectors held by render units.
For example, see the [historical implementation before the leak was fixed](https://github.com/dream-num/univer/blob/7550f1cef8c7ff17caecba7ac3305dd56b30b62e/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts#L433-L468).
**HOW TO FIX**: Please consider extracting the related logic to an `IRenderModule` instead.
### Has big objects in dep arrays of `useEffect` or `useMemo`
React would keep the dep arrays into memory, so if you put a big object into an array, it would cause memory leak.
For example: https://github.com/dream-num/univer/blob/6423ff8ede75ae7b2e003fff99fd9866aa18f1dd/packages/sheets-ui/src/views/sheet-container/SheetContainer.tsx#L88
**HOW TO FIX**: Please consider using `unitId` in dep arrays instead.
## How to Investigate Memory Leak for Node.js
TODO @wzhudev

34
docs/ISOMORPHIC.md Normal file
View File

@@ -0,0 +1,34 @@
# Building Isomorphic Univer
Univer is an isomorphic (full-stack) framework for building productivity tools, which means **support of Node.js is
at the same priority as browsers**.
To make your code aligned with the isomorphic architecture, please pay
attention to the following points:
## Separate Plugins
If the feature your are developing both needs to run on the server and the client, you should separate the feature into
at least two plugins. One for the underlying logic and the other for the UI.
The underlying logic often includes: models, commands and mutations to modify the data, and services to manage the data.
The UI includes menus, shortcuts, React components, Canvas elements, or other modules that depend on the browser environment.
For example, the filter feature is split into two plugins: `sheets-filter` and `sheets-filter-ui`.
Some modules rely on Node.js-only API such as `fs`, `path`, `child_process`, etc. These modules should be
implemented in another server-only plugin.
## Separate Facade API
**The Facade API is designed to be used by both the server and the client**. It should be implemented in each plugins and
composed by users (or the `@univerjs/presets` package) to provide a unified
API for the SDK.
You should implement the Facade API that can run on Node.js and the browser in the underlying logic plugins.
## Consider Implementing Commands in the Underlying Logic
Commands and especially those of type `MUTATION` should be implemented in the underlying logic plugins, and should not
read UI status directly to ensure that they can run on both Node.js and browsers.

240
docs/NAMING_CONVENTION.md Normal file
View File

@@ -0,0 +1,240 @@
# Univer Naming Convention
To ensure code quality and consistency, please adhere to the following guidelines.
## Files & Folders
Use kebab-case for both file names and folder names. If the file contains a React component, it should be in PascalCase. For example:
```txt
// ✅
src/
components/
my-component/
my-util.ts
MyComponent.tsx
// 🚫
src/
components/
myComponent/
myUtil.ts
my-component.tsx
```
Folder names should be in plural format. Files names should be in singular format. For example:
```txt
// ✅
src/
services/
util.ts
// 🚫
src/
service/
utils.ts
```
Do use conventional type names including .service, .controller, .menu, .command, .mutation, and .operation. Invent additional type names if you must but take care not to create too many. For example:
```txt
// ✅
src/
services/
log.service.ts
user.service.ts
controllers/
log.controller.ts
user.controller.ts
```
## Interfaces
Interfaces should be named starting with a capital "I". For example:
```typescript
// ✅
export interface IMyInterface {}
// 🚫
export interface MyInterface {}
```
## Dependency Injection Token
Sometimes you need to defined a dependency injection token. Please adhere to the following naming convention:
```typescript
export const IYourServiceOrControllerName = createIdentifier<IYourServiceOrControllerName>('<package-name>.<your-service-or-controller-name>.(service|controller)');
```
For example:
```typescript
// ✅
export const ILogService = createIdentifier<ILogService>('core.log.service');
// 🚫
export const ILogService = createIdentifier<ILogService>('log-service');
```
## Plugins' Names
Plugin names should be all in format of `<BUSINESS_TYPE>_<PLUGIN_NAME>_PLUGIN`. Words should be separated by underscores and suffixed. For example:
```typescript
// ✅
export const SHEET_CONDITIONAL_FORMATTING_PLUGIN = 'SHEET_CONDITIONAL_FORMATTING_PLUGIN';
// 🚫
export const SHEET_CONDITIONAL_FORMATTING_PLUGIN = 'SHEET_CONDITIONAL_FORMATTING';
// 🚫
export const SHEET_CONDITIONAL_FORMATTING_PLUGIN = 'sheet-conditional-formatting-plugin';
```
### Plugins' classes
Plugin classes should be named in PascalCase and prefixed by `Univer`. For example:
```typescript
// ✅
export class UniverFilterPlugin extends Plugin {}
// 🚫
export class FilterPlugin extends Plugin {}
```
### Resource key
Resource key should be identical to the corresponding plugin's name.
## Commands
Commands' names should follow the convention below:
```typescript
export interface ISomeCommandParams {
// Define the parameters here
}
export const SomeCommand: ICommand<ISomeCommandParams> = {
id: '<business-type>.<command-type>.<command-name>',
};
```
For example:
```typescript
// ✅
export const SetSelectionFrozenCommand: ICommand<ISetSelectionFrozenCommandParams> = {
id: 'sheet.command.set-selection-frozen', // note this should be in single format
}
// 🚫
export const SetSelectionFrozenCommand: ICommand<ISetSelectionFrozenCommandParams> = {
id: 'sheets.command.set-selection-frozen',
}
// 🚫
export const SetSelectionFrozenCommand: ICommand<ISetSelectionFrozenCommandParams> = {
id: 'SetSelectionFrozenCommand',
}
```
If this command is for general purpose, the `business-type` should be the plugin's name. For example:
```typescript
export const ResolveCommentCommand: ICommand<IResolveCommentCommandParams> = {
id: 'thread-comment.command.resolve-comment',
}
```
## Id
Within camelCase or PascalCase identifiers, use `Id` instead of `ID` (for example, `unitId` and `getUnitId`). Keep the standalone property name `id` lowercase.
## Locale Keys
### Syntax
A locale key is a dot-separated path. The first segment is the **package namespace** and MUST match the package name.
```typescript
// ✅
'find-replace.button.confirm'
'sheets-filter-ui.permission.filterErr'
// 🚫
'button.confirm' // missing package namespace
'hyperLink.message.refError' // namespace does not match package name
```
### Package namespace
Each package owns exactly one namespace and it MUST be identical to the package name.
| Package | Namespace |
|---|---|
| `@univerjs/find-replace` | `find-replace` |
| `@univerjs/sheets-filter` | `sheets-filter` |
| `@univerjs/sheets-filter-ui` | `sheets-filter-ui` |
| `@univerjs/sheets-hyper-link` | `sheets-hyper-link` |
| `@univerjs/sheets-hyper-link-ui` | `sheets-hyper-link-ui` |
Core and UI layers of the same feature MUST use **different** namespaces. For example, `sheets-filter` and `sheets-filter-ui` MUST NOT share `sheets-filter`.
### No cross-package references
A package MUST NOT reference a key whose first segment is another package's namespace.
```typescript
// In @univerjs/sheets-filter
// 🚫 references a key from the UI package
localeService.t<LocaleKey>('sheets-filter-ui.panel.empty')
// In @univerjs/sheets-filter-ui
// 🚫 references a key from a common/utility package
localeService.t<LocaleKey>('sheets-ui.permission.dialog.filterErr')
// ✅ sink the key into your own locale file
localeService.t<LocaleKey>('sheets-filter-ui.permission.filterErr')
```
### Namespace must be the single root key
The exported locale object MUST contain exactly one root key: the package namespace. All translations MUST be nested under it.
```typescript
// 🚫
const locale = {
button: { confirm: 'OK' }, // unrelated top-level key
'find-replace': { toolbar: '...' },
};
// ✅
const locale = {
'find-replace': {
toolbar: '...',
button: { confirm: 'OK' }, // nested under the package namespace
},
};
```
### No shared/common locale buckets
Do NOT create a "common" or "shared" namespace (e.g. `button.*`, `permission.dialog.*`) in a utility package for other packages to consume. Every package that needs a key defines it under its own namespace.
```typescript
// 🚫 defined in @univerjs/sheets-ui for others to reuse
'permission.dialog.filterErr'
// ✅ defined locally in @univerjs/sheets-filter-ui
'sheets-filter-ui.permission.filterErr'
// ✅ defined locally in @univerjs/sheets-hyper-link-ui
'sheets-hyper-link-ui.permission.hyperLinkErr'
```
Duplication across namespaces is acceptable.

BIN
docs/img/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

373
docs/readme/es-ES.md Normal file
View File

@@ -0,0 +1,373 @@
<div align="center">
<img src="../img/banner.png" alt="Univer SDK" width="800" />
**Un SDK ofimático full-stack e isomórfico para crear hojas de cálculo, documentos y presentaciones.**
Univer ayuda a crear experiencias de productividad integrables con una arquitectura de plugins,
renderizado basado en Canvas, un motor de fórmulas y una Facade API que funciona tanto en el navegador como en Node.js.
[English](../../README.md) | [简体中文](./zh-CN.md) | [繁體中文](./zh-TW.md) | [日本語](./ja-JP.md) | [한국어](./ko-KR.md) | Español
[📖 Documentación](https://docs.univer.ai) | [✨ Showcase](https://docs.univer.ai/showcase) | [📘 API Reference](https://docs.univer.ai/reference/classes/univer) | [📝 Blog](https://docs.univer.ai/blog)
[![Release](https://img.shields.io/github/v/release/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/releases)
[![License](https://img.shields.io/github/license/dream-num/univer?style=flat-square)](../../LICENSE)
[![Build](https://img.shields.io/github/actions/workflow/status/dream-num/univer/build-packages.yml?style=flat-square)](https://github.com/dream-num/univer/actions/workflows/build-packages.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/dream-num/univer/badge/dev?style=flat-square)](https://www.codefactor.io/repository/github/dream-num/univer/overview/dev)
[![Codecov](https://img.shields.io/codecov/c/gh/dream-num/univer?token=aPfyW2pIMN&style=flat-square)](https://codecov.io/gh/dream-num/univer)
[![Stars](https://img.shields.io/github/stars/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/stargazers)
[![Contributors](https://img.shields.io/github/contributors/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/issues)
[![Last Commit](https://img.shields.io/github/last-commit/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/commits/dev/)
[![Discord](https://img.shields.io/discord/1136129819961217077?logo=discord&logoColor=FFFFFF&label=discord&color=5865F2&style=flat-square)](https://discord.gg/z3NKNT6D2f)
[![Twitter](https://img.shields.io/twitter/follow/univerhq?style=flat-square&logo=x)](https://twitter.com/univerhq)
[![Open Collective](https://img.shields.io/opencollective/all/univer?logo=opencollective&style=flat-square)](https://opencollective.com/univer)
[![Trendshift](https://trendshift.io/api/badge/repositories/4376)](https://trendshift.io/repositories/4376)
</div>
## ✨ ¿Qué es Univer?
Univer es un SDK de código abierto para crear aplicaciones ofimáticas dentro de tu propio producto. Proporciona los bloques necesarios para experiencias de hojas de cálculo, documentos y presentaciones sin obligarte a usar una aplicación alojada ni una UI fija.
Usa Univer cuando necesites:
- Integrar edición de hojas de cálculo o documentos en un SaaS, herramienta interna, flujo de BI o aplicación de IA.
- Ejecutar procesamiento de libros/documentos en el servidor con la misma arquitectura que se usa en el navegador.
- Componer solo las funciones que necesitas mediante plugins o empezar rápido con presets.
- Extender el comportamiento mediante plugins personalizados, comandos, servicios, componentes de UI y Facade APIs.
Univer no es solo un visor de archivos de hojas de cálculo. Es un framework para crear tu propia superficie de productividad.
## 🌟 Highlights
<table>
<tr>
<td align="center" width="33%">
⚡<br />
<strong>Preparado para superficies grandes</strong><br />
<sub>El renderizado Canvas y un motor de fórmulas dedicado mantienen responsivos los libros complejos.</sub>
</td>
<td align="center" width="33%">
🧩<br />
<strong>Extensible por plugins</strong><br />
<sub>Compón, reemplaza, carga bajo demanda o amplía capacidades sin adoptar todo el stack.</sub>
</td>
<td align="center" width="33%">
🤖<br />
<strong>Headless para infraestructura de IA</strong><br />
<sub>Ejecuta lógica de libros y documentos en Node.js para impulsar agentes, automatización y flujos del servidor.</sub>
</td>
</tr>
<tr>
<td align="center" width="33%">
🛠️<br />
<strong>SDK listo para producto</strong><br />
<sub>Adaptadores de framework, Facade APIs, presets y runtime headless encajan en integraciones reales.</sub>
</td>
<td align="center" width="33%">
🌗<br />
<strong>Dark mode listo</strong><br />
<sub>Los componentes de UI y el motor de renderizado se adaptan a temas claros y oscuros.</sub>
</td>
<td align="center" width="33%">
🔌<br />
<strong>Facade API unificada</strong><br />
<sub>Una API consistente para libros, rangos, fórmulas y documentos en el navegador y Node.js.</sub>
</td>
</tr>
</table>
## 🚀 ¿Por qué Univer?
- **Diseño isomórfico**: ejecuta aplicaciones UI en navegadores y procesamiento headless en Node.js.
- **Arquitectura basada en plugins**: cada capacidad se entrega como un plugin componible, por lo que las funciones se pueden añadir, quitar, reemplazar o cargar bajo demanda.
- **Preset mode para integración rápida**: usa las colecciones de plugins preparadas en [`presets/`](../../presets) cuando quieras una aplicación funcional rápidamente.
- **Plugin mode para control total**: compón paquetes manualmente cuando necesites carga personalizada, bundles más pequeños o integración profunda.
- **Facade API**: trabaja con libros, hojas, rangos, documentos, fórmulas, comandos y eventos mediante una API de alto nivel.
- **Motor de renderizado Canvas**: soporta superficies editables grandes y comparte la capa de renderizado entre distintos tipos de documento.
- **UI extensible**: integración con React, Vue, Web Components y shells de aplicación específicos de cada framework.
## ⚡ Inicio rápido
Usa **Plugin Mode** para obtener una cobertura completa del producto y controlar con precisión la composición. Para los perfiles compatibles de Sheets, Docs y Node, **Preset Mode** ofrece una configuración curada más breve.
<details open>
<summary><strong>Plugin Mode</strong></summary>
Plugin Mode te da control de bajo nivel sobre paquetes, imports de estilos, combinación de locales, registro de Facade API y configuración de plugins.
```bash
pnpm add @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-formula-ui @univerjs/sheets-numfmt @univerjs/sheets-numfmt-ui @univerjs/sheets-ui @univerjs/ui
```
```ts
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import { FUniver } from '@univerjs/core/facade'
import DesignEnUS from '@univerjs/design/locale/en-US'
import { UniverDocsPlugin } from '@univerjs/docs'
import { UniverDocsUIPlugin } from '@univerjs/docs-ui'
import DocsUIEnUS from '@univerjs/docs-ui/locale/en-US'
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'
import { UniverRenderEnginePlugin } from '@univerjs/engine-render'
import { UniverSheetsPlugin } from '@univerjs/sheets'
import SheetsEnUS from '@univerjs/sheets/locale/en-US'
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'
import SheetsFormulaEnUS from '@univerjs/sheets-formula/locale/en-US'
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'
import SheetsFormulaUIEnUS from '@univerjs/sheets-formula-ui/locale/en-US'
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt'
import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui'
import SheetsNumfmtUIEnUS from '@univerjs/sheets-numfmt-ui/locale/en-US'
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US'
import { UniverUIPlugin } from '@univerjs/ui'
import UIEnUS from '@univerjs/ui/locale/en-US'
import '@univerjs/design/lib/index.css'
import '@univerjs/ui/lib/index.css'
import '@univerjs/docs-ui/lib/index.css'
import '@univerjs/sheets-ui/lib/index.css'
import '@univerjs/sheets-formula-ui/lib/index.css'
import '@univerjs/sheets-numfmt-ui/lib/index.css'
import '@univerjs/engine-formula/facade'
import '@univerjs/ui/facade'
import '@univerjs/sheets/facade'
import '@univerjs/sheets-ui/facade'
import '@univerjs/sheets-formula/facade'
import '@univerjs/sheets-numfmt/facade'
const univer = new Univer({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(
DesignEnUS,
UIEnUS,
DocsUIEnUS,
SheetsEnUS,
SheetsUIEnUS,
SheetsFormulaEnUS,
SheetsFormulaUIEnUS,
SheetsNumfmtUIEnUS,
),
},
})
univer.registerPlugin(UniverRenderEnginePlugin)
univer.registerPlugin(UniverFormulaEnginePlugin)
univer.registerPlugin(UniverUIPlugin, { container: 'app' })
univer.registerPlugin(UniverDocsPlugin)
univer.registerPlugin(UniverDocsUIPlugin)
univer.registerPlugin(UniverSheetsPlugin)
univer.registerPlugin(UniverSheetsUIPlugin)
univer.registerPlugin(UniverSheetsFormulaPlugin)
univer.registerPlugin(UniverSheetsFormulaUIPlugin)
univer.registerPlugin(UniverSheetsNumfmtPlugin)
univer.registerPlugin(UniverSheetsNumfmtUIPlugin)
const univerAPI = FUniver.newAPI(univer)
univerAPI.createWorkbook({})
```
</details>
<details>
<summary><strong>Preset Mode</strong></summary>
Los presets son colecciones curadas de plugins de Univer que incluyen los registros de Facade API y estilos necesarios.
```bash
pnpm add @univerjs/presets @univerjs/preset-sheets-core
```
```ts
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
import '@univerjs/preset-sheets-core/lib/index.css'
const { univerAPI } = createUniver({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(UniverPresetSheetsCoreEnUS),
},
presets: [
UniverSheetsCorePreset({
container: 'app',
}),
],
})
univerAPI.createWorkbook({})
```
</details>
Tu página necesita un contenedor:
```html
<div id="app" style="height: 100vh"></div>
```
Consulta más detalles en la [guía de instalación y uso básico](https://docs.univer.ai/guides/sheets/getting-started/installation), la [referencia de `createUniver`](https://docs.univer.ai/reference/methods/create-univer) y la [referencia de Facade API](https://docs.univer.ai/reference/classes/univer).
## 🧩 Preset Mode vs Plugin Mode
| Opción | Cuándo usarla | Empieza aquí |
| --- | --- | --- |
| **Plugin Mode** | Necesitas control estricto sobre paquetes, dependencias configuradas, carga bajo demanda o composición personalizada en tiempo de ejecución. | Los [`examples/`](../../examples) de este repositorio y la [guía de arquitectura](https://docs.univer.ai/guides/recipes/architecture/univer) |
| **Preset Mode** | Quieres una configuración funcional de Sheets, Docs o Node con mínima configuración. | Los [`presets/`](../../presets) de este repositorio y la [guía de inicio](https://docs.univer.ai/guides/sheets/getting-started/installation) |
| **Headless Mode** | Necesitas procesamiento de libros/documentos en servidor, cálculo de fórmulas o automatización sin UI. | [Headless Univer](https://docs.univer.ai/guides/sheets/getting-started/node) |
Mantén en la misma versión los paquetes del SDK `@univerjs/*` que formen parte de una misma línea de lanzamiento coordinada de Univer. Los paquetes con un ciclo de publicación independiente, como `@univerjs/icons` y `@univerjs/icons-svg`, deben usar las versiones compatibles declaradas en los manifiestos de los paquetes, no la versión del SDK. Si usas paquetes de Univer Pro, mantén `@univerjs-pro/*` alineados con la línea de lanzamiento coordinada correspondiente.
Para expectativas de compatibilidad de API, APIs experimentales, APIs internas y reglas de deprecación, consulta la [política de estabilidad de API](../API_STABILITY.md).
## 🧭 Compatibilidad
- **Runtime de navegador**: Univer se compila con objetivo Chrome 88 y busca funcionar en Edge `>=88`, Firefox `>=90`, Chrome `>=88`, Safari `>=14.1` y Electron `>=12`.
- **Polyfills**: Univer depende de `Intl.Segmenter`. Añade un polyfill como `@formatjs/intl-segmenter` si tu navegador o runtime objetivo no lo incluye.
- **Herramientas de build**: Recomendamos Vite, esbuild o Webpack 5. Si tu herramienta no soporta el campo `exports` de `package.json` (común en Webpack 4), puede que necesites configurar mapeos de ruta adicionales.
- **React**: La capa de vista de Univer está construida sobre React 18, soporta React 18 y 19, y ofrece compatibilidad mínima para React 16.9+ y 17.
- **Runtime Node.js**: Headless Univer soporta Node.js `>=18.17.0`. Para desarrollar este monorepo se requiere Node.js `>=22.18`.
## 🛠️ Qué puedes construir
| Área | Capacidades open source | Extensiones de Univer Pro |
| --- | --- | --- |
| **Sheets** | Libros, hojas, rangos, selección, fórmulas, formato numérico, filtros, ordenación, validación de datos, formato condicional, hipervínculos, comentarios, buscar y reemplazar, notas, tablas, integración de dibujo y plugins de UI extensibles. | Colaboración en tiempo real, historial de edición, importación/exportación, impresión, gráficos, tablas dinámicas, sparklines, esquemas, formas, gráficos dentro de celdas, conectores de datos, cálculo del lado del servidor y funciones de fórmulas mejoradas. |
| **Docs** | Modelo de documento enriquecido, UI de edición, listas, hipervínculos, integración de dibujo, comentarios, inserción rápida y arquitectura compartida de documentos. | Colaboración, importación/exportación, impresión, tablas y listas mejoradas, columnas, callouts, bloques de código, citas, formas y recursos remotos de comentarios. |
| **Slides** | Modelo de datos de presentaciones y paquetes de UI en desarrollo activo. | Modelo y UI Pro para presentaciones, importación/exportación de slides, plugins de modelo/UI para gráficos y tablas, e infraestructura compartida de edición de formas. |
| **Bases** | Experiencias de datos estructurados personalizadas sobre la arquitectura de plugins, comandos y modelos de Univer. | Modelo de base de datos Base, comandos, integración de fórmulas, UI de workbench, editores de campos y vistas del motor de renderizado. |
| **Runtime** | Aplicaciones en navegador, uso headless en Node.js, patrones Web Worker/RPC, múltiples instancias y automatización orientada al servidor. | Paquetes de cliente/servidor de colaboración, cliente de colaboración para Node.js, servicios Pro de servidor, SSR, delegación de cómputo, cálculo del lado del servidor y herramientas de replay de changesets. |
| **Integrations** | React, Vue, Web Components, plantillas de frameworks, temas, localización y plugins personalizados. | Presets Pro y paquetes de despliegue empresarial. |
Sheets es actualmente la superficie de producto más madura. Docs y Slides comparten la arquitectura de Univer y siguen evolucionando dentro del mismo SDK.
## 🔓 Open Source y Pro
Este repositorio contiene el núcleo open source de Univer y plugins OSS de primera parte. Univer Pro se desarrolla por separado como una capa de extensión comercial para superficies de producto avanzadas, colaboración, capacidades de servidor e integraciones empresariales.
| Categoría | Open source | Univer Pro / comercial |
| --- | --- | --- |
| **Base** | SDK core, sistema de plugins, motor de renderizado, motor de fórmulas, Facade API, temas, i18n y adaptadores de frameworks. | Presets Pro y paquetes de despliegue empresarial. |
| **Sheets** | Edición básica de hojas de cálculo, fórmulas, formato numérico, filtro/ordenación, validación de datos, formato condicional, notas, tablas, hipervínculos, comentarios, dibujo, buscar y reemplazar. | Colaboración, historial de edición, importación/exportación, impresión, gráficos, tablas dinámicas, sparklines, esquemas, formas, gráficos dentro de celdas, conectores de datos, preprocesamiento de rangos y funciones mejoradas del motor de fórmulas. |
| **Docs** | Modelo de documento y UI de edición, listas, hipervínculos, comentarios, inserción rápida e integración de dibujo. | Colaboración, importación/exportación, impresión, tablas/listas mejoradas, columnas, callouts, bloques de código, citas, formas y recursos remotos de comentarios en hilos. |
| **Slides** | Modelo de presentaciones OSS y paquetes de UI. | Paquetes Pro de modelo/UI de slides, importación/exportación de slides, gráficos, tablas y UI reutilizable de editor de formas. |
| **Bases** | Arquitectura de plugins extensible para productos personalizados centrados en datos. | Modelo core de base de datos Base, comandos, mutations, integración de fórmulas, UI de workbench, editores de campos e integración con el motor de renderizado. |
| **Servidor y runtime** | Runtime headless en Node.js, patrones RPC/Web Worker y primitivas de automatización orientada al servidor. | Servidor de colaboración, cliente de colaboración para Node.js, servicios SSR, delegación de cómputo, cálculo del lado del servidor y herramientas de replay de changesets de colaboración. |
Las funciones Pro están documentadas en la [guía de Univer Pro](https://docs.univer.ai/guides/pro). Se separan aquí intencionalmente para que el alcance OSS sea claro.
Principios de separación:
- Los paquetes OSS de este repositorio están pensados para ser útiles por sí mismos bajo la licencia Apache-2.0. Univer Pro es opcional y no se requiere para usar las APIs públicas del SDK OSS.
- Los bugs, regresiones y problemas de seguridad en paquetes OSS deben reportarse y corregirse en el repositorio OSS, incluso cuando exista una función Pro relacionada.
- La documentación OSS no debe sugerir que capacidades Pro-only están disponibles en los paquetes públicos `@univerjs/*`. Las APIs, paquetes y rutas de despliegue Pro-only deben nombrarse explícitamente.
- Cuando una función OSS tenga una mejora Pro, el comportamiento OSS debe seguir documentado de forma independiente para que los usuarios puedan evaluar el alcance open source sin leer primero documentación comercial.
## 🌐 Ecosistema
- **Core SDK**: [`dream-num/univer`](https://github.com/dream-num/univer), este monorepo.
- **Presets**: los [`presets/`](../../presets) de este repositorio, colecciones de plugins para aplicaciones en navegador y Node.js.
- **AI agent skills**: [`dream-num/univer-sdk-skills`](https://github.com/dream-num/univer-sdk-skills), instrucciones reutilizables para agentes de IA que trabajan con integración de Univer, funciones Pro, desarrollo de plugins y backends Node. Consulta la [guía de AI Skills](https://docs.univer.ai/guides/skills).
- **Documentación**: [docs.univer.ai](https://docs.univer.ai), con guías de Sheets, Docs, Slides, recipes y Pro.
- **API Reference**: [docs.univer.ai/reference](https://docs.univer.ai/reference/classes/univer), Facade API y referencia de API generada.
- **Ejemplos y showcase**: [Univer Showcase](https://docs.univer.ai/showcase) y los [`examples/`](../../examples) de este repositorio.
- **AI-native spreadsheets**: [`dream-num/univer-mcp`](https://github.com/dream-num/univer-mcp), integración Univer Platform / MCP para controlar Univer Sheets con lenguaje natural.
## 📦 Guía del repositorio
```text
.
├── packages/ Paquetes core, motores, tipos de documento, plugins UI y plugins de funciones
├── examples/ Banco de trabajo Vite todo-en-uno para desarrollo local en navegador
├── common/ Herramientas internas compartidas, storybook y utilidades
├── tests/ Proyectos adicionales de pruebas de integración
└── docs/ Notas de arquitectura, imágenes y documentación local del repositorio
```
Los README de cada paquete están junto a sus paquetes dentro de [`packages/`](../../packages).
## 🧑‍💻 Desarrollo
Requisitos:
- Node.js `>=22.18`
- pnpm `>=11`
```bash
git clone https://github.com/dream-num/univer.git
cd univer
pnpm install
pnpm dev
```
Comandos útiles:
| Comando | Propósito |
| --- | --- |
| `pnpm dev` | Compila y previsualiza el banco de trabajo todo-en-uno de bajo consumo sin HMR. |
| `pnpm dev:source` | Inicia el banco de trabajo desde el código fuente con HMR; el arranque y el uso de memoria son mayores. |
| `pnpm build` | Compila los paquetes del workspace, excluyendo paquetes internos de common. |
| `pnpm test` | Ejecuta pruebas unitarias mediante Turbo. |
| `pnpm typecheck` | Ejecuta comprobaciones TypeScript mediante Turbo. |
| `pnpm lint` | Ejecuta ESLint. |
| `pnpm storybook:dev` | Inicia Storybook para desarrollo de componentes UI. |
Lee [CONTRIBUTING.md](../../CONTRIBUTING.md) antes de abrir un pull request.
## 📝 Notas para contribuidores
Notas locales del repositorio que vale la pena leer antes de cambios profundos:
- [Building Isomorphic Univer](../ISOMORPHIC.md): cómo separar lógica de navegador, Node.js, UI y plugins compartidos.
- [Política de estabilidad de API](../API_STABILITY.md): expectativas sobre stable, experimental, internal, deprecated y breaking changes.
- [Contributing to Facade API](../CONTRIBUTING-FACADE.md): expectativas de diseño para `FUniver`, `FWorkbook`, `FRange` y clases Facade relacionadas.
- [Naming Convention](../NAMING_CONVENTION.md): convenciones para archivos, carpetas, interfaces, plugins, comandos y tokens de inyección de dependencias.
- [Fixing Memory Leaks](../FIX_MEMORY_LEAK.md): patrones comunes de fugas de memoria y flujo de depuración para instancias Univer.
- [Architecture TLDRs](../tldr): notas breves sobre motor de fórmulas, Web Worker, permisos, selección y comportamiento ref-range.
## 💬 Comunidad
- Haz preguntas en [GitHub Discussions](https://github.com/dream-num/univer/discussions).
- Habla con la comunidad en [Discord](https://discord.gg/z3NKNT6D2f).
- Sigue [Twitter / X](https://twitter.com/univerhq) y [YouTube](https://www.youtube.com/@dreamNum).
Lee el [Código de Conducta](../../CODE_OF_CONDUCT.md) antes de participar.
## 🔒 Seguridad
Si crees haber encontrado un problema de seguridad, sigue la [Política de Seguridad](../../SECURITY.md).
## ❤️ Patrocinadores
Univer cuenta con el apoyo de la comunidad y patrocinadores. Puedes apoyar el proyecto a través de [Open Collective](https://opencollective.com/univer).
<a href="https://opencollective.com/univer/sponsor/0/website"><img src="https://opencollective.com/univer/sponsor/0/avatar.svg" alt="Sponsor 0" /></a>
<a href="https://opencollective.com/univer/sponsor/1/website"><img src="https://opencollective.com/univer/sponsor/1/avatar.svg" alt="Sponsor 1" /></a>
<a href="https://opencollective.com/univer/sponsor/2/website"><img src="https://opencollective.com/univer/sponsor/2/avatar.svg" alt="Sponsor 2" /></a>
<a href="https://opencollective.com/univer/sponsor/3/website"><img src="https://opencollective.com/univer/sponsor/3/avatar.svg" alt="Sponsor 3" /></a>
<a href="https://opencollective.com/univer/sponsor/4/website"><img src="https://opencollective.com/univer/sponsor/4/avatar.svg" alt="Sponsor 4" /></a>
<a href="https://opencollective.com/univer/sponsor/5/website"><img src="https://opencollective.com/univer/sponsor/5/avatar.svg" alt="Sponsor 5" /></a>
<a href="https://opencollective.com/univer/sponsor/6/website"><img src="https://opencollective.com/univer/sponsor/6/avatar.svg" alt="Sponsor 6" /></a>
<a href="https://opencollective.com/univer/backer/0/website"><img src="https://opencollective.com/univer/backer/0/avatar.svg" alt="Backer 0" /></a>
<a href="https://opencollective.com/univer/backer/1/website"><img src="https://opencollective.com/univer/backer/1/avatar.svg" alt="Backer 1" /></a>
<a href="https://opencollective.com/univer/backer/2/website"><img src="https://opencollective.com/univer/backer/2/avatar.svg" alt="Backer 2" /></a>
<a href="https://opencollective.com/univer/backer/3/website"><img src="https://opencollective.com/univer/backer/3/avatar.svg" alt="Backer 3" /></a>
<a href="https://opencollective.com/univer/backer/4/website"><img src="https://opencollective.com/univer/backer/4/avatar.svg" alt="Backer 4" /></a>
<a href="https://opencollective.com/univer/backer/5/website"><img src="https://opencollective.com/univer/backer/5/avatar.svg" alt="Backer 5" /></a>
<a href="https://opencollective.com/univer/backer/6/website"><img src="https://opencollective.com/univer/backer/6/avatar.svg" alt="Backer 6" /></a>
## 📄 Licencia
Copyright (c) 2021-present DreamNum Co., Ltd.
Publicado bajo la licencia [Apache-2.0](../../LICENSE).

374
docs/readme/ja-JP.md Normal file
View File

@@ -0,0 +1,374 @@
<div align="center">
<img src="../img/banner.png" alt="Univer SDK" width="800" />
**スプレッドシート、ドキュメント、プレゼンテーションを構築するためのフルスタックでアイソモーフィックなオフィス SDK。**
Univer は、プラグインアーキテクチャ、Canvas ベースのレンダリング、
数式エンジン、ブラウザと Node.js の両方で使える Facade API により、
組み込み型の生産性体験を構築できます。
[English](../../README.md) | [简体中文](./zh-CN.md) | [繁體中文](./zh-TW.md) | 日本語 | [한국어](./ko-KR.md) | [Español](./es-ES.md)
[📖 ドキュメント](https://docs.univer.ai) | [✨ ショーケース](https://docs.univer.ai/showcase) | [📘 API Reference](https://docs.univer.ai/reference/classes/univer) | [📝 ブログ](https://docs.univer.ai/blog)
[![Release](https://img.shields.io/github/v/release/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/releases)
[![License](https://img.shields.io/github/license/dream-num/univer?style=flat-square)](../../LICENSE)
[![Build](https://img.shields.io/github/actions/workflow/status/dream-num/univer/build-packages.yml?style=flat-square)](https://github.com/dream-num/univer/actions/workflows/build-packages.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/dream-num/univer/badge/dev?style=flat-square)](https://www.codefactor.io/repository/github/dream-num/univer/overview/dev)
[![Codecov](https://img.shields.io/codecov/c/gh/dream-num/univer?token=aPfyW2pIMN&style=flat-square)](https://codecov.io/gh/dream-num/univer)
[![Stars](https://img.shields.io/github/stars/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/stargazers)
[![Contributors](https://img.shields.io/github/contributors/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/issues)
[![Last Commit](https://img.shields.io/github/last-commit/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/commits/dev/)
[![Discord](https://img.shields.io/discord/1136129819961217077?logo=discord&logoColor=FFFFFF&label=discord&color=5865F2&style=flat-square)](https://discord.gg/z3NKNT6D2f)
[![Twitter](https://img.shields.io/twitter/follow/univerhq?style=flat-square&logo=x)](https://twitter.com/univerhq)
[![Open Collective](https://img.shields.io/opencollective/all/univer?logo=opencollective&style=flat-square)](https://opencollective.com/univer)
[![Trendshift](https://trendshift.io/api/badge/repositories/4376)](https://trendshift.io/repositories/4376)
</div>
## ✨ Univer とは?
Univer は、自分のプロダクト内にオフィスアプリケーションを作るためのオープンソース SDK です。スプレッドシート、ドキュメント、プレゼンテーション体験に必要な構成要素を提供しつつ、ホスト型アプリや固定 UI を強制しません。
Univer は次のような場面に適しています。
- SaaS、社内ツール、BI ワークフロー、AI アプリケーションにスプレッドシートやドキュメント編集を組み込む。
- ブラウザと同じアーキテクチャで、サーバー上のワークブック/ドキュメント処理を実行する。
- 必要な機能だけをプラグインで組み合わせる、または presets で素早く始める。
- カスタムプラグイン、コマンド、サービス、UI コンポーネント、Facade API で振る舞いを拡張する。
Univer は単なるスプレッドシートファイルビューアではありません。独自の生産性インターフェースを構築するためのフレームワークです。
## 🌟 Highlights
<table>
<tr>
<td align="center" width="33%">
⚡<br />
<strong>大規模な編集面に対応</strong><br />
<sub>Canvas ベースのレンダリングと専用の数式エンジンにより、複雑なワークブックでも応答性を保ちます。</sub>
</td>
<td align="center" width="33%">
🧩<br />
<strong>プラグイン前提の設計</strong><br />
<sub>必要な機能を組み合わせ、置換、遅延読み込み、拡張できます。</sub>
</td>
<td align="center" width="33%">
🤖<br />
<strong>Headless AI 基盤</strong><br />
<sub>Node.js でワークブックとドキュメントのロジックを実行し、エージェント、自動化、サーバーサイドワークフローを支えます。</sub>
</td>
</tr>
<tr>
<td align="center" width="33%">
🛠️<br />
<strong>プロダクト向け SDK</strong><br />
<sub>フレームワークアダプター、Facade API、presets、headless runtime が実際の統合経路に対応します。</sub>
</td>
<td align="center" width="33%">
🌗<br />
<strong>Dark mode 対応</strong><br />
<sub>UI コンポーネントとレンダリングエンジンの両方がライト/ダークテーマに対応します。</sub>
</td>
<td align="center" width="33%">
🔌<br />
<strong>統合 Facade API</strong><br />
<sub>ブラウザと Node.js の両方で、ワークブック、範囲、数式、ドキュメントを一貫した API で扱えます。</sub>
</td>
</tr>
</table>
## 🚀 なぜ Univer なのか?
- **アイソモーフィック設計**:ブラウザの UI アプリと Node.js のヘッドレス処理の両方で動作します。
- **プラグイン優先アーキテクチャ**:すべての機能は組み合わせ可能なプラグインとして提供され、追加、削除、置換、遅延読み込みが可能です。
- **Preset Mode による高速な統合**:すぐに動くアプリが必要な場合は、このリポジトリの [`presets/`](../../presets) にある curated plugin collection を利用できます。
- **Plugin Mode による完全な制御**:カスタム読み込み、より小さなバンドル、深い統合が必要な場合は、パッケージを手動で組み合わせられます。
- **Facade API**:ワークブック、ワークシート、範囲、ドキュメント、数式、コマンド、イベントを高レベル API で扱えます。
- **Canvas レンダリングエンジン**:大規模な編集可能ドキュメント面をサポートし、複数の文書タイプでレンダリング層を共有します。
- **拡張可能な UI**:React、Vue、Web Components、各種フレームワークのアプリケーションシェルに統合できます。
## ⚡ クイックスタート
製品機能を広く利用し、構成を細かく制御するには **Plugin Mode** を使用します。対応する Sheets、Docs、Node の構成では、**Preset Mode** を使うと curated setup をより短く記述できます。
<details open>
<summary><strong>Plugin Mode</strong></summary>
Plugin Mode では、パッケージ、スタイルの import、locale の merge、Facade API 登録、プラグイン設定をより低レベルで制御できます。
```bash
pnpm add @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-formula-ui @univerjs/sheets-numfmt @univerjs/sheets-numfmt-ui @univerjs/sheets-ui @univerjs/ui
```
```ts
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import { FUniver } from '@univerjs/core/facade'
import DesignEnUS from '@univerjs/design/locale/en-US'
import { UniverDocsPlugin } from '@univerjs/docs'
import { UniverDocsUIPlugin } from '@univerjs/docs-ui'
import DocsUIEnUS from '@univerjs/docs-ui/locale/en-US'
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'
import { UniverRenderEnginePlugin } from '@univerjs/engine-render'
import { UniverSheetsPlugin } from '@univerjs/sheets'
import SheetsEnUS from '@univerjs/sheets/locale/en-US'
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'
import SheetsFormulaEnUS from '@univerjs/sheets-formula/locale/en-US'
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'
import SheetsFormulaUIEnUS from '@univerjs/sheets-formula-ui/locale/en-US'
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt'
import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui'
import SheetsNumfmtUIEnUS from '@univerjs/sheets-numfmt-ui/locale/en-US'
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US'
import { UniverUIPlugin } from '@univerjs/ui'
import UIEnUS from '@univerjs/ui/locale/en-US'
import '@univerjs/design/lib/index.css'
import '@univerjs/ui/lib/index.css'
import '@univerjs/docs-ui/lib/index.css'
import '@univerjs/sheets-ui/lib/index.css'
import '@univerjs/sheets-formula-ui/lib/index.css'
import '@univerjs/sheets-numfmt-ui/lib/index.css'
import '@univerjs/engine-formula/facade'
import '@univerjs/ui/facade'
import '@univerjs/sheets/facade'
import '@univerjs/sheets-ui/facade'
import '@univerjs/sheets-formula/facade'
import '@univerjs/sheets-numfmt/facade'
const univer = new Univer({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(
DesignEnUS,
UIEnUS,
DocsUIEnUS,
SheetsEnUS,
SheetsUIEnUS,
SheetsFormulaEnUS,
SheetsFormulaUIEnUS,
SheetsNumfmtUIEnUS,
),
},
})
univer.registerPlugin(UniverRenderEnginePlugin)
univer.registerPlugin(UniverFormulaEnginePlugin)
univer.registerPlugin(UniverUIPlugin, { container: 'app' })
univer.registerPlugin(UniverDocsPlugin)
univer.registerPlugin(UniverDocsUIPlugin)
univer.registerPlugin(UniverSheetsPlugin)
univer.registerPlugin(UniverSheetsUIPlugin)
univer.registerPlugin(UniverSheetsFormulaPlugin)
univer.registerPlugin(UniverSheetsFormulaUIPlugin)
univer.registerPlugin(UniverSheetsNumfmtPlugin)
univer.registerPlugin(UniverSheetsNumfmtUIPlugin)
const univerAPI = FUniver.newAPI(univer)
univerAPI.createWorkbook({})
```
</details>
<details>
<summary><strong>Preset Mode</strong></summary>
Preset は、必要な Facade API 登録とスタイルを含む Univer プラグインの curated collection です。
```bash
pnpm add @univerjs/presets @univerjs/preset-sheets-core
```
```ts
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
import '@univerjs/preset-sheets-core/lib/index.css'
const { univerAPI } = createUniver({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(UniverPresetSheetsCoreEnUS),
},
presets: [
UniverSheetsCorePreset({
container: 'app',
}),
],
})
univerAPI.createWorkbook({})
```
</details>
ページにはコンテナが必要です。
```html
<div id="app" style="height: 100vh"></div>
```
詳しくは [Installation & Basic Usage guide](https://docs.univer.ai/guides/sheets/getting-started/installation)、[`createUniver` reference](https://docs.univer.ai/reference/methods/create-univer)、[Facade API reference](https://docs.univer.ai/reference/classes/univer) を参照してください。
## 🧩 Preset Mode と Plugin Mode
| 選択肢 | 使う場面 | はじめに読むもの |
| --- | --- | --- |
| **Plugin Mode** | パッケージ、構成済みの依存関係、遅延読み込み、実行時の構成を厳密に制御したい場合。 | このリポジトリの [`examples/`](../../examples) と [architecture guide](https://docs.univer.ai/guides/recipes/architecture/univer) |
| **Preset Mode** | 最小限の設定で Sheets、Docs、Node の動作環境を作りたい場合。 | このリポジトリの [`presets/`](../../presets) と [getting started guide](https://docs.univer.ai/guides/sheets/getting-started/installation) |
| **Headless Mode** | UI なしでサーバー側のワークブック/ドキュメント処理、数式計算、自動化を行いたい場合。 | [Headless Univer](https://docs.univer.ai/guides/sheets/getting-started/node) |
同じ Univer の協調リリースラインに含まれる `@univerjs/*` SDK パッケージは、同一バージョンに揃えてください。`@univerjs/icons` や `@univerjs/icons-svg` など独立してリリースされるパッケージは、SDK のバージョンではなく、各パッケージマニフェストに宣言された互換バージョンを使用します。Univer Pro を使用する場合は、`@univerjs-pro/*` も対応する協調リリースラインに揃えてください。
API 互換性、experimental API、internal API、deprecation rules については [API Stability Policy](../API_STABILITY.md) を参照してください。
## 🧭 互換性
- **ブラウザ実行環境**:Univer は Chrome 88 をターゲットとしてコンパイルされており、Edge `>=88`、Firefox `>=90`、Chrome `>=88`、Safari `>=14.1`、Electron `>=12` で動作することを目指しています。
- **Polyfills**:Univer は `Intl.Segmenter` に依存しています。対象ブラウザや実行環境が対応していない場合は、`@formatjs/intl-segmenter` などの polyfill を追加してください。
- **ビルドツール**:Vite、esbuild、Webpack 5 を推奨します。`package.json` の `exports` フィールドに対応していないビルドツール(Webpack 4 など)では、追加のパスマッピングが必要になる場合があります。
- **React**:Univer の view layer は React 18 ベースで構築されており、React 18 と 19 をサポートします。React 16.9+ と 17 には最小限の互換サポートを提供します。
- **Node.js runtime**:Headless Univer は Node.js `>=18.17.0` をサポートします。この monorepo の開発には Node.js `>=22.18` が必要です。
## 🛠️ 構築できるもの
| 領域 | オープンソースの機能 | Univer Pro 拡張 |
| --- | --- | --- |
| **Sheets** | ワークブック、ワークシート、範囲、選択、数式、数値書式、フィルター、ソート、データ検証、条件付き書式、ハイパーリンク、コメント、検索と置換、ノート、テーブル、描画連携、拡張可能な UI プラグイン。 | リアルタイム共同編集、編集履歴、インポート/エクスポート、印刷、チャート、ピボットテーブル、スパークライン、アウトライン、図形、セル内グラフィックス、データコネクタ、サーバーサイド計算、強化された数式機能。 |
| **Docs** | リッチドキュメントモデル、編集 UI、リスト、ハイパーリンク、描画連携、コメント、クイック挿入、共有ドキュメントアーキテクチャ。 | 共同編集、インポート/エクスポート、印刷、強化されたテーブルとリスト、段組み、コールアウト、コードブロック、引用ブロック、図形、リモートコメントリソース。 |
| **Slides** | プレゼンテーションデータモデルと UI パッケージ。現在も活発に開発中です。 | Pro スライドモデルと UI、スライドのインポート/エクスポート、チャートとテーブルのモデル/UI プラグイン、共有の図形編集基盤。 |
| **Bases** | Univer のプラグイン、コマンド、モデルのアーキテクチャ上に、カスタムの構造化データ体験を構築できます。 | Base データベースモデル、コマンド、数式連携、ワークベンチ UI、フィールドエディタ、レンダリングエンジンビュー。 |
| **Runtime** | ブラウザアプリ、Node.js ヘッドレス利用、Web Worker/RPC パターン、複数インスタンス、サーバー向け自動化。 | 共同編集クライアント/サーバーパッケージ、Node.js 共同編集クライアント、Pro サーバーサービス、SSR、計算委譲、サーバーサイド計算、changeset replay ツール。 |
| **Integrations** | React、Vue、Web Components、フレームワークテンプレート、テーマ、ローカライズ、カスタムプラグイン。 | Pro presets とエンタープライズデプロイパッケージ。 |
現在もっとも成熟しているプロダクト面は Sheets です。Docs と Slides も Univer のアーキテクチャを共有し、同じ SDK の中で継続的に進化しています。
## 🔓 Open Source と Pro
このリポジトリには Univer のオープンソースコアと first-party OSS プラグインが含まれています。Univer Pro は、高度なプロダクトサーフェス、共同編集、サーバー機能、エンタープライズ連携のための商用拡張レイヤーとして別途開発されています。
| カテゴリ | Open source | Univer Pro / commercial |
| --- | --- | --- |
| **Foundation** | Core SDK、プラグインシステム、レンダリングエンジン、数式エンジン、Facade API、テーマ、i18n、フレームワークアダプタ。 | Pro presets とエンタープライズデプロイパッケージ。 |
| **Sheets** | コアのスプレッドシート編集、数式、数値書式、フィルター/ソート、データ検証、条件付き書式、ノート、テーブル、ハイパーリンク、コメント、描画、検索と置換。 | 共同編集、編集履歴、インポート/エクスポート、印刷、チャート、ピボットテーブル、スパークライン、アウトライン、図形、セル内グラフィックス、データコネクタ、範囲の前処理、強化された数式エンジン機能。 |
| **Docs** | ドキュメントモデルと編集 UI、リスト、ハイパーリンク、コメント、クイック挿入、描画連携。 | 共同編集、インポート/エクスポート、印刷、強化されたテーブル/リスト、段組み、コールアウト、コードブロック、引用ブロック、図形、リモートスレッドコメントリソース。 |
| **Slides** | OSS のプレゼンテーションモデルと UI パッケージ。 | Pro スライドモデル/UI パッケージ、スライドのインポート/エクスポート、チャート、テーブル、再利用可能な図形エディタ UI。 |
| **Bases** | カスタムのデータ中心プロダクト向けの拡張可能なプラグインアーキテクチャ。 | Base データベースコアモデル、コマンド、ミューテーション、数式連携、ワークベンチ UI、フィールドエディタ、レンダリングエンジン連携。 |
| **Server and runtime** | Node.js ヘッドレスランタイム、RPC/Web Worker パターン、サーバー向け自動化のプリミティブ。 | 共同編集サーバー、Node.js 共同編集クライアント、SSR サービス、計算委譲、サーバーサイド計算、共同編集 changeset replay ツール。 |
Pro 機能は [Univer Pro guide](https://docs.univer.ai/guides/pro) に記載されています。ここでは OSS パッケージの範囲を明確にするため、意図的に分けて説明しています。
Boundary principles:
- このリポジトリの OSS パッケージは Apache-2.0 license の下で単独利用できることを意図しています。Univer Pro は任意であり、公開 OSS SDK API の利用に Pro は不要です。
- OSS パッケージの bugs、regressions、security issues は、関連する Pro 機能がある場合でも OSS リポジトリで報告・修正されるべきです。
- OSS documentation は、Pro-only capabilities が公開 `@univerjs/*` packages に含まれるかのように示すべきではありません。Pro-only APIs、packages、deployment paths は明示的に名前を出してください。
- OSS feature に Pro enhancement がある場合でも、OSS behavior は独立して文書化し、commercial docs を先に読まなくても open-source surface を評価できるようにします。
## 🌐 エコシステム
- **Core SDK**:[`dream-num/univer`](https://github.com/dream-num/univer)、この monorepo です。
- **Presets**:このリポジトリの [`presets/`](../../presets)。ブラウザと Node.js アプリ向けの curated plugin collection です。
- **AI agent skills**:[`dream-num/univer-sdk-skills`](https://github.com/dream-num/univer-sdk-skills)、Univer 統合、Pro 機能、プラグイン開発、Node バックエンドに取り組む AI agent 向けの再利用可能な指示集です。[AI Skills guide](https://docs.univer.ai/guides/skills) も参照してください。
- **Documentation**:[docs.univer.ai](https://docs.univer.ai)、Sheets、Docs、Slides、recipes、Pro guides を含みます。
- **API Reference**:[docs.univer.ai/reference](https://docs.univer.ai/reference/classes/univer)、Facade API と生成された API reference。
- **Examples and showcase**:[Univer Showcase](https://docs.univer.ai/showcase) とこのリポジトリの [`examples/`](../../examples)。
- **AI-native spreadsheets**:[`dream-num/univer-mcp`](https://github.com/dream-num/univer-mcp)、自然言語で Univer Sheets を操作する Univer Platform / MCP 統合。
## 📦 リポジトリ構成
```text
.
├── packages/ コアパッケージ、エンジン、文書タイプ、UI プラグイン、機能プラグイン
├── examples/ ローカルブラウザ開発用のオールインワン Vite ワークベンチ
├── common/ 共有内部ツール、storybook、ユーティリティ
├── tests/ 追加の統合テストプロジェクト
└── docs/ アーキテクチャメモ、画像、リポジトリ内ドキュメント
```
パッケージごとの README は [`packages/`](../../packages) 配下の各パッケージにあります。
## 🧑‍💻 開発
必要環境:
- Node.js `>=22.18`
- pnpm `>=11`
```bash
git clone https://github.com/dream-num/univer.git
cd univer
pnpm install
pnpm dev
```
よく使うコマンド:
| コマンド | 用途 |
| --- | --- |
| `pnpm dev` | 低メモリのオールインワンワークベンチをビルドし、HMR なしでプレビューします。 |
| `pnpm dev:source` | HMR 対応でソースから起動します。コールドスタートとメモリ使用量は増加します。 |
| `pnpm build` | 内部 common パッケージを除いて workspace パッケージをビルドします。 |
| `pnpm test` | Turbo 経由でユニットテストを実行します。 |
| `pnpm typecheck` | Turbo 経由で TypeScript チェックを実行します。 |
| `pnpm lint` | ESLint を実行します。 |
| `pnpm storybook:dev` | UI コンポーネント開発用の Storybook を起動します。 |
Pull request を作成する前に [CONTRIBUTING.md](../../CONTRIBUTING.md) を読んでください。
## 📝 Contributor Notes
より深い変更を行う前に読む価値のあるリポジトリ内メモです。
- [Building Isomorphic Univer](../ISOMORPHIC.md):ブラウザ、Node.js、UI、共有プラグインロジックの分離方針。
- [API Stability Policy](../API_STABILITY.md):stable、experimental、internal、deprecated、breaking-change expectations。
- [Contributing to Facade API](../CONTRIBUTING-FACADE.md):`FUniver`、`FWorkbook`、`FRange` などの Facade API 設計方針。
- [Naming Convention](../NAMING_CONVENTION.md):ファイル、フォルダ、インターフェース、プラグイン、コマンド、DI token の命名規則。
- [Fixing Memory Leaks](../FIX_MEMORY_LEAK.md):Univer インスタンスでよくあるメモリリークパターンとデバッグ手順。
- [Architecture TLDRs](../tldr):数式エンジン、Web Worker、権限、選択、ref-range の簡潔な設計メモ。
## 💬 コミュニティ
- [GitHub Discussions](https://github.com/dream-num/univer/discussions) で質問できます。
- [Discord](https://discord.gg/z3NKNT6D2f) でコミュニティと交流できます。
- [Twitter / X](https://twitter.com/univerhq) と [YouTube](https://www.youtube.com/@dreamNum) もフォローできます。
参加する前に [Code of Conduct](../../CODE_OF_CONDUCT.md) を読んでください。
## 🔒 セキュリティ
セキュリティ上の問題を見つけたと思われる場合は、[Security Policy](../../SECURITY.md) に従ってください。
## ❤️ スポンサー
Univer はコミュニティとスポンサーによって支えられています。[Open Collective](https://opencollective.com/univer) からプロジェクトを支援できます。
<a href="https://opencollective.com/univer/sponsor/0/website"><img src="https://opencollective.com/univer/sponsor/0/avatar.svg" alt="Sponsor 0" /></a>
<a href="https://opencollective.com/univer/sponsor/1/website"><img src="https://opencollective.com/univer/sponsor/1/avatar.svg" alt="Sponsor 1" /></a>
<a href="https://opencollective.com/univer/sponsor/2/website"><img src="https://opencollective.com/univer/sponsor/2/avatar.svg" alt="Sponsor 2" /></a>
<a href="https://opencollective.com/univer/sponsor/3/website"><img src="https://opencollective.com/univer/sponsor/3/avatar.svg" alt="Sponsor 3" /></a>
<a href="https://opencollective.com/univer/sponsor/4/website"><img src="https://opencollective.com/univer/sponsor/4/avatar.svg" alt="Sponsor 4" /></a>
<a href="https://opencollective.com/univer/sponsor/5/website"><img src="https://opencollective.com/univer/sponsor/5/avatar.svg" alt="Sponsor 5" /></a>
<a href="https://opencollective.com/univer/sponsor/6/website"><img src="https://opencollective.com/univer/sponsor/6/avatar.svg" alt="Sponsor 6" /></a>
<a href="https://opencollective.com/univer/backer/0/website"><img src="https://opencollective.com/univer/backer/0/avatar.svg" alt="Backer 0" /></a>
<a href="https://opencollective.com/univer/backer/1/website"><img src="https://opencollective.com/univer/backer/1/avatar.svg" alt="Backer 1" /></a>
<a href="https://opencollective.com/univer/backer/2/website"><img src="https://opencollective.com/univer/backer/2/avatar.svg" alt="Backer 2" /></a>
<a href="https://opencollective.com/univer/backer/3/website"><img src="https://opencollective.com/univer/backer/3/avatar.svg" alt="Backer 3" /></a>
<a href="https://opencollective.com/univer/backer/4/website"><img src="https://opencollective.com/univer/backer/4/avatar.svg" alt="Backer 4" /></a>
<a href="https://opencollective.com/univer/backer/5/website"><img src="https://opencollective.com/univer/backer/5/avatar.svg" alt="Backer 5" /></a>
<a href="https://opencollective.com/univer/backer/6/website"><img src="https://opencollective.com/univer/backer/6/avatar.svg" alt="Backer 6" /></a>
## 📄 ライセンス
Copyright (c) 2021-present DreamNum Co., Ltd.
[Apache-2.0](../../LICENSE) ライセンスの下で公開されています。

374
docs/readme/ko-KR.md Normal file
View File

@@ -0,0 +1,374 @@
<div align="center">
<img src="../img/banner.png" alt="Univer SDK" width="800" />
**스프레드시트, 문서, 프레젠테이션을 만들기 위한 풀스택 동형 오피스 SDK.**
Univer는 플러그인 아키텍처, Canvas 기반 렌더링, 수식 엔진,
브라우저와 Node.js에서 함께 사용할 수 있는 Facade API로
임베드 가능한 생산성 경험을 만들 수 있게 해줍니다.
[English](../../README.md) | [简体中文](./zh-CN.md) | [繁體中文](./zh-TW.md) | [日本語](./ja-JP.md) | 한국어 | [Español](./es-ES.md)
[📖 문서](https://docs.univer.ai) | [✨ 쇼케이스](https://docs.univer.ai/showcase) | [📘 API Reference](https://docs.univer.ai/reference/classes/univer) | [📝 블로그](https://docs.univer.ai/blog)
[![Release](https://img.shields.io/github/v/release/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/releases)
[![License](https://img.shields.io/github/license/dream-num/univer?style=flat-square)](../../LICENSE)
[![Build](https://img.shields.io/github/actions/workflow/status/dream-num/univer/build-packages.yml?style=flat-square)](https://github.com/dream-num/univer/actions/workflows/build-packages.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/dream-num/univer/badge/dev?style=flat-square)](https://www.codefactor.io/repository/github/dream-num/univer/overview/dev)
[![Codecov](https://img.shields.io/codecov/c/gh/dream-num/univer?token=aPfyW2pIMN&style=flat-square)](https://codecov.io/gh/dream-num/univer)
[![Stars](https://img.shields.io/github/stars/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/stargazers)
[![Contributors](https://img.shields.io/github/contributors/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/issues)
[![Last Commit](https://img.shields.io/github/last-commit/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/commits/dev/)
[![Discord](https://img.shields.io/discord/1136129819961217077?logo=discord&logoColor=FFFFFF&label=discord&color=5865F2&style=flat-square)](https://discord.gg/z3NKNT6D2f)
[![Twitter](https://img.shields.io/twitter/follow/univerhq?style=flat-square&logo=x)](https://twitter.com/univerhq)
[![Open Collective](https://img.shields.io/opencollective/all/univer?logo=opencollective&style=flat-square)](https://opencollective.com/univer)
[![Trendshift](https://trendshift.io/api/badge/repositories/4376)](https://trendshift.io/repositories/4376)
</div>
## ✨ Univer란?
Univer는 제품 안에 오피스 애플리케이션을 만들기 위한 오픈소스 SDK입니다. 호스팅 앱이나 고정된 UI를 강제하지 않으면서 스프레드시트, 문서, 프레젠테이션 경험에 필요한 빌딩 블록을 제공합니다.
Univer는 다음과 같은 경우에 적합합니다.
- SaaS 제품, 내부 도구, BI 워크플로, AI 애플리케이션에 스프레드시트나 문서 편집 기능을 임베드할 때.
- 브라우저와 같은 아키텍처로 서버에서 워크북/문서 처리를 실행할 때.
- 필요한 기능만 플러그인으로 조합하거나 presets로 빠르게 시작할 때.
- 커스텀 플러그인, 명령, 서비스, UI 컴포넌트, Facade API로 동작을 확장할 때.
Univer는 단순한 스프레드시트 파일 뷰어가 아닙니다. 자체 생산성 화면을 구축하기 위한 프레임워크입니다.
## 🌟 Highlights
<table>
<tr>
<td align="center" width="33%">
⚡<br />
<strong>대규모 화면에 맞춘 설계</strong><br />
<sub>Canvas 기반 렌더링과 전용 수식 엔진이 복잡한 워크북도 반응성 있게 유지합니다.</sub>
</td>
<td align="center" width="33%">
🧩<br />
<strong>플러그인 중심 확장</strong><br />
<sub>필요한 기능을 조합, 교체, 지연 로딩하거나 확장할 수 있습니다.</sub>
</td>
<td align="center" width="33%">
🤖<br />
<strong>Headless AI 인프라</strong><br />
<sub>Node.js에서 워크북과 문서 로직을 실행해 에이전트, 자동화, 서버 사이드 워크플로를 지원합니다.</sub>
</td>
</tr>
<tr>
<td align="center" width="33%">
🛠️<br />
<strong>제품 통합을 위한 SDK</strong><br />
<sub>프레임워크 어댑터, Facade API, presets, headless runtime이 실제 통합 경로에 맞춰집니다.</sub>
</td>
<td align="center" width="33%">
🌗<br />
<strong>Dark mode 지원</strong><br />
<sub>UI 컴포넌트와 렌더링 엔진이 모두 라이트/다크 테마를 지원합니다.</sub>
</td>
<td align="center" width="33%">
🔌<br />
<strong>통합 Facade API</strong><br />
<sub>브라우저와 Node.js에서 워크북, 범위, 수식, 문서를 일관된 API로 다룰 수 있습니다.</sub>
</td>
</tr>
</table>
## 🚀 왜 Univer인가?
- **동형 설계**: 브라우저 UI 앱과 Node.js headless 처리를 모두 실행할 수 있습니다.
- **플러그인 우선 아키텍처**: 모든 기능은 조합 가능한 플러그인으로 제공되어 추가, 제거, 교체, 지연 로딩이 가능합니다.
- **빠른 통합을 위한 Preset Mode**: 빠르게 동작하는 앱이 필요할 때 이 저장소의 [`presets/`](../../presets)에 있는 curated plugin collection을 사용할 수 있습니다.
- **완전한 제어를 위한 Plugin Mode**: 커스텀 로딩, 더 작은 번들, 깊은 통합이 필요할 때 패키지를 직접 조합할 수 있습니다.
- **Facade API**: 워크북, 워크시트, 범위, 문서, 수식, 명령, 이벤트를 고수준 API로 다룰 수 있습니다.
- **Canvas 렌더링 엔진**: 큰 편집 가능한 문서 표면을 지원하고 여러 문서 타입이 렌더링 레이어를 공유합니다.
- **확장 가능한 UI**: React, Vue, Web Components 및 프레임워크별 애플리케이션 셸에 통합할 수 있습니다.
## ⚡ 빠른 시작
전체 제품 기능을 활용하고 구성을 정밀하게 제어하려면 **Plugin Mode**를 사용하세요. 지원되는 Sheets, Docs, Node 프로필에서는 **Preset Mode**가 더 짧은 curated setup을 제공합니다.
<details open>
<summary><strong>Plugin Mode</strong></summary>
Plugin Mode는 패키지, 스타일 import, locale 병합, Facade API 등록, 플러그인 구성를 더 낮은 수준에서 제어할 수 있게 해줍니다.
```bash
pnpm add @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-formula-ui @univerjs/sheets-numfmt @univerjs/sheets-numfmt-ui @univerjs/sheets-ui @univerjs/ui
```
```ts
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import { FUniver } from '@univerjs/core/facade'
import DesignEnUS from '@univerjs/design/locale/en-US'
import { UniverDocsPlugin } from '@univerjs/docs'
import { UniverDocsUIPlugin } from '@univerjs/docs-ui'
import DocsUIEnUS from '@univerjs/docs-ui/locale/en-US'
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'
import { UniverRenderEnginePlugin } from '@univerjs/engine-render'
import { UniverSheetsPlugin } from '@univerjs/sheets'
import SheetsEnUS from '@univerjs/sheets/locale/en-US'
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'
import SheetsFormulaEnUS from '@univerjs/sheets-formula/locale/en-US'
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'
import SheetsFormulaUIEnUS from '@univerjs/sheets-formula-ui/locale/en-US'
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt'
import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui'
import SheetsNumfmtUIEnUS from '@univerjs/sheets-numfmt-ui/locale/en-US'
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US'
import { UniverUIPlugin } from '@univerjs/ui'
import UIEnUS from '@univerjs/ui/locale/en-US'
import '@univerjs/design/lib/index.css'
import '@univerjs/ui/lib/index.css'
import '@univerjs/docs-ui/lib/index.css'
import '@univerjs/sheets-ui/lib/index.css'
import '@univerjs/sheets-formula-ui/lib/index.css'
import '@univerjs/sheets-numfmt-ui/lib/index.css'
import '@univerjs/engine-formula/facade'
import '@univerjs/ui/facade'
import '@univerjs/sheets/facade'
import '@univerjs/sheets-ui/facade'
import '@univerjs/sheets-formula/facade'
import '@univerjs/sheets-numfmt/facade'
const univer = new Univer({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(
DesignEnUS,
UIEnUS,
DocsUIEnUS,
SheetsEnUS,
SheetsUIEnUS,
SheetsFormulaEnUS,
SheetsFormulaUIEnUS,
SheetsNumfmtUIEnUS,
),
},
})
univer.registerPlugin(UniverRenderEnginePlugin)
univer.registerPlugin(UniverFormulaEnginePlugin)
univer.registerPlugin(UniverUIPlugin, { container: 'app' })
univer.registerPlugin(UniverDocsPlugin)
univer.registerPlugin(UniverDocsUIPlugin)
univer.registerPlugin(UniverSheetsPlugin)
univer.registerPlugin(UniverSheetsUIPlugin)
univer.registerPlugin(UniverSheetsFormulaPlugin)
univer.registerPlugin(UniverSheetsFormulaUIPlugin)
univer.registerPlugin(UniverSheetsNumfmtPlugin)
univer.registerPlugin(UniverSheetsNumfmtUIPlugin)
const univerAPI = FUniver.newAPI(univer)
univerAPI.createWorkbook({})
```
</details>
<details>
<summary><strong>Preset Mode</strong></summary>
Presets는 필요한 Facade API 등록과 스타일을 포함하는 Univer 플러그인의 curated collection입니다.
```bash
pnpm add @univerjs/presets @univerjs/preset-sheets-core
```
```ts
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
import '@univerjs/preset-sheets-core/lib/index.css'
const { univerAPI } = createUniver({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(UniverPresetSheetsCoreEnUS),
},
presets: [
UniverSheetsCorePreset({
container: 'app',
}),
],
})
univerAPI.createWorkbook({})
```
</details>
페이지에는 컨테이너가 필요합니다.
```html
<div id="app" style="height: 100vh"></div>
```
자세한 내용은 [Installation & Basic Usage guide](https://docs.univer.ai/guides/sheets/getting-started/installation), [`createUniver` reference](https://docs.univer.ai/reference/methods/create-univer), [Facade API reference](https://docs.univer.ai/reference/classes/univer)를 참고하세요.
## 🧩 Preset Mode vs Plugin Mode
| 선택 | 사용 시점 | 시작하기 |
| --- | --- | --- |
| **Plugin Mode** | 패키지, 구성된 종속성, 지연 로딩, 런타임 구성을 엄격하게 제어해야 할 때. | 이 저장소의 [`examples/`](../../examples) 및 [architecture guide](https://docs.univer.ai/guides/recipes/architecture/univer) |
| **Preset Mode** | 최소 설정으로 동작하는 Sheets, Docs, Node 구성이 필요할 때. | 이 저장소의 [`presets/`](../../presets) 및 [getting started guide](https://docs.univer.ai/guides/sheets/getting-started/installation) |
| **Headless Mode** | UI 없이 서버 측 워크북/문서 처리, 수식 계산, 자동화가 필요할 때. | [Headless Univer](https://docs.univer.ai/guides/sheets/getting-started/node) |
동일한 Univer 통합 릴리스 라인에 포함되는 `@univerjs/*` SDK 패키지는 같은 버전으로 맞추세요. `@univerjs/icons`, `@univerjs/icons-svg`처럼 독립적으로 릴리스되는 패키지는 SDK 버전이 아니라 각 패키지 매니페스트에 선언된 호환 버전을 사용합니다. Univer Pro 패키지를 사용한다면 `@univerjs-pro/*`도 해당 통합 릴리스 라인에 맞추세요.
API 호환성 기대치, experimental APIs, internal APIs, deprecation rules는 [API Stability Policy](../API_STABILITY.md)를 참고하세요.
## 🧭 호환성
- **브라우저 런타임**: Univer는 Chrome 88을 대상으로 컴파일되며 Edge `>=88`, Firefox `>=90`, Chrome `>=88`, Safari `>=14.1`, Electron `>=12`에서 잘 동작하도록 노력합니다.
- **Polyfills**: Univer는 `Intl.Segmenter`에 의존합니다. 대상 브라우저나 런타임이 이를 제공하지 않는다면 `@formatjs/intl-segmenter` 같은 polyfill을 추가하세요.
- **빌드 도구**: Vite, esbuild, Webpack 5를 권장합니다. 빌드 도구가 `package.json`의 `exports` 필드를 지원하지 않는 경우(Webpack 4에서 흔함) 추가 path mapping이 필요할 수 있습니다.
- **React**: Univer의 view layer는 React 18 기반이며 React 18과 19를 지원합니다. React 16.9+ 및 17에는 최소한의 호환성 지원을 제공합니다.
- **Node.js runtime**: Headless Univer는 Node.js `>=18.17.0`을 지원합니다. 이 monorepo를 개발하려면 Node.js `>=22.18`이 필요합니다.
## 🛠️ 만들 수 있는 것
| 영역 | 오픈소스 기능 | Univer Pro 확장 |
| --- | --- | --- |
| **Sheets** | 워크북, 워크시트, 범위, 선택, 수식, 숫자 서식, 필터링, 정렬, 데이터 유효성 검사, 조건부 서식, 하이퍼링크, 댓글, 찾기/바꾸기, 노트, 테이블, drawing integration, 확장 가능한 UI 플러그인. | 실시간 협업, 편집 기록, import/export, printing, charts, pivot tables, sparklines, outlines, shapes, in-cell graphics, data connectors, server-side calculation, 향상된 formula 기능. |
| **Docs** | 리치 문서 모델, 편집 UI, 목록, 하이퍼링크, drawing integration, 댓글, quick insert, 공유 문서 아키텍처. | 협업, import/export, printing, 향상된 tables/lists, columns, callouts, code blocks, quotes, shapes, remote comment resources. |
| **Slides** | 프레젠테이션 데이터 모델과 UI 패키지. 현재 활발히 개발 중입니다. | Pro slide model/UI, slide import/export, chart/table model 및 UI plugins, 공유 shape editing infrastructure. |
| **Bases** | Univer의 plugin, command, model 아키텍처 위에서 커스텀 structured-data 경험을 만들 수 있습니다. | Base database model, commands, formula integration, workbench UI, field editors, render-engine views. |
| **Runtime** | 브라우저 앱, Node.js headless 사용, Web Worker/RPC 패턴, multi-instance 사용, 서버 지향 자동화. | Collaboration client/server packages, Node.js collaboration client, Pro server services, SSR, computing delegation, server-side calculation, changeset replay tooling. |
| **Integrations** | React, Vue, Web Components, 프레임워크 템플릿, 테마, 로컬라이제이션, 커스텀 플러그인. | Pro presets, enterprise deployment packages. |
Sheets는 현재 가장 성숙한 제품 영역입니다. Docs와 Slides는 Univer의 아키텍처를 공유하며 같은 SDK 안에서 계속 발전하고 있습니다.
## 🔓 Open Source와 Pro
이 저장소에는 Univer의 오픈소스 코어와 first-party OSS 플러그인이 포함되어 있습니다. Univer Pro는 고급 product surfaces, collaboration, server features, enterprise integrations를 위한 commercial extension layer로 별도 개발됩니다.
| 카테고리 | Open source | Univer Pro / commercial |
| --- | --- | --- |
| **Foundation** | Core SDK, 플러그인 시스템, 렌더링 엔진, 수식 엔진, Facade API, 테마, i18n, framework adapters. | Pro presets, enterprise deployment packages. |
| **Sheets** | 핵심 스프레드시트 편집, 수식, 숫자 서식, filter/sort, 데이터 유효성 검사, 조건부 서식, 노트, 테이블, 하이퍼링크, 댓글, drawing, 찾기/바꾸기. | 협업, 편집 기록, import/export, print, charts, pivot tables, sparklines, outlines, shapes, in-cell graphics, data connectors, range preprocessing, 향상된 formula engine 기능. |
| **Docs** | 문서 모델과 편집 UI, 목록, 하이퍼링크, 댓글, quick insert, drawing integration. | 협업, import/export, print, 향상된 tables/lists, columns, callouts, code blocks, quotes, shapes, remote thread-comment resources. |
| **Slides** | OSS presentation model과 UI packages. | Pro slide model/UI packages, slide import/export, charts, tables, reusable shape editor UI. |
| **Bases** | 커스텀 data-centric products를 위한 확장 가능한 plugin architecture. | Base database core model, commands, mutations, formula integration, workbench UI, field editors, render-engine integration. |
| **Server and runtime** | Node.js headless runtime, RPC/Web Worker patterns, server-oriented automation primitives. | Collaboration server, Node.js collaboration client, SSR services, computing delegation, server-side calculation, collaboration changeset replay tooling. |
Pro 기능은 [Univer Pro guide](https://docs.univer.ai/guides/pro)에 문서화되어 있습니다. 여기서는 OSS 패키지의 범위를 명확히 하기 위해 의도적으로 분리했습니다.
Boundary principles:
- 이 저장소의 OSS 패키지는 Apache-2.0 license 아래에서 독립적으로 유용하게 사용할 수 있도록 의도되었습니다. Univer Pro는 선택 사항이며, 공개 OSS SDK API를 사용하는 데 필요하지 않습니다.
- OSS 패키지의 bugs, regressions, security issues는 관련 Pro 기능이 있더라도 OSS 저장소에서 보고하고 수정해야 합니다.
- OSS documentation은 Pro-only capabilities가 공개 `@univerjs/*` packages에 포함된 것처럼 암시해서는 안 됩니다. Pro-only APIs, packages, deployment paths는 명확히 이름을 표시해야 합니다.
- OSS feature에 Pro enhancement가 있더라도 OSS behavior는 독립적으로 문서화되어야 하며, 사용자가 commercial docs를 먼저 읽지 않고도 open-source surface를 평가할 수 있어야 합니다.
## 🌐 생태계
- **Core SDK**: [`dream-num/univer`](https://github.com/dream-num/univer), 이 monorepo입니다.
- **Presets**: 이 저장소의 [`presets/`](../../presets), 브라우저와 Node.js 앱을 위한 curated plugin collection입니다.
- **AI agent skills**: [`dream-num/univer-sdk-skills`](https://github.com/dream-num/univer-sdk-skills), Univer 통합, Pro 기능, 플러그인 개발, Node 백엔드를 다루는 AI agent용 재사용 지침입니다. [AI Skills guide](https://docs.univer.ai/guides/skills)를 참고하세요.
- **Documentation**: [docs.univer.ai](https://docs.univer.ai), Sheets, Docs, Slides, recipes, Pro guides를 포함합니다.
- **API Reference**: [docs.univer.ai/reference](https://docs.univer.ai/reference/classes/univer), Facade API와 생성된 API reference입니다.
- **Examples and showcase**: [Univer Showcase](https://docs.univer.ai/showcase)와 이 저장소의 [`examples/`](../../examples).
- **AI-native spreadsheets**: [`dream-num/univer-mcp`](https://github.com/dream-num/univer-mcp), 자연어로 Univer Sheets를 제어하기 위한 Univer Platform / MCP 통합입니다.
## 📦 저장소 안내
```text
.
├── packages/ Core packages, engines, document types, UI plugins, feature plugins
├── examples/ 로컬 브라우저 개발을 위한 올인원 Vite workbench
├── common/ 공유 내부 도구, storybook, utilities
├── tests/ 추가 integration test projects
└── docs/ architecture notes, images, repository-local documentation
```
패키지별 README는 [`packages/`](../../packages)의 각 패키지 옆에 있습니다.
## 🧑‍💻 개발
요구 사항:
- Node.js `>=22.18`
- pnpm `>=11`
```bash
git clone https://github.com/dream-num/univer.git
cd univer
pnpm install
pnpm dev
```
유용한 명령:
| 명령 | 목적 |
| --- | --- |
| `pnpm dev` | 저메모리 올인원 workbench를 빌드하고 HMR 없이 미리 봅니다. |
| `pnpm dev:source` | HMR로 소스 workbench를 시작하며 콜드 스타트와 메모리 사용량이 더 큽니다. |
| `pnpm build` | 내부 common 패키지를 제외하고 workspace 패키지를 빌드합니다. |
| `pnpm test` | Turbo를 통해 unit tests를 실행합니다. |
| `pnpm typecheck` | Turbo를 통해 TypeScript checks를 실행합니다. |
| `pnpm lint` | ESLint를 실행합니다. |
| `pnpm storybook:dev` | UI component 개발용 Storybook을 시작합니다. |
Pull request를 열기 전에 [CONTRIBUTING.md](../../CONTRIBUTING.md)를 읽어 주세요.
## 📝 Contributor Notes
더 깊은 변경을 하기 전에 읽어볼 만한 저장소 내부 문서입니다.
- [Building Isomorphic Univer](../ISOMORPHIC.md): 브라우저, Node.js, UI, 공유 플러그인 로직을 나누는 방법.
- [API Stability Policy](../API_STABILITY.md): stable, experimental, internal, deprecated, breaking-change expectations.
- [Contributing to Facade API](../CONTRIBUTING-FACADE.md): `FUniver`, `FWorkbook`, `FRange` 등 Facade API의 설계 기준.
- [Naming Convention](../NAMING_CONVENTION.md): 파일, 폴더, 인터페이스, 플러그인, 명령, DI token naming 규칙.
- [Fixing Memory Leaks](../FIX_MEMORY_LEAK.md): Univer 인스턴스의 흔한 memory leak 패턴과 디버깅 흐름.
- [Architecture TLDRs](../tldr): formula engine, Web Worker, permission, selection, ref-range 동작에 대한 간단한 설계 메모.
## 💬 커뮤니티
- [GitHub Discussions](https://github.com/dream-num/univer/discussions)에서 질문할 수 있습니다.
- [Discord](https://discord.gg/z3NKNT6D2f)에서 커뮤니티와 대화할 수 있습니다.
- [Twitter / X](https://twitter.com/univerhq)와 [YouTube](https://www.youtube.com/@dreamNum)를 팔로우하세요.
참여하기 전에 [Code of Conduct](../../CODE_OF_CONDUCT.md)를 읽어 주세요.
## 🔒 보안
보안 문제를 발견했다고 생각되면 [Security Policy](../../SECURITY.md)를 따라 주세요.
## ❤️ 스폰서
Univer는 커뮤니티와 스폰서의 지원을 받습니다. [Open Collective](https://opencollective.com/univer)를 통해 프로젝트를 지원할 수 있습니다.
<a href="https://opencollective.com/univer/sponsor/0/website"><img src="https://opencollective.com/univer/sponsor/0/avatar.svg" alt="Sponsor 0" /></a>
<a href="https://opencollective.com/univer/sponsor/1/website"><img src="https://opencollective.com/univer/sponsor/1/avatar.svg" alt="Sponsor 1" /></a>
<a href="https://opencollective.com/univer/sponsor/2/website"><img src="https://opencollective.com/univer/sponsor/2/avatar.svg" alt="Sponsor 2" /></a>
<a href="https://opencollective.com/univer/sponsor/3/website"><img src="https://opencollective.com/univer/sponsor/3/avatar.svg" alt="Sponsor 3" /></a>
<a href="https://opencollective.com/univer/sponsor/4/website"><img src="https://opencollective.com/univer/sponsor/4/avatar.svg" alt="Sponsor 4" /></a>
<a href="https://opencollective.com/univer/sponsor/5/website"><img src="https://opencollective.com/univer/sponsor/5/avatar.svg" alt="Sponsor 5" /></a>
<a href="https://opencollective.com/univer/sponsor/6/website"><img src="https://opencollective.com/univer/sponsor/6/avatar.svg" alt="Sponsor 6" /></a>
<a href="https://opencollective.com/univer/backer/0/website"><img src="https://opencollective.com/univer/backer/0/avatar.svg" alt="Backer 0" /></a>
<a href="https://opencollective.com/univer/backer/1/website"><img src="https://opencollective.com/univer/backer/1/avatar.svg" alt="Backer 1" /></a>
<a href="https://opencollective.com/univer/backer/2/website"><img src="https://opencollective.com/univer/backer/2/avatar.svg" alt="Backer 2" /></a>
<a href="https://opencollective.com/univer/backer/3/website"><img src="https://opencollective.com/univer/backer/3/avatar.svg" alt="Backer 3" /></a>
<a href="https://opencollective.com/univer/backer/4/website"><img src="https://opencollective.com/univer/backer/4/avatar.svg" alt="Backer 4" /></a>
<a href="https://opencollective.com/univer/backer/5/website"><img src="https://opencollective.com/univer/backer/5/avatar.svg" alt="Backer 5" /></a>
<a href="https://opencollective.com/univer/backer/6/website"><img src="https://opencollective.com/univer/backer/6/avatar.svg" alt="Backer 6" /></a>
## 📄 라이선스
Copyright (c) 2021-present DreamNum Co., Ltd.
[Apache-2.0](../../LICENSE) 라이선스로 배포됩니다.

373
docs/readme/zh-CN.md Normal file
View File

@@ -0,0 +1,373 @@
<div align="center">
<img src="../img/banner.png" alt="Univer SDK" width="800" />
**用于构建电子表格、文档和演示文稿的全栈、同构办公 SDK。**
Univer 以插件化架构、Canvas 渲染引擎、公式引擎和统一的 Facade API,
帮助你在浏览器和 Node.js 中构建可嵌入的生产力体验。
[English](../../README.md) | 简体中文 | [繁體中文](./zh-TW.md) | [日本語](./ja-JP.md) | [한국어](./ko-KR.md) | [Español](./es-ES.md)
[📖 文档](https://docs.univer.ai) | [✨ 示例](https://docs.univer.ai/showcase) | [📘 API 参考](https://docs.univer.ai/reference/classes/univer) | [📝 博客](https://docs.univer.ai/blog)
[![Release](https://img.shields.io/github/v/release/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/releases)
[![License](https://img.shields.io/github/license/dream-num/univer?style=flat-square)](../../LICENSE)
[![Build](https://img.shields.io/github/actions/workflow/status/dream-num/univer/build-packages.yml?style=flat-square)](https://github.com/dream-num/univer/actions/workflows/build-packages.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/dream-num/univer/badge/dev?style=flat-square)](https://www.codefactor.io/repository/github/dream-num/univer/overview/dev)
[![Codecov](https://img.shields.io/codecov/c/gh/dream-num/univer?token=aPfyW2pIMN&style=flat-square)](https://codecov.io/gh/dream-num/univer)
[![Stars](https://img.shields.io/github/stars/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/stargazers)
[![Contributors](https://img.shields.io/github/contributors/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/issues)
[![Last Commit](https://img.shields.io/github/last-commit/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/commits/dev/)
[![Discord](https://img.shields.io/discord/1136129819961217077?logo=discord&logoColor=FFFFFF&label=discord&color=5865F2&style=flat-square)](https://discord.gg/z3NKNT6D2f)
[![Twitter](https://img.shields.io/twitter/follow/univerhq?style=flat-square&logo=x)](https://twitter.com/univerhq)
[![Open Collective](https://img.shields.io/opencollective/all/univer?logo=opencollective&style=flat-square)](https://opencollective.com/univer)
[![Trendshift](https://trendshift.io/api/badge/repositories/4376)](https://trendshift.io/repositories/4376)
</div>
## ✨ Univer 是什么?
Univer 是一个开源 SDK,用于在你的产品中创建办公应用。它提供电子表格、文档和演示文稿体验所需的基础能力,同时不强制你使用托管应用或固定 UI。
当你需要以下能力时,可以使用 Univer:
- 将电子表格或文档编辑能力嵌入 SaaS 产品、内部工具、BI 流程或 AI 应用。
- 在服务端运行工作簿/文档处理逻辑,并与浏览器端使用同一套架构。
- 通过插件按需组合功能,或通过预设快速启动。
- 通过自定义插件、命令、服务、UI 组件和 Facade API 扩展行为。
Univer 不只是一个电子表格文件查看器。它是用于构建你自己的生产力界面的框架。
## 🌟 Highlights
<table>
<tr>
<td align="center" width="33%">
⚡<br />
<strong>大型场景也流畅</strong><br />
<sub>Canvas 渲染与独立公式引擎,让复杂工作簿保持响应。</sub>
</td>
<td align="center" width="33%">
🧩<br />
<strong>插件化扩展</strong><br />
<sub>按需组合、替换、延迟加载或扩展能力,无需引入整套功能。</sub>
</td>
<td align="center" width="33%">
🤖<br />
<strong>Headless AI 基建</strong><br />
<sub>在 Node.js 中运行工作簿和文档逻辑,为 Agent、自动化和服务端流程提供底层能力。</sub>
</td>
</tr>
<tr>
<td align="center" width="33%">
🛠️<br />
<strong>面向产品集成</strong><br />
<sub>框架适配器、Facade API、预设和无头运行时,覆盖真实集成路径。</sub>
</td>
<td align="center" width="33%">
🌗<br />
<strong>Dark mode 就绪</strong><br />
<sub>UI 组件和渲染引擎都支持浅色与深色主题。</sub>
</td>
<td align="center" width="33%">
🔌<br />
<strong>统一的 Facade API</strong><br />
<sub>共享一致的 API,在浏览器和 Node.js 中操作工作簿、区域、公式和文档。</sub>
</td>
</tr>
</table>
## 🚀 为什么选择 Univer?
- **同构设计**:既可以在浏览器中运行 UI 应用,也可以在 Node.js 中运行无头处理逻辑。
- **插件优先架构**:每个能力都以可组合插件的形式提供,功能可以添加、移除、替换或延迟加载。
- **Preset Mode 便于快速集成**:当你希望快速获得可运行应用时,可以使用本仓库 [`presets/`](../../presets) 中的预设插件集合。
- **Plugin Mode 提供完整控制**:当你需要自定义加载、更小包体或深度集成时,可以手动组合包和插件。
- **Facade API**:通过更高层 API 操作工作簿、工作表、区域、文档、公式、命令和事件。
- **Canvas 渲染引擎**:支持大型可编辑文档界面,并在多种文档类型之间复用渲染层。
- **可扩展 UI**:支持 React、Vue、Web Components 和不同框架下的应用外壳集成。
## ⚡ 快速开始
使用 **Plugin Mode** 可以获得完整的产品能力覆盖并精确控制组合方式。对于受支持的 Sheets、Docs 和 Node 配置,**Preset Mode** 提供了更简短的预设方案。
<details open>
<summary><strong>Plugin Mode</strong></summary>
Plugin Mode 让你更底层地控制包、样式导入、locale 合并、Facade API 注册和插件配置。
```bash
pnpm add @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-formula-ui @univerjs/sheets-numfmt @univerjs/sheets-numfmt-ui @univerjs/sheets-ui @univerjs/ui
```
```ts
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import { FUniver } from '@univerjs/core/facade'
import DesignEnUS from '@univerjs/design/locale/en-US'
import { UniverDocsPlugin } from '@univerjs/docs'
import { UniverDocsUIPlugin } from '@univerjs/docs-ui'
import DocsUIEnUS from '@univerjs/docs-ui/locale/en-US'
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'
import { UniverRenderEnginePlugin } from '@univerjs/engine-render'
import { UniverSheetsPlugin } from '@univerjs/sheets'
import SheetsEnUS from '@univerjs/sheets/locale/en-US'
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'
import SheetsFormulaEnUS from '@univerjs/sheets-formula/locale/en-US'
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'
import SheetsFormulaUIEnUS from '@univerjs/sheets-formula-ui/locale/en-US'
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt'
import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui'
import SheetsNumfmtUIEnUS from '@univerjs/sheets-numfmt-ui/locale/en-US'
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US'
import { UniverUIPlugin } from '@univerjs/ui'
import UIEnUS from '@univerjs/ui/locale/en-US'
import '@univerjs/design/lib/index.css'
import '@univerjs/ui/lib/index.css'
import '@univerjs/docs-ui/lib/index.css'
import '@univerjs/sheets-ui/lib/index.css'
import '@univerjs/sheets-formula-ui/lib/index.css'
import '@univerjs/sheets-numfmt-ui/lib/index.css'
import '@univerjs/engine-formula/facade'
import '@univerjs/ui/facade'
import '@univerjs/sheets/facade'
import '@univerjs/sheets-ui/facade'
import '@univerjs/sheets-formula/facade'
import '@univerjs/sheets-numfmt/facade'
const univer = new Univer({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(
DesignEnUS,
UIEnUS,
DocsUIEnUS,
SheetsEnUS,
SheetsUIEnUS,
SheetsFormulaEnUS,
SheetsFormulaUIEnUS,
SheetsNumfmtUIEnUS,
),
},
})
univer.registerPlugin(UniverRenderEnginePlugin)
univer.registerPlugin(UniverFormulaEnginePlugin)
univer.registerPlugin(UniverUIPlugin, { container: 'app' })
univer.registerPlugin(UniverDocsPlugin)
univer.registerPlugin(UniverDocsUIPlugin)
univer.registerPlugin(UniverSheetsPlugin)
univer.registerPlugin(UniverSheetsUIPlugin)
univer.registerPlugin(UniverSheetsFormulaPlugin)
univer.registerPlugin(UniverSheetsFormulaUIPlugin)
univer.registerPlugin(UniverSheetsNumfmtPlugin)
univer.registerPlugin(UniverSheetsNumfmtUIPlugin)
const univerAPI = FUniver.newAPI(univer)
univerAPI.createWorkbook({})
```
</details>
<details>
<summary><strong>Preset Mode</strong></summary>
Preset 是一组经过整理的 Univer 插件集合,包含所需的 Facade API 注册和样式。
```bash
pnpm add @univerjs/presets @univerjs/preset-sheets-core
```
```ts
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
import '@univerjs/preset-sheets-core/lib/index.css'
const { univerAPI } = createUniver({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(UniverPresetSheetsCoreEnUS),
},
presets: [
UniverSheetsCorePreset({
container: 'app',
}),
],
})
univerAPI.createWorkbook({})
```
</details>
页面需要一个容器:
```html
<div id="app" style="height: 100vh"></div>
```
更多内容请阅读 [安装与基础使用指南](https://docs.univer.ai/guides/sheets/getting-started/installation)、[`createUniver` 参考](https://docs.univer.ai/reference/methods/create-univer) 和 [Facade API 参考](https://docs.univer.ai/reference/classes/univer)。
## 🧩 Preset Mode 与 Plugin Mode
| 选择 | 适用场景 | 从这里开始 |
| --- | --- | --- |
| **Plugin Mode** | 你需要严格控制包、已配置的依赖、延迟加载或自定义运行时组合。 | 本仓库的 [`examples/`](../../examples) 和 [架构指南](https://docs.univer.ai/guides/recipes/architecture/univer) |
| **Preset Mode** | 你希望用最少配置获得可运行的 Sheets、Docs 或 Node 设置。 | 本仓库的 [`presets/`](../../presets) 和 [快速入门指南](https://docs.univer.ai/guides/sheets/getting-started/installation) |
| **Headless Mode** | 你需要在没有 UI 的情况下进行服务端工作簿/文档处理、公式计算或自动化。 | [Headless Univer](https://docs.univer.ai/guides/sheets/getting-started/node) |
同一 Univer 协调发布线中的 `@univerjs/*` SDK 包应保持版本一致。`@univerjs/icons`、`@univerjs/icons-svg` 等独立发布的包应使用各包清单声明的兼容版本,而不是跟随 SDK 版本。使用 Univer Pro 时,也请让 `@univerjs-pro/*` 与对应的协调发布线保持一致。
关于 API 兼容性预期、实验性 API、内部 API 和废弃规则,请阅读 [API 稳定性政策](../API_STABILITY.md)。
## 🧭 兼容性
- **浏览器运行时**:Univer 的编译目标是 Chrome 88,并尽力支持 Edge `>=88`、Firefox `>=90`、Chrome `>=88`、Safari `>=14.1` 和 Electron `>=12`。
- **Polyfills**:Univer 依赖 `Intl.Segmenter`。如果目标浏览器或运行时不支持,请添加 `@formatjs/intl-segmenter` 等 polyfill。
- **构建工具**:推荐使用 Vite、esbuild 或 Webpack 5。如果构建工具不支持 `package.json` 中的 `exports` 字段(Webpack 4 中较常见),可能需要额外配置路径映射。
- **React**:Univer 的视图层基于 React 18 构建,支持 React 18 和 19,并对 React 16.9+ 与 17 提供最低限度的兼容支持。
- **Node.js 运行时**:Headless Univer 支持 Node.js `>=18.17.0`。开发本 monorepo 需要 Node.js `>=22.18`。
## 🛠️ 你可以构建什么
| 领域 | 开源能力 | Univer Pro 扩展 |
| --- | --- | --- |
| **Sheets** | 工作簿、工作表、区域、选择、公式、数字格式、筛选、排序、数据验证、条件格式、超链接、评论、查找替换、批注、表格、绘图集成和可扩展 UI 插件。 | 实时协同、编辑历史、导入导出、打印、图表、数据透视表、迷你图、分级显示、形状、单元格内图形、数据连接器、服务端计算和增强公式能力。 |
| **Docs** | 富文本文档模型、编辑 UI、列表、超链接、绘图集成、评论、快捷插入和共享文档架构。 | 协同、导入导出、打印、增强表格和列表、分栏、提示块、代码块、引用块、形状和远程评论资源。 |
| **Slides** | 演示文稿数据模型和 UI 包,目前仍在积极开发中。 | Pro 演示文稿模型和 UI、幻灯片导入导出、图表和表格模型/UI 插件,以及共享形状编辑基础设施。 |
| **Bases** | 基于 Univer 的插件、命令和模型架构构建自定义结构化数据体验。 | Base 数据库模型、命令、公式集成、工作台 UI、字段编辑器和渲染引擎视图。 |
| **Runtime** | 浏览器应用、Node.js 无头使用、Web Worker/RPC 模式、多实例使用和服务端自动化。 | 协同客户端/服务端包、Node.js 协同客户端、Pro 服务端服务、SSR、计算委托、服务端计算和 changeset 回放工具。 |
| **Integrations** | React、Vue、Web Components、框架模板、主题、本地化和自定义插件。 | Pro 预设和企业部署包。 |
Sheets 是目前最成熟的产品界面。Docs 和 Slides 共享 Univer 的架构,并在同一 SDK 中持续演进。
## 🔓 开源与 Pro
本仓库包含 Univer 的开源核心和第一方 OSS 插件。Univer Pro 作为商业扩展层单独开发,面向高级产品界面、协同、服务端能力和企业集成。
| 类别 | 开源 | Univer Pro / 商业版 |
| --- | --- | --- |
| **基础能力** | 核心 SDK、插件系统、渲染引擎、公式引擎、Facade API、主题、i18n 和框架适配器。 | Pro 预设和企业部署包。 |
| **Sheets** | 核心电子表格编辑、公式、数字格式、筛选/排序、数据验证、条件格式、批注、表格、超链接、评论、绘图、查找替换。 | 协同、编辑历史、导入导出、打印、图表、数据透视表、迷你图、分级显示、形状、单元格内图形、数据连接器、区域预处理和增强公式引擎能力。 |
| **Docs** | 文档模型和编辑 UI、列表、超链接、评论、快捷插入和绘图集成。 | 协同、导入导出、打印、增强表格/列表、分栏、提示块、代码块、引用块、形状和远程线程评论资源。 |
| **Slides** | OSS 演示文稿模型和 UI 包。 | Pro 演示文稿模型/UI 包、幻灯片导入导出、图表、表格和可复用形状编辑器 UI。 |
| **Bases** | 用于自定义数据类产品的可扩展插件架构。 | Base 数据库核心模型、命令、变更、公式集成、工作台 UI、字段编辑器和渲染引擎集成。 |
| **服务端与运行时** | Node.js 无头运行时、RPC/Web Worker 模式和面向服务端自动化的基础能力。 | 协同服务端、Node.js 协同客户端、SSR 服务、计算委托、服务端计算和协同 changeset 回放工具。 |
Pro 功能请参考 [Univer Pro 指南](https://docs.univer.ai/guides/pro)。这里将其单独列出,是为了清晰区分 OSS 包的能力边界。
边界原则:
- 本仓库中的 OSS 包应能在 Apache-2.0 许可证下独立使用。Univer Pro 是可选的,使用公开 OSS SDK API 不需要依赖 Pro。
- OSS 包中的 bug、回归和安全问题应在 OSS 仓库中报告和修复,即使存在相关的 Pro 功能。
- OSS 文档不应暗示 Pro-only 能力已经包含在公开的 `@univerjs/*` 包中。Pro-only API、包和部署路径应被明确命名。
- 当某个 OSS 功能存在 Pro 增强时,OSS 行为仍应被独立记录,便于用户在不先阅读商业文档的情况下评估开源能力。
## 🌐 生态
- **核心 SDK**:[`dream-num/univer`](https://github.com/dream-num/univer),也就是当前 monorepo。
- **Presets**:本仓库的 [`presets/`](../../presets),面向浏览器和 Node.js 应用的预设插件集合。
- **AI agent skills**:[`dream-num/univer-sdk-skills`](https://github.com/dream-num/univer-sdk-skills),供 AI agent 使用的可复用说明,覆盖 Univer 集成、Pro 功能、插件开发和 Node 后端。参见 [AI Skills 指南](https://docs.univer.ai/guides/skills)。
- **文档**:[docs.univer.ai](https://docs.univer.ai),包含 Sheets、Docs、Slides、recipes 和 Pro 指南。
- **API 参考**:[docs.univer.ai/reference](https://docs.univer.ai/reference/classes/univer),包含 Facade API 和生成的 API 参考。
- **示例与展示**:[Univer Showcase](https://docs.univer.ai/showcase) 和本仓库的 [`examples/`](../../examples)。
- **AI-native spreadsheets**:[`dream-num/univer-mcp`](https://github.com/dream-num/univer-mcp),用于通过自然语言驱动 Univer Sheets 的 Univer Platform / MCP 集成。
## 📦 仓库结构
```text
.
├── packages/ 核心包、引擎、文档类型、UI 插件和功能插件
├── examples/ 用于本地浏览器开发的一体化 Vite 工作台
├── common/ 共享内部工具、storybook 和工具函数
├── tests/ 其他集成测试项目
└── docs/ 架构说明、图片和仓库内文档
```
包级 README 位于 [`packages/`](../../packages) 下各包目录中。
## 🧑‍💻 开发
要求:
- Node.js `>=22.18`
- pnpm `>=11`
```bash
git clone https://github.com/dream-num/univer.git
cd univer
pnpm install
pnpm dev
```
常用命令:
| 命令 | 用途 |
| --- | --- |
| `pnpm dev` | 构建并预览低内存、无 HMR 的一体化工作台。 |
| `pnpm dev:source` | 启动支持 HMR 的源码工作台,冷启动和内存占用更高。 |
| `pnpm build` | 构建 workspace 包,不包含内部 common 包。 |
| `pnpm test` | 通过 Turbo 运行单元测试。 |
| `pnpm typecheck` | 通过 Turbo 运行 TypeScript 检查。 |
| `pnpm lint` | 运行 ESLint。 |
| `pnpm storybook:dev` | 启动用于 UI 组件开发的 Storybook。 |
提交 pull request 前请阅读 [CONTRIBUTING.md](../../CONTRIBUTING.md)。
## 📝 贡献者笔记
深入修改前,建议阅读这些仓库内说明:
- [Building Isomorphic Univer](../ISOMORPHIC.md):如何拆分浏览器、Node.js、UI 与共享插件逻辑。
- [API 稳定性政策](../API_STABILITY.md):stable、experimental、internal、deprecated 和破坏性变更预期。
- [Contributing to Facade API](../CONTRIBUTING-FACADE.md):`FUniver`、`FWorkbook`、`FRange` 等 Facade API 的设计约定。
- [Naming Convention](../NAMING_CONVENTION.md):文件、目录、接口、插件、命令和依赖注入 token 的命名规则。
- [Fixing Memory Leaks](../FIX_MEMORY_LEAK.md):Univer 实例常见内存泄漏模式和调试流程。
- [Architecture TLDRs](../tldr):公式引擎、Web Worker、权限、选择区和 ref-range 行为的简明说明。
## 💬 社区
- 在 [GitHub Discussions](https://github.com/dream-num/univer/discussions) 提问。
- 加入 [Discord](https://discord.gg/z3NKNT6D2f) 与社区交流。
- 关注 [Twitter / X](https://twitter.com/univerhq) 和 [YouTube](https://www.youtube.com/@dreamNum)。
参与社区前,请阅读 [行为准则](../../CODE_OF_CONDUCT.md)。
## 🔒 安全
如果你认为发现了安全问题,请遵循 [安全政策](../../SECURITY.md)。
## ❤️ 赞助
Univer 由社区和赞助者共同支持。你可以通过 [Open Collective](https://opencollective.com/univer) 支持这个项目。
<a href="https://opencollective.com/univer/sponsor/0/website"><img src="https://opencollective.com/univer/sponsor/0/avatar.svg" alt="Sponsor 0" /></a>
<a href="https://opencollective.com/univer/sponsor/1/website"><img src="https://opencollective.com/univer/sponsor/1/avatar.svg" alt="Sponsor 1" /></a>
<a href="https://opencollective.com/univer/sponsor/2/website"><img src="https://opencollective.com/univer/sponsor/2/avatar.svg" alt="Sponsor 2" /></a>
<a href="https://opencollective.com/univer/sponsor/3/website"><img src="https://opencollective.com/univer/sponsor/3/avatar.svg" alt="Sponsor 3" /></a>
<a href="https://opencollective.com/univer/sponsor/4/website"><img src="https://opencollective.com/univer/sponsor/4/avatar.svg" alt="Sponsor 4" /></a>
<a href="https://opencollective.com/univer/sponsor/5/website"><img src="https://opencollective.com/univer/sponsor/5/avatar.svg" alt="Sponsor 5" /></a>
<a href="https://opencollective.com/univer/sponsor/6/website"><img src="https://opencollective.com/univer/sponsor/6/avatar.svg" alt="Sponsor 6" /></a>
<a href="https://opencollective.com/univer/backer/0/website"><img src="https://opencollective.com/univer/backer/0/avatar.svg" alt="Backer 0" /></a>
<a href="https://opencollective.com/univer/backer/1/website"><img src="https://opencollective.com/univer/backer/1/avatar.svg" alt="Backer 1" /></a>
<a href="https://opencollective.com/univer/backer/2/website"><img src="https://opencollective.com/univer/backer/2/avatar.svg" alt="Backer 2" /></a>
<a href="https://opencollective.com/univer/backer/3/website"><img src="https://opencollective.com/univer/backer/3/avatar.svg" alt="Backer 3" /></a>
<a href="https://opencollective.com/univer/backer/4/website"><img src="https://opencollective.com/univer/backer/4/avatar.svg" alt="Backer 4" /></a>
<a href="https://opencollective.com/univer/backer/5/website"><img src="https://opencollective.com/univer/backer/5/avatar.svg" alt="Backer 5" /></a>
<a href="https://opencollective.com/univer/backer/6/website"><img src="https://opencollective.com/univer/backer/6/avatar.svg" alt="Backer 6" /></a>
## 📄 许可证
版权所有 (c) 2021-present DreamNum Co., Ltd.
基于 [Apache-2.0](../../LICENSE) 许可证开源。

373
docs/readme/zh-TW.md Normal file
View File

@@ -0,0 +1,373 @@
<div align="center">
<img src="../img/banner.png" alt="Univer SDK" width="800" />
**用於構建試算表、文件和簡報的全端、同構辦公 SDK。**
Univer 以外掛化架構、Canvas 渲染引擎、公式引擎和統一的 Facade API,
協助你在瀏覽器和 Node.js 中構建可嵌入的生產力體驗。
[English](../../README.md) | [简体中文](./zh-CN.md) | 繁體中文 | [日本語](./ja-JP.md) | [한국어](./ko-KR.md) | [Español](./es-ES.md)
[📖 文件](https://docs.univer.ai) | [✨ 示例](https://docs.univer.ai/showcase) | [📘 API 參考](https://docs.univer.ai/reference/classes/univer) | [📝 部落格](https://docs.univer.ai/blog)
[![Release](https://img.shields.io/github/v/release/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/releases)
[![License](https://img.shields.io/github/license/dream-num/univer?style=flat-square)](../../LICENSE)
[![Build](https://img.shields.io/github/actions/workflow/status/dream-num/univer/build-packages.yml?style=flat-square)](https://github.com/dream-num/univer/actions/workflows/build-packages.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/dream-num/univer/badge/dev?style=flat-square)](https://www.codefactor.io/repository/github/dream-num/univer/overview/dev)
[![Codecov](https://img.shields.io/codecov/c/gh/dream-num/univer?token=aPfyW2pIMN&style=flat-square)](https://codecov.io/gh/dream-num/univer)
[![Stars](https://img.shields.io/github/stars/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/stargazers)
[![Contributors](https://img.shields.io/github/contributors/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/issues)
[![Last Commit](https://img.shields.io/github/last-commit/dream-num/univer?style=flat-square)](https://github.com/dream-num/univer/commits/dev/)
[![Discord](https://img.shields.io/discord/1136129819961217077?logo=discord&logoColor=FFFFFF&label=discord&color=5865F2&style=flat-square)](https://discord.gg/z3NKNT6D2f)
[![Twitter](https://img.shields.io/twitter/follow/univerhq?style=flat-square&logo=x)](https://twitter.com/univerhq)
[![Open Collective](https://img.shields.io/opencollective/all/univer?logo=opencollective&style=flat-square)](https://opencollective.com/univer)
[![Trendshift](https://trendshift.io/api/badge/repositories/4376)](https://trendshift.io/repositories/4376)
</div>
## ✨ Univer 是什麼?
Univer 是一個開源 SDK,用於在你的產品中建立辦公應用。它提供試算表、文件和簡報體驗所需的基礎能力,同時不強制你使用託管應用或固定 UI。
當你需要以下能力時,可以使用 Univer:
- 將試算表或文件編輯能力嵌入 SaaS 產品、內部工具、BI 流程或 AI 應用。
- 在伺服器端執行活頁簿/文件處理邏輯,並與瀏覽器端使用同一套架構。
- 透過外掛按需組合功能,或透過預設快速啟動。
- 透過自訂外掛、命令、服務、UI 元件和 Facade API 擴充行為。
Univer 不只是一個試算表檔案檢視器。它是用於構建你自己的生產力介面的框架。
## 🌟 Highlights
<table>
<tr>
<td align="center" width="33%">
⚡<br />
<strong>大型場景也流暢</strong><br />
<sub>Canvas 渲染搭配獨立公式引擎,複雜活頁簿依然流暢。</sub>
</td>
<td align="center" width="33%">
🧩<br />
<strong>外掛化擴充</strong><br />
<sub>需要哪些功能就組合、替換或按需載入,不必引入全套。</sub>
</td>
<td align="center" width="33%">
🤖<br />
<strong>Headless AI 基建</strong><br />
<sub>在 Node.js 中跑活頁簿與文件邏輯,支撐 Agent、自動化和伺服器端流程。</sub>
</td>
</tr>
<tr>
<td align="center" width="33%">
🛠️<br />
<strong>面向產品整合</strong><br />
<sub>框架適配器、Facade API、預設配置、無頭執行環境,對接各種實際整合場景。</sub>
</td>
<td align="center" width="33%">
🌗<br />
<strong>Dark mode 就緒</strong><br />
<sub>UI 元件與渲染引擎均支援淺色和深色主題。</sub>
</td>
<td align="center" width="33%">
🔌<br />
<strong>統一的 Facade API</strong><br />
<sub>共享一致的 API,在瀏覽器和 Node.js 中操作活頁簿、範圍、公式和文件。</sub>
</td>
</tr>
</table>
## 🚀 為什麼選擇 Univer?
- **同構設計**:既可以在瀏覽器中執行 UI 應用,也可以在 Node.js 中執行無頭處理邏輯。
- **外掛優先架構**:每個能力都以可組合外掛的形式提供,功能可以新增、移除、替換或延遲載入。
- **Preset Mode 便於快速整合**:當你希望快速取得可執行應用時,可以使用本倉庫 [`presets/`](../../presets) 中的預設外掛集合。
- **Plugin Mode 提供完整控制**:當你需要自訂載入、更小包體或深度整合時,可以手動組合套件和外掛。
- **Facade API**:透過更高層 API 操作活頁簿、工作表、範圍、文件、公式、命令和事件。
- **Canvas 渲染引擎**:支援大型可編輯文件介面,並在多種文件類型之間共用渲染層。
- **可擴充 UI**:支援 React、Vue、Web Components 和不同框架下的應用外殼整合。
## ⚡ 快速開始
使用 **Plugin Mode** 可以取得完整的產品能力覆蓋並精確控制組合方式。對於支援的 Sheets、Docs 和 Node 設定,**Preset Mode** 提供了更精簡的預設方案。
<details open>
<summary><strong>Plugin Mode</strong></summary>
Plugin Mode 讓你更底層地控制套件、樣式匯入、locale 合併、Facade API 註冊和外掛設定。
```bash
pnpm add @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-formula-ui @univerjs/sheets-numfmt @univerjs/sheets-numfmt-ui @univerjs/sheets-ui @univerjs/ui
```
```ts
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import { FUniver } from '@univerjs/core/facade'
import DesignEnUS from '@univerjs/design/locale/en-US'
import { UniverDocsPlugin } from '@univerjs/docs'
import { UniverDocsUIPlugin } from '@univerjs/docs-ui'
import DocsUIEnUS from '@univerjs/docs-ui/locale/en-US'
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'
import { UniverRenderEnginePlugin } from '@univerjs/engine-render'
import { UniverSheetsPlugin } from '@univerjs/sheets'
import SheetsEnUS from '@univerjs/sheets/locale/en-US'
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'
import SheetsFormulaEnUS from '@univerjs/sheets-formula/locale/en-US'
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'
import SheetsFormulaUIEnUS from '@univerjs/sheets-formula-ui/locale/en-US'
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt'
import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui'
import SheetsNumfmtUIEnUS from '@univerjs/sheets-numfmt-ui/locale/en-US'
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US'
import { UniverUIPlugin } from '@univerjs/ui'
import UIEnUS from '@univerjs/ui/locale/en-US'
import '@univerjs/design/lib/index.css'
import '@univerjs/ui/lib/index.css'
import '@univerjs/docs-ui/lib/index.css'
import '@univerjs/sheets-ui/lib/index.css'
import '@univerjs/sheets-formula-ui/lib/index.css'
import '@univerjs/sheets-numfmt-ui/lib/index.css'
import '@univerjs/engine-formula/facade'
import '@univerjs/ui/facade'
import '@univerjs/sheets/facade'
import '@univerjs/sheets-ui/facade'
import '@univerjs/sheets-formula/facade'
import '@univerjs/sheets-numfmt/facade'
const univer = new Univer({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(
DesignEnUS,
UIEnUS,
DocsUIEnUS,
SheetsEnUS,
SheetsUIEnUS,
SheetsFormulaEnUS,
SheetsFormulaUIEnUS,
SheetsNumfmtUIEnUS,
),
},
})
univer.registerPlugin(UniverRenderEnginePlugin)
univer.registerPlugin(UniverFormulaEnginePlugin)
univer.registerPlugin(UniverUIPlugin, { container: 'app' })
univer.registerPlugin(UniverDocsPlugin)
univer.registerPlugin(UniverDocsUIPlugin)
univer.registerPlugin(UniverSheetsPlugin)
univer.registerPlugin(UniverSheetsUIPlugin)
univer.registerPlugin(UniverSheetsFormulaPlugin)
univer.registerPlugin(UniverSheetsFormulaUIPlugin)
univer.registerPlugin(UniverSheetsNumfmtPlugin)
univer.registerPlugin(UniverSheetsNumfmtUIPlugin)
const univerAPI = FUniver.newAPI(univer)
univerAPI.createWorkbook({})
```
</details>
<details>
<summary><strong>Preset Mode</strong></summary>
Preset 是一組經過整理的 Univer 外掛集合,包含所需的 Facade API 註冊和樣式。
```bash
pnpm add @univerjs/presets @univerjs/preset-sheets-core
```
```ts
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
import '@univerjs/preset-sheets-core/lib/index.css'
const { univerAPI } = createUniver({
locale: LocaleType.EN_US,
locales: {
[LocaleType.EN_US]: mergeLocales(UniverPresetSheetsCoreEnUS),
},
presets: [
UniverSheetsCorePreset({
container: 'app',
}),
],
})
univerAPI.createWorkbook({})
```
</details>
頁面需要一個容器:
```html
<div id="app" style="height: 100vh"></div>
```
更多內容請閱讀 [安裝與基礎使用指南](https://docs.univer.ai/guides/sheets/getting-started/installation)、[`createUniver` 參考](https://docs.univer.ai/reference/methods/create-univer) 和 [Facade API 參考](https://docs.univer.ai/reference/classes/univer)。
## 🧩 Preset Mode 與 Plugin Mode
| 選擇 | 適用場景 | 從這裡開始 |
| --- | --- | --- |
| **Plugin Mode** | 你需要嚴格控制套件、已設定的依賴、延遲載入或自訂執行時組合。 | 本倉庫的 [`examples/`](../../examples) 和 [架構指南](https://docs.univer.ai/guides/recipes/architecture/univer) |
| **Preset Mode** | 你希望用最少配置取得可執行的 Sheets、Docs 或 Node 設定。 | 本倉庫的 [`presets/`](../../presets) 和 [快速入門指南](https://docs.univer.ai/guides/sheets/getting-started/installation) |
| **Headless Mode** | 你需要在沒有 UI 的情況下進行伺服器端活頁簿/文件處理、公式計算或自動化。 | [Headless Univer](https://docs.univer.ai/guides/sheets/getting-started/node) |
同一 Univer 協調發布線中的 `@univerjs/*` SDK 套件應保持版本一致。`@univerjs/icons`、`@univerjs/icons-svg` 等獨立發布的套件應使用各套件資訊清單所宣告的相容版本,而不是跟隨 SDK 版本。使用 Univer Pro 時,也請讓 `@univerjs-pro/*` 與對應的協調發布線保持一致。
關於 API 相容性預期、實驗性 API、內部 API 和棄用規則,請閱讀 [API 穩定性政策](../API_STABILITY.md)。
## 🧭 相容性
- **瀏覽器執行時**:Univer 的編譯目標是 Chrome 88,並盡力支援 Edge `>=88`、Firefox `>=90`、Chrome `>=88`、Safari `>=14.1` 和 Electron `>=12`。
- **Polyfills**:Univer 依賴 `Intl.Segmenter`。如果目標瀏覽器或執行時不支援,請新增 `@formatjs/intl-segmenter` 等 polyfill。
- **建構工具**:推薦使用 Vite、esbuild 或 Webpack 5。如果建構工具不支援 `package.json` 中的 `exports` 欄位(Webpack 4 中較常見),可能需要額外配置路徑映射。
- **React**:Univer 的視圖層基於 React 18 構建,支援 React 18 和 19,並對 React 16.9+ 與 17 提供最低限度的相容支援。
- **Node.js 執行時**:Headless Univer 支援 Node.js `>=18.17.0`。開發本 monorepo 需要 Node.js `>=22.18`。
## 🛠️ 你可以構建什麼
| 領域 | 開源能力 | Univer Pro 擴充 |
| --- | --- | --- |
| **Sheets** | 活頁簿、工作表、範圍、選擇、公式、數字格式、篩選、排序、資料驗證、條件格式、超連結、評論、尋找取代、註記、表格、繪圖整合和可擴充 UI 外掛。 | 即時協作、編輯歷史、匯入匯出、列印、圖表、樞紐分析表、迷你圖、大綱、形狀、儲存格內圖形、資料連接器、伺服器端計算和增強公式能力。 |
| **Docs** | 富文字文件模型、編輯 UI、列表、超連結、繪圖整合、評論、快速插入和共享文件架構。 | 協作、匯入匯出、列印、增強表格和列表、分欄、提示區塊、程式碼區塊、引用區塊、形狀和遠端評論資源。 |
| **Slides** | 簡報資料模型和 UI 套件,目前仍在積極開發中。 | Pro 簡報模型和 UI、投影片匯入匯出、圖表和表格模型/UI 外掛,以及共享形狀編輯基礎設施。 |
| **Bases** | 基於 Univer 的外掛、命令和模型架構構建自訂結構化資料體驗。 | Base 資料庫模型、命令、公式整合、工作台 UI、欄位編輯器和渲染引擎視圖。 |
| **Runtime** | 瀏覽器應用、Node.js 無頭使用、Web Worker/RPC 模式、多實例使用和伺服器端自動化。 | 協作客戶端/伺服器端套件、Node.js 協作客戶端、Pro 伺服器端服務、SSR、計算委派、伺服器端計算和 changeset 回放工具。 |
| **Integrations** | React、Vue、Web Components、框架模板、主題、本地化和自訂外掛。 | Pro 預設和企業部署套件。 |
Sheets 是目前最成熟的產品介面。Docs 和 Slides 共享 Univer 的架構,並在同一 SDK 中持續演進。
## 🔓 開源與 Pro
本倉庫包含 Univer 的開源核心和第一方 OSS 外掛。Univer Pro 作為商業擴充層單獨開發,面向進階產品介面、協作、伺服器端能力和企業整合。
| 類別 | 開源 | Univer Pro / 商業版 |
| --- | --- | --- |
| **基礎能力** | 核心 SDK、外掛系統、渲染引擎、公式引擎、Facade API、主題、i18n 和框架適配器。 | Pro 預設和企業部署套件。 |
| **Sheets** | 核心試算表編輯、公式、數字格式、篩選/排序、資料驗證、條件格式、註記、表格、超連結、評論、繪圖、尋找取代。 | 協作、編輯歷史、匯入匯出、列印、圖表、樞紐分析表、迷你圖、大綱、形狀、儲存格內圖形、資料連接器、範圍預處理和增強公式引擎能力。 |
| **Docs** | 文件模型和編輯 UI、列表、超連結、評論、快速插入和繪圖整合。 | 協作、匯入匯出、列印、增強表格/列表、分欄、提示區塊、程式碼區塊、引用區塊、形狀和遠端執行緒評論資源。 |
| **Slides** | OSS 簡報模型和 UI 套件。 | Pro 簡報模型/UI 套件、投影片匯入匯出、圖表、表格和可重複使用形狀編輯器 UI。 |
| **Bases** | 用於自訂資料類產品的可擴充外掛架構。 | Base 資料庫核心模型、命令、變更、公式整合、工作台 UI、欄位編輯器和渲染引擎整合。 |
| **伺服器端與執行時** | Node.js 無頭執行時、RPC/Web Worker 模式和面向伺服器端自動化的基礎能力。 | 協作伺服器、Node.js 協作客戶端、SSR 服務、計算委派、伺服器端計算和協作 changeset 回放工具。 |
Pro 功能請參考 [Univer Pro 指南](https://docs.univer.ai/guides/pro)。這裡將其單獨列出,是為了清楚區分 OSS 套件的能力邊界。
邊界原則:
- 本倉庫中的 OSS 套件應能在 Apache-2.0 授權下獨立使用。Univer Pro 是選用的,使用公開 OSS SDK API 不需要依賴 Pro。
- OSS 套件中的 bug、回歸和安全問題應在 OSS 倉庫中回報和修復,即使存在相關的 Pro 功能。
- OSS 文件不應暗示 Pro-only 能力已包含在公開的 `@univerjs/*` 套件中。Pro-only API、套件和部署路徑應被明確命名。
- 當某個 OSS 功能存在 Pro 增強時,OSS 行為仍應被獨立記錄,方便使用者在不先閱讀商業文件的情況下評估開源能力。
## 🌐 生態
- **核心 SDK**:[`dream-num/univer`](https://github.com/dream-num/univer),也就是目前的 monorepo。
- **Presets**:本倉庫的 [`presets/`](../../presets),面向瀏覽器和 Node.js 應用的預設外掛集合。
- **AI agent skills**:[`dream-num/univer-sdk-skills`](https://github.com/dream-num/univer-sdk-skills),供 AI agent 使用的可重複使用說明,涵蓋 Univer 整合、Pro 功能、外掛開發和 Node 後端。參見 [AI Skills 指南](https://docs.univer.ai/guides/skills)。
- **文件**:[docs.univer.ai](https://docs.univer.ai),包含 Sheets、Docs、Slides、recipes 和 Pro 指南。
- **API 參考**:[docs.univer.ai/reference](https://docs.univer.ai/reference/classes/univer),包含 Facade API 和生成的 API 參考。
- **示例與展示**:[Univer Showcase](https://docs.univer.ai/showcase) 和本倉庫的 [`examples/`](../../examples)。
- **AI-native spreadsheets**:[`dream-num/univer-mcp`](https://github.com/dream-num/univer-mcp),用於透過自然語言驅動 Univer Sheets 的 Univer Platform / MCP 整合。
## 📦 倉庫結構
```text
.
├── packages/ 核心套件、引擎、文件類型、UI 外掛和功能外掛
├── examples/ 用於本地瀏覽器開發的一體化 Vite 工作台
├── common/ 共享內部工具、storybook 和工具函式
├── tests/ 其他整合測試專案
└── docs/ 架構說明、圖片和倉庫內文件
```
套件級 README 位於 [`packages/`](../../packages) 下各套件目錄中。
## 🧑‍💻 開發
要求:
- Node.js `>=22.18`
- pnpm `>=11`
```bash
git clone https://github.com/dream-num/univer.git
cd univer
pnpm install
pnpm dev
```
常用命令:
| 命令 | 用途 |
| --- | --- |
| `pnpm dev` | 構建並預覽低記憶體、無 HMR 的一體化工作台。 |
| `pnpm dev:source` | 啟動支援 HMR 的原始碼工作台,冷啟動和記憶體用量較高。 |
| `pnpm build` | 構建 workspace 套件,不包含內部 common 套件。 |
| `pnpm test` | 透過 Turbo 執行單元測試。 |
| `pnpm typecheck` | 透過 Turbo 執行 TypeScript 檢查。 |
| `pnpm lint` | 執行 ESLint。 |
| `pnpm storybook:dev` | 啟動用於 UI 元件開發的 Storybook。 |
提交 pull request 前請閱讀 [CONTRIBUTING.md](../../CONTRIBUTING.md)。
## 📝 貢獻者筆記
深入修改前,建議閱讀這些倉庫內說明:
- [Building Isomorphic Univer](../ISOMORPHIC.md):如何拆分瀏覽器、Node.js、UI 與共享外掛邏輯。
- [API 穩定性政策](../API_STABILITY.md):stable、experimental、internal、deprecated 和破壞性變更預期。
- [Contributing to Facade API](../CONTRIBUTING-FACADE.md):`FUniver`、`FWorkbook`、`FRange` 等 Facade API 的設計約定。
- [Naming Convention](../NAMING_CONVENTION.md):檔案、目錄、介面、外掛、命令和依賴注入 token 的命名規則。
- [Fixing Memory Leaks](../FIX_MEMORY_LEAK.md):Univer 實例常見記憶體洩漏模式和除錯流程。
- [Architecture TLDRs](../tldr):公式引擎、Web Worker、權限、選擇區和 ref-range 行為的簡明說明。
## 💬 社群
- 在 [GitHub Discussions](https://github.com/dream-num/univer/discussions) 提問。
- 加入 [Discord](https://discord.gg/z3NKNT6D2f) 與社群交流。
- 關注 [Twitter / X](https://twitter.com/univerhq) 和 [YouTube](https://www.youtube.com/@dreamNum)。
參與社群前,請閱讀 [行為準則](../../CODE_OF_CONDUCT.md)。
## 🔒 安全
如果你認為發現了安全問題,請遵循 [安全政策](../../SECURITY.md)。
## ❤️ 贊助
Univer 由社群和贊助者共同支援。你可以透過 [Open Collective](https://opencollective.com/univer) 支援這個專案。
<a href="https://opencollective.com/univer/sponsor/0/website"><img src="https://opencollective.com/univer/sponsor/0/avatar.svg" alt="Sponsor 0" /></a>
<a href="https://opencollective.com/univer/sponsor/1/website"><img src="https://opencollective.com/univer/sponsor/1/avatar.svg" alt="Sponsor 1" /></a>
<a href="https://opencollective.com/univer/sponsor/2/website"><img src="https://opencollective.com/univer/sponsor/2/avatar.svg" alt="Sponsor 2" /></a>
<a href="https://opencollective.com/univer/sponsor/3/website"><img src="https://opencollective.com/univer/sponsor/3/avatar.svg" alt="Sponsor 3" /></a>
<a href="https://opencollective.com/univer/sponsor/4/website"><img src="https://opencollective.com/univer/sponsor/4/avatar.svg" alt="Sponsor 4" /></a>
<a href="https://opencollective.com/univer/sponsor/5/website"><img src="https://opencollective.com/univer/sponsor/5/avatar.svg" alt="Sponsor 5" /></a>
<a href="https://opencollective.com/univer/sponsor/6/website"><img src="https://opencollective.com/univer/sponsor/6/avatar.svg" alt="Sponsor 6" /></a>
<a href="https://opencollective.com/univer/backer/0/website"><img src="https://opencollective.com/univer/backer/0/avatar.svg" alt="Backer 0" /></a>
<a href="https://opencollective.com/univer/backer/1/website"><img src="https://opencollective.com/univer/backer/1/avatar.svg" alt="Backer 1" /></a>
<a href="https://opencollective.com/univer/backer/2/website"><img src="https://opencollective.com/univer/backer/2/avatar.svg" alt="Backer 2" /></a>
<a href="https://opencollective.com/univer/backer/3/website"><img src="https://opencollective.com/univer/backer/3/avatar.svg" alt="Backer 3" /></a>
<a href="https://opencollective.com/univer/backer/4/website"><img src="https://opencollective.com/univer/backer/4/avatar.svg" alt="Backer 4" /></a>
<a href="https://opencollective.com/univer/backer/5/website"><img src="https://opencollective.com/univer/backer/5/avatar.svg" alt="Backer 5" /></a>
<a href="https://opencollective.com/univer/backer/6/website"><img src="https://opencollective.com/univer/backer/6/avatar.svg" alt="Backer 6" /></a>
## 📄 授權
Copyright (c) 2021-present DreamNum Co., Ltd.
基於 [Apache-2.0](../../LICENSE) 授權開源。

File diff suppressed because one or more lines are too long

2667
docs/tldr/graphs.tldr Normal file

File diff suppressed because it is too large Load Diff

721
docs/tldr/permission.tldr Normal file
View File

@@ -0,0 +1,721 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 2,
"video": 2,
"bookmark": 0
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 1,
"draw": 1,
"geo": 7,
"note": 4,
"line": 1,
"frame": 0,
"arrow": 1,
"highlight": 0,
"embed": 4,
"image": 2,
"video": 1
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 555.6905537601147,
"y": 593.7329937919792,
"lastActivityTimestamp": 1699425334591,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": 630.4706550337846,
"y": 232.30022366844838,
"z": 0.6502462475435885,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:dash": "solid",
"tldraw:geo": "rectangle",
"tldraw:size": "s",
"tldraw:arrowheadStart": "none",
"tldraw:fill": "none"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 1477,
"h": 710
},
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": false,
"devicePixelRatio": 2,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 509.609375,
"y": 302.52734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:cfWgelQMptas1YBaHORr-",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 16,
"text": "",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a1",
"typeName": "shape"
},
{
"x": 435.71875,
"y": 463.671875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:mS-l4AW89fjxR4YSq58MM",
"type": "geo",
"props": {
"w": 258.3125,
"h": 61.6953125,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "network",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"typeName": "shape"
},
{
"x": 426.8203125,
"y": 349.5546875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:JAtrXXL1duBdbmVP24_cA",
"type": "geo",
"props": {
"w": 267.9375,
"h": 71.5625,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "permission.service",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"typeName": "shape"
},
{
"x": 147.21875,
"y": 228.2578125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:0ZsG_62TV_6OY9RQz3O1e",
"type": "geo",
"props": {
"w": 342.53125,
"h": 89.94921875,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "univer.permission.serivce",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a6",
"typeName": "shape"
},
{
"x": 520.5390625,
"y": 227.78515625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:rf-LoZkUy6vpGYVSrvzAC",
"type": "geo",
"props": {
"w": 342.53125,
"h": 89.94921875,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "sheet.permission.serivce",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a7",
"typeName": "shape"
},
{
"x": 884.97265625,
"y": 226.28125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:271jSCWLcOj0KUA3vQFOR",
"type": "geo",
"props": {
"w": 342.53125,
"h": 89.94921875,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "other.permission.serivce",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a8",
"typeName": "shape"
},
{
"x": -209.8046875,
"y": 236.83984375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Gn_sdtXFDgdTRD0pBZJ8-",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 408,
"text": "业务权限服务,用来增删改查或者组合\npermissionPoint,派发业务权限。",
"font": "draw",
"align": "start",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aB",
"typeName": "shape"
},
{
"x": -38.609375,
"y": 450.36328125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:5OhscMwh5sOypD0hQAGwe",
"type": "arrow",
"parentId": "page:page",
"index": "aA",
"props": {
"dash": "draw",
"size": "s",
"fill": "none",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": -210.5551014993154,
"y": -5.752767876852317
},
"end": {
"type": "point",
"x": 1312.44921875,
"y": -8.44921875
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"font": "draw"
},
"typeName": "shape"
},
{
"x": -35.625,
"y": 331.99609375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Z80Ep4Gyg9yjGpdn8EL7j",
"type": "arrow",
"parentId": "page:page",
"index": "a8V",
"props": {
"dash": "draw",
"size": "s",
"fill": "none",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": -227.70898195058965,
"y": -1.3669943469748205
},
"end": {
"type": "point",
"x": 1303.2730187768332,
"y": -7.600694848512887
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"font": "draw"
},
"typeName": "shape"
},
{
"x": -195.99526675112614,
"y": 368.0168606494899,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:o9uNCq750TtxJGcGN5BJW",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 360,
"text": "基础权限服务,用来管理权限点位\n点位注册/权限更新/权限拉取",
"font": "draw",
"align": "start",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aD",
"typeName": "shape"
},
{
"x": 965.7276264912375,
"y": 524.211600551246,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:j0cBZpJO_sLqJhpvuyjj4",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 8,
"text": "",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aE",
"typeName": "shape"
},
{
"x": 115.68236232448254,
"y": 177.31517561179118,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:gnp2CdFhkLoLhv5_PAdTM",
"type": "arrow",
"parentId": "page:page",
"index": "aF",
"props": {
"dash": "draw",
"size": "s",
"fill": "none",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": -1.2343578209806765,
"y": -212.76689691126637
},
"end": {
"type": "point",
"x": 4.737015132919737,
"y": 485.4301349286854
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"font": "draw"
},
"typeName": "shape"
},
{
"x": -263.0733406577134,
"y": 204.43071626492787,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:S-rM8hP_9bPI7bHcM6fA9",
"type": "arrow",
"parentId": "page:page",
"index": "aG",
"props": {
"dash": "draw",
"size": "s",
"fill": "pattern",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": 0,
"y": 0
},
"end": {
"type": "point",
"x": 1533.590296124883,
"y": 2.581030230742101
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"font": "draw"
},
"typeName": "shape"
},
{
"x": -211.76143028276476,
"y": 144.89631076376548,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:7Yp2VISNRq-4yzyDUbRo_",
"type": "draw",
"props": {
"segments": [
{
"type": "free",
"points": [
{
"x": 0,
"y": 0,
"z": 0.5
}
]
}
],
"color": "black",
"fill": "pattern",
"dash": "draw",
"size": "s",
"isComplete": true,
"isClosed": false,
"isPen": false
},
"parentId": "page:page",
"index": "aH",
"typeName": "shape"
},
{
"x": -228.6405644241911,
"y": 127.71208677498385,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:dD9zx-_XXfigp0ztk-xUw",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 109,
"text": "业务使用场景",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aI",
"typeName": "shape"
},
{
"x": 200.3234851905786,
"y": 101.54960228248558,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:c8f27NxMCcl_eEd1cDvDM",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 8,
"text": "",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aJ",
"typeName": "shape"
},
{
"x": 234.14930682731426,
"y": 75.35780666653568,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:V6KdGcs_HpXX_IrhaYduT",
"type": "geo",
"props": {
"w": 184,
"h": 80.59375,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "solid",
"size": "s",
"font": "draw",
"text": "commands.service",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aK",
"typeName": "shape"
},
{
"x": 463.87023129492707,
"y": 76.20967138313347,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:K9h1YmhEJr16gyltlgcyY",
"type": "geo",
"props": {
"w": 133.56201804325144,
"h": 79.71615563961296,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "solid",
"size": "s",
"font": "draw",
"text": "ui.render",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aL",
"typeName": "shape"
},
{
"x": 644.5816371143542,
"y": 74.68981447702538,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:kn8L8FqA2nnXEX5okAEm5",
"type": "geo",
"props": {
"w": 212,
"h": 80.59375,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "solid",
"size": "s",
"font": "draw",
"text": "sheet.interceptor.service",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aLV",
"typeName": "shape"
},
{
"x": 908.0503020268611,
"y": 76.72630258441922,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Z90g80OBLaEosBphyD8n_",
"type": "geo",
"props": {
"w": 212,
"h": 80.59375,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "solid",
"size": "s",
"font": "draw",
"text": "other...",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aLl",
"typeName": "shape"
}
]
}

View File

@@ -0,0 +1,634 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 24
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 4,
"frame": 0,
"arrow": 3,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 783.5026017162536,
"y": 457.5455634395281,
"lastActivityTimestamp": 1712492251467,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": -61.666664216253594,
"y": 17.49999930461251,
"z": 1,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [
"shape:NuDq3OtA6YXplZkvFH0VW",
"shape:lRJ8Rao0PE2SXXh7GBfpR",
"shape:sYS6jISnhOXWHXu_pcfTL",
"shape:yXoCMFfvOgod-F5gpgxWg",
"shape:-6z3WUiXJg8-s1M1O5OBT",
"shape:n8reRvSltdS8fWoW_S6Pe",
"shape:4fjIFqy2-YWVcedp2xUwT",
"shape:yreVzk07y5QjUX2vv4HhE",
"shape:Q-MRA9c4-1NEBAaNSlNIN",
"shape:eeU13ncMBu2f7GUYymKrf",
"shape:A3vESTBPDWb4E8QgY7Jmr",
"shape:RajK2iJ_pkbQzqtNpqfT0",
"shape:tuuFvVAg9iB-9XqfTXZpk",
"shape:O5NT_JV7uY04CLkQy8ky5",
"shape:DReHYeZJcP-IZdT3E1wNe",
"shape:Wm_ZP7XeR8vaQT-4GXR60",
"shape:x3hBc55qV-SZ1LxWcEcPl"
],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:geo": "rectangle",
"tldraw:size": "s",
"tldraw:color": "light-blue"
},
"brush": {
"x": 188.3984299633239,
"y": 62.17447731892265,
"w": 595.1041717529297,
"h": 395.37108612060547
},
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 908.3333129882812,
"h": 602.5
},
"insets": [
false,
true,
true,
false
],
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2.4000000953674316,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"duplicateProps": null,
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 247.62368774414062,
"y": 125.703125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:NuDq3OtA6YXplZkvFH0VW",
"type": "geo",
"props": {
"w": 178.82485961914062,
"h": 142.32745361328125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"typeName": "shape"
},
{
"x": 247.9036407470703,
"y": 269.8893127441406,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:lRJ8Rao0PE2SXXh7GBfpR",
"type": "geo",
"props": {
"w": 179.2057342529297,
"h": 140.43295288085938,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"typeName": "shape"
},
{
"x": 375.7421875,
"y": 225.49478149414062,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:sYS6jISnhOXWHXu_pcfTL",
"type": "geo",
"props": {
"w": 50.751953125,
"h": 41.953125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a3",
"typeName": "shape"
},
{
"x": 354.72003173828125,
"y": 196.5755157470703,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:yXoCMFfvOgod-F5gpgxWg",
"type": "geo",
"props": {
"w": 73.09246826171875,
"h": 127.86131286621094,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"typeName": "shape"
},
{
"x": 251.77862548828125,
"y": 127.67578125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:-6z3WUiXJg8-s1M1O5OBT",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a5",
"typeName": "shape"
},
{
"x": 249.76040649414062,
"y": 267.3046875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:n8reRvSltdS8fWoW_S6Pe",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a6",
"typeName": "shape"
},
{
"x": 374.5390625,
"y": 221.77734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:4fjIFqy2-YWVcedp2xUwT",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a7",
"typeName": "shape"
},
{
"x": 444.6549232668349,
"y": 267.26560488674374,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:yreVzk07y5QjUX2vv4HhE",
"type": "arrow",
"parentId": "page:page",
"index": "a8",
"props": {
"dash": "draw",
"size": "xl",
"fill": "none",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": 0,
"y": 0
},
"end": {
"type": "point",
"x": 72.431640625,
"y": 2.1484375
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"labelPosition": 0.5,
"font": "draw"
},
"typeName": "shape"
},
{
"x": 534.0527038574219,
"y": 124.814453125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Q-MRA9c4-1NEBAaNSlNIN",
"type": "geo",
"props": {
"w": 179.08200073242188,
"h": 72.373046875,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a9",
"typeName": "shape"
},
{
"x": 534.3326568603516,
"y": 269.0006408691406,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:eeU13ncMBu2f7GUYymKrf",
"type": "geo",
"props": {
"w": 106.71549987792969,
"h": 151.04495239257812,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aA",
"typeName": "shape"
},
{
"x": 641.1490478515625,
"y": 195.6868438720703,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:A3vESTBPDWb4E8QgY7Jmr",
"type": "geo",
"props": {
"w": 73.09246826171875,
"h": 127.86131286621094,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aC",
"typeName": "shape"
},
{
"x": 538.2076416015625,
"y": 126.787109375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:RajK2iJ_pkbQzqtNpqfT0",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aD",
"typeName": "shape"
},
{
"x": 536.1894226074219,
"y": 266.416015625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:tuuFvVAg9iB-9XqfTXZpk",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aE",
"typeName": "shape"
},
{
"x": 534.6614540285536,
"y": 196.63410464260312,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:O5NT_JV7uY04CLkQy8ky5",
"type": "geo",
"props": {
"w": 105.90814208984374,
"h": 72.44140625,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aG",
"typeName": "shape"
},
{
"x": 641.2890175051161,
"y": 197.5260418984625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:DReHYeZJcP-IZdT3E1wNe",
"type": "geo",
"props": {
"w": 73.44403076171875,
"h": 70.21157836914062,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aH",
"typeName": "shape"
},
{
"x": 533.5103920168349,
"y": 195.4882763955328,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Wm_ZP7XeR8vaQT-4GXR60",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aI",
"typeName": "shape"
},
{
"x": 645.2259071535536,
"y": 195.2115887734625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:x3hBc55qV-SZ1LxWcEcPl",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aJ",
"typeName": "shape"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,715 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 24
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 4,
"frame": 0,
"arrow": 3,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 754.9478708108269,
"y": 432.87760141823037,
"lastActivityTimestamp": 1712492341185,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": -129.9999948342644,
"y": -69.16666391823034,
"z": 1,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:color": "light-blue",
"tldraw:geo": "rectangle",
"tldraw:size": "s"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 908.3333129882812,
"h": 602.5
},
"insets": [
false,
true,
true,
false
],
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2.4000000953674316,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"duplicateProps": null,
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 247.62368774414062,
"y": 125.703125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:mmPoVopnA6ljcdfSYV59a",
"type": "geo",
"props": {
"w": 178.82485961914062,
"h": 142.32745361328125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"typeName": "shape"
},
{
"x": 247.9036407470703,
"y": 269.8893127441406,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:eIcKsf7fIzKEDf8ohaqHg",
"type": "geo",
"props": {
"w": 177.9850311279297,
"h": 127.77670288085938,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"typeName": "shape"
},
{
"x": 375.7421875,
"y": 225.49478149414062,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:3APps3g9p0w1NE_41YT1Q",
"type": "geo",
"props": {
"w": 50.751953125,
"h": 41.953125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a3",
"typeName": "shape"
},
{
"x": 354.72003173828125,
"y": 196.5755157470703,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:qNFcjE6S1pY0inD9H4ng5",
"type": "geo",
"props": {
"w": 73.09246826171875,
"h": 127.86131286621094,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"typeName": "shape"
},
{
"x": 251.77862548828125,
"y": 127.67578125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:NlhysTac33RgFW0D84gFG",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a5",
"typeName": "shape"
},
{
"x": 249.76040649414062,
"y": 267.3046875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:VZt11K02f8Jf8K6vGnnbs",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a6",
"typeName": "shape"
},
{
"x": 374.5390625,
"y": 221.77734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:AGviKyccFrcgBseTWEUvQ",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a7",
"typeName": "shape"
},
{
"x": 444.6549232668349,
"y": 267.26560488674374,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:wbS5ruNc-IW0DGNG473HE",
"type": "arrow",
"parentId": "page:page",
"index": "a8",
"props": {
"dash": "draw",
"size": "xl",
"fill": "none",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": 0,
"y": 0
},
"end": {
"type": "point",
"x": 72.431640625,
"y": 2.1484375
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"labelPosition": 0.5,
"font": "draw"
},
"typeName": "shape"
},
{
"x": 534.0527038574219,
"y": 124.814453125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:anZpGYIScPMNgS6qnraRI",
"type": "geo",
"props": {
"w": 179.08200073242188,
"h": 72.373046875,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a9",
"typeName": "shape"
},
{
"x": 534.3326568603516,
"y": 269.0006408691406,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:g3Ow6Eabc74-0TpSaZ5ml",
"type": "geo",
"props": {
"w": 106.46482849121094,
"h": 125.9505615234375,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aA",
"typeName": "shape"
},
{
"x": 641.1490478515625,
"y": 195.6868438720703,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:yB6c6qLpGVgUWHY5GWdVP",
"type": "geo",
"props": {
"w": 73.09246826171875,
"h": 127.86131286621094,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aB",
"typeName": "shape"
},
{
"x": 538.2076416015625,
"y": 126.787109375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Vau4D_HwAk-Nq6wVAxDHQ",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aC",
"typeName": "shape"
},
{
"x": 536.1894226074219,
"y": 266.416015625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:NszqQRZNQqB_SfSv4ul8V",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 16,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aD",
"typeName": "shape"
},
{
"x": 534.6614540285536,
"y": 196.63410464260312,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:qSHE5B2jyduHjYW8lGcUe",
"type": "geo",
"props": {
"w": 105.90814208984374,
"h": 72.44140625,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aE",
"typeName": "shape"
},
{
"x": 641.2922523683974,
"y": 323.8736981484625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:M0kdP5q8uV1YxTBfYohmU",
"type": "geo",
"props": {
"w": 73.44403076171875,
"h": 70.21157836914062,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aF",
"typeName": "shape"
},
{
"x": 533.5103920168349,
"y": 195.4882763955328,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:PfQgIf7GFHeJhklUQ-fgL",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aG",
"typeName": "shape"
},
{
"x": 645.5221107668349,
"y": 323.0599011513922,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:S2nneJa6uMFkx8l4_wJg0",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aH",
"typeName": "shape"
},
{
"x": 641.2304635842644,
"y": 396.33463266823037,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:6MLqK6YXKOUXZ2TMz24_c",
"type": "geo",
"props": {
"w": 75.24737548828125,
"h": 109.94464111328125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aI",
"typeName": "shape"
},
{
"x": 643.6633859475456,
"y": 395.60221079323037,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:EkEWMdwXKZVTrWMKfNgNT",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aJ",
"typeName": "shape"
},
{
"x": 663.5969848632812,
"y": 350.98631286621094,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:qNJm7SiL5BR0PiMzU2q88",
"type": "geo",
"props": {
"w": 50.751953125,
"h": 41.953125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aK",
"typeName": "shape"
},
{
"x": 663.9986520608269,
"y": 349.095039162371,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:DBeP4hqxqXQy3RhfTXkGt",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aL",
"typeName": "shape"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,394 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 1,
"frame": 0,
"arrow": 2,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 441.20678725647406,
"y": 717.4154166216588,
"lastActivityTimestamp": 1705059734322,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": 313.56545603361076,
"y": -96.44512964628294,
"z": 0.8489108876169202,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:geo": "rectangle",
"tldraw:color": "black"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 1575,
"h": 673
},
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 430.53125,
"y": 247.2265625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 311.86328125,
"h": 268.765625,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"id": "shape:4idwpdW4KAPqYl5B3a34G",
"typeName": "shape"
},
{
"x": 185.3125,
"y": 314.78125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 95.90234375,
"h": 91.19140625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "1",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"id": "shape:LCLLuZDiicxJE18t92ekv",
"typeName": "shape"
},
{
"x": 374.1484375,
"y": 318.5234375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 115.875,
"h": 85.67578125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "2",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a3",
"id": "shape:6ekhVWZFvmmHzfSx0KQPs",
"typeName": "shape"
},
{
"x": 521.7734375,
"y": 319.2734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 132.921875,
"h": 86.96484375,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "3",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"id": "shape:roGZuo7XSNGiSeYJdtraw",
"typeName": "shape"
},
{
"x": 685.984375,
"y": 317.96875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 146.40234375,
"h": 86.8046875,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "4",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a5",
"id": "shape:Uzq0ovWsE0mwFZpTjW1bk",
"typeName": "shape"
},
{
"x": 903.46875,
"y": 313.140625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 139.40625,
"h": 90.7734375,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "5",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a6",
"id": "shape:Y-u90SxUICucw7KpswIL-",
"typeName": "shape"
},
{
"x": 347.375,
"y": 293.752002197541,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 506.15684718407937,
"h": 166.00337903431023,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a7",
"id": "shape:6kg1tECqONm9_tZ1XKwMh",
"typeName": "shape"
},
{
"x": 584.2291067675287,
"y": 421.5804471759829,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.8046875,
"text": "6",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a8",
"id": "shape:96rYG1eVH150aOXA3ZPC_",
"typeName": "shape"
},
{
"x": 569.4296875,
"y": 641.2488867187501,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 115.1953125,
"text": "2,6 扩容\n3,4,5 平移",
"font": "draw",
"align": "start",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a9",
"id": "shape:5DBmvgnhnHOTafO11QRqD",
"typeName": "shape"
}
]
}

View File

@@ -0,0 +1,987 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 24
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 4,
"frame": 0,
"arrow": 3,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 421.8819878759555,
"y": 1106.349397374137,
"lastActivityTimestamp": 1712490939341,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": 374.8665834686408,
"y": -91.09704365731895,
"z": 0.5871192680004972,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:color": "light-blue",
"tldraw:geo": "rectangle",
"tldraw:size": "s",
"tldraw:dash": "dashed"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 958.3333129882812,
"h": 602.5
},
"insets": [
false,
true,
true,
false
],
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2.4000000953674316,
"isCoarsePointer": false,
"isHoveringCanvas": false,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"duplicateProps": null,
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 36.62252443180677,
"y": 176.13338185011935,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Z7xkMeeNXDzNin2Lw3W4B",
"type": "geo",
"props": {
"w": 309.417660085907,
"h": 129.1754945779055,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"typeName": "shape"
},
{
"x": 561.796875,
"y": 158.87890625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:HXtCy6rMZ1V_Ti7WAx8fS",
"type": "geo",
"props": {
"w": 302.83203125,
"h": 137.01171875,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"typeName": "shape"
},
{
"x": 142.80624866569656,
"y": 196.2152141803311,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:WnvWq34NHMyf6CKwBOvYH",
"type": "geo",
"props": {
"w": 62.37890625,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "5",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"typeName": "shape"
},
{
"x": -33.453125,
"y": 140.28018818537623,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:RQ6pvlUHxkfHIwE2VblAj",
"type": "geo",
"props": {
"w": 434.5127179371963,
"h": 359.604832486845,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a6",
"typeName": "shape"
},
{
"x": 153.91418558699297,
"y": 469.72340478018043,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:qqMcpCBEVRurWJwUo1jsC",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.80338478088379,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a7",
"typeName": "shape"
},
{
"x": 670.328125,
"y": 206.125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:RWzgXvy0T1kpUTQS6j8h8",
"type": "geo",
"props": {
"w": 101.7578125,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "6",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aA",
"typeName": "shape"
},
{
"x": 504.3515625,
"y": 133.2734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:_EEHxCoV1f0GCpdnd9c13",
"type": "geo",
"props": {
"w": 438.6465149490318,
"h": 365.84093880847024,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aB",
"typeName": "shape"
},
{
"x": 735.7846767987926,
"y": 463.3469788073762,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:LpDTkDTmnOrQRjRWIsVuT",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 18.54557228088379,
"text": "4",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aC",
"typeName": "shape"
},
{
"x": -176.70483075582942,
"y": 80.13551038325613,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:aZ1fOq7m3B3bJRqVCADtw",
"type": "geo",
"props": {
"w": 1160.1568202167912,
"h": 511.1298111516582,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aD",
"typeName": "shape"
},
{
"x": 416.3944036995879,
"y": 562.9777716706179,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:kg-0xEoFEL72VyabbD_lu",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aE",
"typeName": "shape"
},
{
"x": 232.16000398280585,
"y": 188.0785920544024,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:-tf6EyMBUgH6oUE5g_und",
"type": "geo",
"props": {
"w": 401.86133470949346,
"h": 358.1623468320988,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aF",
"typeName": "shape"
},
{
"x": 436.47888907043784,
"y": 508.79678364274645,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:gDvMZAb4Rf6GA5eA76xfo",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 20.57773056511335,
"text": "2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1.155832490190769
},
"parentId": "page:page",
"index": "aG",
"typeName": "shape"
},
{
"x": 160.4110698891767,
"y": 648.9019921690615,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:6UXQihpNfMNAcH4XUhm_B",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 799.125,
"text": "5 被迁移到镜像位置\n6 被清除\n3 的 o区域迁移到镜像位置,其余的部分拆分成多个小的range (=3-o+o')\n4 o'区域被清除 (=4-o')\n7 的7.4迁移到镜像的8.4\n8 的8.4 被清除\n2.1 迁移到2.1‘,2.2被清除",
"font": "draw",
"align": "start",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aH",
"typeName": "shape"
},
{
"x": -27.381971286011108,
"y": 111.44075153624149,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:FX3hwp2fAi5auYGmtUwyN",
"type": "geo",
"props": {
"w": 62.82253446711813,
"h": 61.69400978088379,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "7.1",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aJ",
"typeName": "shape"
},
{
"x": 77.38466666973028,
"y": 296.55130999429696,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:qLW3-92vPvSEaJq3XKgZf",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 16,
"text": "o",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aU",
"typeName": "shape"
},
{
"x": 650.487335065217,
"y": 296.3863891776495,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:llNh-FmikyNSyn2dX2gwS",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 20.661457061767578,
"text": "o'",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aV",
"typeName": "shape"
},
{
"x": 36.34216398634031,
"y": 111.38823822359635,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:WktGMRojfOh09ytX4Vrgt",
"type": "geo",
"props": {
"w": 59.90364456176758,
"h": 60.867081405132986,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "7.2",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aW",
"typeName": "shape"
},
{
"x": -24.7408753522907,
"y": 174.86916476534546,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:1IVPDNlZbNdJF7k3eZWhx",
"type": "geo",
"props": {
"w": 60.60792809050062,
"h": 67.14085015453615,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "7.3",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aX",
"typeName": "shape"
},
{
"x": 37.17118520224808,
"y": 174.99903612020003,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:WyJJjUEveJC3Cnt0K3VDC",
"type": "geo",
"props": {
"w": 61.44487981334692,
"h": 64.25095219066625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "7.4",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aY",
"typeName": "shape"
},
{
"x": -27.96773690185489,
"y": 104.62874708300444,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:7gAf9ldUffUmi9Tryow7T",
"type": "geo",
"props": {
"w": 126.69101573829815,
"h": 136.92114401932835,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aZ",
"typeName": "shape"
},
{
"x": 15.710536373735692,
"y": 77.98792281791688,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:i-4t1QKTI7I-KRkqt9Eqt",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.7578125,
"text": "7",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aa",
"typeName": "shape"
},
{
"x": 502.11456401846743,
"y": 90.34457305135983,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:4oMV0zdRJ7Hitpb-Zmk-C",
"type": "geo",
"props": {
"w": 59.9345346046502,
"h": 65.2026964715675,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "8.1",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ab",
"typeName": "shape"
},
{
"x": 563.4845548665834,
"y": 88.04600059623392,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:ooQN7A-VB4tFD2_Mm_vVg",
"type": "geo",
"props": {
"w": 61.264898001174515,
"h": 67.68059026946725,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "8.2",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ac",
"typeName": "shape"
},
{
"x": 497.8270649955389,
"y": 157.28167297114751,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:_wQcHqRyFbN7UN3aDt5AH",
"type": "geo",
"props": {
"w": 61.56793884418107,
"h": 67.01377969102066,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "8.3",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ad",
"typeName": "shape"
},
{
"x": 499.17465397838816,
"y": 87.0412552888065,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:3pHgX6adpLkidrJ_UFmgl",
"type": "geo",
"props": {
"w": 126.69101573829815,
"h": 136.92114401932835,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ae",
"typeName": "shape"
},
{
"x": 542.8301411135369,
"y": 60.40043102371894,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:IaSDq4wgW9naMxfYTlLl7",
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.80338478088379,
"text": "8",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "af",
"typeName": "shape"
},
{
"x": 562.4121211816865,
"y": 159.39077441911633,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:JdYLLwDGRsi8wp32-PN6X",
"type": "geo",
"props": {
"w": 63.16826544555806,
"h": 63.103088964583435,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "8.4",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ag",
"typeName": "shape"
},
{
"x": 276.7467140331292,
"y": 218.34524188697964,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Usl50hONQS9BSzS5zSgCS",
"type": "text",
"props": {
"color": "black",
"size": "s",
"w": 24.118488311767578,
"text": "2.1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "ah",
"typeName": "shape"
},
{
"x": 763.3710549959251,
"y": 189.08828302066794,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:AsZwMCjgc1bzNYQFpN4B6",
"type": "geo",
"props": {
"w": 97.78611008717803,
"h": 104.810848254783,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "dashed",
"size": "s",
"font": "draw",
"text": "2.1‘",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ai",
"typeName": "shape"
},
{
"x": 579.4879858872264,
"y": 239.6245375565262,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:Og45Ay_n74-R9Y7qJyQqF",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 30.55729103088379,
"text": "2.2",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aj",
"typeName": "shape"
},
{
"x": 561.0568077085461,
"y": 189.38767917334172,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:S_F8i-VlBd3Mzo5BGmGnY",
"type": "geo",
"props": {
"w": 70.1862549615455,
"h": 104.17878971024942,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "dashed",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "ak",
"typeName": "shape"
}
]
}

View File

@@ -0,0 +1,956 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 1,
"frame": 0,
"arrow": 2,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 55.55685250781136,
"y": 703.8297520724325,
"lastActivityTimestamp": 1705030248183,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": 294.76991661362814,
"y": 43.29961849732369,
"z": 0.9776586609665379,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:geo": "rectangle",
"tldraw:color": "violet"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 1575,
"h": 966
},
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 34.375,
"y": 170.8671875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 292.27734375,
"h": 126.5546875,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"id": "shape:H-zLGWrcyFpLqrgs6E6mO",
"typeName": "shape"
},
{
"x": 561.796875,
"y": 158.87890625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 302.83203125,
"h": 137.01171875,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"id": "shape:_BydIVgQzTwJUTRDNv9qa",
"typeName": "shape"
},
{
"x": -14.040786027659124,
"y": 194.577429467257,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 75.1484375,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "1",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a3",
"id": "shape:lBICTbCCCqT56GHsEj6wS",
"typeName": "shape"
},
{
"x": 142.80624866569656,
"y": 196.2152141803311,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 62.37890625,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "2",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"id": "shape:d2rF4Ufm_ed2XsM0xfEGF",
"typeName": "shape"
},
{
"x": 284.0804436373687,
"y": 199.8219717500258,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 100.76171875,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "3",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a5",
"id": "shape:xTyt7wP7NwV4dXFf9Iy7C",
"typeName": "shape"
},
{
"x": -33.453125,
"y": 135.7734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 444.54103337099724,
"h": 364.11158317222123,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a6",
"id": "shape:veaoXZ6Hn3ZMlB1ih05jo",
"typeName": "shape"
},
{
"x": 153.54309183699297,
"y": 469.72340478018043,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 18.546875,
"text": "4",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a7",
"id": "shape:pTQ-hYYeH3qzxqXtGW8_L",
"typeName": "shape"
},
{
"x": 521.8435057175018,
"y": 196.54186299601008,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 64.79296875,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "5",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a8",
"id": "shape:-I4xH7aKMUnqE8T62RLoC",
"typeName": "shape"
},
{
"x": 828.7578125,
"y": 201.6015625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 79.69140625,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "7",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a9",
"id": "shape:7o7qdgGunwqOVq34lqrPW",
"typeName": "shape"
},
{
"x": 670.328125,
"y": 206.125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 101.7578125,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "6",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aA",
"id": "shape:TYqU4N62GAAHUAk7YflVq",
"typeName": "shape"
},
{
"x": 504.3515625,
"y": 133.2734375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 438.6465149490318,
"h": 365.84093880847024,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aB",
"id": "shape:9qciaH4DoNBgbaJ9y_FkK",
"typeName": "shape"
},
{
"x": 736.1557705487926,
"y": 463.3469788073762,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.8046875,
"text": "8",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aC",
"id": "shape:NGe8HZM-aDU-DQwVzm-OW",
"typeName": "shape"
},
{
"x": -89.8095083258051,
"y": 83.53401470284712,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 1160.1568202167912,
"h": 511.1298111516582,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aD",
"id": "shape:lEWGrDHw_OdXdEozsdPWK",
"typeName": "shape"
},
{
"x": 415.492711309146,
"y": 562.9777716706179,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.8046875,
"text": "9",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aE",
"id": "shape:_obbk7On5uNsbQGM-kdXg",
"typeName": "shape"
},
{
"x": 232.16000398280585,
"y": 188.0785920544024,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 401.86133470949346,
"h": 358.1623468320988,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aF",
"id": "shape:KOTdkz2gG5oGvHBw1dbj8",
"typeName": "shape"
},
{
"x": 428.87513449839116,
"y": 511.4842887616377,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 27.359375,
"text": "10",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aG",
"id": "shape:mgfjYlDTpnzr0aaF3fRth",
"typeName": "shape"
},
{
"x": 160.4110698891767,
"y": 647.7666624618896,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 218.0390625,
"text": "2 被迁移到镜像位置\n6 被清除",
"font": "draw",
"align": "start",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aH",
"id": "shape:crQuzsYKqBHlGoP1paG6a",
"typeName": "shape"
},
{
"x": -14.769730291894462,
"y": 263.9072737045833,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 75.82795710103414,
"h": 63.73892890993045,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "11",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aI",
"id": "shape:bEwvXVbx6FQ9uAWlcSOC7",
"typeName": "shape"
},
{
"x": -5.183508718480198,
"y": 123.99211979162874,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 58.47359045950839,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "12",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aJ",
"id": "shape:-CxLGtLMdxhRemGOOa3MV",
"typeName": "shape"
},
{
"x": 132.55349509558891,
"y": 273.8830831005623,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 84.88504354236989,
"h": 91.390625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "14",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aK",
"id": "shape:tZUmBHCxJXuDlxax8hR5k",
"typeName": "shape"
},
{
"x": 145.38037901124733,
"y": 123.45496082415295,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.3984375,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "13",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aL",
"id": "shape:SoOMkByarmJZNMw7db-l2",
"typeName": "shape"
},
{
"x": 294.4567496002726,
"y": 126.40048087657524,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.3984375,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "15",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aM",
"id": "shape:Y-v1VlJcfY2zaG-gNQcze",
"typeName": "shape"
},
{
"x": 299.9995218031272,
"y": 274.945595343921,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.6015625,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "16",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aN",
"id": "shape:oLAtOdjoZhj_LlxH4asiS",
"typeName": "shape"
},
{
"x": 524.4611360584538,
"y": 121.22958795889613,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.421875,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "17",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aO",
"id": "shape:wohN0-W24P18xuQWxL6BC",
"typeName": "shape"
},
{
"x": 519.9100419494005,
"y": 273.82405464259796,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.8203125,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "18",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aP",
"id": "shape:IO5l9fSNBQJgPIa1xNR2h",
"typeName": "shape"
},
{
"x": 686.9192580680024,
"y": 131.28213435022886,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.8203125,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "19",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aQ",
"id": "shape:Hidx4XWfdBudLzxQAlnME",
"typeName": "shape"
},
{
"x": 693.50093113103,
"y": 273.77092903043,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 76.04848338510328,
"h": 91.390625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "20",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aR",
"id": "shape:rCq_wYz9FS4pTy0Dol7g1",
"typeName": "shape"
},
{
"x": 835.0806875585799,
"y": 122.9414132398629,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 56.8203125,
"h": 61.6953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "21",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aS",
"id": "shape:WuBi8JzgT17VQfdJRuZwC",
"typeName": "shape"
},
{
"x": 833.9119240908853,
"y": 273.12751883861824,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 74.00019589373937,
"h": 91.390625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "22",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aT",
"id": "shape:9RIZ2-2GdEJlt-KlMKHcu",
"typeName": "shape"
}
]
}

View File

@@ -0,0 +1,785 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 24
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 4,
"frame": 0,
"arrow": 3,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 1255.3905494482942,
"y": 167.71229914279735,
"lastActivityTimestamp": 1712497349510,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": -674.531795241653,
"y": 22.109098806580008,
"z": 0.8913257676681506,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:geo": "rectangle",
"tldraw:color": "light-blue",
"tldraw:size": "s"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 908.3333129882812,
"h": 602.5
},
"insets": [
false,
true,
true,
false
],
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2.4000000953674316,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"duplicateProps": null,
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 166.2044219970703,
"y": 11.871749877929688,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:34yHP5cqUyj1sUzXYvGG_",
"type": "geo",
"props": {
"w": 57.05731201171876,
"h": 539.8860626220703,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"typeName": "shape"
},
{
"x": 105.42317199707031,
"y": 112.09635162353516,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:S0lUSLL7krS7mJ6Ke2Jt1",
"type": "geo",
"props": {
"w": 181.1490936279297,
"h": 78.40169525146484,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"typeName": "shape"
},
{
"x": 171.39928478199744,
"y": 250.23697756122317,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:hZ2vPygFFYyLnhcuBemCv",
"type": "geo",
"props": {
"w": 48.88801956176758,
"h": 66.14581298828125,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "5",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a3",
"typeName": "shape"
},
{
"x": 67.22004699707031,
"y": 60.592445373535156,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:HluOJgiOyqopIqXDF5S9R",
"type": "geo",
"props": {
"w": 247.7897186279297,
"h": 463.42122650146484,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"typeName": "shape"
},
{
"x": 515.6966094970703,
"y": 5.9798126220703125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:EFGA1-V22biG3ATmjL6Cn",
"type": "geo",
"props": {
"w": 57.91015625,
"h": 554.8632659912108,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a5",
"typeName": "shape"
},
{
"x": 416.7122344970703,
"y": 61.37042999267578,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:QabyY2x9yG9CXCbImwk65",
"type": "geo",
"props": {
"w": 247.7897186279297,
"h": 463.42122650146484,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a8",
"typeName": "shape"
},
{
"x": 83.52343314223816,
"y": 67.49348390102391,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:mvJKUtoBmicgrdwEQld72",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a9",
"typeName": "shape"
},
{
"x": 115.18614605047046,
"y": 117.47362519973734,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:iUViMjV9iCWSVEVPyueNQ",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aB",
"typeName": "shape"
},
{
"x": 1002.4517246923492,
"y": 4.889925326311641,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:DRUWAUHqsFDK-Geg5wgdo",
"type": "geo",
"props": {
"w": 57.05731201171876,
"h": 539.8860626220703,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aD",
"typeName": "shape"
},
{
"x": 941.6704746923492,
"y": 105.11452707191711,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:A9xIt9L9jNGc0oweLZPnW",
"type": "geo",
"props": {
"w": 60.26514566415449,
"h": 74.1340945400321,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aE",
"typeName": "shape"
},
{
"x": 903.4673496923492,
"y": 53.61062082191711,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:2uCxXh6cnNAxnZyb_KuDH",
"type": "geo",
"props": {
"w": 99.36425064789591,
"h": 461.26928683828396,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aG",
"typeName": "shape"
},
{
"x": 1351.9439121923492,
"y": -1.0020119295477343,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:YX46lpEXwsP_hDEfdMsD9",
"type": "geo",
"props": {
"w": 57.91015625,
"h": 554.8632659912108,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aH",
"typeName": "shape"
},
{
"x": 1356.7978541724624,
"y": 244.31275517707417,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:8Svx_N7tJ-qYJ0llQp1IU",
"type": "geo",
"props": {
"w": 48.88801956176758,
"h": 65.26476272972224,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "5",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aJ",
"typeName": "shape"
},
{
"x": 919.7707358375171,
"y": 60.51165934940586,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:6s2XH02MusvP6oFWgMQcb",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aL",
"typeName": "shape"
},
{
"x": 951.4334487457494,
"y": 110.4918006481193,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:GnvsePN4zv2AJZm61LBQz",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aN",
"typeName": "shape"
},
{
"x": 701.2647232635863,
"y": 263.38123474876966,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:bWvcwdw9py4Vu5H4zO4T_",
"type": "arrow",
"parentId": "page:page",
"index": "aP",
"props": {
"dash": "draw",
"size": "xl",
"fill": "none",
"color": "light-blue",
"labelColor": "black",
"bend": 0,
"start": {
"type": "point",
"x": 0,
"y": 0
},
"end": {
"type": "point",
"x": 133.3045156202329,
"y": -0.21178503374801494
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"labelPosition": 0.5,
"font": "draw"
},
"typeName": "shape"
},
{
"x": 1059.4133089551478,
"y": 105.57886256417618,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:oCQTPmRoVscXxrOwK5pK7",
"type": "geo",
"props": {
"w": 56.05233069734595,
"h": 71.63415732885807,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aQ",
"typeName": "shape"
},
{
"x": 1357.016832647147,
"y": 103.64725591791213,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:N9IB_pAyKkgHU9d8pg-N9",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aR",
"typeName": "shape"
},
{
"x": 1060.1204957350876,
"y": 53.31898405311833,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:sYztnUSygK7T27htroeVd",
"type": "geo",
"props": {
"w": 99.36425064789591,
"h": 461.26928683828396,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aW",
"typeName": "shape"
},
{
"x": 1066.5314514261336,
"y": 55.051774724258536,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:YTzysZoy6xyaBVXBeK8IS",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "1",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aX",
"typeName": "shape"
},
{
"x": 1059.4133089551478,
"y": 105.57886256417618,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:h32QlyTDcBmBR6nKNU5Fy",
"type": "geo",
"props": {
"w": 56.05233069734595,
"h": 71.63415732885807,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aY",
"typeName": "shape"
},
{
"x": 1352.9496098313912,
"y": 103.66690984048108,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:qa04yggT2SX3P5k3GYmhJ",
"type": "geo",
"props": {
"w": 56.05233069734595,
"h": 71.63415732885807,
"geo": "rectangle",
"color": "light-blue",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "s",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "aZ",
"typeName": "shape"
},
{
"x": 1059.790925494965,
"y": 106.88667183369284,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"id": "shape:9wqvv0_37l2RzNsssd5yo",
"type": "text",
"props": {
"color": "light-blue",
"size": "s",
"w": 16,
"text": "3",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "aa",
"typeName": "shape"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,394 @@
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {
"image": 3,
"video": 3,
"bookmark": 1
}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 1,
"frame": 0,
"arrow": 2,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"records": [
{
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
{
"id": "pointer:pointer",
"typeName": "pointer",
"x": 496.1347911746003,
"y": 741.6432807390081,
"lastActivityTimestamp": 1705117237892,
"meta": {}
},
{
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
{
"x": 681.4900753997093,
"y": 58.853197674418595,
"z": 0.6197325826882477,
"meta": {},
"id": "camera:page:page",
"typeName": "camera"
},
{
"editingShapeId": null,
"croppingShapeId": null,
"selectedShapeIds": [],
"hoveredShapeId": null,
"erasingShapeIds": [],
"hintingShapeIds": [],
"focusedGroupId": null,
"meta": {},
"id": "instance_page_state:page:page",
"pageId": "page:page",
"typeName": "instance_page_state"
},
{
"followingUserId": null,
"opacityForNextShape": 1,
"stylesForNextShape": {
"tldraw:geo": "rectangle",
"tldraw:color": "black"
},
"brush": null,
"scribbles": [],
"cursor": {
"type": "default",
"rotation": 0
},
"isFocusMode": false,
"exportBackground": true,
"isDebugMode": false,
"isToolLocked": false,
"screenBounds": {
"x": 0,
"y": 0,
"w": 1547,
"h": 686
},
"zoomBrush": null,
"isGridMode": false,
"isPenMode": false,
"chatMessage": "",
"isChatting": false,
"highlightedUserIds": [],
"canMoveCamera": true,
"isFocused": true,
"devicePixelRatio": 2,
"isCoarsePointer": false,
"isHoveringCanvas": true,
"openMenus": [],
"isChangingStyle": false,
"isReadonly": false,
"meta": {},
"id": "instance:instance",
"currentPageId": "page:page",
"typeName": "instance"
},
{
"x": 332.8046875,
"y": 175.328125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 411.91015625,
"h": 380.8828125,
"geo": "rectangle",
"color": "black",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a1",
"id": "shape:YOAcn0CPIwJfmfgk8DMKT",
"typeName": "shape"
},
{
"x": 75.1640625,
"y": 264.9140625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 140.72265625,
"h": 125.4765625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "1",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a2",
"id": "shape:MiB10BJywnRxyA1ytUuHA",
"typeName": "shape"
},
{
"x": 266.4453125,
"y": 266.84375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 134.375,
"h": 121.37109375,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "2",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a3",
"id": "shape:GLs1Xhlcp2sFkTUpqJW-1",
"typeName": "shape"
},
{
"x": 469.984375,
"y": 268.8359375,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 135.1171875,
"h": 107.390625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "3",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a4",
"id": "shape:a0-6K3aBeivzXIKEGiciE",
"typeName": "shape"
},
{
"x": 682.578125,
"y": 268.765625,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 137.578125,
"h": 120.51953125,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "4",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a5",
"id": "shape:z8yTguOE2HfQXCsbWMMnO",
"typeName": "shape"
},
{
"x": 916.2109375,
"y": 272.96875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 141.8828125,
"h": 105.56640625,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "5",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a6",
"id": "shape:fEbeB8oq6JimKFbBOFTE4",
"typeName": "shape"
},
{
"x": 229.671875,
"y": 214.09719209892808,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "geo",
"props": {
"w": 627.5712599643441,
"h": 300.5655125462732,
"geo": "rectangle",
"color": "violet",
"labelColor": "black",
"fill": "none",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
},
"parentId": "page:page",
"index": "a7",
"id": "shape:Gvrsw9_ks1tQENQ1wS9pY",
"typeName": "shape"
},
{
"x": 541.0948314223178,
"y": 479.98268003241975,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 17.8046875,
"text": "6",
"font": "draw",
"align": "middle",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a8",
"id": "shape:EEACmJ41COUk9brpPwNYC",
"typeName": "shape"
},
{
"x": 514.80078125,
"y": 679.54296875,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 139.578125,
"text": "\n2,6 缩减\n3 删除\n4 缩减+平移\n5 平移",
"font": "draw",
"align": "start",
"autoSize": true,
"scale": 1
},
"parentId": "page:page",
"index": "a9",
"id": "shape:IlTeELWUQoR37EpmGtFpB",
"typeName": "shape"
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff