@weaverse/core 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +100 -90
- package/dist/index.mjs +100 -90
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -133,27 +133,12 @@ var stitchesUtils = {
|
|
|
133
133
|
|
|
134
134
|
// src/core.ts
|
|
135
135
|
var WeaverseItemStore = class {
|
|
136
|
+
weaverse;
|
|
137
|
+
listeners = /* @__PURE__ */ new Set();
|
|
138
|
+
ref = { current: null };
|
|
139
|
+
stitchesClass = "";
|
|
140
|
+
_store = { id: "", type: "" };
|
|
136
141
|
constructor(itemData, weaverse) {
|
|
137
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
138
|
-
this.ref = { current: null };
|
|
139
|
-
this.stitchesClass = "";
|
|
140
|
-
this._store = { id: "", type: "" };
|
|
141
|
-
this.setData = (update) => {
|
|
142
|
-
this.data = Object.assign(this.data, update);
|
|
143
|
-
this.triggerUpdate();
|
|
144
|
-
return this.data;
|
|
145
|
-
};
|
|
146
|
-
this.subscribe = (fn) => {
|
|
147
|
-
this.listeners.add(fn);
|
|
148
|
-
};
|
|
149
|
-
this.unsubscribe = (fn) => {
|
|
150
|
-
this.listeners.delete(fn);
|
|
151
|
-
};
|
|
152
|
-
this.triggerUpdate = () => {
|
|
153
|
-
this.listeners.forEach((fn) => {
|
|
154
|
-
return fn(this.data);
|
|
155
|
-
});
|
|
156
|
-
};
|
|
157
142
|
let { type, id } = itemData;
|
|
158
143
|
this.weaverse = weaverse;
|
|
159
144
|
if (id && type) {
|
|
@@ -189,78 +174,96 @@ var WeaverseItemStore = class {
|
|
|
189
174
|
let extraData = this.Element?.extraData;
|
|
190
175
|
return { ...defaultData, ...extraData, ...this._store, css };
|
|
191
176
|
}
|
|
177
|
+
setData = (update) => {
|
|
178
|
+
this.data = Object.assign(this.data, update);
|
|
179
|
+
this.triggerUpdate();
|
|
180
|
+
return this.data;
|
|
181
|
+
};
|
|
182
|
+
subscribe = (fn) => {
|
|
183
|
+
this.listeners.add(fn);
|
|
184
|
+
};
|
|
185
|
+
unsubscribe = (fn) => {
|
|
186
|
+
this.listeners.delete(fn);
|
|
187
|
+
};
|
|
188
|
+
triggerUpdate = () => {
|
|
189
|
+
this.listeners.forEach((fn) => {
|
|
190
|
+
return fn(this.data);
|
|
191
|
+
});
|
|
192
|
+
};
|
|
192
193
|
};
|
|
193
194
|
var Weaverse = class {
|
|
195
|
+
/**
|
|
196
|
+
* The `weaverse-content-root` element of Weaverse SDK
|
|
197
|
+
*/
|
|
198
|
+
contentRootElement;
|
|
199
|
+
/**
|
|
200
|
+
* For storing, registering element React component from Weaverse or created by user/developer
|
|
201
|
+
*/
|
|
202
|
+
elementInstances = /* @__PURE__ */ new Map();
|
|
203
|
+
/**
|
|
204
|
+
* list of element/items store to provide data, handle state update, state sharing, etc.
|
|
205
|
+
*/
|
|
206
|
+
itemInstances = /* @__PURE__ */ new Map();
|
|
207
|
+
/**
|
|
208
|
+
* Weaverse base URL that can provide by user/developer. for local development, use localhost:3000
|
|
209
|
+
*/
|
|
210
|
+
weaverseHost = "https://weaverse.io";
|
|
211
|
+
/**
|
|
212
|
+
* Weaverse version, it can be used to load the correct version of Weaverse SDK
|
|
213
|
+
*/
|
|
214
|
+
weaverseVersion = "";
|
|
215
|
+
/**
|
|
216
|
+
* Weaverse project key to access project data via API
|
|
217
|
+
*/
|
|
218
|
+
projectId = "";
|
|
219
|
+
pageId = "";
|
|
220
|
+
internal = {};
|
|
221
|
+
requestInfo = {};
|
|
222
|
+
/**
|
|
223
|
+
* Weaverse project data, by default, user can provide project data via React Component:
|
|
224
|
+
* <WeaverseRoot data={data} /> it will be used to server-side rendering
|
|
225
|
+
*/
|
|
226
|
+
data = {
|
|
227
|
+
rootId: "",
|
|
228
|
+
items: [],
|
|
229
|
+
script: { css: "", js: "" }
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Storing subscribe callback function for any component that want to listen to the change of WeaverseRoot
|
|
233
|
+
*/
|
|
234
|
+
listeners = /* @__PURE__ */ new Set();
|
|
235
|
+
/**
|
|
236
|
+
* Check whether the sdk is in editor or not.
|
|
237
|
+
* If isDesignMode is true, it means the sdk is isDesignMode mode, render the editor UI,
|
|
238
|
+
* else render the preview UI, plain HTML + CSS + React hydrate
|
|
239
|
+
*/
|
|
240
|
+
isDesignMode = false;
|
|
241
|
+
/**
|
|
242
|
+
* Check the platform, shopify-section or react-ssr(hydrogen)
|
|
243
|
+
*/
|
|
244
|
+
platformType = "shopify-section";
|
|
245
|
+
/**
|
|
246
|
+
* Check whether the sdk is in preview mode or not
|
|
247
|
+
*/
|
|
248
|
+
isPreviewMode = false;
|
|
249
|
+
/**
|
|
250
|
+
* Use in element to optionally render special HTML for hydration
|
|
251
|
+
*/
|
|
252
|
+
ssrMode = false;
|
|
253
|
+
/**
|
|
254
|
+
* Stitches instance for handling CSS stylesheet, media, theme for Weaverse project
|
|
255
|
+
*/
|
|
256
|
+
stitchesInstance;
|
|
257
|
+
studioBridge;
|
|
258
|
+
elementSchemas = [];
|
|
259
|
+
static WeaverseItemStore = WeaverseItemStore;
|
|
260
|
+
mediaBreakPoints = {
|
|
261
|
+
desktop: "all",
|
|
262
|
+
// max-width need to subtract 0.02px to prevent bug https://getbootstrap.com/docs/5.1/layout/breakpoints/#max-width
|
|
263
|
+
// tablet: "(max-width: 1023.98px)", // to set css for tablet, {'@tablet' : { // css }},
|
|
264
|
+
mobile: "(max-width: 767.98px)"
|
|
265
|
+
};
|
|
194
266
|
constructor(params = {}) {
|
|
195
|
-
/**
|
|
196
|
-
* For storing, registering element React component from Weaverse or created by user/developer
|
|
197
|
-
*/
|
|
198
|
-
this.elementInstances = /* @__PURE__ */ new Map();
|
|
199
|
-
/**
|
|
200
|
-
* list of element/items store to provide data, handle state update, state sharing, etc.
|
|
201
|
-
*/
|
|
202
|
-
this.itemInstances = /* @__PURE__ */ new Map();
|
|
203
|
-
/**
|
|
204
|
-
* Weaverse base URL that can provide by user/developer. for local development, use localhost:3000
|
|
205
|
-
*/
|
|
206
|
-
this.weaverseHost = "https://weaverse.io";
|
|
207
|
-
/**
|
|
208
|
-
* Weaverse version, it can be used to load the correct version of Weaverse SDK
|
|
209
|
-
*/
|
|
210
|
-
this.weaverseVersion = "";
|
|
211
|
-
/**
|
|
212
|
-
* Weaverse project key to access project data via API
|
|
213
|
-
*/
|
|
214
|
-
this.projectId = "";
|
|
215
|
-
this.pageId = "";
|
|
216
|
-
this.internal = {};
|
|
217
|
-
this.requestInfo = {};
|
|
218
|
-
/**
|
|
219
|
-
* Weaverse project data, by default, user can provide project data via React Component:
|
|
220
|
-
* <WeaverseRoot data={data} /> it will be used to server-side rendering
|
|
221
|
-
*/
|
|
222
|
-
this.data = {
|
|
223
|
-
rootId: "",
|
|
224
|
-
items: [],
|
|
225
|
-
script: { css: "", js: "" }
|
|
226
|
-
};
|
|
227
|
-
/**
|
|
228
|
-
* Storing subscribe callback function for any component that want to listen to the change of WeaverseRoot
|
|
229
|
-
*/
|
|
230
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
231
|
-
/**
|
|
232
|
-
* Check whether the sdk is in editor or not.
|
|
233
|
-
* If isDesignMode is true, it means the sdk is isDesignMode mode, render the editor UI,
|
|
234
|
-
* else render the preview UI, plain HTML + CSS + React hydrate
|
|
235
|
-
*/
|
|
236
|
-
this.isDesignMode = false;
|
|
237
|
-
/**
|
|
238
|
-
* Check the platform, shopify-section or react-ssr(hydrogen)
|
|
239
|
-
*/
|
|
240
|
-
this.platformType = "shopify-section";
|
|
241
|
-
/**
|
|
242
|
-
* Check whether the sdk is in preview mode or not
|
|
243
|
-
*/
|
|
244
|
-
this.isPreviewMode = false;
|
|
245
|
-
/**
|
|
246
|
-
* Use in element to optionally render special HTML for hydration
|
|
247
|
-
*/
|
|
248
|
-
this.ssrMode = false;
|
|
249
|
-
this.elementSchemas = [];
|
|
250
|
-
this.mediaBreakPoints = {
|
|
251
|
-
desktop: "all",
|
|
252
|
-
// max-width need to subtract 0.02px to prevent bug https://getbootstrap.com/docs/5.1/layout/breakpoints/#max-width
|
|
253
|
-
// tablet: "(max-width: 1023.98px)", // to set css for tablet, {'@tablet' : { // css }},
|
|
254
|
-
mobile: "(max-width: 767.98px)"
|
|
255
|
-
};
|
|
256
|
-
this.initStitches = (externalConfig = {}) => {
|
|
257
|
-
this.stitchesInstance = this.stitchesInstance || stitches.createStitches({
|
|
258
|
-
prefix: "weaverse",
|
|
259
|
-
media: this.mediaBreakPoints,
|
|
260
|
-
utils: stitchesUtils,
|
|
261
|
-
...externalConfig
|
|
262
|
-
});
|
|
263
|
-
};
|
|
264
267
|
Object.entries(params).forEach(([k, v]) => {
|
|
265
268
|
let key = k;
|
|
266
269
|
if (key in this) {
|
|
@@ -283,6 +286,14 @@ var Weaverse = class {
|
|
|
283
286
|
console.error("Weaverse: registerElement: `type` is required");
|
|
284
287
|
}
|
|
285
288
|
}
|
|
289
|
+
initStitches = (externalConfig = {}) => {
|
|
290
|
+
this.stitchesInstance = this.stitchesInstance || stitches.createStitches({
|
|
291
|
+
prefix: "weaverse",
|
|
292
|
+
media: this.mediaBreakPoints,
|
|
293
|
+
utils: stitchesUtils,
|
|
294
|
+
...externalConfig
|
|
295
|
+
});
|
|
296
|
+
};
|
|
286
297
|
subscribe(fn) {
|
|
287
298
|
this.listeners.add(fn);
|
|
288
299
|
}
|
|
@@ -325,7 +336,6 @@ var Weaverse = class {
|
|
|
325
336
|
}
|
|
326
337
|
}
|
|
327
338
|
};
|
|
328
|
-
Weaverse.WeaverseItemStore = WeaverseItemStore;
|
|
329
339
|
// Annotate the CommonJS export names for ESM import in node:
|
|
330
340
|
0 && (module.exports = {
|
|
331
341
|
Weaverse,
|
package/dist/index.mjs
CHANGED
|
@@ -90,27 +90,12 @@ var stitchesUtils = {
|
|
|
90
90
|
|
|
91
91
|
// src/core.ts
|
|
92
92
|
var WeaverseItemStore = class {
|
|
93
|
+
weaverse;
|
|
94
|
+
listeners = /* @__PURE__ */ new Set();
|
|
95
|
+
ref = { current: null };
|
|
96
|
+
stitchesClass = "";
|
|
97
|
+
_store = { id: "", type: "" };
|
|
93
98
|
constructor(itemData, weaverse) {
|
|
94
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
95
|
-
this.ref = { current: null };
|
|
96
|
-
this.stitchesClass = "";
|
|
97
|
-
this._store = { id: "", type: "" };
|
|
98
|
-
this.setData = (update) => {
|
|
99
|
-
this.data = Object.assign(this.data, update);
|
|
100
|
-
this.triggerUpdate();
|
|
101
|
-
return this.data;
|
|
102
|
-
};
|
|
103
|
-
this.subscribe = (fn) => {
|
|
104
|
-
this.listeners.add(fn);
|
|
105
|
-
};
|
|
106
|
-
this.unsubscribe = (fn) => {
|
|
107
|
-
this.listeners.delete(fn);
|
|
108
|
-
};
|
|
109
|
-
this.triggerUpdate = () => {
|
|
110
|
-
this.listeners.forEach((fn) => {
|
|
111
|
-
return fn(this.data);
|
|
112
|
-
});
|
|
113
|
-
};
|
|
114
99
|
let { type, id } = itemData;
|
|
115
100
|
this.weaverse = weaverse;
|
|
116
101
|
if (id && type) {
|
|
@@ -146,78 +131,96 @@ var WeaverseItemStore = class {
|
|
|
146
131
|
let extraData = this.Element?.extraData;
|
|
147
132
|
return { ...defaultData, ...extraData, ...this._store, css };
|
|
148
133
|
}
|
|
134
|
+
setData = (update) => {
|
|
135
|
+
this.data = Object.assign(this.data, update);
|
|
136
|
+
this.triggerUpdate();
|
|
137
|
+
return this.data;
|
|
138
|
+
};
|
|
139
|
+
subscribe = (fn) => {
|
|
140
|
+
this.listeners.add(fn);
|
|
141
|
+
};
|
|
142
|
+
unsubscribe = (fn) => {
|
|
143
|
+
this.listeners.delete(fn);
|
|
144
|
+
};
|
|
145
|
+
triggerUpdate = () => {
|
|
146
|
+
this.listeners.forEach((fn) => {
|
|
147
|
+
return fn(this.data);
|
|
148
|
+
});
|
|
149
|
+
};
|
|
149
150
|
};
|
|
150
151
|
var Weaverse = class {
|
|
152
|
+
/**
|
|
153
|
+
* The `weaverse-content-root` element of Weaverse SDK
|
|
154
|
+
*/
|
|
155
|
+
contentRootElement;
|
|
156
|
+
/**
|
|
157
|
+
* For storing, registering element React component from Weaverse or created by user/developer
|
|
158
|
+
*/
|
|
159
|
+
elementInstances = /* @__PURE__ */ new Map();
|
|
160
|
+
/**
|
|
161
|
+
* list of element/items store to provide data, handle state update, state sharing, etc.
|
|
162
|
+
*/
|
|
163
|
+
itemInstances = /* @__PURE__ */ new Map();
|
|
164
|
+
/**
|
|
165
|
+
* Weaverse base URL that can provide by user/developer. for local development, use localhost:3000
|
|
166
|
+
*/
|
|
167
|
+
weaverseHost = "https://weaverse.io";
|
|
168
|
+
/**
|
|
169
|
+
* Weaverse version, it can be used to load the correct version of Weaverse SDK
|
|
170
|
+
*/
|
|
171
|
+
weaverseVersion = "";
|
|
172
|
+
/**
|
|
173
|
+
* Weaverse project key to access project data via API
|
|
174
|
+
*/
|
|
175
|
+
projectId = "";
|
|
176
|
+
pageId = "";
|
|
177
|
+
internal = {};
|
|
178
|
+
requestInfo = {};
|
|
179
|
+
/**
|
|
180
|
+
* Weaverse project data, by default, user can provide project data via React Component:
|
|
181
|
+
* <WeaverseRoot data={data} /> it will be used to server-side rendering
|
|
182
|
+
*/
|
|
183
|
+
data = {
|
|
184
|
+
rootId: "",
|
|
185
|
+
items: [],
|
|
186
|
+
script: { css: "", js: "" }
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Storing subscribe callback function for any component that want to listen to the change of WeaverseRoot
|
|
190
|
+
*/
|
|
191
|
+
listeners = /* @__PURE__ */ new Set();
|
|
192
|
+
/**
|
|
193
|
+
* Check whether the sdk is in editor or not.
|
|
194
|
+
* If isDesignMode is true, it means the sdk is isDesignMode mode, render the editor UI,
|
|
195
|
+
* else render the preview UI, plain HTML + CSS + React hydrate
|
|
196
|
+
*/
|
|
197
|
+
isDesignMode = false;
|
|
198
|
+
/**
|
|
199
|
+
* Check the platform, shopify-section or react-ssr(hydrogen)
|
|
200
|
+
*/
|
|
201
|
+
platformType = "shopify-section";
|
|
202
|
+
/**
|
|
203
|
+
* Check whether the sdk is in preview mode or not
|
|
204
|
+
*/
|
|
205
|
+
isPreviewMode = false;
|
|
206
|
+
/**
|
|
207
|
+
* Use in element to optionally render special HTML for hydration
|
|
208
|
+
*/
|
|
209
|
+
ssrMode = false;
|
|
210
|
+
/**
|
|
211
|
+
* Stitches instance for handling CSS stylesheet, media, theme for Weaverse project
|
|
212
|
+
*/
|
|
213
|
+
stitchesInstance;
|
|
214
|
+
studioBridge;
|
|
215
|
+
elementSchemas = [];
|
|
216
|
+
static WeaverseItemStore = WeaverseItemStore;
|
|
217
|
+
mediaBreakPoints = {
|
|
218
|
+
desktop: "all",
|
|
219
|
+
// max-width need to subtract 0.02px to prevent bug https://getbootstrap.com/docs/5.1/layout/breakpoints/#max-width
|
|
220
|
+
// tablet: "(max-width: 1023.98px)", // to set css for tablet, {'@tablet' : { // css }},
|
|
221
|
+
mobile: "(max-width: 767.98px)"
|
|
222
|
+
};
|
|
151
223
|
constructor(params = {}) {
|
|
152
|
-
/**
|
|
153
|
-
* For storing, registering element React component from Weaverse or created by user/developer
|
|
154
|
-
*/
|
|
155
|
-
this.elementInstances = /* @__PURE__ */ new Map();
|
|
156
|
-
/**
|
|
157
|
-
* list of element/items store to provide data, handle state update, state sharing, etc.
|
|
158
|
-
*/
|
|
159
|
-
this.itemInstances = /* @__PURE__ */ new Map();
|
|
160
|
-
/**
|
|
161
|
-
* Weaverse base URL that can provide by user/developer. for local development, use localhost:3000
|
|
162
|
-
*/
|
|
163
|
-
this.weaverseHost = "https://weaverse.io";
|
|
164
|
-
/**
|
|
165
|
-
* Weaverse version, it can be used to load the correct version of Weaverse SDK
|
|
166
|
-
*/
|
|
167
|
-
this.weaverseVersion = "";
|
|
168
|
-
/**
|
|
169
|
-
* Weaverse project key to access project data via API
|
|
170
|
-
*/
|
|
171
|
-
this.projectId = "";
|
|
172
|
-
this.pageId = "";
|
|
173
|
-
this.internal = {};
|
|
174
|
-
this.requestInfo = {};
|
|
175
|
-
/**
|
|
176
|
-
* Weaverse project data, by default, user can provide project data via React Component:
|
|
177
|
-
* <WeaverseRoot data={data} /> it will be used to server-side rendering
|
|
178
|
-
*/
|
|
179
|
-
this.data = {
|
|
180
|
-
rootId: "",
|
|
181
|
-
items: [],
|
|
182
|
-
script: { css: "", js: "" }
|
|
183
|
-
};
|
|
184
|
-
/**
|
|
185
|
-
* Storing subscribe callback function for any component that want to listen to the change of WeaverseRoot
|
|
186
|
-
*/
|
|
187
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
188
|
-
/**
|
|
189
|
-
* Check whether the sdk is in editor or not.
|
|
190
|
-
* If isDesignMode is true, it means the sdk is isDesignMode mode, render the editor UI,
|
|
191
|
-
* else render the preview UI, plain HTML + CSS + React hydrate
|
|
192
|
-
*/
|
|
193
|
-
this.isDesignMode = false;
|
|
194
|
-
/**
|
|
195
|
-
* Check the platform, shopify-section or react-ssr(hydrogen)
|
|
196
|
-
*/
|
|
197
|
-
this.platformType = "shopify-section";
|
|
198
|
-
/**
|
|
199
|
-
* Check whether the sdk is in preview mode or not
|
|
200
|
-
*/
|
|
201
|
-
this.isPreviewMode = false;
|
|
202
|
-
/**
|
|
203
|
-
* Use in element to optionally render special HTML for hydration
|
|
204
|
-
*/
|
|
205
|
-
this.ssrMode = false;
|
|
206
|
-
this.elementSchemas = [];
|
|
207
|
-
this.mediaBreakPoints = {
|
|
208
|
-
desktop: "all",
|
|
209
|
-
// max-width need to subtract 0.02px to prevent bug https://getbootstrap.com/docs/5.1/layout/breakpoints/#max-width
|
|
210
|
-
// tablet: "(max-width: 1023.98px)", // to set css for tablet, {'@tablet' : { // css }},
|
|
211
|
-
mobile: "(max-width: 767.98px)"
|
|
212
|
-
};
|
|
213
|
-
this.initStitches = (externalConfig = {}) => {
|
|
214
|
-
this.stitchesInstance = this.stitchesInstance || stitches.createStitches({
|
|
215
|
-
prefix: "weaverse",
|
|
216
|
-
media: this.mediaBreakPoints,
|
|
217
|
-
utils: stitchesUtils,
|
|
218
|
-
...externalConfig
|
|
219
|
-
});
|
|
220
|
-
};
|
|
221
224
|
Object.entries(params).forEach(([k, v]) => {
|
|
222
225
|
let key = k;
|
|
223
226
|
if (key in this) {
|
|
@@ -240,6 +243,14 @@ var Weaverse = class {
|
|
|
240
243
|
console.error("Weaverse: registerElement: `type` is required");
|
|
241
244
|
}
|
|
242
245
|
}
|
|
246
|
+
initStitches = (externalConfig = {}) => {
|
|
247
|
+
this.stitchesInstance = this.stitchesInstance || stitches.createStitches({
|
|
248
|
+
prefix: "weaverse",
|
|
249
|
+
media: this.mediaBreakPoints,
|
|
250
|
+
utils: stitchesUtils,
|
|
251
|
+
...externalConfig
|
|
252
|
+
});
|
|
253
|
+
};
|
|
243
254
|
subscribe(fn) {
|
|
244
255
|
this.listeners.add(fn);
|
|
245
256
|
}
|
|
@@ -282,7 +293,6 @@ var Weaverse = class {
|
|
|
282
293
|
}
|
|
283
294
|
}
|
|
284
295
|
};
|
|
285
|
-
Weaverse.WeaverseItemStore = WeaverseItemStore;
|
|
286
296
|
export {
|
|
287
297
|
Weaverse,
|
|
288
298
|
WeaverseItemStore,
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
2
|
+
"version": "1.3.3",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dist/*"
|
|
12
12
|
],
|
|
13
13
|
"engines": {
|
|
14
|
-
"node": ">=
|
|
14
|
+
"node": ">=16"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"start": "npm run dev",
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"optionalDependencies": {
|
|
29
29
|
"@esbuild/darwin-x64": "*"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|