├── .gitignore ├── ECS.ts ├── LICENSE ├── README.md ├── imgs ├── cc_inspector.png └── ecs_debug.png ├── jest.config.js ├── package-lock.json ├── package.json ├── test ├── comp.test.ts ├── ent.test.ts ├── matcher.test.ts └── register.test.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /ECS.ts: -------------------------------------------------------------------------------- 1 | // 重构原则:如无必要,勿增实体。 2 | export module ecs { 3 | export interface IComp { 4 | canRecycle: boolean; 5 | ent: Entity; 6 | 7 | reset(): void; 8 | } 9 | 10 | export interface CompCtor { 11 | new(): T; 12 | tid: number; 13 | compName: string; 14 | } 15 | 16 | /** 17 | * 组件里面只放数据可能在实际写代码的时候比较麻烦。如果是单纯对组件内的数据操作可以在组件里面写方法。 18 | */ 19 | export abstract class Comp implements IComp { 20 | /** 21 | * 组件的类型id,-1表示未给该组件分配id 22 | */ 23 | static tid: number = -1; 24 | static compName: string; 25 | /** 26 | * 拥有该组件的实体 27 | */ 28 | ent!: Entity; 29 | 30 | /** 31 | * 是否可回收组件对象,默认情况下都是可回收的。 32 | * 如果该组件对象是由ecs系统外部创建的,则不可回收,需要用户自己手动进行回收。 33 | */ 34 | canRecycle: boolean = true; 35 | 36 | /** 37 | * 组件被回收时会调用这个接口。可以在这里重置数据,或者解除引用。 38 | * 39 | * **不要偷懒,除非你能确定并保证组件在复用时,里面的数据是先赋值然后再使用。** 40 | */ 41 | abstract reset(): void; 42 | } 43 | 44 | //#region 类型声明 45 | 46 | type CompAddOrRemove = (entity: Entity) => void; 47 | 48 | export type CompType = CompCtor | number; 49 | //#endregion 50 | 51 | //#region 注册组件 52 | 53 | /** 54 | * 组件缓存池 55 | */ 56 | let compPools: Map = new Map(); 57 | 58 | /** 59 | * 组件类型id 60 | */ 61 | let compTid = 0; 62 | 63 | /** 64 | * 组件构造函数 65 | */ 66 | let compCtors: (CompCtor | number)[] = []; 67 | 68 | /** 69 | * 每个组件的添加和删除的动作都要派送到“关心”它们的group上。goup对当前拥有或者之前(删除前)拥有该组件的实体进行组件规则判断。判断该实体是否满足group 70 | * 所期望的组件组合。 71 | */ 72 | let compAddOrRemove: Map = new Map(); 73 | 74 | let tags: Map = new Map(); 75 | 76 | /** 77 | * 注册组件到ecs系统中 78 | * @param compName 由于js打包会改变类名,所以这里必须手动传入组件的名称。 79 | * @param canNew 标识是否可以new对象。想继承自Cocos Creator的组件就不能去new,需要写成@ecs.register('name', false) 80 | */ 81 | export function register(compName: string, canNew: boolean = true) { 82 | return function (ctor: CompCtor) { 83 | if (ctor.tid === -1) { 84 | ctor.tid = compTid++; 85 | ctor.compName = compName; 86 | if (canNew) { 87 | compCtors.push(ctor); 88 | compPools.set(ctor.tid, []); 89 | } 90 | else { 91 | compCtors.push(null); 92 | } 93 | compAddOrRemove.set(ctor.tid, []); 94 | } 95 | else { 96 | throw new Error(`重复注册组件: ${compName}.`); 97 | } 98 | } 99 | } 100 | 101 | /** 102 | * 添加tag 103 | * 104 | * eg. 105 | * @registerTag() 106 | * class Tag { 107 | * static A: number; 108 | * static B: number 109 | * } 110 | * @returns 111 | */ 112 | export function registerTag() { 113 | return function (_class: any) { 114 | let tid = compTid; 115 | for (let k in _class) { 116 | tid = compTid++; 117 | _class[k] = tid; 118 | compCtors.push(tid); 119 | compPools.set(tid, []); 120 | compAddOrRemove.set(tid, []); 121 | tags.set(tid, k); 122 | } 123 | } 124 | } 125 | //#endregion 126 | 127 | //#region context 128 | 129 | /** 130 | * 实体对象缓存池 131 | */ 132 | let entityPool: Entity[] = []; 133 | 134 | /** 135 | * 通过实体id查找实体对象 136 | */ 137 | let eid2Entity: Map = new Map(); 138 | 139 | /** 140 | * 缓存的group 141 | * 142 | * key是组件的筛选规则,一个筛选规则对应一个group 143 | */ 144 | let groups: Map = new Map(); 145 | 146 | /** 147 | * 实体自增id 148 | */ 149 | let eid = 1; 150 | 151 | /** 152 | * 创建实体 153 | */ 154 | export function createEntity(): E { 155 | let entity = entityPool.pop(); 156 | if (!entity) { 157 | entity = new Entity(); 158 | // @ts-ignore 159 | entity.eid = eid++; // 实体id也是有限的资源 160 | } 161 | eid2Entity.set(entity.eid, entity); 162 | return entity as E; 163 | } 164 | 165 | /** 166 | * 创建组件对象 167 | * @param ctor 168 | */ 169 | function createComp(ctor: CompCtor): T { 170 | if (!compCtors[ctor.tid]) { 171 | throw Error(`没有找到该组件的构造函数,检查${ctor.compName}是否为不可构造的组件`); 172 | } 173 | let component = compPools.get(ctor.tid)!.pop() || new (compCtors[ctor.tid] as CompCtor); 174 | return component as T; 175 | } 176 | 177 | /** 178 | * 指定一个组件创建实体,返回组件对象。 179 | * @param ctor 180 | */ 181 | export function createEntityWithComp(obj: T): Entity; 182 | export function createEntityWithComp(ctor: number): Entity; 183 | export function createEntityWithComp(ctor: CompType): T; 184 | // export function createEntityWithComp(ctor: CompCtor): T; 185 | // export function createEntityWithComp(ctor: CompType | T): T | Entity; 186 | export function createEntityWithComp(ctor: CompType): T | Entity { 187 | let entity = createEntity(); 188 | return entity.add(ctor); 189 | } 190 | 191 | /** 192 | * 指定多个组件创建实体,返回实体对象。 193 | * @param ctors 194 | */ 195 | export function createEntityWithComps(...ctors: CompType[]): E { 196 | let entity = createEntity(); 197 | entity.addComponents(...ctors); 198 | return entity as E; 199 | } 200 | 201 | /** 202 | * 销毁实体。 203 | * 204 | * 缓存销毁的实体,下次新建实体时会优先从缓存中拿。 205 | * @param entity 206 | */ 207 | function destroyEntity(entity: Entity) { 208 | if (eid2Entity.has(entity.eid)) { 209 | entityPool.push(entity); 210 | eid2Entity.delete(entity.eid); 211 | } 212 | else { 213 | console.warn('试图销毁不存在的实体!'); 214 | } 215 | } 216 | 217 | /** 218 | * 创建group,每个group只关心对应组件的添加和删除 219 | * @param matcher 实体筛选器 220 | */ 221 | export function createGroup(matcher: IMatcher): Group { 222 | let group = groups.get(matcher.mid); 223 | if (!group) { 224 | group = new Group(matcher); 225 | groups.set(matcher.mid, group); 226 | let careComponentTypeIds = matcher.indices; 227 | for (let i = 0; i < careComponentTypeIds.length; i++) { 228 | compAddOrRemove.get(careComponentTypeIds[i])!.push(group.onComponentAddOrRemove.bind(group)); 229 | } 230 | } 231 | return group as unknown as Group; 232 | } 233 | 234 | /** 235 | * 动态查询实体 236 | * @param matcher 237 | * @returns 238 | */ 239 | export function query(matcher: IMatcher): E[] { 240 | let group = groups.get(matcher.mid); 241 | if (!group) { 242 | group = createGroup(matcher); 243 | eid2Entity.forEach(group.onComponentAddOrRemove, group); 244 | } 245 | return group.matchEntities as E[]; 246 | } 247 | 248 | /** 249 | * 清理所有的实体 250 | */ 251 | export function clear() { 252 | eid2Entity.forEach((entity) => { 253 | entity.destroy(); 254 | }); 255 | groups.forEach((group) => { 256 | group.clear(); 257 | }); 258 | compAddOrRemove.forEach(callbackLst => { 259 | callbackLst.length = 0; 260 | }); 261 | eid2Entity.clear(); 262 | groups.clear(); 263 | } 264 | 265 | /** 266 | * 实体身上组件有增删操作,广播通知对应的观察者。 267 | * @param entity 实体对象 268 | * @param componentTypeId 组件类型id 269 | */ 270 | function broadcastCompAddOrRemove(entity: Entity, componentTypeId: number) { 271 | let events = compAddOrRemove.get(componentTypeId); 272 | for (let i = events!.length - 1; i >= 0; i--) { 273 | events![i](entity); 274 | } 275 | // 判断是不是删了单例组件 276 | if (tid2comp.has(componentTypeId)) { 277 | tid2comp.delete(componentTypeId); 278 | } 279 | } 280 | 281 | /** 282 | * 根据实体id获得实体对象 283 | * @param eid 284 | */ 285 | export function getEntityByEid(eid: number): E { 286 | return eid2Entity.get(eid) as E; 287 | } 288 | 289 | /** 290 | * 当前活动中的实体数量 291 | */ 292 | export function activeEntityCount() { 293 | return eid2Entity.size; 294 | } 295 | //#endregion 296 | 297 | 298 | /** 299 | * 表示只关心这些组件的添加和删除动作。虽然实体可能有这些组件之外的组件,但是它们的添加和删除没有被关注,所以不会存在对关注之外的组件 300 | * 进行添加操作引发Group重复添加实体。 301 | * @param args 302 | */ 303 | export function allOf(...args: CompType[]) { 304 | return new Matcher().allOf(...args); 305 | } 306 | 307 | /** 308 | * 组件间是或的关系,表示关注拥有任意一个这些组件的实体。 309 | * @param args 组件索引 310 | */ 311 | export function anyOf(...args: CompType[]) { 312 | return new Matcher().anyOf(...args); 313 | } 314 | 315 | /** 316 | * 表示关注只拥有这些组件的实体 317 | * 318 | * 注意: 319 | * 不是特殊情况不建议使用onlyOf。因为onlyOf会监听所有组件的添加和删除事件。 320 | * @param args 组件索引 321 | */ 322 | export function onlyOf(...args: CompType[]) { 323 | return new Matcher().onlyOf(...args); 324 | } 325 | 326 | /** 327 | * 不包含指定的任意一个组件 328 | * 329 | * eg. 330 | * ecs.excludeOf(A, B);表示不包含组件A或者组件B 331 | * @param args 332 | */ 333 | export function excludeOf(...args: CompType[]) { 334 | return new Matcher().excludeOf(...args); 335 | } 336 | 337 | //#region 单例组件 338 | let tid2comp: Map = new Map(); 339 | /** 340 | * 获取单例组件 341 | * @param ctor 组件类 342 | */ 343 | export function getSingleton(ctor: CompCtor) { 344 | if (!tid2comp.has(ctor.tid)) { 345 | let comp = createEntityWithComp(ctor) as T; 346 | tid2comp.set(ctor.tid, comp); 347 | } 348 | return tid2comp.get(ctor.tid) as T; 349 | } 350 | 351 | /** 352 | * 注册单例。主要用于那些不能手动创建对象的组件 353 | * @param obj 354 | */ 355 | export function addSingleton(obj: IComp) { 356 | let tid = (obj.constructor as CompCtor).tid; 357 | if (!tid2comp.has(tid)) { 358 | tid2comp.set(tid, obj); 359 | } 360 | } 361 | //#endregion 362 | 363 | class Mask { 364 | private mask: Uint32Array; 365 | private size: number = 0; 366 | 367 | constructor() { 368 | let length = Math.ceil(compTid / 31); 369 | this.mask = new Uint32Array(length); 370 | this.size = length; 371 | } 372 | 373 | set(num: number) { 374 | // https://stackoverflow.com/questions/34896909/is-it-correct-to-set-bit-31-in-javascript 375 | // this.mask[((num / 32) >>> 0)] |= ((1 << (num % 32)) >>> 0); 376 | this.mask[((num / 31) >>> 0)] |= (1 << (num % 31)); 377 | } 378 | 379 | delete(num: number) { 380 | this.mask[((num / 31) >>> 0)] &= ~(1 << (num % 31)); 381 | } 382 | 383 | has(num: number) { 384 | return !!(this.mask[((num / 31) >>> 0)] & (1 << (num % 31))); 385 | } 386 | 387 | or(other: Mask) { 388 | for (let i = 0; i < this.size; i++) { 389 | // &操作符最大也只能对2^30进行操作,如果对2^31&2^31会得到负数。当然可以(2^31&2^31) >>> 0,这样多了一步右移操作。 390 | if (this.mask[i] & other.mask[i]) { 391 | return true; 392 | } 393 | } 394 | return false; 395 | } 396 | 397 | and(other: Mask) { 398 | for (let i = 0; i < this.size; i++) { 399 | if ((this.mask[i] & other.mask[i]) != this.mask[i]) { 400 | return false; 401 | } 402 | } 403 | return true; 404 | } 405 | 406 | clear() { 407 | for (let i = 0; i < this.size; i++) { 408 | this.mask[i] = 0; 409 | } 410 | } 411 | } 412 | export class Entity { 413 | /** 414 | * 实体唯一标识,不要手动修改。 415 | */ 416 | public eid: number = -1; 417 | 418 | private mask = new Mask(); 419 | 420 | /** 421 | * 当前实体身上附加的组件构造函数 422 | */ 423 | private compTid2Ctor: Map> = new Map(); 424 | 425 | private compTid2Obj: Map = new Map(); 426 | 427 | constructor() { } 428 | 429 | /** 430 | * 根据组件id动态创建组件,并通知关心的系统。 431 | * 432 | * 如果实体存在了这个组件,那么会先删除之前的组件然后添加新的。 433 | * 434 | * 注意:不要直接new Component,new来的Component不会从Component的缓存池拿缓存的数据。 435 | * @param componentTypeId 组件id 436 | * @param isReAdd true-表示用户指定这个实体可能已经存在了该组件,那么再次add组件的时候会先移除该组件然后再添加一遍。false-表示不重复添加组件。 437 | */ 438 | add(obj: T): Entity; 439 | add(ctor: number, isReAdd?: boolean): Entity; 440 | // add(ctor: CompCtor, isReAdd?: boolean): T; 441 | add(ctor: CompType, isReAdd?: boolean): T; 442 | add(ctor: CompType | T, isReAdd: boolean = false): T | Entity { 443 | // console.log('typeof: ', typeof ctor); 444 | if (typeof ctor === 'function') { 445 | let compTid = ctor.tid; 446 | if (ctor.tid === -1) { 447 | throw Error('组件未注册!'); 448 | } 449 | if (this.compTid2Ctor.has(compTid)) {// 判断是否有该组件,如果有则先移除 450 | if (isReAdd) { 451 | this.remove(ctor); 452 | } 453 | else { 454 | console.log(`已经存在组件:${ctor.compName}`); 455 | // @ts-ignore 456 | return this[ctor.compName] as T; 457 | } 458 | } 459 | this.mask.set(compTid); 460 | 461 | let comp: T; 462 | if (this.compTid2Obj.has(compTid)) { 463 | comp = this.compTid2Obj.get(compTid) as T; 464 | this.compTid2Obj.delete(compTid); 465 | } 466 | else { 467 | // 创建组件对象 468 | comp = createComp(ctor) as T; 469 | } 470 | // 将组件对象直接附加到实体对象身上,方便直接获取。 471 | // @ts-ignore 472 | this[ctor.compName] = comp; 473 | this.compTid2Ctor.set(compTid, ctor); 474 | comp.ent = this; 475 | // 广播实体添加组件的消息 476 | broadcastCompAddOrRemove(this, compTid); 477 | 478 | return comp; 479 | } 480 | else if (typeof ctor === 'number') { 481 | if (tags.has(ctor)) { 482 | this.mask.set(ctor); 483 | this.compTid2Ctor.set(ctor, ctor); 484 | let tagName = tags.get(ctor)!; 485 | // @ts-ignore 486 | this[tagName] = ctor; 487 | broadcastCompAddOrRemove(this, ctor); 488 | } 489 | else { 490 | throw Error('不存在的tag!'); 491 | } 492 | return this; 493 | } 494 | else { 495 | let tmpCtor = (ctor.constructor as CompCtor); 496 | let compTid = tmpCtor.tid; 497 | // console.assert(compTid !== -1 || !compTid, '组件未注册!'); 498 | // console.assert(this.compTid2Ctor.has(compTid), '已存在该组件!'); 499 | if (compTid === -1 || compTid == null) { 500 | throw Error('组件未注册!'); 501 | } 502 | if (this.compTid2Ctor.has(compTid)) { 503 | throw Error('已经存在该组件!'); 504 | } 505 | 506 | this.mask.set(compTid); 507 | this[tmpCtor.compName] = ctor; 508 | this.compTid2Ctor.set(compTid, tmpCtor); 509 | ctor.ent = this; 510 | ctor.canRecycle = false; 511 | broadcastCompAddOrRemove(this, compTid); 512 | return this; 513 | } 514 | } 515 | 516 | addComponents(...ctors: CompType[]) { 517 | for (let ctor of ctors) { 518 | this.add(ctor); 519 | } 520 | return this; 521 | } 522 | 523 | get(ctor: number): number; 524 | get(ctor: CompCtor): T; 525 | get(ctor: CompCtor | number): T { 526 | let compName: string; 527 | if (typeof (ctor) === 'number') { 528 | compName = tags.get(ctor)!; 529 | } 530 | else { 531 | compName = ctor.compName; 532 | } 533 | // @ts-ignore 534 | return this[compName]; 535 | } 536 | 537 | has(ctor: CompType): boolean { 538 | if (typeof ctor == "number") { 539 | return this.mask.has(ctor); 540 | } 541 | else { 542 | return this.compTid2Ctor.has(ctor.tid); 543 | } 544 | } 545 | 546 | /** 547 | * 548 | * @param ctor 组件构造函数或者组件Tag 549 | * @param isRecycle 是否回收该组件对象。对于有些组件上有大量数据,当要描述移除组件但是不想清除组件上的数据是可以 550 | * 设置该参数为false,这样该组件对象会缓存在实体身上,下次重新添加组件时会将该组件对象添加回来,不会重新从组件缓存 551 | * 池中拿一个组件来用。 552 | */ 553 | remove(ctor: CompType, isRecycle: boolean = true) { 554 | let componentTypeId = -1; 555 | let compName = ''; 556 | let hasComp = false; 557 | if (typeof ctor === "number") { 558 | componentTypeId = ctor; 559 | if (this.mask.has(ctor)) { 560 | hasComp = true; 561 | compName = tags.get(ctor)!; 562 | } 563 | } 564 | else { 565 | componentTypeId = ctor.tid; 566 | compName = ctor.compName; 567 | if (this.mask.has(componentTypeId)) { 568 | hasComp = true; 569 | let comp = this[ctor.compName] as IComp; 570 | comp.ent = null; 571 | if (isRecycle) { 572 | comp.reset(); 573 | if (comp.canRecycle) { 574 | compPools.get(componentTypeId).push(comp); 575 | } 576 | } 577 | else { 578 | this.compTid2Obj.set(componentTypeId, comp); 579 | } 580 | } 581 | } 582 | 583 | if (hasComp) { 584 | this[compName] = null; 585 | this.mask.delete(componentTypeId); 586 | this.compTid2Ctor.delete(componentTypeId); 587 | broadcastCompAddOrRemove(this, componentTypeId); 588 | } 589 | } 590 | 591 | private _remove(comp: CompType) { 592 | this.remove(comp, false); 593 | } 594 | 595 | /** 596 | * 销毁实体,实体会被回收到实体缓存池中。 597 | */ 598 | destroy() { 599 | this.compTid2Ctor.forEach(this._remove, this); 600 | destroyEntity(this); 601 | this.compTid2Obj.clear(); 602 | } 603 | } 604 | 605 | export class Group { 606 | /** 607 | * 实体筛选规则 608 | */ 609 | private matcher: IMatcher; 610 | 611 | private _matchEntities: Map = new Map(); 612 | 613 | private _entitiesCache: E[] | null = null; 614 | 615 | /** 616 | * 符合规则的实体 617 | */ 618 | public get matchEntities() { 619 | if (this._entitiesCache === null) { 620 | this._entitiesCache = Array.from(this._matchEntities.values()); 621 | } 622 | return this._entitiesCache; 623 | } 624 | 625 | /** 626 | * 当前group中实体的数量。 627 | * 628 | * 不要手动修改这个属性值。 629 | */ 630 | public count = 0; // 其实可以通过this._matchEntities.size获得实体数量,但是需要封装get方法。为了减少一次方法的调用所以才直接创建一个count属性 631 | 632 | /** 633 | * 获取matchEntities中第一个实体 634 | */ 635 | get entity(): E { 636 | return this.matchEntities[0]; 637 | } 638 | 639 | private _enteredEntities: Map | null = null; 640 | private _removedEntities: Map | null = null; 641 | 642 | constructor(matcher: IMatcher) { 643 | this.matcher = matcher; 644 | } 645 | 646 | public onComponentAddOrRemove(entity: E) { 647 | if (this.matcher.isMatch(entity)) { // Group只关心指定组件在实体身上的添加和删除动作。 648 | this._matchEntities.set(entity.eid, entity); 649 | this._entitiesCache = null; 650 | this.count++; 651 | 652 | if (this._enteredEntities) { 653 | this._enteredEntities.set(entity.eid, entity); 654 | this._removedEntities!.delete(entity.eid); 655 | } 656 | } 657 | else if (this._matchEntities.has(entity.eid)) { // 如果Group中有这个实体,但是这个实体已经不满足匹配规则,则从Group中移除该实体 658 | this._matchEntities.delete(entity.eid); 659 | this._entitiesCache = null; 660 | this.count--; 661 | 662 | if (this._enteredEntities) { 663 | this._enteredEntities.delete(entity.eid); 664 | this._removedEntities!.set(entity.eid, entity); 665 | } 666 | } 667 | } 668 | 669 | public watchEntityEnterAndRemove(enteredEntities: Map, removedEntities: Map) { 670 | this._enteredEntities = enteredEntities; 671 | this._removedEntities = removedEntities; 672 | } 673 | 674 | clear() { 675 | this._matchEntities.clear(); 676 | this._entitiesCache = null; 677 | this.count = 0; 678 | this._enteredEntities?.clear(); 679 | this._removedEntities?.clear(); 680 | } 681 | } 682 | 683 | abstract class BaseOf { 684 | protected mask = new Mask(); 685 | public indices: number[] = []; 686 | constructor(...args: CompType[]) { 687 | let componentTypeId = -1; 688 | let len = args.length; 689 | for (let i = 0; i < len; i++) { 690 | if (typeof (args[i]) === "number") { 691 | componentTypeId = args[i] as number; 692 | } 693 | else { 694 | componentTypeId = (args[i] as CompCtor).tid; 695 | } 696 | if (componentTypeId == -1) { 697 | throw Error('存在没有注册的组件!'); 698 | } 699 | this.mask.set(componentTypeId); 700 | 701 | if (this.indices.indexOf(componentTypeId) < 0) { // 去重 702 | this.indices.push(componentTypeId); 703 | } 704 | } 705 | if (len > 1) { 706 | this.indices.sort((a, b) => { return a - b; }); // 对组件类型id进行排序,这样关注相同组件的系统就能共用同一个group 707 | } 708 | } 709 | 710 | public toString(): string { 711 | return this.indices.join('-'); // 生成group的key 712 | } 713 | 714 | public abstract getKey(): string; 715 | 716 | public abstract isMatch(entity: Entity): boolean; 717 | } 718 | 719 | /** 720 | * 用于描述包含任意一个这些组件的实体 721 | */ 722 | class AnyOf extends BaseOf { 723 | public isMatch(entity: Entity): boolean { 724 | // @ts-ignore 725 | return this.mask.or(entity.mask); 726 | } 727 | 728 | getKey(): string { 729 | return 'anyOf:' + this.toString(); 730 | } 731 | } 732 | 733 | /** 734 | * 用于描述包含了“这些”组件的实体,这个实体除了包含这些组件还可以包含其他组件 735 | */ 736 | class AllOf extends BaseOf { 737 | public isMatch(entity: Entity): boolean { 738 | // @ts-ignore 739 | return this.mask.and(entity.mask); 740 | } 741 | 742 | getKey(): string { 743 | return 'allOf:' + this.toString(); 744 | } 745 | } 746 | 747 | /** 748 | * 不包含指定的任意一个组件 749 | */ 750 | class ExcludeOf extends BaseOf { 751 | 752 | public getKey(): string { 753 | return 'excludeOf:' + this.toString(); 754 | } 755 | 756 | public isMatch(entity: Entity): boolean { 757 | // @ts-ignore 758 | return !this.mask.or(entity.mask); 759 | } 760 | } 761 | 762 | export interface IMatcher { 763 | mid: number; 764 | indices: number[]; 765 | key: string; 766 | isMatch(entity: Entity): boolean; 767 | } 768 | 769 | let macherId: number = 1; 770 | 771 | /** 772 | * 筛选规则间是“与”的关系 773 | * 比如:ecs.Macher.allOf(...).excludeOf(...)表达的是allOf && excludeOf,即实体有“这些组件” 并且 “没有这些组件” 774 | */ 775 | class Matcher implements IMatcher { 776 | protected rules: BaseOf[] = []; 777 | protected _indices: number[] | null = null; 778 | public isMatch!: (entity: Entity) => boolean; 779 | public mid: number = -1; 780 | 781 | private _key: string | null = null; 782 | public get key(): string { 783 | if (!this._key) { 784 | let s = ''; 785 | for (let i = 0; i < this.rules.length; i++) { 786 | s += this.rules[i].getKey() 787 | if (i < this.rules.length - 1) { 788 | s += ' && ' 789 | } 790 | } 791 | this._key = s; 792 | } 793 | return this._key; 794 | } 795 | 796 | constructor() { 797 | this.mid = macherId++; 798 | } 799 | 800 | /** 801 | * 匹配器关注的组件索引。在创建Group时,Context根据组件id去给Group关联组件的添加和移除事件。 802 | */ 803 | public get indices() { 804 | if (this._indices === null) { 805 | this._indices = []; 806 | this.rules.forEach((rule) => { 807 | Array.prototype.push.apply(this._indices, rule.indices); 808 | }); 809 | } 810 | return this._indices; 811 | } 812 | 813 | /** 814 | * 组件间是或的关系,表示关注拥有任意一个这些组件的实体。 815 | * @param args 组件索引 816 | */ 817 | public anyOf(...args: CompType[]): Matcher { 818 | this.rules.push(new AnyOf(...args)); 819 | this.bindMatchMethod(); 820 | return this; 821 | } 822 | 823 | /** 824 | * 组件间是与的关系,表示关注拥有所有这些组件的实体。 825 | * @param args 组件索引 826 | */ 827 | public allOf(...args: CompType[]): Matcher { 828 | this.rules.push(new AllOf(...args)); 829 | this.bindMatchMethod(); 830 | return this; 831 | } 832 | 833 | /** 834 | * 表示关注只拥有这些组件的实体 835 | * 836 | * 注意: 837 | * 不是特殊情况不建议使用onlyOf。因为onlyOf会监听所有组件的添加和删除事件。 838 | * @param args 组件索引 839 | */ 840 | public onlyOf(...args: CompType[]): Matcher { 841 | this.rules.push(new AllOf(...args)); 842 | let otherTids: CompType[] = []; 843 | for (let ctor of compCtors) { 844 | if (args.indexOf(ctor) < 0) { 845 | otherTids.push(ctor); 846 | } 847 | } 848 | this.rules.push(new ExcludeOf(...otherTids)); 849 | this.bindMatchMethod(); 850 | return this; 851 | } 852 | 853 | /** 854 | * 不包含指定的任意一个组件 855 | * @param args 856 | */ 857 | public excludeOf(...args: CompType[]) { 858 | this.rules.push(new ExcludeOf(...args)); 859 | this.bindMatchMethod(); 860 | return this; 861 | } 862 | 863 | private bindMatchMethod() { 864 | if (this.rules.length === 1) { 865 | this.isMatch = this.isMatch1; 866 | } 867 | else if (this.rules.length === 2) { 868 | this.isMatch = this.isMatch2; 869 | } 870 | else { 871 | this.isMatch = this.isMatchMore; 872 | } 873 | } 874 | 875 | private isMatch1(entity: Entity): boolean { 876 | return this.rules[0].isMatch(entity); 877 | } 878 | 879 | private isMatch2(entity: Entity): boolean { 880 | return this.rules[0].isMatch(entity) && this.rules[1].isMatch(entity); 881 | } 882 | 883 | private isMatchMore(entity: Entity): boolean { 884 | for (let rule of this.rules) { 885 | if (!rule.isMatch(entity)) { 886 | return false; 887 | } 888 | } 889 | return true; 890 | } 891 | 892 | public clone(): Matcher { 893 | let newMatcher = new Matcher(); 894 | newMatcher.mid = macherId++; 895 | this.rules.forEach(rule => newMatcher.rules.push(rule)); 896 | return newMatcher; 897 | } 898 | } 899 | 900 | //#region System 901 | /** 902 | * 如果需要监听实体首次进入System的情况,实现这个接口。 903 | * 904 | * entityEnter会在update方法之前执行,实体进入后,不会再次进入entityEnter方法中。 905 | * 当实体从当前System移除,下次再次符合条件进入System也会执行上述流程。 906 | */ 907 | export interface IEntityEnterSystem { 908 | entityEnter(entities: E[]): void; 909 | } 910 | 911 | /** 912 | * 如果需要监听实体从当前System移除,需要实现这个接口。 913 | */ 914 | export interface IEntityRemoveSystem { 915 | entityRemove(entities: E[]): void; 916 | } 917 | 918 | /** 919 | * 第一次执行update 920 | */ 921 | export interface ISystemFirstUpdate { 922 | firstUpdate(entities: E[]): void; 923 | } 924 | 925 | export abstract class ComblockSystem { 926 | protected group: Group; 927 | protected dt: number = 0; 928 | 929 | private enteredEntities: Map | null = null; 930 | private removedEntities: Map | null = null; 931 | 932 | private hasEntityEnter: boolean = false; 933 | private hasEntityRemove: boolean = false; 934 | 935 | private tmpExecute: ((dt: number) => void) | null = null; 936 | private execute!: (dt: number) => void; 937 | 938 | constructor() { 939 | let hasOwnProperty = Object.hasOwnProperty; 940 | let prototype = Object.getPrototypeOf(this); 941 | let hasEntityEnter = hasOwnProperty.call(prototype, 'entityEnter'); 942 | let hasEntityRemove = hasOwnProperty.call(prototype, 'entityRemove'); 943 | let hasFirstUpdate = hasOwnProperty.call(prototype, 'firstUpdate'); 944 | 945 | this.hasEntityEnter = hasEntityEnter; 946 | this.hasEntityRemove = hasEntityRemove; 947 | 948 | if (hasEntityEnter || hasEntityRemove) { 949 | this.enteredEntities = new Map(); 950 | this.removedEntities = new Map(); 951 | 952 | this.execute = this.execute1; 953 | this.group = createGroup(this.filter()); 954 | this.group.watchEntityEnterAndRemove(this.enteredEntities, this.removedEntities); 955 | } 956 | else { 957 | this.execute = this.execute0; 958 | this.group = createGroup(this.filter()); 959 | } 960 | 961 | if (hasFirstUpdate) { 962 | this.tmpExecute = this.execute; 963 | this.execute = this.updateOnce; 964 | } 965 | } 966 | 967 | init(): void { 968 | 969 | } 970 | 971 | onDestroy(): void { 972 | 973 | } 974 | 975 | hasEntity(): boolean { 976 | return this.group.count > 0; 977 | } 978 | 979 | private updateOnce(dt: number) { 980 | if (this.group.count === 0) { 981 | return; 982 | } 983 | this.dt = dt; 984 | // 处理刚进来的实体 985 | if (this.enteredEntities!.size > 0) { 986 | (this as unknown as IEntityEnterSystem).entityEnter(Array.from(this.enteredEntities!.values()) as E[]); 987 | this.enteredEntities!.clear(); 988 | } 989 | (this as unknown as ISystemFirstUpdate).firstUpdate(this.group.matchEntities); 990 | this.execute = this.tmpExecute!; 991 | this.execute(dt); 992 | this.tmpExecute = null; 993 | } 994 | 995 | /** 996 | * 只执行update 997 | * @param dt 998 | * @returns 999 | */ 1000 | private execute0(dt: number): void { 1001 | if (this.group.count === 0) { 1002 | return; 1003 | } 1004 | this.dt = dt; 1005 | this.update(this.group.matchEntities); 1006 | } 1007 | 1008 | /** 1009 | * 先执行entityRemove,再执行entityEnter,最后执行update。 1010 | * @param dt 1011 | * @returns 1012 | */ 1013 | private execute1(dt: number): void { 1014 | if (this.removedEntities!.size > 0) { 1015 | if (this.hasEntityRemove) { 1016 | (this as unknown as IEntityRemoveSystem).entityRemove(Array.from(this.removedEntities!.values()) as E[]); 1017 | } 1018 | this.removedEntities!.clear(); 1019 | } 1020 | if (this.group.count === 0) { 1021 | return; 1022 | } 1023 | this.dt = dt; 1024 | // 处理刚进来的实体 1025 | if (this.enteredEntities!.size > 0) { 1026 | if (this.hasEntityEnter) { 1027 | (this as unknown as IEntityEnterSystem).entityEnter(Array.from(this.enteredEntities!.values()) as E[]); 1028 | } 1029 | this.enteredEntities!.clear(); 1030 | } 1031 | this.update(this.group.matchEntities as E[]); 1032 | } 1033 | 1034 | /** 1035 | * 实体过滤规则 1036 | * 1037 | * 根据提供的组件过滤实体。 1038 | */ 1039 | abstract filter(): IMatcher; 1040 | abstract update(entities: E[]): void; 1041 | } 1042 | 1043 | /** 1044 | * System的root,对游戏中的System遍历从这里开始。 1045 | * 1046 | * 一个System组合中只能有一个RootSystem,可以有多个并行的RootSystem。 1047 | */ 1048 | export class RootSystem { 1049 | private executeSystemFlows: ComblockSystem[] = []; 1050 | private systemCnt: number = 0; 1051 | 1052 | add(system: System | ComblockSystem) { 1053 | if (system instanceof System) { 1054 | // 将嵌套的System都“摊平”,放在根System中进行遍历,减少execute的频繁进入退出。 1055 | Array.prototype.push.apply(this.executeSystemFlows, system.comblockSystems); 1056 | } 1057 | else { 1058 | this.executeSystemFlows.push(system as ComblockSystem); 1059 | } 1060 | this.systemCnt = this.executeSystemFlows.length; 1061 | return this; 1062 | } 1063 | 1064 | init() { 1065 | this.executeSystemFlows.forEach(sys => sys.init()); 1066 | } 1067 | 1068 | execute(dt: number) { 1069 | for (let i = 0; i < this.systemCnt; i++) { 1070 | // @ts-ignore 1071 | this.executeSystemFlows[i].execute(dt); 1072 | } 1073 | } 1074 | 1075 | clear() { 1076 | this.executeSystemFlows.forEach(sys => sys.onDestroy()); 1077 | } 1078 | } 1079 | 1080 | /** 1081 | * 系统组合器,用于将多个相同功能模块的系统逻辑上放在一起。System也可以嵌套System。 1082 | */ 1083 | export class System { 1084 | private _comblockSystems: ComblockSystem[] = []; 1085 | get comblockSystems() { 1086 | return this._comblockSystems; 1087 | } 1088 | 1089 | add(system: System | ComblockSystem) { 1090 | if (system instanceof System) { 1091 | Array.prototype.push.apply(this._comblockSystems, system._comblockSystems); 1092 | system._comblockSystems.length = 0; 1093 | } 1094 | else { 1095 | this._comblockSystems.push(system as ComblockSystem); 1096 | } 1097 | return this; 1098 | } 1099 | } 1100 | //#endregion 1101 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 shangdibaozi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 这是一个Typescript语言版的Entity-Component-System框架。框架参考了Unity的[Entitas](https://github.com/sschmid/Entitas-CSharp)框架。 3 | 4 | # 案例 5 | 【[Crimsonland](https://github.com/shangdibaozi/Crimsonland)】 6 | 7 | 【[InfinityWar](https://github.com/shangdibaozi/InfinityWar)】 8 | 9 | # 使用说明 10 | ## 组件 11 | 自定义组件必须继承ecs.Comp,并且需要使用ecs.register注册组件。 12 | ```TypeScript 13 | @ecs.register('Hello') 14 | export class HelloComponent extends ecs.Comp { 15 | info: string; 16 | data: number; 17 | 18 | // 组件被回收前会调用这个方法。 19 | reset() { 20 | this.info = ''; 21 | this.data = 0; 22 | } 23 | } 24 | ``` 25 | 26 | tag类组件 27 | ```Typescript 28 | @ecs.registerTag() 29 | export class ECSTag { 30 | static Tag1: number; 31 | static Tag2: number; 32 | static tag3: number; 33 | } 34 | 35 | // 相关使用方法 36 | ecs.createEntityWithComps(Comp1, ECSTag.Tag1) 37 | 38 | ent.has(ECSTag.Tag1) 39 | 40 | ent.add(ECSTag.Tag2) 41 | 42 | ent.remove(ECSTag.Tag2) 43 | ``` 44 | 45 | ## ecs.register功能 46 | - 能通过```entity.Hello```获得组件对象; 47 | - 将组件的构造函数存入ecs上下文中,并且给该类组件分配一个组件id。 48 | 49 | ## ecs.registerTag 50 | - tag类组件必须用registerTag来装饰 51 | 52 | ## 实体 53 | 为了能利用Typescript的类型提示机制,在使用实体的时候需要用户自己继承ecs.Entity。 54 | ```TypeScript 55 | export class HelloEntity extends ecs.Entity { 56 | Hello: HelloComponent; // 这里的Hello要和ecs.register中填入的参数一致 57 | } 58 | ``` 59 | 60 | - 添加组件: 61 | ```TypeScript 62 | entity.add(HelloComponent); // 添加组件时会优先从组件缓存池中获取无用的组件对象,如果没有才会新创建一个组件对象 63 | ``` 64 | 65 | - 添加组件对象:注意,外部创建的组件对象ecs系统不负责回收,需要用户自己管理该组件对象的生命周期。 66 | ```Typescript 67 | let compObj = new HelloComponent(); 68 | entity.add(compObj) 69 | ``` 70 | 71 | - 删除组件: 72 | ```TypeScript 73 | entity.remove(HelloComponent); // 组件对象会从实体身上移除并放入组件缓存池中 74 | ``` 75 | 76 | - 删除组件但不删除组件对象:实际开发中,组件身上有很多属性,如果删除了后面再添加,属性值还原是个麻烦的问题, 77 | remove方法可以删除组件,但是不真正从实体身上移除该组件对象,这样下次重新添加组件时还是会添加那个组件对象。 78 | ```Typescript 79 | entity.remove(HelloComponent, false) 80 | ``` 81 | 82 | - 获得组件对象 83 | ```TypeScript 84 | 1、entity.Hello; // 见上方自定义实体操作 85 | 86 | 2、entity.get(HelloComponent); 87 | ``` 88 | 89 | - 判断是否拥有组件: 90 | ```TypeScript 91 | 1、entity.has(HelloComponent); 92 | 93 | 2、!!entity.Hello; 94 | ``` 95 | 96 | - 销毁实体: 97 | ```TypeScript 98 | entity.destroy() // 销毁实体时会先删除实体身上的所有组件,然后将实体放入实体缓存池中 99 | ``` 100 | 101 | ## 实体筛选 102 | 目前提供了四种类型的筛选能力,但是这四种筛选能力可以组合从而提供更强大的筛选功能。 103 | - anyOf: 用来描述包含任意一个这些组件的实体; 104 | - allOf: 用来描述同时包含了这些组件的实体; 105 | - onlyOf: 用来描述只包含了这些组件的实体;不是特殊情况不建议使用onlyOf,因为onlyOf会监听所有组件的添加和删除事件; 106 | - excludeOf: 表示不包含所有这里面的组件(“与”关系); 107 | 108 | 使用方式: 109 | 110 | - 表示同时拥有多个组件 111 | ```TypeScript 112 | ecs.allOf(AComponent, BComponent, CComponent); 113 | ``` 114 | - 表示拥有任意一个组件 115 | ```Typescript 116 | ecs.anyOf(AComponent, BComponent); 117 | ``` 118 | - 表示拥有某些组件,并且不包含某些组件 119 | ```Typescript 120 | // 不包含CComponent或者DComponent 121 | ecs.allOf(AComponent, BComponent).excludeOf(CComponent, DComponent); 122 | 123 | // 不同时包含CComponent和DComponent 124 | ecs.allOf(AComponent, BComponent).excludeOf(CComponent).excludeOf(DComponent); 125 | ``` 126 | 127 | ### 直接查询并获得实体 128 | ```Typescript 129 | ecs.query(ecs.allOf(Comp1, Comp2)) 130 | ``` 131 | 132 | ## 系统 133 | - ecs.System: 用来组合某一功能所包含的System; 134 | - ecs.RootSystem: System的root; 135 | - ecs.ComblockSystem: 抽象类,组合式的System。默认情况,如果该System有实体,则每帧都会执行update方法; 136 | - ecs.IEntityEnterSystem: 实现这个接口表示关注实体的首次进入; 137 | - ecs.IEntityRemoveSystem: 实现这个接口表示关注实体的移除; 138 | - ecs.ISystemFirstUpdate: 实现这个接口会在System第一次执行update前执行一次firstUpdate 139 | 140 | # 怎么使用 141 | 1、声明组件 142 | ```TypeScript 143 | @ecs.register('Node') 144 | export class NodeComponent extends ecs.Comp { 145 | val: cc.Node = null; 146 | 147 | reset() { 148 | this.val = null; 149 | } 150 | } 151 | 152 | @ecs.reigster('Move') 153 | export class MoveComponent extends ecs.Comp { 154 | heading: cc.Vec2 = cc.v2(); 155 | speed: number = 0; 156 | 157 | reset() { 158 | this.heading.x = 0; 159 | this.heading.y = 0; 160 | this.speed = 0; 161 | } 162 | } 163 | 164 | @ecs.register('Transform') 165 | export class TransformComponent extends ecs.Comp { 166 | position: cc.Vec2 = cc.v2(); 167 | angle: number; 168 | reset() { 169 | 170 | } 171 | } 172 | 173 | export class AvatarEntity extends ecs.Entity { 174 | Node: NodeComponent; 175 | Move: MoveComponent; 176 | Transform: TransformComponent; 177 | } 178 | ``` 179 | 180 | 2、创建系统 181 | ```TypeScript 182 | export class RoomSystem extends ecs.RootSystem { 183 | constructor() { 184 | super(); 185 | this.add(new MoveSystem()); 186 | this.add(new RenderSystem()); 187 | } 188 | } 189 | 190 | export class MoveSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem { 191 | 192 | init() { 193 | 194 | } 195 | 196 | filter(): ecs.IMatcher { 197 | return ecs.allOf(MoveComponent, TransformComponent); 198 | } 199 | 200 | // 实体第一次进入MoveSystem会进入此方法 201 | entityEnter(entities: AvatarEntity[]) { 202 | for(e of entities) { 203 | e.Move.speed = 100; 204 | } 205 | } 206 | 207 | // 每帧都会更新 208 | update(entities: AvatarEntity[]) { 209 | for(let e of entities) { 210 | let moveComp = e.Move; // e.get(MoveComponent); 211 | lel position = e.Transform.position; 212 | 213 | position.x += moveComp.heading.x * moveComp.speed * this.dt; 214 | position.y += moveComp.heading.y * moveComp.speed * this.dt; 215 | 216 | e.Transform.angle = cc.misc.lerp(e.Transform.angle, Math.atan2(moveComp.speed.y, moveComp.speed.x) * cc.macro.DEG, dt); 217 | } 218 | } 219 | } 220 | 221 | export class RenderSystem extends.ecs.ComblockSystem implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem { 222 | filter(): ecs.IMatcher { 223 | return ecs.allOf(NodeComponent, TransformComponent); 224 | } 225 | 226 | // 实体第一次进入MoveSystem会进入此方法 227 | entityEnter(entities: AvatarEntity[]) { 228 | for(e of entities) { 229 | e.Node.val.active = true; 230 | } 231 | } 232 | 233 | entityRemove(entities: AvatarEntity[]) { 234 | for(let e of entities) { 235 | // Global.avatarNodePool.put(e.Node.val); 236 | } 237 | } 238 | 239 | update(entities: AvatarEntity[]) { 240 | for(let e of entities) { 241 | e.Node.val.setPosition(e.Transform.position); 242 | e.Node.val.angle = e.Transform.angle; 243 | } 244 | } 245 | } 246 | ``` 247 | 248 | 3、驱动ecs框架 249 | ```TypeScript 250 | const { ccclass, property } = cc._decorator; 251 | @ccclass 252 | export class GameControllerBehaviour extends cc.Component { 253 | rootSystem: RootSystem = null; 254 | 255 | onLoad() { 256 | this.rootSystem = new RootSystem(); 257 | this.rootSystem.init(); 258 | } 259 | 260 | createAvatar(node: cc.Node) { 261 | let entity = ecs.createEntityWithComps(NodeComponent, TransformComponent, MoveComponent); 262 | entity.Node.val = node; 263 | // entity.Move.speed = 100; 264 | } 265 | 266 | update(dt: number) { 267 | this.rootSystem.execute(dt); 268 | } 269 | } 270 | 271 | ``` 272 | 273 | # 和Cocos Creator的组件混合使用 274 | ## 创建基类 275 | ```Typescript 276 | import { Component, _decorator } from "cc"; 277 | import { ecs } from "../../../Libs/ECS"; 278 | const { ccclass, property } = _decorator; 279 | 280 | @ccclass('CCComp') 281 | export abstract class CCComp extends Component implements ecs.IComp { 282 | 283 | static tid: number = -1; 284 | static compName: string; 285 | 286 | canRecycle: boolean; 287 | ent: ecs.Entity; 288 | 289 | onLoad() { 290 | this.ent = ecs.createEntity(); 291 | this.ent.add(this); 292 | } 293 | 294 | abstract reset(): void; 295 | } 296 | ``` 297 | 298 | ## 创建ecs组件并且赋予序列化的功能,这样就能在Cocos Creator的“属性检查器”上修改参数 299 | ```Typescript 300 | import { _decorator, toDegree, v3, Node, Vec3 } from "cc"; 301 | import { ecs } from "../../../Libs/ECS"; 302 | const { ccclass, property } = _decorator; 303 | 304 | let outV3 = v3(); 305 | @ccclass('MovementComponent') 306 | @ecs.register('Movement') 307 | export class MovementComponent extends ecs.Comp { 308 | pos: Vec3 = v3(); 309 | angle: number = 0; 310 | speed: number = 0; 311 | 312 | @property 313 | acceleration: number = 0; 314 | 315 | @property 316 | private _maxSpeed: number = 0; 317 | @property 318 | set maxSpeed(val: number) { 319 | this._maxSpeed = val; 320 | } 321 | get maxSpeed() { 322 | return this._maxSpeed; 323 | } 324 | 325 | @property 326 | heading: Vec3 = v3(); 327 | 328 | @property 329 | targetHeading: Vec3 = v3(); 330 | 331 | reset() { 332 | 333 | } 334 | 335 | update(dt: number) { 336 | if(!Vec3.equals(this.heading, this.targetHeading, 0.01)) { 337 | Vec3.subtract(outV3, this.targetHeading, this.heading); 338 | outV3.multiplyScalar(0.025); 339 | this.heading.add(outV3); 340 | this.heading.normalize(); 341 | this.angle = toDegree(Math.atan2(this.heading.y, this.heading.x)) - 90; 342 | } 343 | 344 | this.speed = Math.min(this.speed + this.acceleration * dt, this._maxSpeed); 345 | 346 | this.pos.add3f(this.heading.x * this.speed * dt, this.heading.y * this.speed * dt, 0); 347 | } 348 | 349 | calcAngle() { 350 | this.angle = toDegree(Math.atan2(this.heading.y, this.heading.x)) - 90; 351 | return this.angle; 352 | } 353 | } 354 | 355 | 356 | ``` 357 | 358 | ## 创建面向Cocos Creator的组件 359 | ```Typescript 360 | import { Component, _decorator } from "cc"; 361 | const { ccclass, property } = _decorator; 362 | @ccclass('Player') 363 | @ecs.register('Player', false) 364 | export class Player extends CCComp { 365 | @property({ 366 | type: MovementComponent 367 | }) 368 | movement: MovementComponent; 369 | 370 | onLoad() { 371 | super.onLoad(); 372 | 373 | // 添加MovementComponent组件对象 374 | this.ent.add(this.movement); 375 | } 376 | } 377 | ``` 378 | ![](./imgs/cc_inspector.png) 379 | 380 | # 调试 381 | 添加如下代码 382 | ```TypeScript 383 | windows['ecs'] = ecs; 384 | ``` 385 | 在chrome浏览器的console中输入ecs可看到 386 | ![](./imgs/ecs_debug.png) 387 | 388 | 其中红框内为ecs上下文数据。 389 | 390 | # 相关ecs框架 391 | https://github.com/dualface/ecs-typescript 392 | 393 | https://github.com/nomos/lokas-ts 394 | 395 | https://github.com/darkoverlordofdata/entitas-ts 396 | 397 | https://github.com/NateTheGreatt/bitecs 398 | 399 | https://github.com/ecsyjs/ecsy 400 | 401 | https://github.com/dannyfritz/flock-ecs 402 | 403 | https://github.com/ddmills/geotic 404 | 405 | https://github.com/fireveined/perform-ecs 406 | 407 | https://github.com/ayebear/picoes 408 | 409 | https://github.com/bvalosek/tiny-ecs 410 | -------------------------------------------------------------------------------- /imgs/cc_inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shangdibaozi/ECS/2bac67de1a4acc075298a53bcc73f39ff180ecea/imgs/cc_inspector.png -------------------------------------------------------------------------------- /imgs/ecs_debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shangdibaozi/ECS/2bac67de1a4acc075298a53bcc73f39ff180ecea/imgs/ecs_debug.png -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * For a detailed explanation regarding each configuration property, visit: 3 | * https://jestjs.io/docs/configuration 4 | */ 5 | 6 | module.exports = { 7 | // All imported modules in your tests should be mocked automatically 8 | // automock: false, 9 | 10 | // Stop running tests after `n` failures 11 | // bail: 0, 12 | 13 | // The directory where Jest should store its cached dependency information 14 | // cacheDirectory: "C:\\Users\\shang\\AppData\\Local\\Temp\\jest", 15 | 16 | // Automatically clear mock calls and instances between every test 17 | // clearMocks: false, 18 | 19 | // Indicates whether the coverage information should be collected while executing the test 20 | // collectCoverage: false, 21 | 22 | // An array of glob patterns indicating a set of files for which coverage information should be collected 23 | // collectCoverageFrom: undefined, 24 | 25 | // The directory where Jest should output its coverage files 26 | // coverageDirectory: undefined, 27 | 28 | // An array of regexp pattern strings used to skip coverage collection 29 | // coveragePathIgnorePatterns: [ 30 | // "\\\\node_modules\\\\" 31 | // ], 32 | 33 | // Indicates which provider should be used to instrument code for coverage 34 | coverageProvider: "v8", 35 | 36 | // A list of reporter names that Jest uses when writing coverage reports 37 | // coverageReporters: [ 38 | // "json", 39 | // "text", 40 | // "lcov", 41 | // "clover" 42 | // ], 43 | 44 | // An object that configures minimum threshold enforcement for coverage results 45 | // coverageThreshold: undefined, 46 | 47 | // A path to a custom dependency extractor 48 | // dependencyExtractor: undefined, 49 | 50 | // Make calling deprecated APIs throw helpful error messages 51 | // errorOnDeprecated: false, 52 | 53 | // Force coverage collection from ignored files using an array of glob patterns 54 | // forceCoverageMatch: [], 55 | 56 | // A path to a module which exports an async function that is triggered once before all test suites 57 | // globalSetup: undefined, 58 | 59 | // A path to a module which exports an async function that is triggered once after all test suites 60 | // globalTeardown: undefined, 61 | 62 | // A set of global variables that need to be available in all test environments 63 | // globals: {}, 64 | 65 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. 66 | // maxWorkers: "50%", 67 | 68 | // An array of directory names to be searched recursively up from the requiring module's location 69 | // moduleDirectories: [ 70 | // "node_modules" 71 | // ], 72 | 73 | // An array of file extensions your modules use 74 | // moduleFileExtensions: [ 75 | // "js", 76 | // "jsx", 77 | // "ts", 78 | // "tsx", 79 | // "json", 80 | // "node" 81 | // ], 82 | 83 | // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module 84 | // moduleNameMapper: {}, 85 | 86 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 87 | // modulePathIgnorePatterns: [], 88 | 89 | // Activates notifications for test results 90 | // notify: false, 91 | 92 | // An enum that specifies notification mode. Requires { notify: true } 93 | // notifyMode: "failure-change", 94 | 95 | // A preset that is used as a base for Jest's configuration 96 | preset: 'ts-jest', 97 | 98 | // Run tests from one or more projects 99 | // projects: undefined, 100 | 101 | // Use this configuration option to add custom reporters to Jest 102 | // reporters: undefined, 103 | 104 | // Automatically reset mock state between every test 105 | // resetMocks: false, 106 | 107 | // Reset the module registry before running each individual test 108 | // resetModules: false, 109 | 110 | // A path to a custom resolver 111 | // resolver: undefined, 112 | 113 | // Automatically restore mock state between every test 114 | // restoreMocks: false, 115 | 116 | // The root directory that Jest should scan for tests and modules within 117 | // rootDir: undefined, 118 | 119 | // A list of paths to directories that Jest should use to search for files in 120 | // roots: [ 121 | // "" 122 | // ], 123 | 124 | // Allows you to use a custom runner instead of Jest's default test runner 125 | // runner: "jest-runner", 126 | 127 | // The paths to modules that run some code to configure or set up the testing environment before each test 128 | // setupFiles: [], 129 | 130 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 131 | // setupFilesAfterEnv: [], 132 | 133 | // The number of seconds after which a test is considered as slow and reported as such in the results. 134 | // slowTestThreshold: 5, 135 | 136 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 137 | // snapshotSerializers: [], 138 | 139 | // The test environment that will be used for testing 140 | // testEnvironment: "jest-environment-node", 141 | 142 | // Options that will be passed to the testEnvironment 143 | // testEnvironmentOptions: {}, 144 | 145 | // Adds a location field to test results 146 | // testLocationInResults: false, 147 | 148 | // The glob patterns Jest uses to detect test files 149 | // testMatch: [ 150 | // "**/__tests__/**/*.[jt]s?(x)", 151 | // "**/?(*.)+(spec|test).[tj]s?(x)" 152 | // ], 153 | 154 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 155 | // testPathIgnorePatterns: [ 156 | // "\\\\node_modules\\\\" 157 | // ], 158 | 159 | // The regexp pattern or array of patterns that Jest uses to detect test files 160 | // testRegex: [], 161 | 162 | // This option allows the use of a custom results processor 163 | // testResultsProcessor: undefined, 164 | 165 | // This option allows use of a custom test runner 166 | // testRunner: "jest-circus/runner", 167 | 168 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href 169 | // testURL: "http://localhost", 170 | 171 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" 172 | // timers: "real", 173 | 174 | // A map from regular expressions to paths to transformers 175 | // transform: undefined, 176 | 177 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 178 | // transformIgnorePatterns: [ 179 | // "\\\\node_modules\\\\", 180 | // "\\.pnp\\.[^\\\\]+$" 181 | // ], 182 | 183 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 184 | // unmockedModulePathPatterns: undefined, 185 | 186 | // Indicates whether each individual test should be reported during the run 187 | // verbose: undefined, 188 | 189 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 190 | // watchPathIgnorePatterns: [], 191 | 192 | // Whether to use watchman for file crawling 193 | // watchman: true, 194 | }; 195 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecs", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.15.8", 9 | "resolved": "https://registry.npmmirror.com/@babel/code-frame/download/@babel/code-frame-7.15.8.tgz?cache=0&sync_timestamp=1633554059214&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40babel%2Fcode-frame%2Fdownload%2F%40babel%2Fcode-frame-7.15.8.tgz", 10 | "integrity": "sha1-RZkMR62tsAwDZ3uqiSIffMI9JQM=", 11 | "requires": { 12 | "@babel/highlight": "^7.14.5" 13 | } 14 | }, 15 | "@babel/compat-data": { 16 | "version": "7.15.0", 17 | "resolved": "https://registry.nlark.com/@babel/compat-data/download/@babel/compat-data-7.15.0.tgz", 18 | "integrity": "sha1-Lbr4uFM0eWyvuw9Xk6kKL8AQsXY=" 19 | }, 20 | "@babel/core": { 21 | "version": "7.15.8", 22 | "resolved": "https://registry.npmmirror.com/@babel/core/download/@babel/core-7.15.8.tgz?cache=0&sync_timestamp=1633554060461&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.15.8.tgz", 23 | "integrity": "sha1-GVufK//pldLGwVnnL+UltBFOjBA=", 24 | "requires": { 25 | "@babel/code-frame": "^7.15.8", 26 | "@babel/generator": "^7.15.8", 27 | "@babel/helper-compilation-targets": "^7.15.4", 28 | "@babel/helper-module-transforms": "^7.15.8", 29 | "@babel/helpers": "^7.15.4", 30 | "@babel/parser": "^7.15.8", 31 | "@babel/template": "^7.15.4", 32 | "@babel/traverse": "^7.15.4", 33 | "@babel/types": "^7.15.6", 34 | "convert-source-map": "^1.7.0", 35 | "debug": "^4.1.0", 36 | "gensync": "^1.0.0-beta.2", 37 | "json5": "^2.1.2", 38 | "semver": "^6.3.0", 39 | "source-map": "^0.5.0" 40 | }, 41 | "dependencies": { 42 | "source-map": { 43 | "version": "0.5.7", 44 | "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", 45 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 46 | } 47 | } 48 | }, 49 | "@babel/generator": { 50 | "version": "7.15.8", 51 | "resolved": "https://registry.npmmirror.com/@babel/generator/download/@babel/generator-7.15.8.tgz?cache=0&sync_timestamp=1633554059295&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.15.8.tgz", 52 | "integrity": "sha1-+la+a1lpUs6yMQSM+E7kmaGcDNE=", 53 | "requires": { 54 | "@babel/types": "^7.15.6", 55 | "jsesc": "^2.5.1", 56 | "source-map": "^0.5.0" 57 | }, 58 | "dependencies": { 59 | "source-map": { 60 | "version": "0.5.7", 61 | "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", 62 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 63 | } 64 | } 65 | }, 66 | "@babel/helper-compilation-targets": { 67 | "version": "7.15.4", 68 | "resolved": "https://registry.nlark.com/@babel/helper-compilation-targets/download/@babel/helper-compilation-targets-7.15.4.tgz", 69 | "integrity": "sha1-z22U8w++/BORI+J91rAvZa7tt7k=", 70 | "requires": { 71 | "@babel/compat-data": "^7.15.0", 72 | "@babel/helper-validator-option": "^7.14.5", 73 | "browserslist": "^4.16.6", 74 | "semver": "^6.3.0" 75 | } 76 | }, 77 | "@babel/helper-function-name": { 78 | "version": "7.15.4", 79 | "resolved": "https://registry.nlark.com/@babel/helper-function-name/download/@babel/helper-function-name-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.15.4.tgz", 80 | "integrity": "sha1-hFdE2vxDgaSl+2r6bD02+Yp4frw=", 81 | "requires": { 82 | "@babel/helper-get-function-arity": "^7.15.4", 83 | "@babel/template": "^7.15.4", 84 | "@babel/types": "^7.15.4" 85 | } 86 | }, 87 | "@babel/helper-get-function-arity": { 88 | "version": "7.15.4", 89 | "resolved": "https://registry.nlark.com/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.15.4.tgz?cache=0&sync_timestamp=1630619280332&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-get-function-arity%2Fdownload%2F%40babel%2Fhelper-get-function-arity-7.15.4.tgz", 90 | "integrity": "sha1-CYgYk0oTf854tTaj4BWGS+Hih5s=", 91 | "requires": { 92 | "@babel/types": "^7.15.4" 93 | } 94 | }, 95 | "@babel/helper-hoist-variables": { 96 | "version": "7.15.4", 97 | "resolved": "https://registry.nlark.com/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.15.4.tgz?cache=0&sync_timestamp=1630619282917&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.15.4.tgz", 98 | "integrity": "sha1-CZk6MlnA6Rj5nRBCYd/fwDPxeN8=", 99 | "requires": { 100 | "@babel/types": "^7.15.4" 101 | } 102 | }, 103 | "@babel/helper-member-expression-to-functions": { 104 | "version": "7.15.4", 105 | "resolved": "https://registry.nlark.com/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.15.4.tgz", 106 | "integrity": "sha1-v9NNybupgkpGWLAxfsL9VxpR5u8=", 107 | "requires": { 108 | "@babel/types": "^7.15.4" 109 | } 110 | }, 111 | "@babel/helper-module-imports": { 112 | "version": "7.15.4", 113 | "resolved": "https://registry.nlark.com/@babel/helper-module-imports/download/@babel/helper-module-imports-7.15.4.tgz?cache=0&sync_timestamp=1630619282311&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.15.4.tgz", 114 | "integrity": "sha1-4YAH0jBjLeoZtHhTuYRHbntOED8=", 115 | "requires": { 116 | "@babel/types": "^7.15.4" 117 | } 118 | }, 119 | "@babel/helper-module-transforms": { 120 | "version": "7.15.8", 121 | "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.15.8.tgz?cache=0&sync_timestamp=1633554061737&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.15.8.tgz", 122 | "integrity": "sha1-2MDnWoelLjdKjyX4VRdHhqCUmLI=", 123 | "requires": { 124 | "@babel/helper-module-imports": "^7.15.4", 125 | "@babel/helper-replace-supers": "^7.15.4", 126 | "@babel/helper-simple-access": "^7.15.4", 127 | "@babel/helper-split-export-declaration": "^7.15.4", 128 | "@babel/helper-validator-identifier": "^7.15.7", 129 | "@babel/template": "^7.15.4", 130 | "@babel/traverse": "^7.15.4", 131 | "@babel/types": "^7.15.6" 132 | } 133 | }, 134 | "@babel/helper-optimise-call-expression": { 135 | "version": "7.15.4", 136 | "resolved": "https://registry.nlark.com/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.15.4.tgz?cache=0&sync_timestamp=1630619283276&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.15.4.tgz", 137 | "integrity": "sha1-8xClEho7nMUtmrGRIr1ymCLe4XE=", 138 | "requires": { 139 | "@babel/types": "^7.15.4" 140 | } 141 | }, 142 | "@babel/helper-plugin-utils": { 143 | "version": "7.14.5", 144 | "resolved": "https://registry.nlark.com/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.14.5.tgz?cache=0&sync_timestamp=1623280296194&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.14.5.tgz", 145 | "integrity": "sha1-WsgizpfuxGdBq3ClF5ceRDpwxak=" 146 | }, 147 | "@babel/helper-replace-supers": { 148 | "version": "7.15.4", 149 | "resolved": "https://registry.nlark.com/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.15.4.tgz", 150 | "integrity": "sha1-UqirJrqRjH9t7ihiiwcHGse3NHo=", 151 | "requires": { 152 | "@babel/helper-member-expression-to-functions": "^7.15.4", 153 | "@babel/helper-optimise-call-expression": "^7.15.4", 154 | "@babel/traverse": "^7.15.4", 155 | "@babel/types": "^7.15.4" 156 | } 157 | }, 158 | "@babel/helper-simple-access": { 159 | "version": "7.15.4", 160 | "resolved": "https://registry.nlark.com/@babel/helper-simple-access/download/@babel/helper-simple-access-7.15.4.tgz?cache=0&sync_timestamp=1630619284456&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-simple-access%2Fdownload%2F%40babel%2Fhelper-simple-access-7.15.4.tgz", 161 | "integrity": "sha1-rDaJBavx3o6XgUNLY12PhnS8wTs=", 162 | "requires": { 163 | "@babel/types": "^7.15.4" 164 | } 165 | }, 166 | "@babel/helper-split-export-declaration": { 167 | "version": "7.15.4", 168 | "resolved": "https://registry.nlark.com/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.15.4.tgz", 169 | "integrity": "sha1-rsq5Lc2+9qEKo7YqsgSwhfd24lc=", 170 | "requires": { 171 | "@babel/types": "^7.15.4" 172 | } 173 | }, 174 | "@babel/helper-validator-identifier": { 175 | "version": "7.15.7", 176 | "resolved": "https://registry.nlark.com/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.15.7.tgz?cache=0&sync_timestamp=1631920857390&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.15.7.tgz", 177 | "integrity": "sha1-Ig35k7/pBKSmsCq08zhaXr9uI4k=" 178 | }, 179 | "@babel/helper-validator-option": { 180 | "version": "7.14.5", 181 | "resolved": "https://registry.nlark.com/@babel/helper-validator-option/download/@babel/helper-validator-option-7.14.5.tgz?cache=0&sync_timestamp=1623280304150&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-validator-option%2Fdownload%2F%40babel%2Fhelper-validator-option-7.14.5.tgz", 182 | "integrity": "sha1-bnKh//GNXfy4eOHmLxoCHEty1aM=" 183 | }, 184 | "@babel/helpers": { 185 | "version": "7.15.4", 186 | "resolved": "https://registry.nlark.com/@babel/helpers/download/@babel/helpers-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelpers%2Fdownload%2F%40babel%2Fhelpers-7.15.4.tgz", 187 | "integrity": "sha1-X0DwIFCjAnEho89I1JfAXFVer0M=", 188 | "requires": { 189 | "@babel/template": "^7.15.4", 190 | "@babel/traverse": "^7.15.4", 191 | "@babel/types": "^7.15.4" 192 | } 193 | }, 194 | "@babel/highlight": { 195 | "version": "7.14.5", 196 | "resolved": "https://registry.nlark.com/@babel/highlight/download/@babel/highlight-7.14.5.tgz", 197 | "integrity": "sha1-aGGlLwOWZAUAH2qlNKAaJNmejNk=", 198 | "requires": { 199 | "@babel/helper-validator-identifier": "^7.14.5", 200 | "chalk": "^2.0.0", 201 | "js-tokens": "^4.0.0" 202 | }, 203 | "dependencies": { 204 | "ansi-styles": { 205 | "version": "3.2.1", 206 | "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1618995588464&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz", 207 | "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", 208 | "requires": { 209 | "color-convert": "^1.9.0" 210 | } 211 | }, 212 | "chalk": { 213 | "version": "2.4.2", 214 | "resolved": "https://registry.nlark.com/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1627646655305&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz", 215 | "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", 216 | "requires": { 217 | "ansi-styles": "^3.2.1", 218 | "escape-string-regexp": "^1.0.5", 219 | "supports-color": "^5.3.0" 220 | } 221 | }, 222 | "color-convert": { 223 | "version": "1.9.3", 224 | "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz", 225 | "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", 226 | "requires": { 227 | "color-name": "1.1.3" 228 | } 229 | }, 230 | "color-name": { 231 | "version": "1.1.3", 232 | "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz", 233 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 234 | }, 235 | "has-flag": { 236 | "version": "3.0.0", 237 | "resolved": "https://registry.nlark.com/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1626715907927&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz", 238 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 239 | }, 240 | "supports-color": { 241 | "version": "5.5.0", 242 | "resolved": "https://registry.nlark.com/supports-color/download/supports-color-5.5.0.tgz", 243 | "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", 244 | "requires": { 245 | "has-flag": "^3.0.0" 246 | } 247 | } 248 | } 249 | }, 250 | "@babel/parser": { 251 | "version": "7.15.8", 252 | "resolved": "https://registry.npmmirror.com/@babel/parser/download/@babel/parser-7.15.8.tgz?cache=0&sync_timestamp=1633554059632&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.15.8.tgz", 253 | "integrity": "sha1-e6zcvnG9w/+TbVEMFdzqfPC5kBY=" 254 | }, 255 | "@babel/plugin-syntax-async-generators": { 256 | "version": "7.8.4", 257 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.8.4.tgz", 258 | "integrity": "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0=", 259 | "requires": { 260 | "@babel/helper-plugin-utils": "^7.8.0" 261 | } 262 | }, 263 | "@babel/plugin-syntax-bigint": { 264 | "version": "7.8.3", 265 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-bigint/download/@babel/plugin-syntax-bigint-7.8.3.tgz", 266 | "integrity": "sha1-TJpvZp9dDN8bkKFnHpoUa+UwDOo=", 267 | "requires": { 268 | "@babel/helper-plugin-utils": "^7.8.0" 269 | } 270 | }, 271 | "@babel/plugin-syntax-class-properties": { 272 | "version": "7.12.13", 273 | "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-class-properties/download/@babel/plugin-syntax-class-properties-7.12.13.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.12.13.tgz", 274 | "integrity": "sha1-tcmHJ0xKOoK4lxR5aTGmtTVErhA=", 275 | "requires": { 276 | "@babel/helper-plugin-utils": "^7.12.13" 277 | } 278 | }, 279 | "@babel/plugin-syntax-import-meta": { 280 | "version": "7.10.4", 281 | "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-import-meta/download/@babel/plugin-syntax-import-meta-7.10.4.tgz", 282 | "integrity": "sha1-7mATSMNw+jNNIge+FYd3SWUh/VE=", 283 | "requires": { 284 | "@babel/helper-plugin-utils": "^7.10.4" 285 | } 286 | }, 287 | "@babel/plugin-syntax-json-strings": { 288 | "version": "7.8.3", 289 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.8.3.tgz", 290 | "integrity": "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo=", 291 | "requires": { 292 | "@babel/helper-plugin-utils": "^7.8.0" 293 | } 294 | }, 295 | "@babel/plugin-syntax-logical-assignment-operators": { 296 | "version": "7.10.4", 297 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-logical-assignment-operators/download/@babel/plugin-syntax-logical-assignment-operators-7.10.4.tgz", 298 | "integrity": "sha1-ypHvRjA1MESLkGZSusLp/plB9pk=", 299 | "requires": { 300 | "@babel/helper-plugin-utils": "^7.10.4" 301 | } 302 | }, 303 | "@babel/plugin-syntax-nullish-coalescing-operator": { 304 | "version": "7.8.3", 305 | "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-nullish-coalescing-operator/download/@babel/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", 306 | "integrity": "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak=", 307 | "requires": { 308 | "@babel/helper-plugin-utils": "^7.8.0" 309 | } 310 | }, 311 | "@babel/plugin-syntax-numeric-separator": { 312 | "version": "7.10.4", 313 | "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-numeric-separator/download/@babel/plugin-syntax-numeric-separator-7.10.4.tgz?cache=0&sync_timestamp=1593522054358&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz", 314 | "integrity": "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c=", 315 | "requires": { 316 | "@babel/helper-plugin-utils": "^7.10.4" 317 | } 318 | }, 319 | "@babel/plugin-syntax-object-rest-spread": { 320 | "version": "7.8.3", 321 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.8.3.tgz", 322 | "integrity": "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE=", 323 | "requires": { 324 | "@babel/helper-plugin-utils": "^7.8.0" 325 | } 326 | }, 327 | "@babel/plugin-syntax-optional-catch-binding": { 328 | "version": "7.8.3", 329 | "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.8.3.tgz", 330 | "integrity": "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE=", 331 | "requires": { 332 | "@babel/helper-plugin-utils": "^7.8.0" 333 | } 334 | }, 335 | "@babel/plugin-syntax-optional-chaining": { 336 | "version": "7.8.3", 337 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-optional-chaining/download/@babel/plugin-syntax-optional-chaining-7.8.3.tgz", 338 | "integrity": "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io=", 339 | "requires": { 340 | "@babel/helper-plugin-utils": "^7.8.0" 341 | } 342 | }, 343 | "@babel/plugin-syntax-top-level-await": { 344 | "version": "7.14.5", 345 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.14.5.tgz?cache=0&sync_timestamp=1623280427172&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.14.5.tgz", 346 | "integrity": "sha1-wc/a3DWmRiQAAfBhOCR7dBw02Uw=", 347 | "requires": { 348 | "@babel/helper-plugin-utils": "^7.14.5" 349 | } 350 | }, 351 | "@babel/plugin-syntax-typescript": { 352 | "version": "7.14.5", 353 | "resolved": "https://registry.nlark.com/@babel/plugin-syntax-typescript/download/@babel/plugin-syntax-typescript-7.14.5.tgz", 354 | "integrity": "sha1-uCxs5HGxZbXOQgz5KRTW+0YiVxY=", 355 | "requires": { 356 | "@babel/helper-plugin-utils": "^7.14.5" 357 | } 358 | }, 359 | "@babel/template": { 360 | "version": "7.15.4", 361 | "resolved": "https://registry.nlark.com/@babel/template/download/@babel/template-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.15.4.tgz", 362 | "integrity": "sha1-UYmNNdzz+qZwxO5q/P1RfuE58ZQ=", 363 | "requires": { 364 | "@babel/code-frame": "^7.14.5", 365 | "@babel/parser": "^7.15.4", 366 | "@babel/types": "^7.15.4" 367 | } 368 | }, 369 | "@babel/traverse": { 370 | "version": "7.15.4", 371 | "resolved": "https://registry.nlark.com/@babel/traverse/download/@babel/traverse-7.15.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.15.4.tgz", 372 | "integrity": "sha1-/4UQNnoUS/v/VS2eGOKPPiiJwi0=", 373 | "requires": { 374 | "@babel/code-frame": "^7.14.5", 375 | "@babel/generator": "^7.15.4", 376 | "@babel/helper-function-name": "^7.15.4", 377 | "@babel/helper-hoist-variables": "^7.15.4", 378 | "@babel/helper-split-export-declaration": "^7.15.4", 379 | "@babel/parser": "^7.15.4", 380 | "@babel/types": "^7.15.4", 381 | "debug": "^4.1.0", 382 | "globals": "^11.1.0" 383 | } 384 | }, 385 | "@babel/types": { 386 | "version": "7.15.6", 387 | "resolved": "https://registry.nlark.com/@babel/types/download/@babel/types-7.15.6.tgz?cache=0&sync_timestamp=1631216248664&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.15.6.tgz", 388 | "integrity": "sha1-mavcSCGLKIHAWN0KerBbmcm+dY8=", 389 | "requires": { 390 | "@babel/helper-validator-identifier": "^7.14.9", 391 | "to-fast-properties": "^2.0.0" 392 | } 393 | }, 394 | "@bcoe/v8-coverage": { 395 | "version": "0.2.3", 396 | "resolved": "https://registry.npm.taobao.org/@bcoe/v8-coverage/download/@bcoe/v8-coverage-0.2.3.tgz", 397 | "integrity": "sha1-daLotRy3WKdVPWgEpZMteqznXDk=" 398 | }, 399 | "@cspotcode/source-map-consumer": { 400 | "version": "0.8.0", 401 | "resolved": "https://registry.nlark.com/@cspotcode/source-map-consumer/download/@cspotcode/source-map-consumer-0.8.0.tgz", 402 | "integrity": "sha1-M79LeznBeIIWBvZpu8RHpqYpeGs=" 403 | }, 404 | "@cspotcode/source-map-support": { 405 | "version": "0.7.0", 406 | "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/download/@cspotcode/source-map-support-0.7.0.tgz?cache=0&sync_timestamp=1633908984001&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40cspotcode%2Fsource-map-support%2Fdownload%2F%40cspotcode%2Fsource-map-support-0.7.0.tgz", 407 | "integrity": "sha1-R4mECqhZ5G0vMXNyercHxmvzRPU=", 408 | "requires": { 409 | "@cspotcode/source-map-consumer": "0.8.0" 410 | } 411 | }, 412 | "@istanbuljs/load-nyc-config": { 413 | "version": "1.1.0", 414 | "resolved": "https://registry.nlark.com/@istanbuljs/load-nyc-config/download/@istanbuljs/load-nyc-config-1.1.0.tgz", 415 | "integrity": "sha1-/T2x1Z7PfPEh6AZQu4ZxL5tV7O0=", 416 | "requires": { 417 | "camelcase": "^5.3.1", 418 | "find-up": "^4.1.0", 419 | "get-package-type": "^0.1.0", 420 | "js-yaml": "^3.13.1", 421 | "resolve-from": "^5.0.0" 422 | } 423 | }, 424 | "@istanbuljs/schema": { 425 | "version": "0.1.3", 426 | "resolved": "https://registry.nlark.com/@istanbuljs/schema/download/@istanbuljs/schema-0.1.3.tgz", 427 | "integrity": "sha1-5F44TkuOwWvOL9kDr3hFD2v37Jg=" 428 | }, 429 | "@jest/console": { 430 | "version": "27.2.5", 431 | "resolved": "https://registry.npmmirror.com/@jest/console/download/@jest/console-27.2.5.tgz?cache=0&sync_timestamp=1633701038723&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Fconsole%2Fdownload%2F%40jest%2Fconsole-27.2.5.tgz", 432 | "integrity": "sha1-vdv41BwZHxe1K/DJ5sDRhgXjXW4=", 433 | "requires": { 434 | "@jest/types": "^27.2.5", 435 | "@types/node": "*", 436 | "chalk": "^4.0.0", 437 | "jest-message-util": "^27.2.5", 438 | "jest-util": "^27.2.5", 439 | "slash": "^3.0.0" 440 | } 441 | }, 442 | "@jest/core": { 443 | "version": "27.2.5", 444 | "resolved": "https://registry.npmmirror.com/@jest/core/download/@jest/core-27.2.5.tgz", 445 | "integrity": "sha1-hUwxRwjO4NiSrE9TG5Ep8Aoh7mk=", 446 | "requires": { 447 | "@jest/console": "^27.2.5", 448 | "@jest/reporters": "^27.2.5", 449 | "@jest/test-result": "^27.2.5", 450 | "@jest/transform": "^27.2.5", 451 | "@jest/types": "^27.2.5", 452 | "@types/node": "*", 453 | "ansi-escapes": "^4.2.1", 454 | "chalk": "^4.0.0", 455 | "emittery": "^0.8.1", 456 | "exit": "^0.1.2", 457 | "graceful-fs": "^4.2.4", 458 | "jest-changed-files": "^27.2.5", 459 | "jest-config": "^27.2.5", 460 | "jest-haste-map": "^27.2.5", 461 | "jest-message-util": "^27.2.5", 462 | "jest-regex-util": "^27.0.6", 463 | "jest-resolve": "^27.2.5", 464 | "jest-resolve-dependencies": "^27.2.5", 465 | "jest-runner": "^27.2.5", 466 | "jest-runtime": "^27.2.5", 467 | "jest-snapshot": "^27.2.5", 468 | "jest-util": "^27.2.5", 469 | "jest-validate": "^27.2.5", 470 | "jest-watcher": "^27.2.5", 471 | "micromatch": "^4.0.4", 472 | "rimraf": "^3.0.0", 473 | "slash": "^3.0.0", 474 | "strip-ansi": "^6.0.0" 475 | } 476 | }, 477 | "@jest/environment": { 478 | "version": "27.2.5", 479 | "resolved": "https://registry.npmmirror.com/@jest/environment/download/@jest/environment-27.2.5.tgz?cache=0&sync_timestamp=1633701039181&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Fenvironment%2Fdownload%2F%40jest%2Fenvironment-27.2.5.tgz", 480 | "integrity": "sha1-uFUXzPzsVWkMgsVvWgGjswxePIQ=", 481 | "requires": { 482 | "@jest/fake-timers": "^27.2.5", 483 | "@jest/types": "^27.2.5", 484 | "@types/node": "*", 485 | "jest-mock": "^27.2.5" 486 | } 487 | }, 488 | "@jest/fake-timers": { 489 | "version": "27.2.5", 490 | "resolved": "https://registry.npmmirror.com/@jest/fake-timers/download/@jest/fake-timers-27.2.5.tgz", 491 | "integrity": "sha1-DH5XYte/5uJp57SSebCXpSpC8KA=", 492 | "requires": { 493 | "@jest/types": "^27.2.5", 494 | "@sinonjs/fake-timers": "^8.0.1", 495 | "@types/node": "*", 496 | "jest-message-util": "^27.2.5", 497 | "jest-mock": "^27.2.5", 498 | "jest-util": "^27.2.5" 499 | } 500 | }, 501 | "@jest/globals": { 502 | "version": "27.2.5", 503 | "resolved": "https://registry.npmmirror.com/@jest/globals/download/@jest/globals-27.2.5.tgz?cache=0&sync_timestamp=1633701043623&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Fglobals%2Fdownload%2F%40jest%2Fglobals-27.2.5.tgz", 504 | "integrity": "sha1-QRVTj5jtbO5AUakP29CFQGKQIJk=", 505 | "requires": { 506 | "@jest/environment": "^27.2.5", 507 | "@jest/types": "^27.2.5", 508 | "expect": "^27.2.5" 509 | } 510 | }, 511 | "@jest/reporters": { 512 | "version": "27.2.5", 513 | "resolved": "https://registry.npmmirror.com/@jest/reporters/download/@jest/reporters-27.2.5.tgz?cache=0&sync_timestamp=1633701043652&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Freporters%2Fdownload%2F%40jest%2Freporters-27.2.5.tgz", 514 | "integrity": "sha1-ZRmO0fP0RJ4/ZWEpdk3Gxbsn6+M=", 515 | "requires": { 516 | "@bcoe/v8-coverage": "^0.2.3", 517 | "@jest/console": "^27.2.5", 518 | "@jest/test-result": "^27.2.5", 519 | "@jest/transform": "^27.2.5", 520 | "@jest/types": "^27.2.5", 521 | "@types/node": "*", 522 | "chalk": "^4.0.0", 523 | "collect-v8-coverage": "^1.0.0", 524 | "exit": "^0.1.2", 525 | "glob": "^7.1.2", 526 | "graceful-fs": "^4.2.4", 527 | "istanbul-lib-coverage": "^3.0.0", 528 | "istanbul-lib-instrument": "^4.0.3", 529 | "istanbul-lib-report": "^3.0.0", 530 | "istanbul-lib-source-maps": "^4.0.0", 531 | "istanbul-reports": "^3.0.2", 532 | "jest-haste-map": "^27.2.5", 533 | "jest-resolve": "^27.2.5", 534 | "jest-util": "^27.2.5", 535 | "jest-worker": "^27.2.5", 536 | "slash": "^3.0.0", 537 | "source-map": "^0.6.0", 538 | "string-length": "^4.0.1", 539 | "terminal-link": "^2.0.0", 540 | "v8-to-istanbul": "^8.1.0" 541 | } 542 | }, 543 | "@jest/source-map": { 544 | "version": "27.0.6", 545 | "resolved": "https://registry.nlark.com/@jest/source-map/download/@jest/source-map-27.0.6.tgz?cache=0&sync_timestamp=1624900091449&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40jest%2Fsource-map%2Fdownload%2F%40jest%2Fsource-map-27.0.6.tgz", 546 | "integrity": "sha1-vp6bk1ZdSbBUi4biMgkkkftgVR8=", 547 | "requires": { 548 | "callsites": "^3.0.0", 549 | "graceful-fs": "^4.2.4", 550 | "source-map": "^0.6.0" 551 | } 552 | }, 553 | "@jest/test-result": { 554 | "version": "27.2.5", 555 | "resolved": "https://registry.npmmirror.com/@jest/test-result/download/@jest/test-result-27.2.5.tgz?cache=0&sync_timestamp=1633701038663&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Ftest-result%2Fdownload%2F%40jest%2Ftest-result-27.2.5.tgz", 556 | "integrity": "sha1-6fc89s1eLMbrMQUzkkjeohH5Mg4=", 557 | "requires": { 558 | "@jest/console": "^27.2.5", 559 | "@jest/types": "^27.2.5", 560 | "@types/istanbul-lib-coverage": "^2.0.0", 561 | "collect-v8-coverage": "^1.0.0" 562 | } 563 | }, 564 | "@jest/test-sequencer": { 565 | "version": "27.2.5", 566 | "resolved": "https://registry.npmmirror.com/@jest/test-sequencer/download/@jest/test-sequencer-27.2.5.tgz?cache=0&sync_timestamp=1633701044730&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Ftest-sequencer%2Fdownload%2F%40jest%2Ftest-sequencer-27.2.5.tgz", 567 | "integrity": "sha1-7VrpHADmI/txkRHVjjgDleFs77s=", 568 | "requires": { 569 | "@jest/test-result": "^27.2.5", 570 | "graceful-fs": "^4.2.4", 571 | "jest-haste-map": "^27.2.5", 572 | "jest-runtime": "^27.2.5" 573 | } 574 | }, 575 | "@jest/transform": { 576 | "version": "27.2.5", 577 | "resolved": "https://registry.npmmirror.com/@jest/transform/download/@jest/transform-27.2.5.tgz?cache=0&sync_timestamp=1633701042377&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Ftransform%2Fdownload%2F%40jest%2Ftransform-27.2.5.tgz", 578 | "integrity": "sha1-ArCIYqVtvt3fC6PC6uQeBJolDik=", 579 | "requires": { 580 | "@babel/core": "^7.1.0", 581 | "@jest/types": "^27.2.5", 582 | "babel-plugin-istanbul": "^6.0.0", 583 | "chalk": "^4.0.0", 584 | "convert-source-map": "^1.4.0", 585 | "fast-json-stable-stringify": "^2.0.0", 586 | "graceful-fs": "^4.2.4", 587 | "jest-haste-map": "^27.2.5", 588 | "jest-regex-util": "^27.0.6", 589 | "jest-util": "^27.2.5", 590 | "micromatch": "^4.0.4", 591 | "pirates": "^4.0.1", 592 | "slash": "^3.0.0", 593 | "source-map": "^0.6.1", 594 | "write-file-atomic": "^3.0.0" 595 | } 596 | }, 597 | "@jest/types": { 598 | "version": "27.2.5", 599 | "resolved": "https://registry.npmmirror.com/@jest/types/download/@jest/types-27.2.5.tgz?cache=0&sync_timestamp=1633701040380&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40jest%2Ftypes%2Fdownload%2F%40jest%2Ftypes-27.2.5.tgz", 600 | "integrity": "sha1-QgdlwFJgXnVoaYLSSwYbTLuiITI=", 601 | "requires": { 602 | "@types/istanbul-lib-coverage": "^2.0.0", 603 | "@types/istanbul-reports": "^3.0.0", 604 | "@types/node": "*", 605 | "@types/yargs": "^16.0.0", 606 | "chalk": "^4.0.0" 607 | } 608 | }, 609 | "@sinonjs/commons": { 610 | "version": "1.8.3", 611 | "resolved": "https://registry.nlark.com/@sinonjs/commons/download/@sinonjs/commons-1.8.3.tgz", 612 | "integrity": "sha1-OALd0hpQqUm2ch3dcto25n5/Gy0=", 613 | "requires": { 614 | "type-detect": "4.0.8" 615 | } 616 | }, 617 | "@sinonjs/fake-timers": { 618 | "version": "8.0.1", 619 | "resolved": "https://registry.npmmirror.com/@sinonjs/fake-timers/download/@sinonjs/fake-timers-8.0.1.tgz", 620 | "integrity": "sha1-HByakUGfgE5Zro3zFqB90cOna5Q=", 621 | "requires": { 622 | "@sinonjs/commons": "^1.7.0" 623 | } 624 | }, 625 | "@tootallnate/once": { 626 | "version": "1.1.2", 627 | "resolved": "https://registry.npmmirror.com/@tootallnate/once/download/@tootallnate/once-1.1.2.tgz?cache=0&sync_timestamp=1632734160633&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40tootallnate%2Fonce%2Fdownload%2F%40tootallnate%2Fonce-1.1.2.tgz", 628 | "integrity": "sha1-zLkURTYBeaBOf+av94wA/8Hur4I=" 629 | }, 630 | "@tsconfig/node10": { 631 | "version": "1.0.8", 632 | "resolved": "https://registry.nlark.com/@tsconfig/node10/download/@tsconfig/node10-1.0.8.tgz?cache=0&sync_timestamp=1623230113943&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40tsconfig%2Fnode10%2Fdownload%2F%40tsconfig%2Fnode10-1.0.8.tgz", 633 | "integrity": "sha1-weToDW+WT77LM1nEO9SLQPfK2tk=" 634 | }, 635 | "@tsconfig/node12": { 636 | "version": "1.0.9", 637 | "resolved": "https://registry.nlark.com/@tsconfig/node12/download/@tsconfig/node12-1.0.9.tgz", 638 | "integrity": "sha1-YsH23uLr2a6tgNw6+laBDljhoEw=" 639 | }, 640 | "@tsconfig/node14": { 641 | "version": "1.0.1", 642 | "resolved": "https://registry.nlark.com/@tsconfig/node14/download/@tsconfig/node14-1.0.1.tgz?cache=0&sync_timestamp=1623230113946&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40tsconfig%2Fnode14%2Fdownload%2F%40tsconfig%2Fnode14-1.0.1.tgz", 643 | "integrity": "sha1-lfLRZ/+5uNIGiwsjUwL6/U33EfI=" 644 | }, 645 | "@tsconfig/node16": { 646 | "version": "1.0.2", 647 | "resolved": "https://registry.nlark.com/@tsconfig/node16/download/@tsconfig/node16-1.0.2.tgz?cache=0&sync_timestamp=1626840702633&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40tsconfig%2Fnode16%2Fdownload%2F%40tsconfig%2Fnode16-1.0.2.tgz", 648 | "integrity": "sha1-Qjx3h30Fadsg4fyAiFrEEYMUAQ4=" 649 | }, 650 | "@types/babel__core": { 651 | "version": "7.1.16", 652 | "resolved": "https://registry.nlark.com/@types/babel__core/download/@types/babel__core-7.1.16.tgz", 653 | "integrity": "sha1-vBLHS31l6C0ph2tdC69cYlrFhwI=", 654 | "requires": { 655 | "@babel/parser": "^7.1.0", 656 | "@babel/types": "^7.0.0", 657 | "@types/babel__generator": "*", 658 | "@types/babel__template": "*", 659 | "@types/babel__traverse": "*" 660 | } 661 | }, 662 | "@types/babel__generator": { 663 | "version": "7.6.3", 664 | "resolved": "https://registry.nlark.com/@types/babel__generator/download/@types/babel__generator-7.6.3.tgz?cache=0&sync_timestamp=1629706648808&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fbabel__generator%2Fdownload%2F%40types%2Fbabel__generator-7.6.3.tgz", 665 | "integrity": "sha1-9Fa0ss55E392iqEw0kI9LwzPq6U=", 666 | "requires": { 667 | "@babel/types": "^7.0.0" 668 | } 669 | }, 670 | "@types/babel__template": { 671 | "version": "7.4.1", 672 | "resolved": "https://registry.nlark.com/@types/babel__template/download/@types/babel__template-7.4.1.tgz?cache=0&sync_timestamp=1629706636298&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fbabel__template%2Fdownload%2F%40types%2Fbabel__template-7.4.1.tgz", 673 | "integrity": "sha1-PRpI/Z1sDt/Vby/1eNrtSPNsiWk=", 674 | "requires": { 675 | "@babel/parser": "^7.1.0", 676 | "@babel/types": "^7.0.0" 677 | } 678 | }, 679 | "@types/babel__traverse": { 680 | "version": "7.14.2", 681 | "resolved": "https://registry.nlark.com/@types/babel__traverse/download/@types/babel__traverse-7.14.2.tgz?cache=0&sync_timestamp=1629706636317&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fbabel__traverse%2Fdownload%2F%40types%2Fbabel__traverse-7.14.2.tgz", 682 | "integrity": "sha1-/81HC7s/i/MEgWePtVAieMqDOkM=", 683 | "requires": { 684 | "@babel/types": "^7.3.0" 685 | } 686 | }, 687 | "@types/graceful-fs": { 688 | "version": "4.1.5", 689 | "resolved": "https://registry.nlark.com/@types/graceful-fs/download/@types/graceful-fs-4.1.5.tgz", 690 | "integrity": "sha1-If+6DZjaQ1DbZIkfkqnl2zzbThU=", 691 | "requires": { 692 | "@types/node": "*" 693 | } 694 | }, 695 | "@types/istanbul-lib-coverage": { 696 | "version": "2.0.3", 697 | "resolved": "https://registry.nlark.com/@types/istanbul-lib-coverage/download/@types/istanbul-lib-coverage-2.0.3.tgz", 698 | "integrity": "sha1-S6jdtyAiH0MuRDvV+RF/0iz9R2I=" 699 | }, 700 | "@types/istanbul-lib-report": { 701 | "version": "3.0.0", 702 | "resolved": "https://registry.nlark.com/@types/istanbul-lib-report/download/@types/istanbul-lib-report-3.0.0.tgz?cache=0&sync_timestamp=1629708072640&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fistanbul-lib-report%2Fdownload%2F%40types%2Fistanbul-lib-report-3.0.0.tgz", 703 | "integrity": "sha1-wUwk8Y6oGQwRjudWK3/5mjZVJoY=", 704 | "requires": { 705 | "@types/istanbul-lib-coverage": "*" 706 | } 707 | }, 708 | "@types/istanbul-reports": { 709 | "version": "3.0.1", 710 | "resolved": "https://registry.nlark.com/@types/istanbul-reports/download/@types/istanbul-reports-3.0.1.tgz", 711 | "integrity": "sha1-kVP+mLuivVZaY63ZQ21vDX+EaP8=", 712 | "requires": { 713 | "@types/istanbul-lib-report": "*" 714 | } 715 | }, 716 | "@types/jest": { 717 | "version": "27.0.2", 718 | "resolved": "https://registry.nlark.com/@types/jest/download/@types/jest-27.0.2.tgz", 719 | "integrity": "sha1-rDg8TUqt3Sm78rkW2NEFwwSl/Nc=", 720 | "requires": { 721 | "jest-diff": "^27.0.0", 722 | "pretty-format": "^27.0.0" 723 | } 724 | }, 725 | "@types/node": { 726 | "version": "16.11.0", 727 | "resolved": "https://registry.npmmirror.com/@types/node/download/@types/node-16.11.0.tgz?cache=0&sync_timestamp=1634237166526&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-16.11.0.tgz", 728 | "integrity": "sha1-S5XyMnus0e+PCNjO2hkwOcXX9S4=" 729 | }, 730 | "@types/prettier": { 731 | "version": "2.4.1", 732 | "resolved": "https://registry.npmmirror.com/@types/prettier/download/@types/prettier-2.4.1.tgz?cache=0&sync_timestamp=1632784208226&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fprettier%2Fdownload%2F%40types%2Fprettier-2.4.1.tgz", 733 | "integrity": "sha1-4TAwSNU4lWPhMPW92J03qZrLdes=" 734 | }, 735 | "@types/stack-utils": { 736 | "version": "2.0.1", 737 | "resolved": "https://registry.nlark.com/@types/stack-utils/download/@types/stack-utils-2.0.1.tgz", 738 | "integrity": "sha1-IPGClPeX8iCbX2XI47XI6CYdEnw=" 739 | }, 740 | "@types/yargs": { 741 | "version": "16.0.4", 742 | "resolved": "https://registry.npmmirror.com/@types/yargs/download/@types/yargs-16.0.4.tgz?cache=0&sync_timestamp=1634259802415&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fyargs%2Fdownload%2F%40types%2Fyargs-16.0.4.tgz", 743 | "integrity": "sha1-JqrZjdLCo45CEIbqmtQrnlFkKXc=", 744 | "requires": { 745 | "@types/yargs-parser": "*" 746 | } 747 | }, 748 | "@types/yargs-parser": { 749 | "version": "20.2.1", 750 | "resolved": "https://registry.nlark.com/@types/yargs-parser/download/@types/yargs-parser-20.2.1.tgz?cache=0&sync_timestamp=1629709862537&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fyargs-parser%2Fdownload%2F%40types%2Fyargs-parser-20.2.1.tgz", 751 | "integrity": "sha1-O5ziSJkZ2eT+pDm3aRarw0st8Sk=" 752 | }, 753 | "abab": { 754 | "version": "2.0.5", 755 | "resolved": "https://registry.npm.taobao.org/abab/download/abab-2.0.5.tgz?cache=0&sync_timestamp=1599850271460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fabab%2Fdownload%2Fabab-2.0.5.tgz", 756 | "integrity": "sha1-wLZ4+zLWD8EhnHhNaoJv44Wut5o=" 757 | }, 758 | "acorn": { 759 | "version": "8.5.0", 760 | "resolved": "https://registry.nlark.com/acorn/download/acorn-8.5.0.tgz", 761 | "integrity": "sha1-RRLMuZs2mMdSWR6btEcuOK1DzuI=" 762 | }, 763 | "acorn-globals": { 764 | "version": "6.0.0", 765 | "resolved": "https://registry.npm.taobao.org/acorn-globals/download/acorn-globals-6.0.0.tgz", 766 | "integrity": "sha1-Rs3Tnw+P8IqHZhm1X1rIptx3C0U=", 767 | "requires": { 768 | "acorn": "^7.1.1", 769 | "acorn-walk": "^7.1.1" 770 | }, 771 | "dependencies": { 772 | "acorn": { 773 | "version": "7.4.1", 774 | "resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz", 775 | "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=" 776 | }, 777 | "acorn-walk": { 778 | "version": "7.2.0", 779 | "resolved": "https://registry.nlark.com/acorn-walk/download/acorn-walk-7.2.0.tgz?cache=0&sync_timestamp=1630916608758&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn-walk%2Fdownload%2Facorn-walk-7.2.0.tgz", 780 | "integrity": "sha1-DeiJpgEgOQmw++B7iTjcIdLpZ7w=" 781 | } 782 | } 783 | }, 784 | "acorn-walk": { 785 | "version": "8.2.0", 786 | "resolved": "https://registry.nlark.com/acorn-walk/download/acorn-walk-8.2.0.tgz?cache=0&sync_timestamp=1630916608758&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn-walk%2Fdownload%2Facorn-walk-8.2.0.tgz", 787 | "integrity": "sha1-dBIQ8uJCZFRQiFOi9E0KuDt/acE=" 788 | }, 789 | "agent-base": { 790 | "version": "6.0.2", 791 | "resolved": "https://registry.nlark.com/agent-base/download/agent-base-6.0.2.tgz", 792 | "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", 793 | "requires": { 794 | "debug": "4" 795 | } 796 | }, 797 | "ansi-escapes": { 798 | "version": "4.3.2", 799 | "resolved": "https://registry.nlark.com/ansi-escapes/download/ansi-escapes-4.3.2.tgz", 800 | "integrity": "sha1-ayKR0dt9mLZSHV8e+kLQ86n+tl4=", 801 | "requires": { 802 | "type-fest": "^0.21.3" 803 | } 804 | }, 805 | "ansi-regex": { 806 | "version": "5.0.1", 807 | "resolved": "https://registry.nlark.com/ansi-regex/download/ansi-regex-5.0.1.tgz?cache=0&sync_timestamp=1631634988487&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-regex%2Fdownload%2Fansi-regex-5.0.1.tgz", 808 | "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=" 809 | }, 810 | "ansi-styles": { 811 | "version": "4.3.0", 812 | "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995588464&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz", 813 | "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", 814 | "requires": { 815 | "color-convert": "^2.0.1" 816 | } 817 | }, 818 | "anymatch": { 819 | "version": "3.1.2", 820 | "resolved": "https://registry.nlark.com/anymatch/download/anymatch-3.1.2.tgz", 821 | "integrity": "sha1-wFV8CWrzLxBhmPT04qODU343hxY=", 822 | "requires": { 823 | "normalize-path": "^3.0.0", 824 | "picomatch": "^2.0.4" 825 | } 826 | }, 827 | "arg": { 828 | "version": "4.1.3", 829 | "resolved": "https://registry.nlark.com/arg/download/arg-4.1.3.tgz?cache=0&sync_timestamp=1629166537485&other_urls=https%3A%2F%2Fregistry.nlark.com%2Farg%2Fdownload%2Farg-4.1.3.tgz", 830 | "integrity": "sha1-Jp/HrVuOQstjyJbVZmAXJhwUQIk=" 831 | }, 832 | "argparse": { 833 | "version": "1.0.10", 834 | "resolved": "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz", 835 | "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", 836 | "requires": { 837 | "sprintf-js": "~1.0.2" 838 | } 839 | }, 840 | "asynckit": { 841 | "version": "0.4.0", 842 | "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz", 843 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 844 | }, 845 | "babel-jest": { 846 | "version": "27.2.5", 847 | "resolved": "https://registry.npmmirror.com/babel-jest/download/babel-jest-27.2.5.tgz?cache=0&sync_timestamp=1633701039240&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fbabel-jest%2Fdownload%2Fbabel-jest-27.2.5.tgz", 848 | "integrity": "sha1-a7vBu0IA/gv9Gx+8vgL8YuvtFqo=", 849 | "requires": { 850 | "@jest/transform": "^27.2.5", 851 | "@jest/types": "^27.2.5", 852 | "@types/babel__core": "^7.1.14", 853 | "babel-plugin-istanbul": "^6.0.0", 854 | "babel-preset-jest": "^27.2.0", 855 | "chalk": "^4.0.0", 856 | "graceful-fs": "^4.2.4", 857 | "slash": "^3.0.0" 858 | } 859 | }, 860 | "babel-plugin-istanbul": { 861 | "version": "6.0.0", 862 | "resolved": "https://registry.nlark.com/babel-plugin-istanbul/download/babel-plugin-istanbul-6.0.0.tgz", 863 | "integrity": "sha1-4VnM3Jr5XgtXDHW0Vzt8NNZx12U=", 864 | "requires": { 865 | "@babel/helper-plugin-utils": "^7.0.0", 866 | "@istanbuljs/load-nyc-config": "^1.0.0", 867 | "@istanbuljs/schema": "^0.1.2", 868 | "istanbul-lib-instrument": "^4.0.0", 869 | "test-exclude": "^6.0.0" 870 | } 871 | }, 872 | "babel-plugin-jest-hoist": { 873 | "version": "27.2.0", 874 | "resolved": "https://registry.nlark.com/babel-plugin-jest-hoist/download/babel-plugin-jest-hoist-27.2.0.tgz?cache=0&sync_timestamp=1631520505618&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbabel-plugin-jest-hoist%2Fdownload%2Fbabel-plugin-jest-hoist-27.2.0.tgz", 875 | "integrity": "sha1-efN9Q/flxP3Esso+EMxs9UViYnc=", 876 | "requires": { 877 | "@babel/template": "^7.3.3", 878 | "@babel/types": "^7.3.3", 879 | "@types/babel__core": "^7.0.0", 880 | "@types/babel__traverse": "^7.0.6" 881 | } 882 | }, 883 | "babel-preset-current-node-syntax": { 884 | "version": "1.0.1", 885 | "resolved": "https://registry.npm.taobao.org/babel-preset-current-node-syntax/download/babel-preset-current-node-syntax-1.0.1.tgz", 886 | "integrity": "sha1-tDmSObibKgEfndvj5PQB/EDP9zs=", 887 | "requires": { 888 | "@babel/plugin-syntax-async-generators": "^7.8.4", 889 | "@babel/plugin-syntax-bigint": "^7.8.3", 890 | "@babel/plugin-syntax-class-properties": "^7.8.3", 891 | "@babel/plugin-syntax-import-meta": "^7.8.3", 892 | "@babel/plugin-syntax-json-strings": "^7.8.3", 893 | "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", 894 | "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", 895 | "@babel/plugin-syntax-numeric-separator": "^7.8.3", 896 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3", 897 | "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", 898 | "@babel/plugin-syntax-optional-chaining": "^7.8.3", 899 | "@babel/plugin-syntax-top-level-await": "^7.8.3" 900 | } 901 | }, 902 | "babel-preset-jest": { 903 | "version": "27.2.0", 904 | "resolved": "https://registry.nlark.com/babel-preset-jest/download/babel-preset-jest-27.2.0.tgz?cache=0&sync_timestamp=1631520509203&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbabel-preset-jest%2Fdownload%2Fbabel-preset-jest-27.2.0.tgz", 905 | "integrity": "sha1-VWu780Bgj+1WcKsOoMjvJEn7qIU=", 906 | "requires": { 907 | "babel-plugin-jest-hoist": "^27.2.0", 908 | "babel-preset-current-node-syntax": "^1.0.0" 909 | } 910 | }, 911 | "balanced-match": { 912 | "version": "1.0.2", 913 | "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.2.tgz?cache=0&sync_timestamp=1617714233441&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbalanced-match%2Fdownload%2Fbalanced-match-1.0.2.tgz", 914 | "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=" 915 | }, 916 | "brace-expansion": { 917 | "version": "1.1.11", 918 | "resolved": "https://registry.nlark.com/brace-expansion/download/brace-expansion-1.1.11.tgz", 919 | "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", 920 | "requires": { 921 | "balanced-match": "^1.0.0", 922 | "concat-map": "0.0.1" 923 | } 924 | }, 925 | "braces": { 926 | "version": "3.0.2", 927 | "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz", 928 | "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=", 929 | "requires": { 930 | "fill-range": "^7.0.1" 931 | } 932 | }, 933 | "browser-process-hrtime": { 934 | "version": "1.0.0", 935 | "resolved": "https://registry.nlark.com/browser-process-hrtime/download/browser-process-hrtime-1.0.0.tgz", 936 | "integrity": "sha1-PJtLfXgsgSHlbxAQbYTA0P/JRiY=" 937 | }, 938 | "browserslist": { 939 | "version": "4.17.4", 940 | "resolved": "https://registry.npmmirror.com/browserslist/download/browserslist-4.17.4.tgz?cache=0&sync_timestamp=1634137893850&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.17.4.tgz", 941 | "integrity": "sha1-cuJQivKkA67ApJhH7zG9gjxX6tQ=", 942 | "requires": { 943 | "caniuse-lite": "^1.0.30001265", 944 | "electron-to-chromium": "^1.3.867", 945 | "escalade": "^3.1.1", 946 | "node-releases": "^2.0.0", 947 | "picocolors": "^1.0.0" 948 | } 949 | }, 950 | "bs-logger": { 951 | "version": "0.2.6", 952 | "resolved": "https://registry.npm.taobao.org/bs-logger/download/bs-logger-0.2.6.tgz", 953 | "integrity": "sha1-6302UwenLPl0zGzadraDVK0za9g=", 954 | "requires": { 955 | "fast-json-stable-stringify": "2.x" 956 | } 957 | }, 958 | "bser": { 959 | "version": "2.1.1", 960 | "resolved": "https://registry.npm.taobao.org/bser/download/bser-2.1.1.tgz", 961 | "integrity": "sha1-5nh9og7OnQeZhTPP2d5vXDj0vAU=", 962 | "requires": { 963 | "node-int64": "^0.4.0" 964 | } 965 | }, 966 | "buffer-from": { 967 | "version": "1.1.2", 968 | "resolved": "https://registry.nlark.com/buffer-from/download/buffer-from-1.1.2.tgz?cache=0&sync_timestamp=1627578450949&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbuffer-from%2Fdownload%2Fbuffer-from-1.1.2.tgz", 969 | "integrity": "sha1-KxRqb9cugLT1XSVfNe1Zo6mkG9U=" 970 | }, 971 | "callsites": { 972 | "version": "3.1.0", 973 | "resolved": "https://registry.nlark.com/callsites/download/callsites-3.1.0.tgz", 974 | "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=" 975 | }, 976 | "camelcase": { 977 | "version": "5.3.1", 978 | "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz", 979 | "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=" 980 | }, 981 | "caniuse-lite": { 982 | "version": "1.0.30001267", 983 | "resolved": "https://registry.npmmirror.com/caniuse-lite/download/caniuse-lite-1.0.30001267.tgz", 984 | "integrity": "sha1-sc8pNxda/AVw5GFfwtL5Bp+g7TA=" 985 | }, 986 | "chalk": { 987 | "version": "4.1.2", 988 | "resolved": "https://registry.nlark.com/chalk/download/chalk-4.1.2.tgz?cache=0&sync_timestamp=1627646655305&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.2.tgz", 989 | "integrity": "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE=", 990 | "requires": { 991 | "ansi-styles": "^4.1.0", 992 | "supports-color": "^7.1.0" 993 | } 994 | }, 995 | "char-regex": { 996 | "version": "1.0.2", 997 | "resolved": "https://registry.nlark.com/char-regex/download/char-regex-1.0.2.tgz?cache=0&sync_timestamp=1622809103243&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchar-regex%2Fdownload%2Fchar-regex-1.0.2.tgz", 998 | "integrity": "sha1-10Q1giYhf5ge1Y9Hmx1rzClUXc8=" 999 | }, 1000 | "ci-info": { 1001 | "version": "3.2.0", 1002 | "resolved": "https://registry.nlark.com/ci-info/download/ci-info-3.2.0.tgz", 1003 | "integrity": "sha1-KHbLlIpJh5e1I28AlbwFfQ3KOLY=" 1004 | }, 1005 | "cjs-module-lexer": { 1006 | "version": "1.2.2", 1007 | "resolved": "https://registry.nlark.com/cjs-module-lexer/download/cjs-module-lexer-1.2.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcjs-module-lexer%2Fdownload%2Fcjs-module-lexer-1.2.2.tgz", 1008 | "integrity": "sha1-n4S6MkSlEvOlTlJ36O70xImGTkA=" 1009 | }, 1010 | "cliui": { 1011 | "version": "7.0.4", 1012 | "resolved": "https://registry.nlark.com/cliui/download/cliui-7.0.4.tgz", 1013 | "integrity": "sha1-oCZe5lVHb8gHrqnfPfjfd4OAi08=", 1014 | "requires": { 1015 | "string-width": "^4.2.0", 1016 | "strip-ansi": "^6.0.0", 1017 | "wrap-ansi": "^7.0.0" 1018 | } 1019 | }, 1020 | "co": { 1021 | "version": "4.6.0", 1022 | "resolved": "https://registry.npm.taobao.org/co/download/co-4.6.0.tgz", 1023 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 1024 | }, 1025 | "collect-v8-coverage": { 1026 | "version": "1.0.1", 1027 | "resolved": "https://registry.npm.taobao.org/collect-v8-coverage/download/collect-v8-coverage-1.0.1.tgz", 1028 | "integrity": "sha1-zCyOlPwYu9/+ZNZTRXDIpnOyf1k=" 1029 | }, 1030 | "color-convert": { 1031 | "version": "2.0.1", 1032 | "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", 1033 | "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", 1034 | "requires": { 1035 | "color-name": "~1.1.4" 1036 | } 1037 | }, 1038 | "color-name": { 1039 | "version": "1.1.4", 1040 | "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", 1041 | "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=" 1042 | }, 1043 | "combined-stream": { 1044 | "version": "1.0.8", 1045 | "resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz", 1046 | "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=", 1047 | "requires": { 1048 | "delayed-stream": "~1.0.0" 1049 | } 1050 | }, 1051 | "concat-map": { 1052 | "version": "0.0.1", 1053 | "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", 1054 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 1055 | }, 1056 | "convert-source-map": { 1057 | "version": "1.8.0", 1058 | "resolved": "https://registry.nlark.com/convert-source-map/download/convert-source-map-1.8.0.tgz?cache=0&sync_timestamp=1624045420970&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.8.0.tgz", 1059 | "integrity": "sha1-8zc8MtIbTXgN2ABFFGhPt5HKQ2k=", 1060 | "requires": { 1061 | "safe-buffer": "~5.1.1" 1062 | } 1063 | }, 1064 | "create-require": { 1065 | "version": "1.1.1", 1066 | "resolved": "https://registry.npm.taobao.org/create-require/download/create-require-1.1.1.tgz", 1067 | "integrity": "sha1-wdfo8eX2z8n/ZfnNNS03NIdWwzM=" 1068 | }, 1069 | "cross-spawn": { 1070 | "version": "7.0.3", 1071 | "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz", 1072 | "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=", 1073 | "requires": { 1074 | "path-key": "^3.1.0", 1075 | "shebang-command": "^2.0.0", 1076 | "which": "^2.0.1" 1077 | } 1078 | }, 1079 | "cssom": { 1080 | "version": "0.4.4", 1081 | "resolved": "https://registry.nlark.com/cssom/download/cssom-0.4.4.tgz", 1082 | "integrity": "sha1-WmbPk9LQtmHYC/akT7ZfXC5OChA=" 1083 | }, 1084 | "cssstyle": { 1085 | "version": "2.3.0", 1086 | "resolved": "https://registry.nlark.com/cssstyle/download/cssstyle-2.3.0.tgz", 1087 | "integrity": "sha1-/2ZaDdvcMYZLCWR/NBY0Q9kLCFI=", 1088 | "requires": { 1089 | "cssom": "~0.3.6" 1090 | }, 1091 | "dependencies": { 1092 | "cssom": { 1093 | "version": "0.3.8", 1094 | "resolved": "https://registry.nlark.com/cssom/download/cssom-0.3.8.tgz", 1095 | "integrity": "sha1-nxJ29bK0Y/IRTT8sdSUK+MGjb0o=" 1096 | } 1097 | } 1098 | }, 1099 | "data-urls": { 1100 | "version": "2.0.0", 1101 | "resolved": "https://registry.npmmirror.com/data-urls/download/data-urls-2.0.0.tgz", 1102 | "integrity": "sha1-FWSFpyljqXD11YIar2Qr7yvy25s=", 1103 | "requires": { 1104 | "abab": "^2.0.3", 1105 | "whatwg-mimetype": "^2.3.0", 1106 | "whatwg-url": "^8.0.0" 1107 | } 1108 | }, 1109 | "debug": { 1110 | "version": "4.3.2", 1111 | "resolved": "https://registry.nlark.com/debug/download/debug-4.3.2.tgz?cache=0&sync_timestamp=1625374648057&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdebug%2Fdownload%2Fdebug-4.3.2.tgz", 1112 | "integrity": "sha1-8KScGKyHeeMdSgxgKd+3aHPHQos=", 1113 | "requires": { 1114 | "ms": "2.1.2" 1115 | } 1116 | }, 1117 | "decimal.js": { 1118 | "version": "10.3.1", 1119 | "resolved": "https://registry.nlark.com/decimal.js/download/decimal.js-10.3.1.tgz", 1120 | "integrity": "sha1-2MOkRKnGd0umDKatcmHDqU/V54M=" 1121 | }, 1122 | "dedent": { 1123 | "version": "0.7.0", 1124 | "resolved": "https://registry.nlark.com/dedent/download/dedent-0.7.0.tgz", 1125 | "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" 1126 | }, 1127 | "deep-is": { 1128 | "version": "0.1.4", 1129 | "resolved": "https://registry.nlark.com/deep-is/download/deep-is-0.1.4.tgz", 1130 | "integrity": "sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=" 1131 | }, 1132 | "deepmerge": { 1133 | "version": "4.2.2", 1134 | "resolved": "https://registry.nlark.com/deepmerge/download/deepmerge-4.2.2.tgz", 1135 | "integrity": "sha1-RNLqNnm49NT/ujPwPYZfwee/SVU=" 1136 | }, 1137 | "delayed-stream": { 1138 | "version": "1.0.0", 1139 | "resolved": "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz", 1140 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 1141 | }, 1142 | "detect-newline": { 1143 | "version": "3.1.0", 1144 | "resolved": "https://registry.npmmirror.com/detect-newline/download/detect-newline-3.1.0.tgz?cache=0&sync_timestamp=1634200380130&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fdetect-newline%2Fdownload%2Fdetect-newline-3.1.0.tgz", 1145 | "integrity": "sha1-V29d/GOuGhkv8ZLYrTr2MImRtlE=" 1146 | }, 1147 | "diff": { 1148 | "version": "4.0.2", 1149 | "resolved": "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz", 1150 | "integrity": "sha1-YPOuy4nV+uUgwRqhnvwruYKq3n0=" 1151 | }, 1152 | "diff-sequences": { 1153 | "version": "27.0.6", 1154 | "resolved": "https://registry.nlark.com/diff-sequences/download/diff-sequences-27.0.6.tgz?cache=0&sync_timestamp=1624900057366&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdiff-sequences%2Fdownload%2Fdiff-sequences-27.0.6.tgz", 1155 | "integrity": "sha1-MwXLLlWgM5JAVGlcxmAZ/X+OVyM=" 1156 | }, 1157 | "domexception": { 1158 | "version": "2.0.1", 1159 | "resolved": "https://registry.npmmirror.com/domexception/download/domexception-2.0.1.tgz", 1160 | "integrity": "sha1-+0Su+6eT4VdLCvau0oAdBXUp8wQ=", 1161 | "requires": { 1162 | "webidl-conversions": "^5.0.0" 1163 | }, 1164 | "dependencies": { 1165 | "webidl-conversions": { 1166 | "version": "5.0.0", 1167 | "resolved": "https://registry.nlark.com/webidl-conversions/download/webidl-conversions-5.0.0.tgz", 1168 | "integrity": "sha1-rlnIoAsSFUOirMZcBDT1ew/BGv8=" 1169 | } 1170 | } 1171 | }, 1172 | "electron-to-chromium": { 1173 | "version": "1.3.870", 1174 | "resolved": "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.3.870.tgz", 1175 | "integrity": "sha1-wVySHmakaYUYGyYfgJO5HCq7ZgQ=" 1176 | }, 1177 | "emittery": { 1178 | "version": "0.8.1", 1179 | "resolved": "https://registry.nlark.com/emittery/download/emittery-0.8.1.tgz", 1180 | "integrity": "sha1-uyPMhtA7MKp1p/c0gZ3uLhunCGA=" 1181 | }, 1182 | "emoji-regex": { 1183 | "version": "8.0.0", 1184 | "resolved": "https://registry.npmmirror.com/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1632751333727&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz", 1185 | "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=" 1186 | }, 1187 | "escalade": { 1188 | "version": "3.1.1", 1189 | "resolved": "https://registry.npm.taobao.org/escalade/download/escalade-3.1.1.tgz", 1190 | "integrity": "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA=" 1191 | }, 1192 | "escape-string-regexp": { 1193 | "version": "1.0.5", 1194 | "resolved": "https://registry.nlark.com/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", 1195 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 1196 | }, 1197 | "escodegen": { 1198 | "version": "2.0.0", 1199 | "resolved": "https://registry.nlark.com/escodegen/download/escodegen-2.0.0.tgz", 1200 | "integrity": "sha1-XjKxKDPoqo+jXhvwvvqJOASEx90=", 1201 | "requires": { 1202 | "esprima": "^4.0.1", 1203 | "estraverse": "^5.2.0", 1204 | "esutils": "^2.0.2", 1205 | "optionator": "^0.8.1", 1206 | "source-map": "~0.6.1" 1207 | } 1208 | }, 1209 | "esprima": { 1210 | "version": "4.0.1", 1211 | "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz", 1212 | "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=" 1213 | }, 1214 | "estraverse": { 1215 | "version": "5.2.0", 1216 | "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-5.2.0.tgz", 1217 | "integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=" 1218 | }, 1219 | "esutils": { 1220 | "version": "2.0.3", 1221 | "resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz", 1222 | "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=" 1223 | }, 1224 | "execa": { 1225 | "version": "5.1.1", 1226 | "resolved": "https://registry.nlark.com/execa/download/execa-5.1.1.tgz", 1227 | "integrity": "sha1-+ArZy/Qpj3vR1MlVXCHpN0HEEd0=", 1228 | "requires": { 1229 | "cross-spawn": "^7.0.3", 1230 | "get-stream": "^6.0.0", 1231 | "human-signals": "^2.1.0", 1232 | "is-stream": "^2.0.0", 1233 | "merge-stream": "^2.0.0", 1234 | "npm-run-path": "^4.0.1", 1235 | "onetime": "^5.1.2", 1236 | "signal-exit": "^3.0.3", 1237 | "strip-final-newline": "^2.0.0" 1238 | } 1239 | }, 1240 | "exit": { 1241 | "version": "0.1.2", 1242 | "resolved": "https://registry.npm.taobao.org/exit/download/exit-0.1.2.tgz", 1243 | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" 1244 | }, 1245 | "expect": { 1246 | "version": "27.2.5", 1247 | "resolved": "https://registry.npmmirror.com/expect/download/expect-27.2.5.tgz?cache=0&sync_timestamp=1633701043669&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fexpect%2Fdownload%2Fexpect-27.2.5.tgz", 1248 | "integrity": "sha1-FhVKqmC02aWwraz+o+TWF49Lk/0=", 1249 | "requires": { 1250 | "@jest/types": "^27.2.5", 1251 | "ansi-styles": "^5.0.0", 1252 | "jest-get-type": "^27.0.6", 1253 | "jest-matcher-utils": "^27.2.5", 1254 | "jest-message-util": "^27.2.5", 1255 | "jest-regex-util": "^27.0.6" 1256 | }, 1257 | "dependencies": { 1258 | "ansi-styles": { 1259 | "version": "5.2.0", 1260 | "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-5.2.0.tgz?cache=0&sync_timestamp=1618995588464&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-5.2.0.tgz", 1261 | "integrity": "sha1-B0SWkK1Fd30ZJKwquy/IiV26g2s=" 1262 | } 1263 | } 1264 | }, 1265 | "fast-json-stable-stringify": { 1266 | "version": "2.1.0", 1267 | "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz?cache=0&sync_timestamp=1576340291001&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-json-stable-stringify%2Fdownload%2Ffast-json-stable-stringify-2.1.0.tgz", 1268 | "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=" 1269 | }, 1270 | "fast-levenshtein": { 1271 | "version": "2.0.6", 1272 | "resolved": "https://registry.nlark.com/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz", 1273 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 1274 | }, 1275 | "fb-watchman": { 1276 | "version": "2.0.1", 1277 | "resolved": "https://registry.npm.taobao.org/fb-watchman/download/fb-watchman-2.0.1.tgz", 1278 | "integrity": "sha1-/IT7OdJwnPP/bXQ3BhV7tXCKioU=", 1279 | "requires": { 1280 | "bser": "2.1.1" 1281 | } 1282 | }, 1283 | "fill-range": { 1284 | "version": "7.0.1", 1285 | "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz", 1286 | "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=", 1287 | "requires": { 1288 | "to-regex-range": "^5.0.1" 1289 | } 1290 | }, 1291 | "find-up": { 1292 | "version": "4.1.0", 1293 | "resolved": "https://registry.npmmirror.com/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1633618631704&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz", 1294 | "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", 1295 | "requires": { 1296 | "locate-path": "^5.0.0", 1297 | "path-exists": "^4.0.0" 1298 | } 1299 | }, 1300 | "form-data": { 1301 | "version": "3.0.1", 1302 | "resolved": "https://registry.nlark.com/form-data/download/form-data-3.0.1.tgz", 1303 | "integrity": "sha1-69U3kbeDVqma+aMA1CgsTV65dV8=", 1304 | "requires": { 1305 | "asynckit": "^0.4.0", 1306 | "combined-stream": "^1.0.8", 1307 | "mime-types": "^2.1.12" 1308 | } 1309 | }, 1310 | "fs.realpath": { 1311 | "version": "1.0.0", 1312 | "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz", 1313 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 1314 | }, 1315 | "fsevents": { 1316 | "version": "2.3.2", 1317 | "resolved": "https://registry.nlark.com/fsevents/download/fsevents-2.3.2.tgz", 1318 | "integrity": "sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=", 1319 | "optional": true 1320 | }, 1321 | "function-bind": { 1322 | "version": "1.1.1", 1323 | "resolved": "https://registry.nlark.com/function-bind/download/function-bind-1.1.1.tgz", 1324 | "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=" 1325 | }, 1326 | "gensync": { 1327 | "version": "1.0.0-beta.2", 1328 | "resolved": "https://registry.nlark.com/gensync/download/gensync-1.0.0-beta.2.tgz", 1329 | "integrity": "sha1-MqbudsPX9S1GsrGuXZP+qFgKJeA=" 1330 | }, 1331 | "get-caller-file": { 1332 | "version": "2.0.5", 1333 | "resolved": "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz", 1334 | "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=" 1335 | }, 1336 | "get-package-type": { 1337 | "version": "0.1.0", 1338 | "resolved": "https://registry.nlark.com/get-package-type/download/get-package-type-0.1.0.tgz", 1339 | "integrity": "sha1-jeLYA8/0TfO8bEVuZmizbDkm4Ro=" 1340 | }, 1341 | "get-stream": { 1342 | "version": "6.0.1", 1343 | "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-6.0.1.tgz", 1344 | "integrity": "sha1-omLY7vZ6ztV8KFKtYWdSakPL97c=" 1345 | }, 1346 | "glob": { 1347 | "version": "7.2.0", 1348 | "resolved": "https://registry.npmmirror.com/glob/download/glob-7.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fglob%2Fdownload%2Fglob-7.2.0.tgz", 1349 | "integrity": "sha1-0VU1r3cy4C6Uj0xBYovZECk/YCM=", 1350 | "requires": { 1351 | "fs.realpath": "^1.0.0", 1352 | "inflight": "^1.0.4", 1353 | "inherits": "2", 1354 | "minimatch": "^3.0.4", 1355 | "once": "^1.3.0", 1356 | "path-is-absolute": "^1.0.0" 1357 | } 1358 | }, 1359 | "globals": { 1360 | "version": "11.12.0", 1361 | "resolved": "https://registry.nlark.com/globals/download/globals-11.12.0.tgz", 1362 | "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=" 1363 | }, 1364 | "graceful-fs": { 1365 | "version": "4.2.8", 1366 | "resolved": "https://registry.nlark.com/graceful-fs/download/graceful-fs-4.2.8.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.8.tgz", 1367 | "integrity": "sha1-5BK40z9eAGWTy9PO5t+fLOu+gCo=" 1368 | }, 1369 | "has": { 1370 | "version": "1.0.3", 1371 | "resolved": "https://registry.nlark.com/has/download/has-1.0.3.tgz", 1372 | "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", 1373 | "requires": { 1374 | "function-bind": "^1.1.1" 1375 | } 1376 | }, 1377 | "has-flag": { 1378 | "version": "4.0.0", 1379 | "resolved": "https://registry.nlark.com/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1626715907927&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz", 1380 | "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=" 1381 | }, 1382 | "html-encoding-sniffer": { 1383 | "version": "2.0.1", 1384 | "resolved": "https://registry.nlark.com/html-encoding-sniffer/download/html-encoding-sniffer-2.0.1.tgz?cache=0&sync_timestamp=1632005059408&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhtml-encoding-sniffer%2Fdownload%2Fhtml-encoding-sniffer-2.0.1.tgz", 1385 | "integrity": "sha1-QqbcT9M/ACgRduiyN1nKTk+hhfM=", 1386 | "requires": { 1387 | "whatwg-encoding": "^1.0.5" 1388 | } 1389 | }, 1390 | "html-escaper": { 1391 | "version": "2.0.2", 1392 | "resolved": "https://registry.npm.taobao.org/html-escaper/download/html-escaper-2.0.2.tgz", 1393 | "integrity": "sha1-39YAJ9o2o238viNiYsAKWCJoFFM=" 1394 | }, 1395 | "http-proxy-agent": { 1396 | "version": "4.0.1", 1397 | "resolved": "https://registry.npmmirror.com/http-proxy-agent/download/http-proxy-agent-4.0.1.tgz?cache=0&sync_timestamp=1632357525203&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhttp-proxy-agent%2Fdownload%2Fhttp-proxy-agent-4.0.1.tgz", 1398 | "integrity": "sha1-ioyO9/WTLM+VPClsqCkblap0qjo=", 1399 | "requires": { 1400 | "@tootallnate/once": "1", 1401 | "agent-base": "6", 1402 | "debug": "4" 1403 | } 1404 | }, 1405 | "https-proxy-agent": { 1406 | "version": "5.0.0", 1407 | "resolved": "https://registry.nlark.com/https-proxy-agent/download/https-proxy-agent-5.0.0.tgz", 1408 | "integrity": "sha1-4qkFQqu2inYuCghQ9sntrf2FBrI=", 1409 | "requires": { 1410 | "agent-base": "6", 1411 | "debug": "4" 1412 | } 1413 | }, 1414 | "human-signals": { 1415 | "version": "2.1.0", 1416 | "resolved": "https://registry.nlark.com/human-signals/download/human-signals-2.1.0.tgz", 1417 | "integrity": "sha1-3JH8ukLk0G5Kuu0zs+ejwC9RTqA=" 1418 | }, 1419 | "iconv-lite": { 1420 | "version": "0.4.24", 1421 | "resolved": "https://registry.nlark.com/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1621826342262&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz", 1422 | "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", 1423 | "requires": { 1424 | "safer-buffer": ">= 2.1.2 < 3" 1425 | } 1426 | }, 1427 | "import-local": { 1428 | "version": "3.0.3", 1429 | "resolved": "https://registry.npmmirror.com/import-local/download/import-local-3.0.3.tgz?cache=0&sync_timestamp=1633327317807&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fimport-local%2Fdownload%2Fimport-local-3.0.3.tgz", 1430 | "integrity": "sha1-TVHCxJXKk5PaJZ7Ga2LgIpICEeA=", 1431 | "requires": { 1432 | "pkg-dir": "^4.2.0", 1433 | "resolve-cwd": "^3.0.0" 1434 | } 1435 | }, 1436 | "imurmurhash": { 1437 | "version": "0.1.4", 1438 | "resolved": "https://registry.nlark.com/imurmurhash/download/imurmurhash-0.1.4.tgz", 1439 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 1440 | }, 1441 | "inflight": { 1442 | "version": "1.0.6", 1443 | "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz", 1444 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1445 | "requires": { 1446 | "once": "^1.3.0", 1447 | "wrappy": "1" 1448 | } 1449 | }, 1450 | "inherits": { 1451 | "version": "2.0.4", 1452 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz", 1453 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" 1454 | }, 1455 | "is-ci": { 1456 | "version": "3.0.0", 1457 | "resolved": "https://registry.nlark.com/is-ci/download/is-ci-3.0.0.tgz?cache=0&sync_timestamp=1618847026826&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fis-ci%2Fdownload%2Fis-ci-3.0.0.tgz", 1458 | "integrity": "sha1-x+e+PJ2O730PoUQ5C9HkuI3EyZQ=", 1459 | "requires": { 1460 | "ci-info": "^3.1.1" 1461 | } 1462 | }, 1463 | "is-core-module": { 1464 | "version": "2.8.0", 1465 | "resolved": "https://registry.npmmirror.com/is-core-module/download/is-core-module-2.8.0.tgz", 1466 | "integrity": "sha1-AyEzbD0JJeSX/Zf12VyxFKXM1Ug=", 1467 | "requires": { 1468 | "has": "^1.0.3" 1469 | } 1470 | }, 1471 | "is-fullwidth-code-point": { 1472 | "version": "3.0.0", 1473 | "resolved": "https://registry.nlark.com/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz", 1474 | "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=" 1475 | }, 1476 | "is-generator-fn": { 1477 | "version": "2.1.0", 1478 | "resolved": "https://registry.nlark.com/is-generator-fn/download/is-generator-fn-2.1.0.tgz", 1479 | "integrity": "sha1-fRQK3DiarzARqPKipM+m+q3/sRg=" 1480 | }, 1481 | "is-number": { 1482 | "version": "7.0.0", 1483 | "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz", 1484 | "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=" 1485 | }, 1486 | "is-potential-custom-element-name": { 1487 | "version": "1.0.1", 1488 | "resolved": "https://registry.nlark.com/is-potential-custom-element-name/download/is-potential-custom-element-name-1.0.1.tgz", 1489 | "integrity": "sha1-Fx7W8Z46xVQ5Tt94yqBXhKRb67U=" 1490 | }, 1491 | "is-stream": { 1492 | "version": "2.0.1", 1493 | "resolved": "https://registry.nlark.com/is-stream/download/is-stream-2.0.1.tgz", 1494 | "integrity": "sha1-+sHj1TuXrVqdCunO8jifWBClwHc=" 1495 | }, 1496 | "is-typedarray": { 1497 | "version": "1.0.0", 1498 | "resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz", 1499 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 1500 | }, 1501 | "isexe": { 1502 | "version": "2.0.0", 1503 | "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz", 1504 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 1505 | }, 1506 | "istanbul-lib-coverage": { 1507 | "version": "3.0.2", 1508 | "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/download/istanbul-lib-coverage-3.0.2.tgz?cache=0&sync_timestamp=1633993102487&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fistanbul-lib-coverage%2Fdownload%2Fistanbul-lib-coverage-3.0.2.tgz", 1509 | "integrity": "sha1-NnhtTYKq0upZEQB+JV4tprX4DYY=" 1510 | }, 1511 | "istanbul-lib-instrument": { 1512 | "version": "4.0.3", 1513 | "resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/download/istanbul-lib-instrument-4.0.3.tgz?cache=0&sync_timestamp=1633533408700&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fistanbul-lib-instrument%2Fdownload%2Fistanbul-lib-instrument-4.0.3.tgz", 1514 | "integrity": "sha1-hzxv/4l0UBGCIndGlqPyiQLXfB0=", 1515 | "requires": { 1516 | "@babel/core": "^7.7.5", 1517 | "@istanbuljs/schema": "^0.1.2", 1518 | "istanbul-lib-coverage": "^3.0.0", 1519 | "semver": "^6.3.0" 1520 | } 1521 | }, 1522 | "istanbul-lib-report": { 1523 | "version": "3.0.0", 1524 | "resolved": "https://registry.npm.taobao.org/istanbul-lib-report/download/istanbul-lib-report-3.0.0.tgz", 1525 | "integrity": "sha1-dRj+UupE3jcvRgp2tezan/tz2KY=", 1526 | "requires": { 1527 | "istanbul-lib-coverage": "^3.0.0", 1528 | "make-dir": "^3.0.0", 1529 | "supports-color": "^7.1.0" 1530 | } 1531 | }, 1532 | "istanbul-lib-source-maps": { 1533 | "version": "4.0.1", 1534 | "resolved": "https://registry.npmmirror.com/istanbul-lib-source-maps/download/istanbul-lib-source-maps-4.0.1.tgz", 1535 | "integrity": "sha1-iV86cJ/PujTG3lpCk5Ai8+Q1hVE=", 1536 | "requires": { 1537 | "debug": "^4.1.1", 1538 | "istanbul-lib-coverage": "^3.0.0", 1539 | "source-map": "^0.6.1" 1540 | } 1541 | }, 1542 | "istanbul-reports": { 1543 | "version": "3.0.5", 1544 | "resolved": "https://registry.npmmirror.com/istanbul-reports/download/istanbul-reports-3.0.5.tgz", 1545 | "integrity": "sha1-olgBB+cSeeptZh3e3pKf/G1pM4Q=", 1546 | "requires": { 1547 | "html-escaper": "^2.0.0", 1548 | "istanbul-lib-report": "^3.0.0" 1549 | } 1550 | }, 1551 | "jest": { 1552 | "version": "27.2.5", 1553 | "resolved": "https://registry.npmmirror.com/jest/download/jest-27.2.5.tgz", 1554 | "integrity": "sha1-fYpch4GhYPaTvut8aORsFu+UgUg=", 1555 | "requires": { 1556 | "@jest/core": "^27.2.5", 1557 | "import-local": "^3.0.2", 1558 | "jest-cli": "^27.2.5" 1559 | }, 1560 | "dependencies": { 1561 | "jest-cli": { 1562 | "version": "27.2.5", 1563 | "resolved": "https://registry.npmmirror.com/jest-cli/download/jest-cli-27.2.5.tgz", 1564 | "integrity": "sha1-iHGMjwXxwPIJFSlS7NYa/kwzEbs=", 1565 | "requires": { 1566 | "@jest/core": "^27.2.5", 1567 | "@jest/test-result": "^27.2.5", 1568 | "@jest/types": "^27.2.5", 1569 | "chalk": "^4.0.0", 1570 | "exit": "^0.1.2", 1571 | "graceful-fs": "^4.2.4", 1572 | "import-local": "^3.0.2", 1573 | "jest-config": "^27.2.5", 1574 | "jest-util": "^27.2.5", 1575 | "jest-validate": "^27.2.5", 1576 | "prompts": "^2.0.1", 1577 | "yargs": "^16.2.0" 1578 | } 1579 | } 1580 | } 1581 | }, 1582 | "jest-changed-files": { 1583 | "version": "27.2.5", 1584 | "resolved": "https://registry.npmmirror.com/jest-changed-files/download/jest-changed-files-27.2.5.tgz?cache=0&sync_timestamp=1633701041412&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-changed-files%2Fdownload%2Fjest-changed-files-27.2.5.tgz", 1585 | "integrity": "sha1-nf1VDRWCYLy2+oCv9JH1ZH99rso=", 1586 | "requires": { 1587 | "@jest/types": "^27.2.5", 1588 | "execa": "^5.0.0", 1589 | "throat": "^6.0.1" 1590 | } 1591 | }, 1592 | "jest-circus": { 1593 | "version": "27.2.5", 1594 | "resolved": "https://registry.npmmirror.com/jest-circus/download/jest-circus-27.2.5.tgz?cache=0&sync_timestamp=1633701315294&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-circus%2Fdownload%2Fjest-circus-27.2.5.tgz", 1595 | "integrity": "sha1-VzJWpvtuRHrC/H4K3pN1ATMJA38=", 1596 | "requires": { 1597 | "@jest/environment": "^27.2.5", 1598 | "@jest/test-result": "^27.2.5", 1599 | "@jest/types": "^27.2.5", 1600 | "@types/node": "*", 1601 | "chalk": "^4.0.0", 1602 | "co": "^4.6.0", 1603 | "dedent": "^0.7.0", 1604 | "expect": "^27.2.5", 1605 | "is-generator-fn": "^2.0.0", 1606 | "jest-each": "^27.2.5", 1607 | "jest-matcher-utils": "^27.2.5", 1608 | "jest-message-util": "^27.2.5", 1609 | "jest-runtime": "^27.2.5", 1610 | "jest-snapshot": "^27.2.5", 1611 | "jest-util": "^27.2.5", 1612 | "pretty-format": "^27.2.5", 1613 | "slash": "^3.0.0", 1614 | "stack-utils": "^2.0.3", 1615 | "throat": "^6.0.1" 1616 | } 1617 | }, 1618 | "jest-config": { 1619 | "version": "27.2.5", 1620 | "resolved": "https://registry.npmmirror.com/jest-config/download/jest-config-27.2.5.tgz", 1621 | "integrity": "sha1-wuTsbqK/T/0srj2SeZn+YVnLogc=", 1622 | "requires": { 1623 | "@babel/core": "^7.1.0", 1624 | "@jest/test-sequencer": "^27.2.5", 1625 | "@jest/types": "^27.2.5", 1626 | "babel-jest": "^27.2.5", 1627 | "chalk": "^4.0.0", 1628 | "deepmerge": "^4.2.2", 1629 | "glob": "^7.1.1", 1630 | "graceful-fs": "^4.2.4", 1631 | "is-ci": "^3.0.0", 1632 | "jest-circus": "^27.2.5", 1633 | "jest-environment-jsdom": "^27.2.5", 1634 | "jest-environment-node": "^27.2.5", 1635 | "jest-get-type": "^27.0.6", 1636 | "jest-jasmine2": "^27.2.5", 1637 | "jest-regex-util": "^27.0.6", 1638 | "jest-resolve": "^27.2.5", 1639 | "jest-runner": "^27.2.5", 1640 | "jest-util": "^27.2.5", 1641 | "jest-validate": "^27.2.5", 1642 | "micromatch": "^4.0.4", 1643 | "pretty-format": "^27.2.5" 1644 | } 1645 | }, 1646 | "jest-diff": { 1647 | "version": "27.2.5", 1648 | "resolved": "https://registry.npmmirror.com/jest-diff/download/jest-diff-27.2.5.tgz?cache=0&sync_timestamp=1633701044655&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-diff%2Fdownload%2Fjest-diff-27.2.5.tgz", 1649 | "integrity": "sha1-kI96aspWU4JFFq0w4Kn9l2flNiM=", 1650 | "requires": { 1651 | "chalk": "^4.0.0", 1652 | "diff-sequences": "^27.0.6", 1653 | "jest-get-type": "^27.0.6", 1654 | "pretty-format": "^27.2.5" 1655 | } 1656 | }, 1657 | "jest-docblock": { 1658 | "version": "27.0.6", 1659 | "resolved": "https://registry.nlark.com/jest-docblock/download/jest-docblock-27.0.6.tgz", 1660 | "integrity": "sha1-zHgmas9/5pPKRiy72g6k5jnk5fM=", 1661 | "requires": { 1662 | "detect-newline": "^3.0.0" 1663 | } 1664 | }, 1665 | "jest-each": { 1666 | "version": "27.2.5", 1667 | "resolved": "https://registry.npmmirror.com/jest-each/download/jest-each-27.2.5.tgz?cache=0&sync_timestamp=1633701045095&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-each%2Fdownload%2Fjest-each-27.2.5.tgz", 1668 | "integrity": "sha1-N4EY1RbbcwuSCWqWB7hxEWWUY1M=", 1669 | "requires": { 1670 | "@jest/types": "^27.2.5", 1671 | "chalk": "^4.0.0", 1672 | "jest-get-type": "^27.0.6", 1673 | "jest-util": "^27.2.5", 1674 | "pretty-format": "^27.2.5" 1675 | } 1676 | }, 1677 | "jest-environment-jsdom": { 1678 | "version": "27.2.5", 1679 | "resolved": "https://registry.npmmirror.com/jest-environment-jsdom/download/jest-environment-jsdom-27.2.5.tgz?cache=0&sync_timestamp=1633701043685&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-environment-jsdom%2Fdownload%2Fjest-environment-jsdom-27.2.5.tgz", 1680 | "integrity": "sha1-Id460OiUQdlhtZK6dWGxYkEnkgg=", 1681 | "requires": { 1682 | "@jest/environment": "^27.2.5", 1683 | "@jest/fake-timers": "^27.2.5", 1684 | "@jest/types": "^27.2.5", 1685 | "@types/node": "*", 1686 | "jest-mock": "^27.2.5", 1687 | "jest-util": "^27.2.5", 1688 | "jsdom": "^16.6.0" 1689 | } 1690 | }, 1691 | "jest-environment-node": { 1692 | "version": "27.2.5", 1693 | "resolved": "https://registry.npmmirror.com/jest-environment-node/download/jest-environment-node-27.2.5.tgz?cache=0&sync_timestamp=1633701043715&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-environment-node%2Fdownload%2Fjest-environment-node-27.2.5.tgz", 1694 | "integrity": "sha1-/6Gvs2BMZA7IQfBE1SbGWRLgLO8=", 1695 | "requires": { 1696 | "@jest/environment": "^27.2.5", 1697 | "@jest/fake-timers": "^27.2.5", 1698 | "@jest/types": "^27.2.5", 1699 | "@types/node": "*", 1700 | "jest-mock": "^27.2.5", 1701 | "jest-util": "^27.2.5" 1702 | } 1703 | }, 1704 | "jest-get-type": { 1705 | "version": "27.0.6", 1706 | "resolved": "https://registry.nlark.com/jest-get-type/download/jest-get-type-27.0.6.tgz?cache=0&sync_timestamp=1624900056951&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjest-get-type%2Fdownload%2Fjest-get-type-27.0.6.tgz", 1707 | "integrity": "sha1-DrXH91WFQnnOm2ip8aQSL2kEfP4=" 1708 | }, 1709 | "jest-haste-map": { 1710 | "version": "27.2.5", 1711 | "resolved": "https://registry.npmmirror.com/jest-haste-map/download/jest-haste-map-27.2.5.tgz?cache=0&sync_timestamp=1633701044155&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-haste-map%2Fdownload%2Fjest-haste-map-27.2.5.tgz", 1712 | "integrity": "sha1-Ake3KZJQZDRyu89bSthcctUXji4=", 1713 | "requires": { 1714 | "@jest/types": "^27.2.5", 1715 | "@types/graceful-fs": "^4.1.2", 1716 | "@types/node": "*", 1717 | "anymatch": "^3.0.3", 1718 | "fb-watchman": "^2.0.0", 1719 | "fsevents": "^2.3.2", 1720 | "graceful-fs": "^4.2.4", 1721 | "jest-regex-util": "^27.0.6", 1722 | "jest-serializer": "^27.0.6", 1723 | "jest-util": "^27.2.5", 1724 | "jest-worker": "^27.2.5", 1725 | "micromatch": "^4.0.4", 1726 | "walker": "^1.0.7" 1727 | } 1728 | }, 1729 | "jest-jasmine2": { 1730 | "version": "27.2.5", 1731 | "resolved": "https://registry.npmmirror.com/jest-jasmine2/download/jest-jasmine2-27.2.5.tgz", 1732 | "integrity": "sha1-uq+WxpkTxSvOAQAADPByECfA/WY=", 1733 | "requires": { 1734 | "@babel/traverse": "^7.1.0", 1735 | "@jest/environment": "^27.2.5", 1736 | "@jest/source-map": "^27.0.6", 1737 | "@jest/test-result": "^27.2.5", 1738 | "@jest/types": "^27.2.5", 1739 | "@types/node": "*", 1740 | "chalk": "^4.0.0", 1741 | "co": "^4.6.0", 1742 | "expect": "^27.2.5", 1743 | "is-generator-fn": "^2.0.0", 1744 | "jest-each": "^27.2.5", 1745 | "jest-matcher-utils": "^27.2.5", 1746 | "jest-message-util": "^27.2.5", 1747 | "jest-runtime": "^27.2.5", 1748 | "jest-snapshot": "^27.2.5", 1749 | "jest-util": "^27.2.5", 1750 | "pretty-format": "^27.2.5", 1751 | "throat": "^6.0.1" 1752 | } 1753 | }, 1754 | "jest-leak-detector": { 1755 | "version": "27.2.5", 1756 | "resolved": "https://registry.npmmirror.com/jest-leak-detector/download/jest-leak-detector-27.2.5.tgz?cache=0&sync_timestamp=1633701047111&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-leak-detector%2Fdownload%2Fjest-leak-detector-27.2.5.tgz", 1757 | "integrity": "sha1-4u3Ds3046NmlJ+EORWtAPDFRsgY=", 1758 | "requires": { 1759 | "jest-get-type": "^27.0.6", 1760 | "pretty-format": "^27.2.5" 1761 | } 1762 | }, 1763 | "jest-matcher-utils": { 1764 | "version": "27.2.5", 1765 | "resolved": "https://registry.npmmirror.com/jest-matcher-utils/download/jest-matcher-utils-27.2.5.tgz?cache=0&sync_timestamp=1633701047064&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-matcher-utils%2Fdownload%2Fjest-matcher-utils-27.2.5.tgz", 1766 | "integrity": "sha1-RoT6qo6zK/Febtrq1oNAMYl+KYA=", 1767 | "requires": { 1768 | "chalk": "^4.0.0", 1769 | "jest-diff": "^27.2.5", 1770 | "jest-get-type": "^27.0.6", 1771 | "pretty-format": "^27.2.5" 1772 | } 1773 | }, 1774 | "jest-message-util": { 1775 | "version": "27.2.5", 1776 | "resolved": "https://registry.npmmirror.com/jest-message-util/download/jest-message-util-27.2.5.tgz?cache=0&sync_timestamp=1633701043625&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-message-util%2Fdownload%2Fjest-message-util-27.2.5.tgz", 1777 | "integrity": "sha1-7Yt7CWUke7h1pJwfm5qy0dCCACg=", 1778 | "requires": { 1779 | "@babel/code-frame": "^7.12.13", 1780 | "@jest/types": "^27.2.5", 1781 | "@types/stack-utils": "^2.0.0", 1782 | "chalk": "^4.0.0", 1783 | "graceful-fs": "^4.2.4", 1784 | "micromatch": "^4.0.4", 1785 | "pretty-format": "^27.2.5", 1786 | "slash": "^3.0.0", 1787 | "stack-utils": "^2.0.3" 1788 | } 1789 | }, 1790 | "jest-mock": { 1791 | "version": "27.2.5", 1792 | "resolved": "https://registry.npmmirror.com/jest-mock/download/jest-mock-27.2.5.tgz?cache=0&sync_timestamp=1633701043679&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-mock%2Fdownload%2Fjest-mock-27.2.5.tgz", 1793 | "integrity": "sha1-DsONX/HknEgC56SoF56Nei/YTeA=", 1794 | "requires": { 1795 | "@jest/types": "^27.2.5", 1796 | "@types/node": "*" 1797 | } 1798 | }, 1799 | "jest-pnp-resolver": { 1800 | "version": "1.2.2", 1801 | "resolved": "https://registry.npm.taobao.org/jest-pnp-resolver/download/jest-pnp-resolver-1.2.2.tgz", 1802 | "integrity": "sha1-twSsCuAoqJEIpNBAs/kZ393I4zw=" 1803 | }, 1804 | "jest-regex-util": { 1805 | "version": "27.0.6", 1806 | "resolved": "https://registry.nlark.com/jest-regex-util/download/jest-regex-util-27.0.6.tgz?cache=0&sync_timestamp=1624900088428&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjest-regex-util%2Fdownload%2Fjest-regex-util-27.0.6.tgz", 1807 | "integrity": "sha1-AuESCCk1rpSc5dE7JnXbPYyH2cU=" 1808 | }, 1809 | "jest-resolve": { 1810 | "version": "27.2.5", 1811 | "resolved": "https://registry.npmmirror.com/jest-resolve/download/jest-resolve-27.2.5.tgz?cache=0&sync_timestamp=1633701044359&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-resolve%2Fdownload%2Fjest-resolve-27.2.5.tgz", 1812 | "integrity": "sha1-BNrb/BMSolQfXBmcUBGUXpz+XO8=", 1813 | "requires": { 1814 | "@jest/types": "^27.2.5", 1815 | "chalk": "^4.0.0", 1816 | "escalade": "^3.1.1", 1817 | "graceful-fs": "^4.2.4", 1818 | "jest-haste-map": "^27.2.5", 1819 | "jest-pnp-resolver": "^1.2.2", 1820 | "jest-util": "^27.2.5", 1821 | "jest-validate": "^27.2.5", 1822 | "resolve": "^1.20.0", 1823 | "slash": "^3.0.0" 1824 | } 1825 | }, 1826 | "jest-resolve-dependencies": { 1827 | "version": "27.2.5", 1828 | "resolved": "https://registry.npmmirror.com/jest-resolve-dependencies/download/jest-resolve-dependencies-27.2.5.tgz?cache=0&sync_timestamp=1633701044666&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-resolve-dependencies%2Fdownload%2Fjest-resolve-dependencies-27.2.5.tgz", 1829 | "integrity": "sha1-/NjsoAWz0RujLaRDBFwCgWS4O+E=", 1830 | "requires": { 1831 | "@jest/types": "^27.2.5", 1832 | "jest-regex-util": "^27.0.6", 1833 | "jest-snapshot": "^27.2.5" 1834 | } 1835 | }, 1836 | "jest-runner": { 1837 | "version": "27.2.5", 1838 | "resolved": "https://registry.npmmirror.com/jest-runner/download/jest-runner-27.2.5.tgz?cache=0&sync_timestamp=1633701043682&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-runner%2Fdownload%2Fjest-runner-27.2.5.tgz", 1839 | "integrity": "sha1-PZ0GJvNRSAuyz/z7v6wkDACX69Q=", 1840 | "requires": { 1841 | "@jest/console": "^27.2.5", 1842 | "@jest/environment": "^27.2.5", 1843 | "@jest/test-result": "^27.2.5", 1844 | "@jest/transform": "^27.2.5", 1845 | "@jest/types": "^27.2.5", 1846 | "@types/node": "*", 1847 | "chalk": "^4.0.0", 1848 | "emittery": "^0.8.1", 1849 | "exit": "^0.1.2", 1850 | "graceful-fs": "^4.2.4", 1851 | "jest-docblock": "^27.0.6", 1852 | "jest-environment-jsdom": "^27.2.5", 1853 | "jest-environment-node": "^27.2.5", 1854 | "jest-haste-map": "^27.2.5", 1855 | "jest-leak-detector": "^27.2.5", 1856 | "jest-message-util": "^27.2.5", 1857 | "jest-resolve": "^27.2.5", 1858 | "jest-runtime": "^27.2.5", 1859 | "jest-util": "^27.2.5", 1860 | "jest-worker": "^27.2.5", 1861 | "source-map-support": "^0.5.6", 1862 | "throat": "^6.0.1" 1863 | } 1864 | }, 1865 | "jest-runtime": { 1866 | "version": "27.2.5", 1867 | "resolved": "https://registry.npmmirror.com/jest-runtime/download/jest-runtime-27.2.5.tgz", 1868 | "integrity": "sha1-0UTD9oibknquHmlbY6QaMyO3AWs=", 1869 | "requires": { 1870 | "@jest/console": "^27.2.5", 1871 | "@jest/environment": "^27.2.5", 1872 | "@jest/fake-timers": "^27.2.5", 1873 | "@jest/globals": "^27.2.5", 1874 | "@jest/source-map": "^27.0.6", 1875 | "@jest/test-result": "^27.2.5", 1876 | "@jest/transform": "^27.2.5", 1877 | "@jest/types": "^27.2.5", 1878 | "@types/yargs": "^16.0.0", 1879 | "chalk": "^4.0.0", 1880 | "cjs-module-lexer": "^1.0.0", 1881 | "collect-v8-coverage": "^1.0.0", 1882 | "execa": "^5.0.0", 1883 | "exit": "^0.1.2", 1884 | "glob": "^7.1.3", 1885 | "graceful-fs": "^4.2.4", 1886 | "jest-haste-map": "^27.2.5", 1887 | "jest-message-util": "^27.2.5", 1888 | "jest-mock": "^27.2.5", 1889 | "jest-regex-util": "^27.0.6", 1890 | "jest-resolve": "^27.2.5", 1891 | "jest-snapshot": "^27.2.5", 1892 | "jest-util": "^27.2.5", 1893 | "jest-validate": "^27.2.5", 1894 | "slash": "^3.0.0", 1895 | "strip-bom": "^4.0.0", 1896 | "yargs": "^16.2.0" 1897 | } 1898 | }, 1899 | "jest-serializer": { 1900 | "version": "27.0.6", 1901 | "resolved": "https://registry.nlark.com/jest-serializer/download/jest-serializer-27.0.6.tgz", 1902 | "integrity": "sha1-k6bHTgEyuBotVGIyUcRsSYu1vsE=", 1903 | "requires": { 1904 | "@types/node": "*", 1905 | "graceful-fs": "^4.2.4" 1906 | } 1907 | }, 1908 | "jest-snapshot": { 1909 | "version": "27.2.5", 1910 | "resolved": "https://registry.npmmirror.com/jest-snapshot/download/jest-snapshot-27.2.5.tgz?cache=0&sync_timestamp=1633701044690&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-snapshot%2Fdownload%2Fjest-snapshot-27.2.5.tgz", 1911 | "integrity": "sha1-imEv4x4pZ/WK02RUIZjf9h+S7zI=", 1912 | "requires": { 1913 | "@babel/core": "^7.7.2", 1914 | "@babel/generator": "^7.7.2", 1915 | "@babel/parser": "^7.7.2", 1916 | "@babel/plugin-syntax-typescript": "^7.7.2", 1917 | "@babel/traverse": "^7.7.2", 1918 | "@babel/types": "^7.0.0", 1919 | "@jest/transform": "^27.2.5", 1920 | "@jest/types": "^27.2.5", 1921 | "@types/babel__traverse": "^7.0.4", 1922 | "@types/prettier": "^2.1.5", 1923 | "babel-preset-current-node-syntax": "^1.0.0", 1924 | "chalk": "^4.0.0", 1925 | "expect": "^27.2.5", 1926 | "graceful-fs": "^4.2.4", 1927 | "jest-diff": "^27.2.5", 1928 | "jest-get-type": "^27.0.6", 1929 | "jest-haste-map": "^27.2.5", 1930 | "jest-matcher-utils": "^27.2.5", 1931 | "jest-message-util": "^27.2.5", 1932 | "jest-resolve": "^27.2.5", 1933 | "jest-util": "^27.2.5", 1934 | "natural-compare": "^1.4.0", 1935 | "pretty-format": "^27.2.5", 1936 | "semver": "^7.3.2" 1937 | }, 1938 | "dependencies": { 1939 | "semver": { 1940 | "version": "7.3.5", 1941 | "resolved": "https://registry.nlark.com/semver/download/semver-7.3.5.tgz?cache=0&sync_timestamp=1618846864940&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-7.3.5.tgz", 1942 | "integrity": "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc=", 1943 | "requires": { 1944 | "lru-cache": "^6.0.0" 1945 | } 1946 | } 1947 | } 1948 | }, 1949 | "jest-util": { 1950 | "version": "27.2.5", 1951 | "resolved": "https://registry.npmmirror.com/jest-util/download/jest-util-27.2.5.tgz?cache=0&sync_timestamp=1633701042974&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-util%2Fdownload%2Fjest-util-27.2.5.tgz", 1952 | "integrity": "sha1-iHQMQCTSI2NKgs58ImPovG3zs7o=", 1953 | "requires": { 1954 | "@jest/types": "^27.2.5", 1955 | "@types/node": "*", 1956 | "chalk": "^4.0.0", 1957 | "graceful-fs": "^4.2.4", 1958 | "is-ci": "^3.0.0", 1959 | "picomatch": "^2.2.3" 1960 | } 1961 | }, 1962 | "jest-validate": { 1963 | "version": "27.2.5", 1964 | "resolved": "https://registry.npmmirror.com/jest-validate/download/jest-validate-27.2.5.tgz?cache=0&sync_timestamp=1633701043211&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-validate%2Fdownload%2Fjest-validate-27.2.5.tgz", 1965 | "integrity": "sha1-LVm/FifRgPOVuljyRZmw7g78+98=", 1966 | "requires": { 1967 | "@jest/types": "^27.2.5", 1968 | "camelcase": "^6.2.0", 1969 | "chalk": "^4.0.0", 1970 | "jest-get-type": "^27.0.6", 1971 | "leven": "^3.1.0", 1972 | "pretty-format": "^27.2.5" 1973 | }, 1974 | "dependencies": { 1975 | "camelcase": { 1976 | "version": "6.2.0", 1977 | "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-6.2.0.tgz", 1978 | "integrity": "sha1-kkr4gcnVJaydh/QNlk5c6pgqGAk=" 1979 | } 1980 | } 1981 | }, 1982 | "jest-watcher": { 1983 | "version": "27.2.5", 1984 | "resolved": "https://registry.npmmirror.com/jest-watcher/download/jest-watcher-27.2.5.tgz?cache=0&sync_timestamp=1633701044909&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjest-watcher%2Fdownload%2Fjest-watcher-27.2.5.tgz", 1985 | "integrity": "sha1-Qc0+ZNxb6opDJwg9cbp2Z75ABWc=", 1986 | "requires": { 1987 | "@jest/test-result": "^27.2.5", 1988 | "@jest/types": "^27.2.5", 1989 | "@types/node": "*", 1990 | "ansi-escapes": "^4.2.1", 1991 | "chalk": "^4.0.0", 1992 | "jest-util": "^27.2.5", 1993 | "string-length": "^4.0.1" 1994 | } 1995 | }, 1996 | "jest-worker": { 1997 | "version": "27.2.5", 1998 | "resolved": "https://registry.npmmirror.com/jest-worker/download/jest-worker-27.2.5.tgz", 1999 | "integrity": "sha1-7UKGVmGVlIiqAg6KMl3wEFl8NtQ=", 2000 | "requires": { 2001 | "@types/node": "*", 2002 | "merge-stream": "^2.0.0", 2003 | "supports-color": "^8.0.0" 2004 | }, 2005 | "dependencies": { 2006 | "supports-color": { 2007 | "version": "8.1.1", 2008 | "resolved": "https://registry.nlark.com/supports-color/download/supports-color-8.1.1.tgz", 2009 | "integrity": "sha1-zW/BfihQDP9WwbhsCn/UpUpzAFw=", 2010 | "requires": { 2011 | "has-flag": "^4.0.0" 2012 | } 2013 | } 2014 | } 2015 | }, 2016 | "js-tokens": { 2017 | "version": "4.0.0", 2018 | "resolved": "https://registry.nlark.com/js-tokens/download/js-tokens-4.0.0.tgz", 2019 | "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=" 2020 | }, 2021 | "js-yaml": { 2022 | "version": "3.14.1", 2023 | "resolved": "https://registry.nlark.com/js-yaml/download/js-yaml-3.14.1.tgz", 2024 | "integrity": "sha1-2ugS/bOCX6MGYJqHFzg8UMNqBTc=", 2025 | "requires": { 2026 | "argparse": "^1.0.7", 2027 | "esprima": "^4.0.0" 2028 | } 2029 | }, 2030 | "jsdom": { 2031 | "version": "16.7.0", 2032 | "resolved": "https://registry.npmmirror.com/jsdom/download/jsdom-16.7.0.tgz?cache=0&sync_timestamp=1633714173424&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fjsdom%2Fdownload%2Fjsdom-16.7.0.tgz", 2033 | "integrity": "sha1-kYrnGWVCSxl8gZ+Bg6dU4Yl3txA=", 2034 | "requires": { 2035 | "abab": "^2.0.5", 2036 | "acorn": "^8.2.4", 2037 | "acorn-globals": "^6.0.0", 2038 | "cssom": "^0.4.4", 2039 | "cssstyle": "^2.3.0", 2040 | "data-urls": "^2.0.0", 2041 | "decimal.js": "^10.2.1", 2042 | "domexception": "^2.0.1", 2043 | "escodegen": "^2.0.0", 2044 | "form-data": "^3.0.0", 2045 | "html-encoding-sniffer": "^2.0.1", 2046 | "http-proxy-agent": "^4.0.1", 2047 | "https-proxy-agent": "^5.0.0", 2048 | "is-potential-custom-element-name": "^1.0.1", 2049 | "nwsapi": "^2.2.0", 2050 | "parse5": "6.0.1", 2051 | "saxes": "^5.0.1", 2052 | "symbol-tree": "^3.2.4", 2053 | "tough-cookie": "^4.0.0", 2054 | "w3c-hr-time": "^1.0.2", 2055 | "w3c-xmlserializer": "^2.0.0", 2056 | "webidl-conversions": "^6.1.0", 2057 | "whatwg-encoding": "^1.0.5", 2058 | "whatwg-mimetype": "^2.3.0", 2059 | "whatwg-url": "^8.5.0", 2060 | "ws": "^7.4.6", 2061 | "xml-name-validator": "^3.0.0" 2062 | } 2063 | }, 2064 | "jsesc": { 2065 | "version": "2.5.2", 2066 | "resolved": "https://registry.nlark.com/jsesc/download/jsesc-2.5.2.tgz", 2067 | "integrity": "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q=" 2068 | }, 2069 | "json5": { 2070 | "version": "2.2.0", 2071 | "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.2.0.tgz", 2072 | "integrity": "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM=", 2073 | "requires": { 2074 | "minimist": "^1.2.5" 2075 | } 2076 | }, 2077 | "kleur": { 2078 | "version": "3.0.3", 2079 | "resolved": "https://registry.nlark.com/kleur/download/kleur-3.0.3.tgz", 2080 | "integrity": "sha1-p5yezIbuHOP6YgbRIWxQHxR/wH4=" 2081 | }, 2082 | "leven": { 2083 | "version": "3.1.0", 2084 | "resolved": "https://registry.nlark.com/leven/download/leven-3.1.0.tgz?cache=0&sync_timestamp=1628597917913&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fleven%2Fdownload%2Fleven-3.1.0.tgz", 2085 | "integrity": "sha1-d4kd6DQGTMy6gq54QrtrFKE+1/I=" 2086 | }, 2087 | "levn": { 2088 | "version": "0.3.0", 2089 | "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz", 2090 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 2091 | "requires": { 2092 | "prelude-ls": "~1.1.2", 2093 | "type-check": "~0.3.2" 2094 | } 2095 | }, 2096 | "locate-path": { 2097 | "version": "5.0.0", 2098 | "resolved": "https://registry.nlark.com/locate-path/download/locate-path-5.0.0.tgz", 2099 | "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", 2100 | "requires": { 2101 | "p-locate": "^4.1.0" 2102 | } 2103 | }, 2104 | "lodash": { 2105 | "version": "4.17.21", 2106 | "resolved": "https://registry.nlark.com/lodash/download/lodash-4.17.21.tgz?cache=0&sync_timestamp=1618847150612&other_urls=https%3A%2F%2Fregistry.nlark.com%2Flodash%2Fdownload%2Flodash-4.17.21.tgz", 2107 | "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=" 2108 | }, 2109 | "lodash.memoize": { 2110 | "version": "4.1.2", 2111 | "resolved": "https://registry.nlark.com/lodash.memoize/download/lodash.memoize-4.1.2.tgz", 2112 | "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" 2113 | }, 2114 | "lru-cache": { 2115 | "version": "6.0.0", 2116 | "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-6.0.0.tgz", 2117 | "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=", 2118 | "requires": { 2119 | "yallist": "^4.0.0" 2120 | } 2121 | }, 2122 | "make-dir": { 2123 | "version": "3.1.0", 2124 | "resolved": "https://registry.nlark.com/make-dir/download/make-dir-3.1.0.tgz", 2125 | "integrity": "sha1-QV6WcEazp/HRhSd9hKpYIDcmoT8=", 2126 | "requires": { 2127 | "semver": "^6.0.0" 2128 | } 2129 | }, 2130 | "make-error": { 2131 | "version": "1.3.6", 2132 | "resolved": "https://registry.npm.taobao.org/make-error/download/make-error-1.3.6.tgz", 2133 | "integrity": "sha1-LrLjfqm2fEiR9oShOUeZr0hM96I=" 2134 | }, 2135 | "makeerror": { 2136 | "version": "1.0.11", 2137 | "resolved": "https://registry.npm.taobao.org/makeerror/download/makeerror-1.0.11.tgz", 2138 | "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", 2139 | "requires": { 2140 | "tmpl": "1.0.x" 2141 | } 2142 | }, 2143 | "merge-stream": { 2144 | "version": "2.0.0", 2145 | "resolved": "https://registry.nlark.com/merge-stream/download/merge-stream-2.0.0.tgz", 2146 | "integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=" 2147 | }, 2148 | "micromatch": { 2149 | "version": "4.0.4", 2150 | "resolved": "https://registry.nlark.com/micromatch/download/micromatch-4.0.4.tgz", 2151 | "integrity": "sha1-iW1Rnf6dsl/OlM63pQCRm/iB6/k=", 2152 | "requires": { 2153 | "braces": "^3.0.1", 2154 | "picomatch": "^2.2.3" 2155 | } 2156 | }, 2157 | "mime-db": { 2158 | "version": "1.50.0", 2159 | "resolved": "https://registry.nlark.com/mime-db/download/mime-db-1.50.0.tgz?cache=0&sync_timestamp=1631863129751&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fmime-db%2Fdownload%2Fmime-db-1.50.0.tgz", 2160 | "integrity": "sha1-q9SslOmNPA4YUBbGerRdX95AwR8=" 2161 | }, 2162 | "mime-types": { 2163 | "version": "2.1.33", 2164 | "resolved": "https://registry.npmmirror.com/mime-types/download/mime-types-2.1.33.tgz?cache=0&sync_timestamp=1633108241037&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fmime-types%2Fdownload%2Fmime-types-2.1.33.tgz", 2165 | "integrity": "sha1-H6EqkERy+v0GjkjZ6EAfdNP3Dts=", 2166 | "requires": { 2167 | "mime-db": "1.50.0" 2168 | } 2169 | }, 2170 | "mimic-fn": { 2171 | "version": "2.1.0", 2172 | "resolved": "https://registry.nlark.com/mimic-fn/download/mimic-fn-2.1.0.tgz", 2173 | "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=" 2174 | }, 2175 | "minimatch": { 2176 | "version": "3.0.4", 2177 | "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz", 2178 | "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", 2179 | "requires": { 2180 | "brace-expansion": "^1.1.7" 2181 | } 2182 | }, 2183 | "minimist": { 2184 | "version": "1.2.6", 2185 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 2186 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" 2187 | }, 2188 | "ms": { 2189 | "version": "2.1.2", 2190 | "resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz", 2191 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" 2192 | }, 2193 | "natural-compare": { 2194 | "version": "1.4.0", 2195 | "resolved": "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz", 2196 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" 2197 | }, 2198 | "node-int64": { 2199 | "version": "0.4.0", 2200 | "resolved": "https://registry.npm.taobao.org/node-int64/download/node-int64-0.4.0.tgz", 2201 | "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" 2202 | }, 2203 | "node-modules-regexp": { 2204 | "version": "1.0.0", 2205 | "resolved": "https://registry.npm.taobao.org/node-modules-regexp/download/node-modules-regexp-1.0.0.tgz", 2206 | "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" 2207 | }, 2208 | "node-releases": { 2209 | "version": "2.0.0", 2210 | "resolved": "https://registry.npmmirror.com/node-releases/download/node-releases-2.0.0.tgz?cache=0&sync_timestamp=1634124829358&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fnode-releases%2Fdownload%2Fnode-releases-2.0.0.tgz", 2211 | "integrity": "sha1-Z9x0kDEAp96wRAN7ii5fRTuwVAA=" 2212 | }, 2213 | "normalize-path": { 2214 | "version": "3.0.0", 2215 | "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz", 2216 | "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=" 2217 | }, 2218 | "npm-run-path": { 2219 | "version": "4.0.1", 2220 | "resolved": "https://registry.npmmirror.com/npm-run-path/download/npm-run-path-4.0.1.tgz?cache=0&sync_timestamp=1633420549182&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-4.0.1.tgz", 2221 | "integrity": "sha1-t+zR5e1T2o43pV4cImnguX7XSOo=", 2222 | "requires": { 2223 | "path-key": "^3.0.0" 2224 | } 2225 | }, 2226 | "nwsapi": { 2227 | "version": "2.2.0", 2228 | "resolved": "https://registry.nlark.com/nwsapi/download/nwsapi-2.2.0.tgz", 2229 | "integrity": "sha1-IEh5qePQaP8qVROcLHcngGgaOLc=" 2230 | }, 2231 | "once": { 2232 | "version": "1.4.0", 2233 | "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", 2234 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2235 | "requires": { 2236 | "wrappy": "1" 2237 | } 2238 | }, 2239 | "onetime": { 2240 | "version": "5.1.2", 2241 | "resolved": "https://registry.nlark.com/onetime/download/onetime-5.1.2.tgz", 2242 | "integrity": "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=", 2243 | "requires": { 2244 | "mimic-fn": "^2.1.0" 2245 | } 2246 | }, 2247 | "optionator": { 2248 | "version": "0.8.3", 2249 | "resolved": "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz", 2250 | "integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=", 2251 | "requires": { 2252 | "deep-is": "~0.1.3", 2253 | "fast-levenshtein": "~2.0.6", 2254 | "levn": "~0.3.0", 2255 | "prelude-ls": "~1.1.2", 2256 | "type-check": "~0.3.2", 2257 | "word-wrap": "~1.2.3" 2258 | } 2259 | }, 2260 | "p-limit": { 2261 | "version": "2.3.0", 2262 | "resolved": "https://registry.nlark.com/p-limit/download/p-limit-2.3.0.tgz", 2263 | "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", 2264 | "requires": { 2265 | "p-try": "^2.0.0" 2266 | } 2267 | }, 2268 | "p-locate": { 2269 | "version": "4.1.0", 2270 | "resolved": "https://registry.nlark.com/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1629892721671&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz", 2271 | "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", 2272 | "requires": { 2273 | "p-limit": "^2.2.0" 2274 | } 2275 | }, 2276 | "p-try": { 2277 | "version": "2.2.0", 2278 | "resolved": "https://registry.npmmirror.com/p-try/download/p-try-2.2.0.tgz", 2279 | "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=" 2280 | }, 2281 | "parse5": { 2282 | "version": "6.0.1", 2283 | "resolved": "https://registry.nlark.com/parse5/download/parse5-6.0.1.tgz", 2284 | "integrity": "sha1-4aHAhcVps9wIMhGE8Zo5zCf3wws=" 2285 | }, 2286 | "path-exists": { 2287 | "version": "4.0.0", 2288 | "resolved": "https://registry.nlark.com/path-exists/download/path-exists-4.0.0.tgz", 2289 | "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=" 2290 | }, 2291 | "path-is-absolute": { 2292 | "version": "1.0.1", 2293 | "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz", 2294 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 2295 | }, 2296 | "path-key": { 2297 | "version": "3.1.1", 2298 | "resolved": "https://registry.nlark.com/path-key/download/path-key-3.1.1.tgz", 2299 | "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=" 2300 | }, 2301 | "path-parse": { 2302 | "version": "1.0.7", 2303 | "resolved": "https://registry.nlark.com/path-parse/download/path-parse-1.0.7.tgz", 2304 | "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=" 2305 | }, 2306 | "picocolors": { 2307 | "version": "1.0.0", 2308 | "resolved": "https://registry.npmmirror.com/picocolors/download/picocolors-1.0.0.tgz?cache=0&sync_timestamp=1634093378416&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fpicocolors%2Fdownload%2Fpicocolors-1.0.0.tgz", 2309 | "integrity": "sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw=" 2310 | }, 2311 | "picomatch": { 2312 | "version": "2.3.0", 2313 | "resolved": "https://registry.nlark.com/picomatch/download/picomatch-2.3.0.tgz?cache=0&sync_timestamp=1621648246651&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpicomatch%2Fdownload%2Fpicomatch-2.3.0.tgz", 2314 | "integrity": "sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI=" 2315 | }, 2316 | "pirates": { 2317 | "version": "4.0.1", 2318 | "resolved": "https://registry.npm.taobao.org/pirates/download/pirates-4.0.1.tgz", 2319 | "integrity": "sha1-ZDqSyviUVm+RsrmG0sZpUKji+4c=", 2320 | "requires": { 2321 | "node-modules-regexp": "^1.0.0" 2322 | } 2323 | }, 2324 | "pkg-dir": { 2325 | "version": "4.2.0", 2326 | "resolved": "https://registry.npmmirror.com/pkg-dir/download/pkg-dir-4.2.0.tgz?cache=0&sync_timestamp=1633498133295&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fpkg-dir%2Fdownload%2Fpkg-dir-4.2.0.tgz", 2327 | "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=", 2328 | "requires": { 2329 | "find-up": "^4.0.0" 2330 | } 2331 | }, 2332 | "prelude-ls": { 2333 | "version": "1.1.2", 2334 | "resolved": "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz", 2335 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 2336 | }, 2337 | "pretty-format": { 2338 | "version": "27.2.5", 2339 | "resolved": "https://registry.npmmirror.com/pretty-format/download/pretty-format-27.2.5.tgz?cache=0&sync_timestamp=1633701045920&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fpretty-format%2Fdownload%2Fpretty-format-27.2.5.tgz", 2340 | "integrity": "sha1-fP4qjo8BpbWykpagtw9BQN8IMMU=", 2341 | "requires": { 2342 | "@jest/types": "^27.2.5", 2343 | "ansi-regex": "^5.0.1", 2344 | "ansi-styles": "^5.0.0", 2345 | "react-is": "^17.0.1" 2346 | }, 2347 | "dependencies": { 2348 | "ansi-styles": { 2349 | "version": "5.2.0", 2350 | "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-5.2.0.tgz?cache=0&sync_timestamp=1618995588464&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-5.2.0.tgz", 2351 | "integrity": "sha1-B0SWkK1Fd30ZJKwquy/IiV26g2s=" 2352 | } 2353 | } 2354 | }, 2355 | "prompts": { 2356 | "version": "2.4.2", 2357 | "resolved": "https://registry.npmmirror.com/prompts/download/prompts-2.4.2.tgz", 2358 | "integrity": "sha1-e1fnOzpIAprRDr1E90sBcipMsGk=", 2359 | "requires": { 2360 | "kleur": "^3.0.3", 2361 | "sisteransi": "^1.0.5" 2362 | } 2363 | }, 2364 | "psl": { 2365 | "version": "1.8.0", 2366 | "resolved": "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz", 2367 | "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ=" 2368 | }, 2369 | "punycode": { 2370 | "version": "2.1.1", 2371 | "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz", 2372 | "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" 2373 | }, 2374 | "react-is": { 2375 | "version": "17.0.2", 2376 | "resolved": "https://registry.npmmirror.com/react-is/download/react-is-17.0.2.tgz?cache=0&sync_timestamp=1634230618572&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-is%2Fdownload%2Freact-is-17.0.2.tgz", 2377 | "integrity": "sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA=" 2378 | }, 2379 | "require-directory": { 2380 | "version": "2.1.1", 2381 | "resolved": "https://registry.nlark.com/require-directory/download/require-directory-2.1.1.tgz", 2382 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 2383 | }, 2384 | "resolve": { 2385 | "version": "1.20.0", 2386 | "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.20.0.tgz", 2387 | "integrity": "sha1-YpoBP7P3B1XW8LeTXMHCxTeLGXU=", 2388 | "requires": { 2389 | "is-core-module": "^2.2.0", 2390 | "path-parse": "^1.0.6" 2391 | } 2392 | }, 2393 | "resolve-cwd": { 2394 | "version": "3.0.0", 2395 | "resolved": "https://registry.nlark.com/resolve-cwd/download/resolve-cwd-3.0.0.tgz", 2396 | "integrity": "sha1-DwB18bslRHZs9zumpuKt/ryxPy0=", 2397 | "requires": { 2398 | "resolve-from": "^5.0.0" 2399 | } 2400 | }, 2401 | "resolve-from": { 2402 | "version": "5.0.0", 2403 | "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-5.0.0.tgz", 2404 | "integrity": "sha1-w1IlhD3493bfIcV1V7wIfp39/Gk=" 2405 | }, 2406 | "rimraf": { 2407 | "version": "3.0.2", 2408 | "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-3.0.2.tgz", 2409 | "integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=", 2410 | "requires": { 2411 | "glob": "^7.1.3" 2412 | } 2413 | }, 2414 | "safe-buffer": { 2415 | "version": "5.1.2", 2416 | "resolved": "https://registry.nlark.com/safe-buffer/download/safe-buffer-5.1.2.tgz", 2417 | "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" 2418 | }, 2419 | "safer-buffer": { 2420 | "version": "2.1.2", 2421 | "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz", 2422 | "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" 2423 | }, 2424 | "saxes": { 2425 | "version": "5.0.1", 2426 | "resolved": "https://registry.nlark.com/saxes/download/saxes-5.0.1.tgz", 2427 | "integrity": "sha1-7rq5U/o7dgjb6U5drbFciI+maW0=", 2428 | "requires": { 2429 | "xmlchars": "^2.2.0" 2430 | } 2431 | }, 2432 | "semver": { 2433 | "version": "6.3.0", 2434 | "resolved": "https://registry.nlark.com/semver/download/semver-6.3.0.tgz?cache=0&sync_timestamp=1618846864940&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz", 2435 | "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=" 2436 | }, 2437 | "shebang-command": { 2438 | "version": "2.0.0", 2439 | "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz", 2440 | "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", 2441 | "requires": { 2442 | "shebang-regex": "^3.0.0" 2443 | } 2444 | }, 2445 | "shebang-regex": { 2446 | "version": "3.0.0", 2447 | "resolved": "https://registry.nlark.com/shebang-regex/download/shebang-regex-3.0.0.tgz", 2448 | "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=" 2449 | }, 2450 | "signal-exit": { 2451 | "version": "3.0.5", 2452 | "resolved": "https://registry.npmmirror.com/signal-exit/download/signal-exit-3.0.5.tgz?cache=0&sync_timestamp=1632948374592&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fsignal-exit%2Fdownload%2Fsignal-exit-3.0.5.tgz", 2453 | "integrity": "sha1-nj6MwMdamUcrRDIQM6dwLnc4JS8=" 2454 | }, 2455 | "sisteransi": { 2456 | "version": "1.0.5", 2457 | "resolved": "https://registry.npm.taobao.org/sisteransi/download/sisteransi-1.0.5.tgz", 2458 | "integrity": "sha1-E01oEpd1ZDfMBcoBNw06elcQde0=" 2459 | }, 2460 | "slash": { 2461 | "version": "3.0.0", 2462 | "resolved": "https://registry.nlark.com/slash/download/slash-3.0.0.tgz", 2463 | "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=" 2464 | }, 2465 | "source-map": { 2466 | "version": "0.6.1", 2467 | "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz", 2468 | "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" 2469 | }, 2470 | "source-map-support": { 2471 | "version": "0.5.20", 2472 | "resolved": "https://registry.nlark.com/source-map-support/download/source-map-support-0.5.20.tgz", 2473 | "integrity": "sha1-EhZgifj15ejFaSazd2Mzkt0stsk=", 2474 | "requires": { 2475 | "buffer-from": "^1.0.0", 2476 | "source-map": "^0.6.0" 2477 | } 2478 | }, 2479 | "sprintf-js": { 2480 | "version": "1.0.3", 2481 | "resolved": "https://registry.nlark.com/sprintf-js/download/sprintf-js-1.0.3.tgz", 2482 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 2483 | }, 2484 | "stack-utils": { 2485 | "version": "2.0.5", 2486 | "resolved": "https://registry.nlark.com/stack-utils/download/stack-utils-2.0.5.tgz", 2487 | "integrity": "sha1-0lJl/KmVFUZZ27+6O0klR3jS/dU=", 2488 | "requires": { 2489 | "escape-string-regexp": "^2.0.0" 2490 | }, 2491 | "dependencies": { 2492 | "escape-string-regexp": { 2493 | "version": "2.0.0", 2494 | "resolved": "https://registry.nlark.com/escape-string-regexp/download/escape-string-regexp-2.0.0.tgz", 2495 | "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=" 2496 | } 2497 | } 2498 | }, 2499 | "string-length": { 2500 | "version": "4.0.2", 2501 | "resolved": "https://registry.nlark.com/string-length/download/string-length-4.0.2.tgz?cache=0&sync_timestamp=1631558009435&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fstring-length%2Fdownload%2Fstring-length-4.0.2.tgz", 2502 | "integrity": "sha1-qKjce9XBqCubPIuH4SX2aHG25Xo=", 2503 | "requires": { 2504 | "char-regex": "^1.0.2", 2505 | "strip-ansi": "^6.0.0" 2506 | } 2507 | }, 2508 | "string-width": { 2509 | "version": "4.2.3", 2510 | "resolved": "https://registry.npmmirror.com/string-width/download/string-width-4.2.3.tgz?cache=0&sync_timestamp=1632421309919&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fstring-width%2Fdownload%2Fstring-width-4.2.3.tgz", 2511 | "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=", 2512 | "requires": { 2513 | "emoji-regex": "^8.0.0", 2514 | "is-fullwidth-code-point": "^3.0.0", 2515 | "strip-ansi": "^6.0.1" 2516 | } 2517 | }, 2518 | "strip-ansi": { 2519 | "version": "6.0.1", 2520 | "resolved": "https://registry.npmmirror.com/strip-ansi/download/strip-ansi-6.0.1.tgz", 2521 | "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", 2522 | "requires": { 2523 | "ansi-regex": "^5.0.1" 2524 | } 2525 | }, 2526 | "strip-bom": { 2527 | "version": "4.0.0", 2528 | "resolved": "https://registry.nlark.com/strip-bom/download/strip-bom-4.0.0.tgz", 2529 | "integrity": "sha1-nDUFwdtFvO3KPZz3oW9cWqOQGHg=" 2530 | }, 2531 | "strip-final-newline": { 2532 | "version": "2.0.0", 2533 | "resolved": "https://registry.nlark.com/strip-final-newline/download/strip-final-newline-2.0.0.tgz", 2534 | "integrity": "sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0=" 2535 | }, 2536 | "supports-color": { 2537 | "version": "7.2.0", 2538 | "resolved": "https://registry.nlark.com/supports-color/download/supports-color-7.2.0.tgz", 2539 | "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", 2540 | "requires": { 2541 | "has-flag": "^4.0.0" 2542 | } 2543 | }, 2544 | "supports-hyperlinks": { 2545 | "version": "2.2.0", 2546 | "resolved": "https://registry.npm.taobao.org/supports-hyperlinks/download/supports-hyperlinks-2.2.0.tgz?cache=0&sync_timestamp=1617751242412&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-hyperlinks%2Fdownload%2Fsupports-hyperlinks-2.2.0.tgz", 2547 | "integrity": "sha1-T3e0JIh2WJF3S3DHm6vYf5vVlLs=", 2548 | "requires": { 2549 | "has-flag": "^4.0.0", 2550 | "supports-color": "^7.0.0" 2551 | } 2552 | }, 2553 | "symbol-tree": { 2554 | "version": "3.2.4", 2555 | "resolved": "https://registry.npm.taobao.org/symbol-tree/download/symbol-tree-3.2.4.tgz", 2556 | "integrity": "sha1-QwY30ki6d+B4iDlR+5qg7tfGP6I=" 2557 | }, 2558 | "terminal-link": { 2559 | "version": "2.1.1", 2560 | "resolved": "https://registry.npm.taobao.org/terminal-link/download/terminal-link-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterminal-link%2Fdownload%2Fterminal-link-2.1.1.tgz", 2561 | "integrity": "sha1-FKZKJ6s8Dfkz6lRvulXy0HjtyZQ=", 2562 | "requires": { 2563 | "ansi-escapes": "^4.2.1", 2564 | "supports-hyperlinks": "^2.0.0" 2565 | } 2566 | }, 2567 | "test-exclude": { 2568 | "version": "6.0.0", 2569 | "resolved": "https://registry.npm.taobao.org/test-exclude/download/test-exclude-6.0.0.tgz", 2570 | "integrity": "sha1-BKhphmHYBepvopO2y55jrARO8V4=", 2571 | "requires": { 2572 | "@istanbuljs/schema": "^0.1.2", 2573 | "glob": "^7.1.4", 2574 | "minimatch": "^3.0.4" 2575 | } 2576 | }, 2577 | "throat": { 2578 | "version": "6.0.1", 2579 | "resolved": "https://registry.npm.taobao.org/throat/download/throat-6.0.1.tgz", 2580 | "integrity": "sha1-1RT+2tlXQMEsLX/HDqhj61Gt43U=" 2581 | }, 2582 | "tmpl": { 2583 | "version": "1.0.5", 2584 | "resolved": "https://registry.nlark.com/tmpl/download/tmpl-1.0.5.tgz?cache=0&sync_timestamp=1630997200432&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftmpl%2Fdownload%2Ftmpl-1.0.5.tgz", 2585 | "integrity": "sha1-hoPguQK7nCDE9ybjwLafNlGMB8w=" 2586 | }, 2587 | "to-fast-properties": { 2588 | "version": "2.0.0", 2589 | "resolved": "https://registry.nlark.com/to-fast-properties/download/to-fast-properties-2.0.0.tgz?cache=0&sync_timestamp=1628418893613&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fto-fast-properties%2Fdownload%2Fto-fast-properties-2.0.0.tgz", 2590 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" 2591 | }, 2592 | "to-regex-range": { 2593 | "version": "5.0.1", 2594 | "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz", 2595 | "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", 2596 | "requires": { 2597 | "is-number": "^7.0.0" 2598 | } 2599 | }, 2600 | "tough-cookie": { 2601 | "version": "4.0.0", 2602 | "resolved": "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-4.0.0.tgz", 2603 | "integrity": "sha1-2CIjTuyogvmR8PkIgkrSYi3b7OQ=", 2604 | "requires": { 2605 | "psl": "^1.1.33", 2606 | "punycode": "^2.1.1", 2607 | "universalify": "^0.1.2" 2608 | } 2609 | }, 2610 | "tr46": { 2611 | "version": "2.1.0", 2612 | "resolved": "https://registry.npmmirror.com/tr46/download/tr46-2.1.0.tgz?cache=0&sync_timestamp=1633302501959&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Ftr46%2Fdownload%2Ftr46-2.1.0.tgz", 2613 | "integrity": "sha1-+oeqgcpdWUHajL8fm3SdyWmk4kA=", 2614 | "requires": { 2615 | "punycode": "^2.1.1" 2616 | } 2617 | }, 2618 | "ts-jest": { 2619 | "version": "27.0.6", 2620 | "resolved": "https://registry.npmmirror.com/ts-jest/download/ts-jest-27.0.6.tgz", 2621 | "integrity": "sha1-mWDbvbM3krecXuJNHGJRT9e2AFI=", 2622 | "requires": { 2623 | "bs-logger": "0.x", 2624 | "fast-json-stable-stringify": "2.x", 2625 | "jest-util": "^27.0.0", 2626 | "json5": "2.x", 2627 | "lodash.memoize": "4.x", 2628 | "make-error": "1.x", 2629 | "semver": "7.x", 2630 | "yargs-parser": "20.x" 2631 | }, 2632 | "dependencies": { 2633 | "semver": { 2634 | "version": "7.3.5", 2635 | "resolved": "https://registry.nlark.com/semver/download/semver-7.3.5.tgz?cache=0&sync_timestamp=1618846864940&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-7.3.5.tgz", 2636 | "integrity": "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc=", 2637 | "requires": { 2638 | "lru-cache": "^6.0.0" 2639 | } 2640 | } 2641 | } 2642 | }, 2643 | "ts-node": { 2644 | "version": "10.3.0", 2645 | "resolved": "https://registry.npmmirror.com/ts-node/download/ts-node-10.3.0.tgz", 2646 | "integrity": "sha1-p5fy7T/1DJpdgUzkAEN8sMHASLQ=", 2647 | "requires": { 2648 | "@cspotcode/source-map-support": "0.7.0", 2649 | "@tsconfig/node10": "^1.0.7", 2650 | "@tsconfig/node12": "^1.0.7", 2651 | "@tsconfig/node14": "^1.0.0", 2652 | "@tsconfig/node16": "^1.0.2", 2653 | "acorn": "^8.4.1", 2654 | "acorn-walk": "^8.1.1", 2655 | "arg": "^4.1.0", 2656 | "create-require": "^1.1.0", 2657 | "diff": "^4.0.1", 2658 | "make-error": "^1.1.1", 2659 | "yn": "3.1.1" 2660 | } 2661 | }, 2662 | "type-check": { 2663 | "version": "0.3.2", 2664 | "resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz", 2665 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2666 | "requires": { 2667 | "prelude-ls": "~1.1.2" 2668 | } 2669 | }, 2670 | "type-detect": { 2671 | "version": "4.0.8", 2672 | "resolved": "https://registry.nlark.com/type-detect/download/type-detect-4.0.8.tgz", 2673 | "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=" 2674 | }, 2675 | "type-fest": { 2676 | "version": "0.21.3", 2677 | "resolved": "https://registry.npmmirror.com/type-fest/download/type-fest-0.21.3.tgz", 2678 | "integrity": "sha1-0mCiSwGYQ24TP6JqUkptZfo7Ljc=" 2679 | }, 2680 | "typedarray-to-buffer": { 2681 | "version": "3.1.5", 2682 | "resolved": "https://registry.npm.taobao.org/typedarray-to-buffer/download/typedarray-to-buffer-3.1.5.tgz", 2683 | "integrity": "sha1-qX7nqf9CaRufeD/xvFES/j/KkIA=", 2684 | "requires": { 2685 | "is-typedarray": "^1.0.0" 2686 | } 2687 | }, 2688 | "typescript": { 2689 | "version": "4.4.4", 2690 | "resolved": "https://registry.npmmirror.com/typescript/download/typescript-4.4.4.tgz", 2691 | "integrity": "sha1-LNAaGh8WBwTTEB/VpY/w+fy4Aww=" 2692 | }, 2693 | "universalify": { 2694 | "version": "0.1.2", 2695 | "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz?cache=0&sync_timestamp=1603180004159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-0.1.2.tgz", 2696 | "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=" 2697 | }, 2698 | "v8-to-istanbul": { 2699 | "version": "8.1.0", 2700 | "resolved": "https://registry.npmmirror.com/v8-to-istanbul/download/v8-to-istanbul-8.1.0.tgz?cache=0&sync_timestamp=1632740183099&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fv8-to-istanbul%2Fdownload%2Fv8-to-istanbul-8.1.0.tgz", 2701 | "integrity": "sha1-Cut2OJTxoKFnat+Ki3YSo4kCRGw=", 2702 | "requires": { 2703 | "@types/istanbul-lib-coverage": "^2.0.1", 2704 | "convert-source-map": "^1.6.0", 2705 | "source-map": "^0.7.3" 2706 | }, 2707 | "dependencies": { 2708 | "source-map": { 2709 | "version": "0.7.3", 2710 | "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.7.3.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.7.3.tgz", 2711 | "integrity": "sha1-UwL4FpAxc1ImVECS5kmB91F1A4M=" 2712 | } 2713 | } 2714 | }, 2715 | "w3c-hr-time": { 2716 | "version": "1.0.2", 2717 | "resolved": "https://registry.npm.taobao.org/w3c-hr-time/download/w3c-hr-time-1.0.2.tgz", 2718 | "integrity": "sha1-ConN9cwVgi35w2BUNnaWPgzDCM0=", 2719 | "requires": { 2720 | "browser-process-hrtime": "^1.0.0" 2721 | } 2722 | }, 2723 | "w3c-xmlserializer": { 2724 | "version": "2.0.0", 2725 | "resolved": "https://registry.nlark.com/w3c-xmlserializer/download/w3c-xmlserializer-2.0.0.tgz", 2726 | "integrity": "sha1-PnEEoFt1FGzGD1ZDgLf2g6zxAgo=", 2727 | "requires": { 2728 | "xml-name-validator": "^3.0.0" 2729 | } 2730 | }, 2731 | "walker": { 2732 | "version": "1.0.7", 2733 | "resolved": "https://registry.npm.taobao.org/walker/download/walker-1.0.7.tgz", 2734 | "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", 2735 | "requires": { 2736 | "makeerror": "1.0.x" 2737 | } 2738 | }, 2739 | "webidl-conversions": { 2740 | "version": "6.1.0", 2741 | "resolved": "https://registry.nlark.com/webidl-conversions/download/webidl-conversions-6.1.0.tgz", 2742 | "integrity": "sha1-kRG01+qArNQPUnDWZmIa+ni2lRQ=" 2743 | }, 2744 | "whatwg-encoding": { 2745 | "version": "1.0.5", 2746 | "resolved": "https://registry.nlark.com/whatwg-encoding/download/whatwg-encoding-1.0.5.tgz?cache=0&sync_timestamp=1631479408233&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwhatwg-encoding%2Fdownload%2Fwhatwg-encoding-1.0.5.tgz", 2747 | "integrity": "sha1-WrrPd3wyFmpR0IXWtPPn0nET3bA=", 2748 | "requires": { 2749 | "iconv-lite": "0.4.24" 2750 | } 2751 | }, 2752 | "whatwg-mimetype": { 2753 | "version": "2.3.0", 2754 | "resolved": "https://registry.nlark.com/whatwg-mimetype/download/whatwg-mimetype-2.3.0.tgz?cache=0&sync_timestamp=1631993408310&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwhatwg-mimetype%2Fdownload%2Fwhatwg-mimetype-2.3.0.tgz", 2755 | "integrity": "sha1-PUseAxLSB5h5+Cav8Y2+7KWWD78=" 2756 | }, 2757 | "whatwg-url": { 2758 | "version": "8.7.0", 2759 | "resolved": "https://registry.npmmirror.com/whatwg-url/download/whatwg-url-8.7.0.tgz", 2760 | "integrity": "sha1-ZWp45RD/jzk3vAvL6fXArDWUG3c=", 2761 | "requires": { 2762 | "lodash": "^4.7.0", 2763 | "tr46": "^2.1.0", 2764 | "webidl-conversions": "^6.1.0" 2765 | } 2766 | }, 2767 | "which": { 2768 | "version": "2.0.2", 2769 | "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz", 2770 | "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", 2771 | "requires": { 2772 | "isexe": "^2.0.0" 2773 | } 2774 | }, 2775 | "word-wrap": { 2776 | "version": "1.2.3", 2777 | "resolved": "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz", 2778 | "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=" 2779 | }, 2780 | "wrap-ansi": { 2781 | "version": "7.0.0", 2782 | "resolved": "https://registry.nlark.com/wrap-ansi/download/wrap-ansi-7.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwrap-ansi%2Fdownload%2Fwrap-ansi-7.0.0.tgz", 2783 | "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=", 2784 | "requires": { 2785 | "ansi-styles": "^4.0.0", 2786 | "string-width": "^4.1.0", 2787 | "strip-ansi": "^6.0.0" 2788 | } 2789 | }, 2790 | "wrappy": { 2791 | "version": "1.0.2", 2792 | "resolved": "https://registry.nlark.com/wrappy/download/wrappy-1.0.2.tgz?cache=0&sync_timestamp=1619133505879&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwrappy%2Fdownload%2Fwrappy-1.0.2.tgz", 2793 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 2794 | }, 2795 | "write-file-atomic": { 2796 | "version": "3.0.3", 2797 | "resolved": "https://registry.npm.taobao.org/write-file-atomic/download/write-file-atomic-3.0.3.tgz", 2798 | "integrity": "sha1-Vr1cWlxwSBzRnFcb05q5ZaXeVug=", 2799 | "requires": { 2800 | "imurmurhash": "^0.1.4", 2801 | "is-typedarray": "^1.0.0", 2802 | "signal-exit": "^3.0.2", 2803 | "typedarray-to-buffer": "^3.1.5" 2804 | } 2805 | }, 2806 | "ws": { 2807 | "version": "7.5.5", 2808 | "resolved": "https://registry.npmmirror.com/ws/download/ws-7.5.5.tgz?cache=0&sync_timestamp=1633200113162&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fws%2Fdownload%2Fws-7.5.5.tgz", 2809 | "integrity": "sha1-i0vEr1GM+r0Ec65PmRRCh7M+uIE=" 2810 | }, 2811 | "xml-name-validator": { 2812 | "version": "3.0.0", 2813 | "resolved": "https://registry.nlark.com/xml-name-validator/download/xml-name-validator-3.0.0.tgz?cache=0&sync_timestamp=1632002514407&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fxml-name-validator%2Fdownload%2Fxml-name-validator-3.0.0.tgz", 2814 | "integrity": "sha1-auc+Bt5NjG5H+fsYH3jWSK1FfGo=" 2815 | }, 2816 | "xmlchars": { 2817 | "version": "2.2.0", 2818 | "resolved": "https://registry.npm.taobao.org/xmlchars/download/xmlchars-2.2.0.tgz", 2819 | "integrity": "sha1-Bg/hvLf5x2/ioX24apvDq4lCEMs=" 2820 | }, 2821 | "y18n": { 2822 | "version": "5.0.8", 2823 | "resolved": "https://registry.nlark.com/y18n/download/y18n-5.0.8.tgz", 2824 | "integrity": "sha1-f0k00PfKjFb5UxSTndzS3ZHOHVU=" 2825 | }, 2826 | "yallist": { 2827 | "version": "4.0.0", 2828 | "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz", 2829 | "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=" 2830 | }, 2831 | "yargs": { 2832 | "version": "16.2.0", 2833 | "resolved": "https://registry.npmmirror.com/yargs/download/yargs-16.2.0.tgz?cache=0&sync_timestamp=1632605487521&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fyargs%2Fdownload%2Fyargs-16.2.0.tgz", 2834 | "integrity": "sha1-HIK/D2tqZur85+8w43b0mhJHf2Y=", 2835 | "requires": { 2836 | "cliui": "^7.0.2", 2837 | "escalade": "^3.1.1", 2838 | "get-caller-file": "^2.0.5", 2839 | "require-directory": "^2.1.1", 2840 | "string-width": "^4.2.0", 2841 | "y18n": "^5.0.5", 2842 | "yargs-parser": "^20.2.2" 2843 | } 2844 | }, 2845 | "yargs-parser": { 2846 | "version": "20.2.9", 2847 | "resolved": "https://registry.nlark.com/yargs-parser/download/yargs-parser-20.2.9.tgz?cache=0&sync_timestamp=1624233514145&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fyargs-parser%2Fdownload%2Fyargs-parser-20.2.9.tgz", 2848 | "integrity": "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4=" 2849 | }, 2850 | "yn": { 2851 | "version": "3.1.1", 2852 | "resolved": "https://registry.nlark.com/yn/download/yn-3.1.1.tgz?cache=0&sync_timestamp=1628975005240&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fyn%2Fdownload%2Fyn-3.1.1.tgz", 2853 | "integrity": "sha1-HodAGgnXZ8HV6rJqbkwYUYLS61A=" 2854 | } 2855 | } 2856 | } 2857 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecs", 3 | "version": "1.0.0", 4 | "description": "entity component system framework", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/shangdibaozi/ECS.git" 12 | }, 13 | "keywords": [ 14 | "ecs" 15 | ], 16 | "author": "shangdibaozi", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/shangdibaozi/ECS/issues" 20 | }, 21 | "homepage": "https://github.com/shangdibaozi/ECS#readme", 22 | "dependencies": { 23 | "@types/jest": "^27.0.2", 24 | "jest": "^27.2.5", 25 | "ts-jest": "^27.0.6", 26 | "ts-node": "^10.3.0", 27 | "typescript": "^4.4.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/comp.test.ts: -------------------------------------------------------------------------------- 1 | import { ecs } from "../ECS"; 2 | 3 | @ecs.register('Comp1') 4 | class Comp1 extends ecs.Comp { 5 | reset() { 6 | 7 | } 8 | } 9 | 10 | @ecs.register('Comp2') 11 | class Comp2 extends ecs.Comp { 12 | reset() { 13 | 14 | } 15 | } 16 | 17 | @ecs.register('Comp3') 18 | class Comp3 extends ecs.Comp { 19 | reset() { 20 | 21 | } 22 | } 23 | 24 | test('Comp.tid', () => { 25 | expect(Comp1.tid).toBe(0); 26 | expect(Comp2.tid).toBe(1); 27 | expect(Comp3.tid).toBe(2); 28 | }); 29 | 30 | @ecs.registerTag() 31 | class CompTag { 32 | static Tag1: number = 0; 33 | static Tag2: number = 0; 34 | static Tag3: number = 0; 35 | } 36 | 37 | test('Comp tag', () => { 38 | expect(CompTag.Tag1).toBe(3); 39 | expect(CompTag.Tag2).toBe(4); 40 | expect(CompTag.Tag3).toBe(5); 41 | }); 42 | 43 | test('singleton comp', () => { 44 | let comp = ecs.getSingleton(Comp1); 45 | 46 | expect(comp).toBe(ecs.getSingleton(Comp1)); 47 | expect(comp.ent).toBe(ecs.getSingleton(Comp1).ent); 48 | 49 | 50 | let compObj = new Comp2(); 51 | ecs.addSingleton(compObj); 52 | 53 | expect(compObj).toBe(ecs.getSingleton(Comp2)); 54 | expect(compObj.ent).toBe(ecs.getSingleton(Comp2).ent); 55 | }); -------------------------------------------------------------------------------- /test/ent.test.ts: -------------------------------------------------------------------------------- 1 | import { ecs } from "../ECS"; 2 | 3 | class Ent extends ecs.Entity { 4 | Move: MoveComp; 5 | } 6 | 7 | @ecs.register('Move') 8 | class MoveComp extends ecs.Comp { 9 | 10 | reset() { 11 | 12 | } 13 | } 14 | 15 | @ecs.register('Obj', false) 16 | class ObjComp extends ecs.Comp { 17 | reset() { 18 | 19 | } 20 | } 21 | 22 | test('ent.add(MoveComp)', () => { 23 | let ent = ecs.createEntity(); 24 | let move = ent.add(MoveComp); 25 | expect(ent.has(MoveComp)).toBe(true); 26 | expect(ent.Move).toBe(move); 27 | expect(ent.get(MoveComp)).toBe(move); 28 | }); 29 | 30 | test('ent.remove(MoveComp)', () => { 31 | let ent = ecs.createEntity(); 32 | ent.add(MoveComp); 33 | ent.remove(MoveComp); 34 | expect(ent.has(MoveComp)).toBe(false); 35 | expect(ent.Move).toBe(null); 36 | }); 37 | 38 | test('ent.add(obj)', () => { 39 | let move = new MoveComp(); 40 | 41 | expect(move.constructor).toBe(MoveComp); 42 | expect((move.constructor as unknown as ecs.CompCtor).tid).toBe(MoveComp.tid); 43 | let ent = ecs.createEntity(); 44 | ent.add(move); 45 | expect(ent.has(MoveComp)).toBe(true); 46 | expect(ent.Move).toBe(move); 47 | expect(ent.get(MoveComp)).toBe(move); 48 | }); 49 | 50 | @ecs.registerTag() 51 | class ECSTag { 52 | static Tag1: number = 0; 53 | static Tag2: number = 0; 54 | static Tag3: number = 0; 55 | } 56 | 57 | test('ent.add(tag)', () => { 58 | let ent = ecs.createEntity(); 59 | ent.add(ECSTag.Tag1); 60 | 61 | expect(ent.has(ECSTag.Tag1)).toBe(true); 62 | expect(ent.get(ECSTag.Tag1)).toBe(ECSTag.Tag1); 63 | 64 | ent.remove(ECSTag.Tag1); 65 | expect(ent.has(ECSTag.Tag1)).toBe(false); 66 | expect(ent.get(ECSTag.Tag1)).toBe(null); 67 | }); 68 | 69 | test('ent destroy', () => { 70 | let ent = ecs.createEntity(); 71 | ent.add(MoveComp); 72 | ent.add(new ObjComp()); 73 | 74 | ent.destroy(); 75 | expect(ent.has(MoveComp)).toBe(false); 76 | expect(ent.has(ObjComp)).toBe(false); 77 | }); -------------------------------------------------------------------------------- /test/matcher.test.ts: -------------------------------------------------------------------------------- 1 | import { ecs } from "../ECS"; 2 | 3 | 4 | @ecs.register('Run') 5 | class RunComp extends ecs.Comp { 6 | reset() {} 7 | } 8 | 9 | @ecs.register('Render') 10 | class RenderComp extends ecs.Comp { 11 | reset() {} 12 | } 13 | 14 | @ecs.register('Jump') 15 | class JumpComp extends ecs.Comp { 16 | reset() {} 17 | } 18 | 19 | @ecs.register('Fly') 20 | class FlyComp extends ecs.Comp { 21 | reset() {} 22 | } 23 | 24 | test('ecs.allOf', () => { 25 | let ent = ecs.createEntity(); 26 | ent.add(RenderComp); 27 | ent.add(RunComp); 28 | let matcher = ecs.allOf(RenderComp, RunComp); 29 | 30 | expect(matcher.isMatch(ent)).toBe(true); 31 | 32 | expect(matcher.indices.toString()).toBe(`${RunComp.tid},${RenderComp.tid}`); 33 | 34 | ent.remove(RunComp); 35 | expect(matcher.isMatch(ent)).toBe(false); 36 | 37 | ent.add(RunComp); 38 | ent.add(JumpComp); 39 | expect(matcher.isMatch(ent)).toBe(true); 40 | }); 41 | 42 | test('ecs.anyOf', () => { 43 | let ent = ecs.createEntity(); 44 | ent.add(RenderComp); 45 | ent.add(RunComp); 46 | 47 | 48 | let mathcer = ecs.anyOf(RunComp, JumpComp); 49 | expect(mathcer.isMatch(ent)).toBe(true); 50 | 51 | ent.add(JumpComp); 52 | expect(mathcer.isMatch(ent)).toBe(true); 53 | 54 | ent.remove(RunComp); 55 | expect(mathcer.isMatch(ent)).toBe(true); 56 | 57 | ent.remove(JumpComp); 58 | expect(mathcer.isMatch(ent)).toBe(false); 59 | }); 60 | 61 | test('ecs.excludeOf', () => { 62 | let ent = ecs.createEntity(); 63 | ent.add(RunComp); 64 | 65 | let matcher = ecs.excludeOf(RunComp); 66 | 67 | expect(matcher.isMatch(ent)).toBe(false); 68 | 69 | ent.add(FlyComp); 70 | expect(matcher.isMatch(ent)).toBe(false); 71 | 72 | ent.remove(RunComp); 73 | expect(matcher.isMatch(ent)).toBe(true); 74 | }); 75 | 76 | test('ecs.onlyOf', () => { 77 | let ent = ecs.createEntity(); 78 | ent.add(RunComp); 79 | 80 | let matcher = ecs.onlyOf(RunComp); 81 | expect(matcher.isMatch(ent)).toBe(true); 82 | 83 | ent.add(FlyComp); 84 | expect(matcher.isMatch(ent)).toBe(false); 85 | 86 | ent.remove(FlyComp); 87 | expect(matcher.isMatch(ent)).toBe(true); 88 | }); 89 | 90 | test('ecs.allOf().excludeOf', () => { 91 | let ent = ecs.createEntity(); 92 | ent.add(RenderComp); 93 | ent.add(RunComp); 94 | ent.add(JumpComp); 95 | 96 | let macher = ecs.allOf(RenderComp, RunComp, JumpComp).excludeOf(FlyComp); 97 | expect(macher.isMatch(ent)).toBe(true); 98 | 99 | ent.add(FlyComp); 100 | expect(macher.isMatch(ent)).toBe(false); 101 | 102 | ent.remove(JumpComp); 103 | expect(macher.isMatch(ent)).toBe(false); 104 | 105 | ent.remove(FlyComp); 106 | ent.add(JumpComp); 107 | expect(macher.isMatch(ent)).toBe(true); 108 | }); -------------------------------------------------------------------------------- /test/register.test.ts: -------------------------------------------------------------------------------- 1 | import { ecs } from "../ECS"; 2 | 3 | @ecs.register('Test1') 4 | class Test1Comp extends ecs.Comp { 5 | reset() { 6 | 7 | } 8 | } 9 | 10 | @ecs.register('Test2', false) 11 | class Test2Comp extends ecs.Comp { 12 | reset() { 13 | 14 | } 15 | } 16 | 17 | test('register()', () => { 18 | let comp1 = ecs.createEntityWithComp(Test1Comp); 19 | expect(comp1).not.toBe(null); 20 | 21 | try { 22 | let comp2 = ecs.createComp(Test2Comp); 23 | } catch (error) { 24 | console.log(error); 25 | } 26 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2015", 4 | "module": "ES2015", /* Specify what module code is generated. */ 5 | 6 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 7 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 8 | "strict": false, 9 | "experimentalDecorators": true, 10 | } 11 | } 12 | --------------------------------------------------------------------------------