docs: 错误代码文档

This commit is contained in:
unanmed 2025-03-21 15:31:59 +08:00
parent 704a23254a
commit dc82010e85
14 changed files with 4272 additions and 2738 deletions

View File

@ -1,4 +1,5 @@
import { defineConfig } from 'vitepress';
import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid';
// https://vitepress.dev/reference/site-config
export default defineConfig({
@ -6,7 +7,10 @@ export default defineConfig({
description: 'HTML5 魔塔样板 V2.B 帮助文档',
base: '/_docs/',
markdown: {
math: true
math: true,
config(md) {
md.use(MermaidMarkdown);
}
},
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
@ -24,11 +28,41 @@ export default defineConfig({
items: [
{ text: '差异说明', link: '/guide/diff' },
{ text: '系统说明', link: '/guide/system' },
{ text: 'UI 编写', link: '/guide/ui' },
{ text: 'UI 优化', link: '/guide/ui-perf' },
{ text: 'UI 系统', link: '/guide/ui-system' },
{ text: 'UI 元素', link: '/guide/ui-elements' },
{ text: 'UI 常见问题', link: '/guide/ui-faq' }
{ text: '代码编写', link: '/guide/coding' },
{
text: 'UI 系统',
collapsed: false,
items: [
{ text: 'UI 编写', link: '/guide/ui' },
{ text: 'UI 优化', link: '/guide/ui-perf' },
{ text: 'UI 系统', link: '/guide/ui-system' },
{ text: 'UI 元素', link: '/guide/ui-elements' },
{ text: 'UI 常见问题', link: '/guide/ui-faq' }
]
},
{ text: '音频系统', link: '/guide/audio' }
]
}
],
'/logger/': [
{
text: '错误代码一览',
items: [
{
text: '错误代码',
collapsed: false,
items: [
{ text: '1-50', link: '/logger/error/error1' }
]
},
{
text: '警告代码',
collapsed: false,
items: [
{ text: '1-50', link: '/logger/warn/warn1' },
{ text: '51-100', link: '/logger/warn/warn2' }
]
}
]
}
]
@ -65,5 +99,14 @@ export default defineConfig({
lang: 'zh',
label: '中文'
}
},
vite: {
plugins: [MermaidPlugin()],
optimizeDeps: {
include: ['mermaid']
},
ssr: {
noExternal: ['mermaid']
}
}
});

View File

@ -0,0 +1,7 @@
.mermaid {
max-width: 600px; /* 限制最大宽度 */
max-height: 400px; /* 限制最大高度 */
overflow: auto; /* 允许滚动以防止超出 */
display: block;
margin: 0 auto;
}

View File

@ -0,0 +1,393 @@
# 音频系统
2.B 有了与 2.A 完全不同的音频系统,新的音频系统更加自由,功能更加丰富,可以创建多种自定义效果器。本文将讲解如何使用音频系统。
:::tip
多数情况下,你应该不需要使用本文所介绍的内容,因为样板已经将音效、背景音乐等处理完善。如果你想实现高级效果,例如混响效果等,才需要阅读本文。
:::
## 获取音频播放器
音频播放器在 `@user/client-modules` 模块中,直接引入即可:
```ts
// 在其他模块中使用模块化语法引入
import { audioPlayer } from '@user/client-modules';
// 在 client-modules 模块中使用模块化语法引入
import { audioPlayer } from '../audio'; // 改为你自己的相对路径
// 使用 Mota 全局变量引入
const { audioPlayer } = Mota.require('@user/client-modules');
```
## 音频系统工作流程
音频播放流程如下:
```mermaid
graph LR;
A(音频源) --> B(效果器) --> C(目的地(扬声器、耳机))
```
## 创建音频源
:::tip
本小节的内容极大概率用不到,如果不是需要非常底层的音频接口,可以不看本小节。
:::
样板内置了几种音频源,它们包括:
| 类型 | 适用场景 | 创建方法 |
| --------------- | ----------------------- | ----------------------- |
| `BufferSource` | 预加载的完整音频文件 | `createBufferSource()` |
| `ElementSource` | 通过 `<audio>` 标签播放 | `createElementSource()` |
| `StreamSource` | 流式音频/长音频 | `createStreamSource()` |
### `StreamSource` 音频源
一般情况下,我们推荐使用 `opus` 格式的音频,这时候需要使用 `StreamSource` 音频源来播放。这个音频源包含了对 IOS 的适配,可以正确播放 `opus` 格式的音频。在使用它之前,我们需要先创建一个 `StreamLoader` 类,来对音频流式加载。假如你在 `project/mybgm/` 文件夹下有一个 `xxx.opus` 音频,你可以这么创建:
```ts
import { StreamLoader } from '@user/client-modules';
const stream = new StreamLoader('project/mybgm/xxx.opus');
```
然后,创建音频源,并将流加载对象泵入音频源:
```ts
const source = audioPlayer.createStreamSource();
stream.pipe(source);
stream.start(); // 开始流式加载,如果不需要实时性,也可以不调用,音频播放时会自动开始加载
```
### `ElementSource` 音频源
从一个 `audio` 元素创建音频源,假设你想要播放 `project/mybgm/xxx.mp3`,那么你可以这么创建:
```ts
const source = audioPlayer.createElementSource();
source.setSource('project/mybgm/xxx.mp3');
```
### `BufferSource` 音频源
从音频缓冲创建音频源。音频缓冲是直接存储在内存中的一段原始音频波形数据,不经过任何压缩。假如你想播放 `project/mysound/xxx.wav`,可以这么写:
```ts
async function loadWav(url: string) {
// 使用浏览器接口 fetch 来请求文件
const response = await fetch(url);
// 将文件接收为 ArrayBuffer 形式
const buffer = await response.arraybuffer();
// 创建音频源
const source = audioPlayer.createBufferSource();
// 直接传入 ArrayBuffer内部会自动解析当然也可以自己解析传入 AudioBuffer
await source.setBuffer(source);
// 将音频源返回,供后续使用
return source;
}
```
## 创建音频路由
音频路由包含了音频播放的所有流程,想要播放一段音频,必须首先创建音频路由,然后使用 `audioPlayer` 播放这个音频路由。如下例所示:
```ts
import { AudioRoute, audioPlayer } from '@user/client-modules';
const route = audioPlayer.createRoute(source);
```
下面,我们需要将音频路由添加至音频播放器:
```ts
audioPlayer.addRoute('my-route', route);
```
之后,我们就可以使用 `audioPlayer` 播放这个音频了:
```ts
audioPlayer.play('my-route');
```
## 音频效果器
新的音频系统中最有用的功能就是音频效果器了。音频效果器允许你对音频进行处理,可以实现调节声道音量、回声效果、延迟效果,以及各种自定义效果等。
内置效果器包含这些:
| 效果器类型 | 功能说明 | 创建方法 |
| --------------------- | ------------------ | --------------------------- |
| `VolumeEffect` | 音量控制 | `createVolumeEffect()` |
| `StereoEffect` | 立体声场调节 | `createStereoEffect()` |
| `EchoEffect` | 回声效果 | `createEchoEffect()` |
| `DelayEffect` | 延迟效果 | `createDelay()` |
| `ChannelVolumeEffect` | 调节某个声道的音量 | `createChannelVolumeEffect` |
每个效果器都有自己可以调节的属性,具体可以查看对应效果器的 API 文档,比较简单,这里不在讲解。下面主要讲解一下如何使用效果器,我们直接通过例子来看(代码由 `DeepSeek R1` 模型生成并微调):
```ts
// 创建效果链
const volume = audioPlayer.createVolumeEffect();
const echo = audioPlayer.createEchoEffect();
// 配置效果参数
volume.setGain(0.7); // 振幅变为 0.7 倍
echo.setEchoDelay(0.3); // 回声延迟 0.3 秒
echo.setFeedbackGain(0.5); // 回声增益为 0.5
// 应用效果到音频路由
const route = audioPlayer.getRoute('my-route')!;
route.addEffect([volume, echo]);
// 之后播放就有效果了
route.play();
```
## 空间音效
本音频系统还支持空间音效,可以设置听者位置和音频位置,示例如下(代码由 `DeepSeek R1` 模型生成并微调):
```ts
// 设置听者位置
audioPlayer.setListenerPosition(0, 1.7, 0); // 1.7米高度
audioPlayer.setListenerOrientation(0, 0, -1); // 面朝屏幕内
// 设置声源位置(使用 StereoEffect 效果器)
const stereo = audioPlayer.createStereoEffect();
stereo.setPosition(5, 0, -2); // 右方5米地面下方2米
```
## 淡入淡出效果
音频系统提供了淡入淡出接口,可以搭配 `mutate-animate` 库实现淡入淡出效果:
```ts
import { Transition, linear } from 'mutate-animate';
// 创建音量效果器
const volume = audioPlayer.createVolumeEffect();
// 创建渐变类,使用渐变是因为可以避免来回播放暂停时的音量突变
const trans = new Transition();
trans.value.volume = 0;
// 每帧设置音量
trans.ticker.add(() => {
volume.setVolume(trans.value.volume);
});
// 当音频播放时执行淡入
route.onStart(() => {
// 两秒钟时间线性淡入
trans.time(2000).mode(linear()).transition('volume', 1);
});
route.onEnd(() => {
// 三秒钟时间线性淡出
trans.time(3000).mode(linear()).transition('volume', 0);
});
// 添加音量效果器
route.addEffect(volume);
```
## 音效系统
为了方便播放音效,音频系统内置提供了音效的播放器,允许你播放空间音效。
### 播放音效
样板已经自动将所有注册的音效加入到音效系统中,你只需要直接播放即可,不需要手动加载。播放时,可以指定音频的播放位置,听者(玩家)位置可以通过 `audioPlayer.setPosition``audioPlayer.setOrientation` 设置。示例如下:
```ts
import { soundPlayer } from '@user/client-modules';
// 播放已加载的音效
const soundId = soundPlayer.play(
'mysound.opus',
[1, 0, 0], // 音源位置,在听者前方 1m 处
[0, 1, 0] // 音源朝向,朝向天花板
);
// 停止指定音效
soundPlayer.stop(soundId);
// 停止所有音效
soundPlayer.stopAllSounds();
```
### 设置是否启用音效
你可以自行设置是否启用音效系统:
```ts
soundPlayer.setEnabled(false); // 关闭音效系统
soundPlayer.setEnabled(true); // 启用音效系统
```
## 音乐系统
音乐系统的使用与音频系统类似,包含播放、暂停、继续等功能。示例如下:
```ts
import { bgmController } from '@user/client-modules';
bgmController.play('bgm1.opus'); // 切换到目标音乐
bgmController.pause(); // 暂停当前音乐,会有渐变效果
bgmController.resume(); // 继续当前音乐,会有渐变效果
bgmController.blockChange(); // 禁用音乐切换,之后调用 play, pause, resume 将没有效果
bgmController.unblockChange(); // 启用音乐切换
```
## 自定义效果器
本小节内容由 `DeepSeek R1` 模型生成并微调。
效果器是新的音频系统最强大的功能,而且此系统也允许你自定义一些效果器,实现自定义效果。效果器的工作流程如下:
```mermaid
graph LR
Input[输入源] --> EffectInput[效果器输入]
EffectInput --> Processing[处理节点]
Processing --> EffectOutput[效果器输出]
EffectOutput --> NextEffect[下一效果器]
```
:::info
这一节难度较大,如果你不需要复杂的音效效果,不需要看这一节。
:::
### 创建效果器类
所有效果器都需要继承 `AudioEffect` 抽象类,需要实现这些内容:
```ts
abstract class AudioEffect implements IAudioInput, IAudioOutput {
abstract output: AudioNode; // 输出节点
abstract input: AudioNode; // 输入节点
abstract start(): void; // 效果激活时调用
abstract end(): void; // 效果结束时调用
}
```
### 实现效果器
下面以一个双线性低通滤波器为例,展示如何创建一个自定义滤波器。首先,我们需要继承 `AudioEffect` 抽象类:
```ts
class CustomEffect extends AudioEffect {
// 实现抽象成员
output: AudioNode;
input: AudioNode;
}
```
接下来,我们需要构建音频节点,创建一个 `BiquadFilter`
```ts
class CustomEffect extends AudioEffect {
constructor(ac: AudioContext) {
super(ac);
// 创建处理节点链
const filter = ac.createBiquadFilter(); // 滤波器节点
filter.type = 'lowpass'; // 低通滤波器
// 输入节点和输出节点都是滤波器节点
this.input = filter;
this.output = filter;
}
}
```
然后,我们可以提供接口来让外部能够调整这个效果器的参数:
```ts
class CustomEffect extends AudioEffect {
private Q: number = 1;
private frequency: number = 1000;
/** 设置截止频率 */
setCutoff(freq: number) {
this.frequency = Math.min(20000, Math.max(20, freq));
this.output.frequency.value = this.frequency;
}
/** 设置共振系数 */
setResonance(q: number) {
this.Q = Math.min(10, Math.max(0.1, q));
this.output.Q.value = this.Q;
}
}
```
最后,别忘了实现 `start` 方法和 `end` 方法,虽然不需要有任何内容:
```ts
class CustomEffect extends AudioEffect {
start() {}
end() {}
}
```
### 使用效果器
就如内置的效果器一样,创建效果器实例并添加入路由图即可:
```ts
const myEffect = new CustomEffect(audioPlayer.ac);
myRoute.addEffect(myEffect);
```
### 高级技巧
动画修改属性:
```ts
// 创建参数渐变
rampFrequency(target: number, duration: number) {
const current = this.output.frequency.value;
this.output.frequency.setValueAtTime(current, this.ac.currentTime);
this.output.frequency.linearRampToValueAtTime(
target,
this.ac.currentTime + duration
);
}
```
在一个效果器内添加多个音频节点:
```ts
class ReverbEffect extends AudioEffect {
private convolver: ConvolverNode;
private wetGain: GainNode;
constructor(ac: AudioContext) {
super(ac);
this.input = ac.createGain(); // 输入增益节点
this.wetGain = ac.createGain(); // 卷积增益节点
this.convolver = ac.createConvolver(); // 卷积节点
// 构建混合电路
const dryGain = ac.createGain(); // 原始音频增益节点
this.input.connect(dryGain);
this.input.connect(this.convolver);
this.convolver.connect(this.wetGain);
// 合并输出
const merger = ac.createChannelMerger();
dryGain.connect(merger, 0, 0);
this.wetGain.connect(merger, 0, 1);
this.output = merger;
}
}
```
以上效果器的流程图如下:
```mermaid
graph LR;
A(input 增益节点) --> B(dryGain 增益节点);
A --> C(convolver 卷积节点) --> D(wetGain 增益节点)
B & D --> E(output 声道合并节点)
```

50
docs/guide/coding.md Normal file
View File

@ -0,0 +1,50 @@
# 代码编写指南
本节将介绍如何在 2.B 样板中正确编写代码
## 在哪编写代码?
我们推荐在 `packages-user` 中编写代码,在这里你可以享受到完整的类型支持与代码补全。展开 `packages-user` 文件夹,可以看到里面分为了多个文件夹。我们应该主要在 `client-modules``data-state` 中编写代码,分别是渲染层和数据层的主要代码位置。其余内容一般是系统底层相关的代码,如果看不懂的话不建议修改。
```mermaid
graph LR
root(package-user)
root --> A(client-modules) --> A1(渲染层主要代码)
root --> B(data-base) --> B1(数据层底层代码)
root --> C(data-fallback) --> C1(数据层向后兼容代码)
root --> D(data-state) --> D1(数据层游戏状态代码)
root --> E(data-utils) --> E1(数据层工具代码)
root --> F(entry-client) --> F1(渲染层入口代码)
root --> G(entry-data) --> G1(数据层入口代码)
root --> H(legacy-plugin-client) --> H1(遗留渲染层代码)
root --> I(legacy-plugin-data) --> I1(遗留数据层代码)
```
## 如何使用模块化引入?
在引入时,需要**严格**遵循如下原则:
1. 同一模块间使用相对路径引入 `./xxx`
2. 不同模块间使用绝对路径引入 `@user/xxxx`
例如,如果你在 `@user/client-modules` 中引入自身的代码,就需要使用 `import { xxx } from './xxx`,如果你需要在 `@user/client-modules` 引入 `@user/data-base` 中的代码,就需要使用 `import { xxx } from '@user/data-base'` 引入。
:::warning
注意,在之后的所有文档示例中,都会使用 `import xxx from '@xxx/xxx'` 的绝对路径形式作为示例,而不会使用相对路径,自己编写代码时请注意要引入的内容是否在当前模块(当前包)中,如果是,请使用相对路径,否则请使用绝对路径。
:::
## 使用 TypeScript
所有代码使用 `TypeScript` 编写,后缀名为 `.ts``.tsx`,其中前者表示一般代码,后者表示 UI 代码(即包含 XML 的代码)
编写代码时,需要保证类型正确。如果搞不明白类型系统,类型就写 `any`(但是极其不推荐!这会使得自动补全也消失!)
`TypeScript` 类型系统教程可以查看[我编写的教程](https://h5mota.com/bbs/thread/?tid=1018&p=3#p41)
## 渲染层与数据层分离
渲染层可以直接引用数据层代码,但是数据层**不能**直接引用渲染层代码,具体请查看[系统说明](./system.md#渲染端与数据端通信)
## 避免循环引用依赖
需要避免两个包之间循环引入。如果出现了循环引入,请考虑将它们挪到一个包里面,或者将循环的部分单独拿出来作为一个包。

View File

@ -10,32 +10,32 @@ lang: zh-CN
2.B 样板现在已经迁移至了 monorepo将代码模块化共分为 20 余个模块,每个模块的具体内容可以参考 API 文档,模块列表如下:
- [@motajs/client](../api/motajs-client)
- [@motajs/client-base](../api/motajs-client-base)
- [@motajs/common](../api/motajs-common)
- [@motajs/legacy-client](../api/motajs-legacy-client)
- [@motajs/legacy-common](../api/motajs-legacy-common)
- [@motajs/legacy-data](../api/motajs-legacy-data)
- [@motajs/legacy-system](../api/motajs-legacy-system)
- [@motajs/legacy-ui](../api/motajs-legacy-ui)
- [@motajs/render](../api/motajs-render)
- [@motajs/render-core](../api/motajs-render-core)
- [@motajs/render-elements](../api/motajs-render-elements)
- [@motajs/render-style](../api/motajs-render-style)
- [@motajs/render-vue](../api/motajs-render-vue)
- [@motajs/system](../api/motajs-system)
- [@motajs/system-action](../api/motajs-system-action)
- [@motajs/system-ui](../api/motajs-system-ui)
- [@motajs/types](../api/motajs-types)
- [@user/client-modules](../api/user-client-modules)
- [@user/data-base](../api/user-data-base)
- [@user/data-fallback](../api/user-data-fallback)
- [@user/data-state](../api/user-data-state)
- [@user/data-utils](../api/user-data-utils)
- [@user/entry-client](../api/user-entry-client)
- [@user/entry-data](../api/user-entry-data)
- [@user/legacy-plugin-client](../api/user-legacy-plugin-client)
- [@user/legacy-plugin-data](../api/user-legacy-plugin-data)
- [@motajs/client](../api/motajs-client) 渲染层代码
- [@motajs/client-base](../api/motajs-client-base) 渲染层底层代码
- [@motajs/common](../api/motajs-common) 渲染层和数据层通用代码
- [@motajs/legacy-client](../api/motajs-legacy-client) 遗留渲染层代码
- [@motajs/legacy-common](../api/motajs-legacy-common) 遗留通用代码
- [@motajs/legacy-data](../api/motajs-legacy-data) 遗留数据层代码
- [@motajs/legacy-system](../api/motajs-legacy-system) 遗留渲染层系统代码
- [@motajs/legacy-ui](../api/motajs-legacy-ui) 遗留 UI 相关代码
- [@motajs/render](../api/motajs-render) 渲染系统代码
- [@motajs/render-core](../api/motajs-render-core) 渲染系统核心代码
- [@motajs/render-elements](../api/motajs-render-elements) 渲染系统内置元素代码
- [@motajs/render-style](../api/motajs-render-style) 渲染系统样式代码
- [@motajs/render-vue](../api/motajs-render-vue) 渲染系统 vue 支持代码
- [@motajs/system](../api/motajs-system) 渲染层系统代码
- [@motajs/system-action](../api/motajs-system-action) 渲染层交互系统代码
- [@motajs/system-ui](../api/motajs-system-ui) 渲染层 UI 系统代码
- [@motajs/types](../api/motajs-types) 渲染层类型代码
- [@user/client-modules](../api/user-client-modules) 用户渲染层主要代码
- [@user/data-base](../api/user-data-base) 用户数据层底层代码
- [@user/data-fallback](../api/user-data-fallback) 用户数据层向后兼容代码
- [@user/data-state](../api/user-data-state) 用户数据层状态代码
- [@user/data-utils](../api/user-data-utils) 用户数据层工具代码
- [@user/entry-client](../api/user-entry-client) 用户渲染层入口
- [@user/entry-data](../api/user-entry-data) 用户数据层入口
- [@user/legacy-plugin-client](../api/user-legacy-plugin-client) 用户遗留渲染层代码
- [@user/legacy-plugin-data](../api/user-legacy-plugin-data) 用户遗留数据层代码
## Mota 全局变量
@ -170,6 +170,10 @@ import { Patch } from '@motajs/legacy-common'; // 从样板库中引入接口
import { patchMyFunctions } from './override';
```
:::warning
注意,在之后的所有文档示例中,都会使用 `import xxx from '@xxx/xxx'` 的绝对路径形式作为示例,而不会使用相对路径,自己编写代码时请注意要引入的内容是否在当前模块(当前包)中,如果是,请使用相对路径,否则请使用绝对路径。
:::
然后是从当前模块导出内容:
```ts

View File

@ -8,7 +8,7 @@ hero:
tagline: HTML5魔塔样板从 2.x 到 3.0 的过渡版本
actions:
- theme: brand
text: 快速开始
text: 深度指南
link: /guide/diff
- theme: alt
text: API列表

212
docs/logger/error/error1.md Normal file
View File

@ -0,0 +1,212 @@
# 错误代码一览及其解决方案 1-50
## ERROR CODE 1
```txt
Unexpected error when posting danmaku. Error info: $1
```
- 报错原因:发送弹幕时发生报错。
- 解决方案:查看后面的 Error info检查报错信息内容按照报错信息修复问题。
## ERROR CODE 2
```txt
Unexpected loading error in loading resource '$1/$2'. Error info: $3
```
- 报错原因:加载资源时发生报错,可能是资源不存在,或者是网络问题。
- 解决方案:查看后面的 Error info检查报错信息内容按照报错信息修复问题。
## ERROR CODE 3
```txt
Syntax error in parsing CSS: Unexpected ':'. Col: $1. CSS string: '$2
```
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
## ERROR CODE 4
```txt
Syntax error in parsing CSS: Unexpected ';'. Col: $1. CSS string: '$2'
```
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
## ERROR CODE 5
```txt
Syntax error in parsing CSS: Missing property name after '-'. Col: $1. CSS string: '$2'
```
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
## ERROR CODE 6
```txt
Syntax error in parsing CSS: Unexpected end of css, expecting ':'. Col: $1. CSS string: '$2'
```
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
## ERROR CODE 7
```txt
Syntax error in parsing CSS: Unexpected end of css, expecting property value. Col: $1. CSS string: '$2'
```
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
## ERROR CODE 8
```txt
Post danmaku with not allowed css. Info: $1
```
- 报错原因:弹幕 CSS 中使用了不允许的 css 属性类型。
- 解决方案:目前仅支持 `color` `background-color` `font-size: x%` 属性。
## ERROR CODE 9
```txt
Cannot initialize shader program. Error info: $1
```
- 报错原因:不能够初始化着色器脚本,可能是着色器代码中有语法错误,或者是定义了不存在的变量等。
- 解决方案:查看报错内容,根据报错内容解决。
## ERROR CODE 10
```txt
Cannot compile $1 shader. Error info: $2
```
- 报错原因:不能编译着色器脚本,可能是语法错误,设备不支持 OpenGL 等原因。
- 解决方案:查看报错内容,根据报错内容解决。
## ERROR CODE 11
```txt
Cache depth cannot larger than 31.
```
- 报错原因:`BlockCache` 最大允许 31 层深度缓存。
- 解决方案:降低缓存深度。
## ERROR CODE 12
```txt
Cannot move while status is not 'moving'. Call 'readyMove' first.
```
- 报错原因:调用移动时没有调用 `readyMove` 准备移动。
- 解决方案:在移动前先调用 `readyMove`
## ERROR CODE 13
见 [CODE 10](#error-code-10)
## ERROR CODE 16
```txt
Cannot find log message for $1 code $2.
```
- 报错原因:不能找到错误代码 $2 的消息。
- 解决方案:避免使用 `logger` 输出不存在的错误代码。
## ERROR CODE 17
```txt
Cannot use shader program for shader element that does not belong to it.
```
- 报错原因:在一个着色器上使用了不属于这个着色器的着色器程序。
- 解决方案:确保使用的着色器程序是由着色器对象自身创建的。
## ERROR CODE 18
```txt
Cannot delete shader program for shader element that does not belong to
```
- 报错原因:在一个着色器上删除了不属于这个着色器的着色器程序。
- 解决方案:确保删除的着色器程序是由着色器对象自身创建的。
## ERROR CODE 19
```txt
Cannot create MotaRenderer instance for nonexistent canvas.
```
- 报错原因:在一个不存在的画布上创建了渲染器对象。
- 解决方案:确保目标画布存在。
## ERROR CODE 20
```txt
Cannot create render element for tag '$1', since there's no registration for it.
```
- 报错原因:不能创建 $1 标签,因为没有注册这个标签。
- 解决方案:确保你已经在 `tagMap` 注册了这个标签。
## ERROR CODE 21
```txt
Incorrect render prop type is delivered. key: '$1', expected type: '$2', delivered type: '$3'
```
- 报错原因向元素中传入了错误类型的参数props
- 解决方案:确保传入元素的 $1 参数的类型是 $2。
## ERROR CODE 22
```txt
Incorrect props for custom tag. Please ensure you have delivered 'item' prop and other required props.
```
- 报错原因:没有向 `cutsom` 标签传入 `item` 参数。
- 解决方案:确保传入了 `item` 参数和需要的所有参数。
## ERROR CODE 23
```txt
Cannot get reader when fetching '$1'.
```
- 报错原因:流式加载 URL $1 时不能获取 `StreamReader`
- 解决方案:检查加载的 URL 是否合法,检查浏览器版本是否过老。
## ERROR CODE 24
```txt
Cannot decode source type of '$1', since there is no registered decoder for that type.
```
- 报错原因:音频系统中的流式音频源不能解析 $1 格式的音频,因为没有对应的解码器。
- 解决方案:如果不是 `opus` `ogg` 格式的音频,请使用 `ElementSource`
## ERROR CODE 25
```txt
Unknown audio type. Header: '$1'
```
- 报错原因:未知的音频类型。
- 解决方案:目前仅支持 `mp3` `wav` `flac` `opus` `ogg` `aac` 格式的音频。
## ERROR CODE 26
```txt
Uncaught error when fetching stream data from '$1'. Error info: $2.
```
- 报错原因:流式加载时报错。
- 解决方案:查看报错内容,根据报错内容解决问题。

3
docs/logger/index.md Normal file
View File

@ -0,0 +1,3 @@
# 错误代码一览及解决方案
请在左侧导航栏查找你想查找的错误或警告代码。

445
docs/logger/warn/warn1.md Normal file
View File

@ -0,0 +1,445 @@
# 警告代码一览及其解决方案 1-50
## WARN CODE 1
```txt
Resource with type of 'none' is loaded.
```
- 警告原因:不能加载 `none` 类型的资源。
- 解决方案:加载资源时填写资源类型。
## WARN CODE 2
```txt
Repeat load of resource '$1/$2'.
```
- 警告原因:同一个资源被加载了两次。
- 解决方案:避免对同一个资源调用两次加载。
## WARN CODE 3
```txt
Unknown danmaku tag: $1
```
- 警告原因:出现了未知的弹幕标签(指 `[xxx:xxx]`
- 解决方案:目前仅支持 `[i:xxx]` 标签,如果需要显示方括号,请使用 `\[\]`
## WARN CODE 4
```txt
Ignored a mismatched ']' in danmaku.
```
- 警告原因:出现了不能匹配的右方括号。
- 解决方案:如果需要显示方括号,请使用 `\[\]`
## WARN CODE 5
```txt
Repeat post danmaku.
```
- 警告原因:同一个弹幕被发送了两次。
- 解决方案:确保一个弹幕实例只调用了一次 `post` 方法。
## WARN CODE 6
```txt
Registered special danmaku element: $1.
```
- 警告原因:要注册的弹幕标签已经存在。
- 解决方案:避免使用同一个标签名,如果内容不一样请换一个标签名。
## WARN CODE 7
参考 [CODE 3](#warn-code-3)
## WARN CODE 8
```txt
Incomplete render data is put. None will be filled to the lacked data.
```
- 警告原因:使用 `<layer>` 标签时,向地图渲染传入了不完整的地图信息(数据长度不是指定宽度的倍数),不完整的部分将会补零。
- 解决方案:确保传入的地图信息长度是 `width` 参数的倍数。
## WARN CODE 9
```txt
Data transfered is partially (or totally) out of range. Overflowed data will be ignored.
```
- 警告原因:使用 `<layer>` 标签时,传入地图的渲染数据有一部分(或全部都)在地图之外,在地图之外的部分将会被忽略。
- 解决方案:确保传入的地图信息没有在地图之外的部分。
## WARN CODE 10
```txt
Cannot resolve big image of enemy '$1'.
```
- 警告原因:无法解析怪物 $1 的大怪物贴图(绑定贴图),可能是因为图片不存在。
- 解决方案:确保此怪物绑定的贴图已经在全塔属性注册。
## WARN CODE 11
```txt
Cannot resolve material $1. Material not exists.
```
- 警告原因:不能解析指定类型 $1 的素材,因为对应的素材文件不存在。
- 解决方案:检查 `enemys.png` `npcs.png` 等素材文件是否存在。
## WARN CODE 12
```txt
Cannot mark buffable with a non-number status. Key: '$1'.
```
- 暂时碰不到这个报错。
## WARN CODE 13
```txt
Cannot set buff of non-number status. Key: '$1'.
```
- 暂时碰不到这个报错。
## WARN CODE 14
```txt
Cannot add status of non-number status. Key: '$1'.
```
- 暂时碰不到这个报错。
## WARN CODE 15
```txt
Cannot get item of a non-item block on loc: $1,$2,$3.
```
- 警告原因:不能获取一个不存在物品的图块上的物品对象。
- 解决方案:提前判断那一格是不是物品,或确保要获取的格子包含物品。
## WARN CODE 16
```txt
Override repeated state key: '$1'.
```
- 暂时碰不到这个报错。
## WARN CODE 17
```txt
Floor-damage extension needs 'floor-binder' extension as dependency.
```
- 警告原因:楼层伤害拓展需要以楼层绑定拓展作为依赖。
- 解决方案:确保添加伤害拓展时也添加了楼层绑定拓展。
## WARN CODE 18
```txt
Uncaught error in posting like info for danmaku. Danmaku id: $1.
```
- 警告原因:为弹幕点赞时出现报错。
- 解决方案:可能是网络问题,检查网络。
## WARN CODE 19
```txt
Repeat light id: '$1'
```
- 警告原因:重复的光源 id。
- 解决方案:避免光源 id 出现重复。
## WARN CODE 20
```txt
Cannot apply animation to camera operation that does not belong to it.
```
- 警告原因:不能向摄像机对象添加不属于它的动画操作。
- 解决方案:确保添加的动画操作是由这个摄像机对象创建的。
## WARN CODE 21
```txt
Cannot apply transition to camera operation that does not belong to it.
```
- 警告原因:不能向摄像机对象添加不属于它的渐变操作。
- 解决方案:确保添加的渐变操作是由这个摄像机对象创建的。
## WARN CODE 22
```txt
There is already an active camera for delivered render item. Consider using 'Camera.for' or disable the active camera to avoid some exceptions.
```
- 警告原因:在目标渲染元素上,现在已经有了一个已激活的摄像机对象,这可能导致两个摄像机操作冲突,产生问题。
- 解决方案:考虑使用 [`Camera.for`](../../api/motajs-render-elements/Camera.md#Camera.for) 方法,或先禁用已激活的摄像机,再使用当前摄像机
## WARN CODE 23
```txt
Render item with id of '$1' has already exists. Please avoid repeat id since it may cause issues when use 'getElementById'.
```
- 警告原因:两个渲染元素的 id 出现了重复,这会导致调用 `getElementById` 时出现问题。
- 解决方案:避免出现重复的 id。
## WARN CODE 24
```txt
Uniform block can only be used in glsl version es 300.
```
- 警告原因UBO(Uniform Block Object) 只能在 GLSL ES 300 版本的着色器脚本中使用。
- 解决方案:如果需要使用 UBO考虑换用 es 300 版本的着色器脚本。
## WARN CODE 25
```txt
Cannot activate weather since there's no weather with id of '$1'.
```
- 警告原因:不能启用不存在的天气类型。
- 解决方案:确保要启用的天气类型正确且存在,不存在则需要自行注册。
## WARN CODE 26
```txt
Cannot set attribute when only element number specified. Use 'pointer' or 'pointerI' instead.
```
- 警告原因:使用 `defineAttribute` 时指定了不存在的顶点属性类型。
- 解决方案:如果需要传递数组,考虑使用 `defineAttribArray` 而不是 `defineAttribute`
## WARN CODE 27
```txt
Cannot vertex attribute integer point when specified as float. Use 'set' or 'pointer' instead.
```
- 遇不到这个报错
## WARN CODE 28
```txt
Redefinition of shader $1: '$2'
```
- 警告原因:定义了重复的着色器变量/顶点属性/UBO 等。
- 解决方案:避免对同一个变量调用多次 `defineXxxx`
## WARN CODE 29
```txt
Cannot define new texture since texture index is larger than max texture count.
```
- 警告原因:定义的纹理数量超过了设备支持的上限。
- 解决方案:考虑将多个纹理合并为同一个纹理作为图集,然后使用顶点属性或一致变量进行裁剪。
## WARN CODE 30
```txt
Cannot use indices named $1 since no definition for it. Please define it in advance.
```
- 警告原因:要作为顶点索引的索引数组不存在,因为没有定义。
- 解决方案:提前定义索引数组。
## WARN CODE 31
```txt
Cannot use indices since the indices instance is not belong to the program.
```
- 警告原因:使用的顶点索引数组不属于当前着色器程序。
- 解决方案:确保使用的顶点索引数组是由当前着色器程序创建的。
## WARN CODE 32
```txt
Sub-image exceeds texture dimensions, auto adjusting size.
```
- 警告原因:使用 `IShaderTexture.sub` 时,传入的图像数据超出了纹理大小。
- 解决方案:确保传入的图片不会超出纹理大小。如果需要修改纹理大小,请使用 `IShaderTexture.set` 方法。
## WARN CODE 33
```txt
Cannot modify MotaOffscreenCanvas2D that is freezed.
```
- 警告原因:不能修改已冻结的画布属性。
- 解决方案:如果这个画布后续还需要修改属性,那么就不要冻结它。
## WARN CODE 34
```txt
Repeated render tag registration: '$1'.
```
- 警告原因:注册了重复的渲染标签。
- 解决方案:确保注册的渲染标签名称不重复。
## WARN CODE 35
```txt
Cannot append child on plain render item, please ensure you have overrided 'appendChild' method in your own element.
```
- 警告原因:默认的渲染元素中,只有一部分可以添加子元素,而其他的不能添加。
- 解决方案:不要在不能添加子元素的元素里面添加子元素。如果是自定义元素,请确保实现了 `appendChild` 方法。
## WARN CODE 36
```txt
Cannot remove child on plain render item, please ensure you have overrided 'removeChild' method in your own element.
```
- 警告原因:默认的渲染元素中,只有一部分可以移除子元素,而其他的不能移除。
- 解决方案:不要在不能移除子元素的元素里面移除子元素。如果是自定义元素,请确保实现了 `removeChild` 方法。
## WARN CODE 37
```txt
Cannot execute 'requestSort' on plain render item, please ensure you have overrided 'requestSort' method in your own element.
```
- 警告原因:默认的渲染元素中,只有一部分可以拥有排序功能,而其他的不能排序。
- 解决方案:不要在不能拥有子元素的元素上调用 `requestSort`。如果是自定义元素,请确保实现了 `requestSort` 方法。
## WARN CODE 38
```txt
Using plain text in jsx is strongly not recommended, since you can hardly modify its attributes. Consider using Text element instead.
```
- 警告原因:在 JSX 中直接填写文字内容是极其不推荐的,因为你几乎不能修改它的任何属性。
- 解决方案:考虑使用 `text` 标签替代。
## WARN CODE 39
```txt
Plain text is not supported outside Text element.
```
- 警告原因:不能在 `text` 元素外使用变量作为文字,例如:
```tsx
<container>{text.value}</container>
```
- 解决方案:换用 `text` 标签。
## WARN CODE 40
```txt
Cannot return canvas that is not provided by this pool.
```
- 遇不到这个报错。
## WARN CODE 41
```txt
Width of text content components must be positive. receive: $1
```
- 警告原因:`TextContent` 组件的宽度必须是正值,而你可能传入了一个负值或 0。
- 解决方案:确保宽度属性是正值。
## WARN CODE 42
```txt
Repeated Textbox id: '$1'.
```
- 警告原因:`Textbox` 组件使用了重复的 id。
- 解决方案:避免 `Textbox` 组件的 id 重复。
## WARN CODE 43
```txt
Cannot set icon of '$1', since it does not exists. Please ensure you have delivered correct icon id or number.
```
- 警告原因:向 `icon` 元素中传入了不存在的图标。
- 解决方案:确保传入的图标 id 或数字是正确的。
## WARN CODE 44
```txt
Unexpected end when loading stream audio, reason: '$1'
```
- 警告原因:加载流式音频时被意外中断。
- 解决方案:根据原因解决。
## WARN CODE 45
```txt
Audio route with id of '$1' has already existed. New route will override old route.
```
- 警告原因id 为 $1 的音频路由已经存在,新的路由将会覆盖旧路由。
- 解决方案:确保音频路由不会重复。
## WARN CODE 46
```txt
Cannot pipe new StreamReader object when stream is loading.
```
- 警告原因:在流式加载过程中无法将流加载对象泵入其他对象。
- 解决方案:在流式加载前就执行 `pipe` 方法。
## WARN CODE 47
```txt
Audio stream decoder for audio type '$1' has already existed.
```
- 警告原因:$1 类型的音频解码器已经存在。
- 解决方案:不要为同一种类型的音频注册多种解码器。
## WARN CODE 48
```txt
Sample rate in stream audio must be constant.
```
- 警告原因:流式音频中,音频的采样率应该保持一致。
- 解决方案:确保音频的采样率不会改变,如果会的话,请换一个音频。
## WARN CODE 49
```txt
Repeated patch for '$1', key: '$2'.
```
- 警告原因:对同一个 2.x 样板接口重写了两次。
- 解决方案:将两次重写合并为一次。
## WARN CODE 50
```txt
Unknown audio extension name: '$1'
```
- 警告原因:未知的文件拓展名 $1。
- 解决方案:换一个类型的音频。

118
docs/logger/warn/warn2.md Normal file
View File

@ -0,0 +1,118 @@
# 警告代码一览及其解决方案 51-100
## WARN CODE 51
```txt
Cannot decode sound '$1', since audio file may not supported by 2.b.
```
- 警告原因:不能解码音效 $1可能因为文件类型不支持。
- 解决方案:换一个音乐文件格式,建议使用 `opus` 格式。
## WARN CODE 52
```txt
Cannot play sound '$1', since there is no added data named it.
```
- 警告原因:播放了不存在的音效。
- 解决方案:确保要播放音效名称正确。
## WARN CODE 53
```txt
Cannot $1 audio route '$2', since there is not added route named it.
```
- 警告原因:不能对 $2 路由执行 $1播放、暂停等操作因为没有名字叫这个的音频路由。
- 解决方案:确保要操作的路由存在。
## WARN CODE 54
```txt
Missing start tag for '$1', index: $2.
```
- 警告原因:在 `TextContent` 组件中,匹配不到转义字符 $1 的起始位置。
- 解决方案:确保每个转义字符包含起始标签。
## WARN CODE 55
```txt
Unchildable tag '$1' should follow with param.
```
- 警告原因:在 `TextContent` 组件中,没有子标签的转义字符(`\i`)后面必须跟着参数。
- 解决方案:确保 `\i` 后面紧跟着图标名称,例如 `\i[greenSlime]`
## WARN CODE 56
```txt
Method '$1' has been deprecated. Consider using '$2' instead.
```
- 警告原因:接口 $1 已经弃用。
- 解决方案:考虑换为 $2。
## WARN CODE 57
```txt
Repeated UI controller id '$1'.
```
- 警告原因:重复的 UI 控制器 id。
- 解决方案:避免 UI 控制器的 id 重复。
## WARN CODE 58
```txt
Fail to set ellipse round rect, since length of 'ellipse' property should only be 2, 4, 6 or 8. delivered: $1
```
- 警告原因:椭圆模式的圆角矩形传入的参数数组需要是 2,4,6,8 长度,而传入了 $1 长度的数组。
- 解决方案:确保传入参数正确。
## WARN CODE 59
```txt
Unknown icon '$1' in parsing text content.
```
- 警告原因:在 `TextContent` 中出现了未知的图标。
- 解决方案:确保 `\i` 后的图标参数正确。
## WARN CODE 60
```txt
Repeated Tip id: '$1'.
```
- 警告原因:`Tip` 组件的 id 重复。
- 解决方案:避免 id 重复。
## WARN CODE 61
```txt
Unexpected recursive call of $1.update?$2 in render function. Please ensure you have to do this, if you do, ignore this warn.
```
- 警告原因:在渲染元素的渲染函数中出现了递归 `update` 调用,这会导致元素一直更新而且难以察觉,同时也会引起性能问题。
- 解决方案:避免在渲染函数中调用 `update` 方法。如果你必须这么做,请忽视这个警告。
## WARN CODE 62
```txt
Recursive fallback fonts in '$1'.
```
- 警告原因:字体回退出现了循环。例如 `font1` -> `font2` -> `font1`
- 解决方案:避免出现循环字体回退。
## WARN CODE 63
```txt
Uncaught promise error in waiting box component. Error reason: $1
```
- 警告原因:在等待 box 组件(选择框、确认框等)时,出现了异步报错。
- 解决方案:根据报错内容解决问题。

View File

@ -24,8 +24,8 @@
"@wasm-audio-decoders/ogg-vorbis": "^0.1.16",
"anon-tokyo": "0.0.0-alpha.0",
"ant-design-vue": "^3.2.20",
"axios": "^1.7.4",
"chart.js": "^4.4.3",
"axios": "^1.8.4",
"chart.js": "^4.4.8",
"codec-parser": "^2.5.0",
"eventemitter3": "^5.0.1",
"gl-matrix": "^3.4.3",
@ -38,49 +38,51 @@
"vue": "^3.5.13"
},
"devDependencies": {
"@babel/cli": "^7.24.8",
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/cli": "^7.26.4",
"@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^25.0.8",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-node-resolve": "^15.3.1",
"@rollup/plugin-replace": "^5.0.7",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@types/babel__core": "^7.20.5",
"@types/fontmin": "^0.9.4",
"@types/fontmin": "^0.9.5",
"@types/fs-extra": "^9.0.13",
"@types/lodash-es": "^4.17.12",
"@types/node": "^18.19.44",
"@types/ws": "^8.5.12",
"@vitejs/plugin-legacy": "^4.1.1",
"@vitejs/plugin-vue": "^4.6.2",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@types/node": "^18.19.80",
"@types/ws": "^8.18.0",
"@vitejs/plugin-legacy": "^6.0.2",
"@vitejs/plugin-vue": "^5.2.3",
"@vitejs/plugin-vue-jsx": "^4.1.2",
"chokidar": "^3.6.0",
"compressing": "^1.10.1",
"eslint": "^9.17.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.32.0",
"eslint": "^9.22.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-vue": "^9.33.0",
"fontmin": "^0.9.9",
"form-data": "^4.0.0",
"form-data": "^4.0.2",
"fs-extra": "^10.1.0",
"glob": "^11.0.1",
"globals": "^15.14.0",
"less": "^4.2.0",
"globals": "^15.15.0",
"less": "^4.2.2",
"madge": "^8.0.0",
"markdown-it-mathjax3": "^4.3.2",
"mermaid": "^11.5.0",
"postcss-preset-env": "^9.6.0",
"rollup": "^3.29.4",
"terser": "^5.31.6",
"tsx": "^4.17.0",
"typescript": "^5.5.4",
"typescript-eslint": "^8.18.2",
"rollup": "^3.29.5",
"terser": "^5.39.0",
"tsx": "^4.19.3",
"typescript": "^5.8.2",
"typescript-eslint": "^8.27.0",
"unplugin-vue-components": "^0.22.12",
"vite": "^4.5.9",
"vite-plugin-dts": "^4.4.0",
"vitepress": "^1.5.0",
"vue-tsc": "^2.1.6",
"ws": "^8.18.0"
"vite": "^6.2.2",
"vite-plugin-dts": "^4.5.3",
"vitepress": "^1.6.3",
"vitepress-plugin-mermaid": "^2.0.17",
"vue-tsc": "^2.2.8",
"ws": "^8.18.1"
}
}

View File

@ -12,7 +12,6 @@
"@motajs/system-ui": "workspace:*",
"@user/data-base": "workspace:*",
"@user/data-state": "workspace:*",
"@user/legacy-plugin-client": "workspace:*",
"@user/legacy-plugin-data": "workspace:*"
}
}
}

View File

@ -1,7 +1,7 @@
{
"error": {
"1": "Unexpected error when posting danmaku. Error info: $1",
"2": "Unexpected loading error in loading resource '$1/$2''. Error info: $3",
"2": "Unexpected loading error in loading resource '$1/$2'. Error info: $3",
"3": "Syntax error in parsing CSS: Unexpected ':'. Col: $1. CSS string: '$2'",
"4": "Syntax error in parsing CSS: Unexpected ';'. Col: $1. CSS string: '$2'",
"5": "Syntax error in parsing CSS: Missing property name after '-'. Col: $1. CSS string: '$2'",
@ -41,7 +41,7 @@
"7": "Unknown special danmaku element: '$1'.",
"8": "Incomplete render data is put. None will be filled to the lacked data.",
"9": "Data transfered is partially (or totally) out of range. Overflowed data will be ignored.",
"10": "Cannot resolve big image of enemy '$1;.",
"10": "Cannot resolve big image of enemy '$1'.",
"11": "Cannot resolve material $1. Material not exists.",
"12": "Cannot mark buffable with a non-number status. Key: '$1'.",
"13": "Cannot set buff of non-number status. Key: '$1'.",
@ -53,7 +53,7 @@
"19": "Repeat light id: '$1'.",
"20": "Cannot apply animation to camera operation that does not belong to it.",
"21": "Cannot apply transition to camera operation that does not belong to it.",
"22": "There is already an active camera for delivered render item. Consider using 'Camera.for' or diable the active camera to avoid some exceptions.",
"22": "There is already an active camera for delivered render item. Consider using 'Camera.for' or disable the active camera to avoid some exceptions.",
"23": "Render item with id of '$1' has already exists. Please avoid repeat id since it may cause issues when use 'getElementById'.",
"24": "Uniform block can only be used in glsl version es 300.",
"25": "Cannot activate weather since there's no weather with id of '$1'.",
@ -88,7 +88,7 @@
"54": "Missing start tag for '$1', index: $2.",
"55": "Unchildable tag '$1' should follow with param.",
"56": "Method '$1' has been deprecated. Consider using '$2' instead.",
"57": "Repeated UI controller on item '$1', new controller will not work.",
"57": "Repeated UI controller id '$1'.",
"58": "Fail to set ellipse round rect, since length of 'ellipse' property should only be 2, 4, 6 or 8. delivered: $1",
"59": "Unknown icon '$1' in parsing text content.",
"60": "Repeated Tip id: '$1'.",

File diff suppressed because it is too large Load Diff