@tanstack/table-core 8.9.7 → 8.9.8

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.
Files changed (54) hide show
  1. package/build/lib/core/cell.js +1 -1
  2. package/build/lib/core/cell.js.map +1 -1
  3. package/build/lib/core/column.js +3 -3
  4. package/build/lib/core/column.js.map +1 -1
  5. package/build/lib/core/headers.js +182 -181
  6. package/build/lib/core/headers.js.map +1 -1
  7. package/build/lib/core/row.js +1 -1
  8. package/build/lib/core/row.js.map +1 -1
  9. package/build/lib/core/table.js +4 -3
  10. package/build/lib/core/table.js.map +1 -1
  11. package/build/lib/features/ColumnSizing.js +173 -179
  12. package/build/lib/features/ColumnSizing.js.map +1 -1
  13. package/build/lib/features/Expanding.js +119 -123
  14. package/build/lib/features/Expanding.js.map +1 -1
  15. package/build/lib/features/Filters.js +157 -165
  16. package/build/lib/features/Filters.js.map +1 -1
  17. package/build/lib/features/Grouping.js +71 -79
  18. package/build/lib/features/Grouping.js.map +1 -1
  19. package/build/lib/features/Ordering.js +32 -34
  20. package/build/lib/features/Ordering.js.map +1 -1
  21. package/build/lib/features/Pagination.js +112 -114
  22. package/build/lib/features/Pagination.js.map +1 -1
  23. package/build/lib/features/Pinning.js +120 -126
  24. package/build/lib/features/Pinning.js.map +1 -1
  25. package/build/lib/features/RowSelection.js +245 -247
  26. package/build/lib/features/RowSelection.js.map +1 -1
  27. package/build/lib/features/Sorting.js +163 -167
  28. package/build/lib/features/Sorting.js.map +1 -1
  29. package/build/lib/features/Visibility.js +60 -66
  30. package/build/lib/features/Visibility.js.map +1 -1
  31. package/build/lib/index.esm.js +1469 -1515
  32. package/build/lib/index.esm.js.map +1 -1
  33. package/build/lib/index.mjs +1469 -1515
  34. package/build/lib/index.mjs.map +1 -1
  35. package/build/umd/index.development.js +1469 -1515
  36. package/build/umd/index.development.js.map +1 -1
  37. package/build/umd/index.production.js +1 -1
  38. package/build/umd/index.production.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/core/cell.ts +5 -8
  41. package/src/core/column.ts +3 -3
  42. package/src/core/headers.ts +264 -280
  43. package/src/core/row.ts +1 -1
  44. package/src/core/table.ts +4 -3
  45. package/src/features/ColumnSizing.ts +220 -231
  46. package/src/features/Expanding.ts +132 -140
  47. package/src/features/Filters.ts +193 -206
  48. package/src/features/Grouping.ts +94 -110
  49. package/src/features/Ordering.ts +48 -51
  50. package/src/features/Pagination.ts +150 -154
  51. package/src/features/Pinning.ts +158 -178
  52. package/src/features/RowSelection.ts +280 -286
  53. package/src/features/Sorting.ts +196 -206
  54. package/src/features/Visibility.ts +98 -107
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/table-core",
3
3
  "author": "Tanner Linsley",
4
- "version": "8.9.7",
4
+ "version": "8.9.8",
5
5
  "description": "Headless UI for building powerful tables & datagrids for TS/JS.",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/tanstack/table#readme",
package/src/core/cell.ts CHANGED
@@ -52,14 +52,11 @@ export function createCell<TData extends RowData, TValue>(
52
52
  }
53
53
 
54
54
  table._features.forEach(feature => {
55
- Object.assign(
56
- cell,
57
- feature.createCell?.(
58
- cell as Cell<TData, TValue>,
59
- column,
60
- row as Row<TData>,
61
- table
62
- )
55
+ feature.createCell?.(
56
+ cell as Cell<TData, TValue>,
57
+ column,
58
+ row as Row<TData>,
59
+ table
63
60
  )
64
61
  }, {})
65
62
 
@@ -119,9 +119,9 @@ export function createColumn<TData extends RowData, TValue>(
119
119
  ),
120
120
  }
121
121
 
122
- column = table._features.reduce((obj, feature) => {
123
- return Object.assign(obj, feature.createColumn?.(column, table))
124
- }, column)
122
+ for (const feature of table._features) {
123
+ feature.createColumn?.(column, table)
124
+ }
125
125
 
126
126
  // Yes, we have to convert table to uknown, because we know more than the compiler here.
127
127
  return column as Column<TData, TValue>
@@ -99,292 +99,276 @@ function createHeader<TData extends RowData, TValue>(
99
99
  }
100
100
 
101
101
  table._features.forEach(feature => {
102
- Object.assign(header, feature.createHeader?.(header, table))
102
+ feature.createHeader?.(header, table)
103
103
  })
104
104
 
105
105
  return header as Header<TData, TValue>
106
106
  }
107
107
 
108
108
  export const Headers: TableFeature = {
109
- createTable: <TData extends RowData>(
110
- table: Table<TData>
111
- ): HeadersInstance<TData> => {
112
- return {
113
- // Header Groups
114
-
115
- getHeaderGroups: memo(
116
- () => [
117
- table.getAllColumns(),
118
- table.getVisibleLeafColumns(),
119
- table.getState().columnPinning.left,
120
- table.getState().columnPinning.right,
121
- ],
122
- (allColumns, leafColumns, left, right) => {
123
- const leftColumns =
124
- left
125
- ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
126
- .filter(Boolean) ?? []
127
-
128
- const rightColumns =
129
- right
130
- ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
131
- .filter(Boolean) ?? []
132
-
133
- const centerColumns = leafColumns.filter(
134
- column => !left?.includes(column.id) && !right?.includes(column.id)
135
- )
136
-
137
- const headerGroups = buildHeaderGroups(
138
- allColumns,
139
- [...leftColumns, ...centerColumns, ...rightColumns],
140
- table
141
- )
142
-
143
- return headerGroups
144
- },
145
- {
146
- key: process.env.NODE_ENV === 'development' && 'getHeaderGroups',
147
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
148
- }
149
- ),
150
-
151
- getCenterHeaderGroups: memo(
152
- () => [
153
- table.getAllColumns(),
154
- table.getVisibleLeafColumns(),
155
- table.getState().columnPinning.left,
156
- table.getState().columnPinning.right,
157
- ],
158
- (allColumns, leafColumns, left, right) => {
159
- leafColumns = leafColumns.filter(
160
- column => !left?.includes(column.id) && !right?.includes(column.id)
161
- )
162
- return buildHeaderGroups(allColumns, leafColumns, table, 'center')
163
- },
164
- {
165
- key:
166
- process.env.NODE_ENV === 'development' && 'getCenterHeaderGroups',
167
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
168
- }
169
- ),
170
-
171
- getLeftHeaderGroups: memo(
172
- () => [
173
- table.getAllColumns(),
174
- table.getVisibleLeafColumns(),
175
- table.getState().columnPinning.left,
176
- ],
177
- (allColumns, leafColumns, left) => {
178
- const orderedLeafColumns =
179
- left
180
- ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
181
- .filter(Boolean) ?? []
182
-
183
- return buildHeaderGroups(
184
- allColumns,
185
- orderedLeafColumns,
186
- table,
187
- 'left'
188
- )
189
- },
190
- {
191
- key: process.env.NODE_ENV === 'development' && 'getLeftHeaderGroups',
192
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
193
- }
194
- ),
195
-
196
- getRightHeaderGroups: memo(
197
- () => [
198
- table.getAllColumns(),
199
- table.getVisibleLeafColumns(),
200
- table.getState().columnPinning.right,
201
- ],
202
- (allColumns, leafColumns, right) => {
203
- const orderedLeafColumns =
204
- right
205
- ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
206
- .filter(Boolean) ?? []
207
-
208
- return buildHeaderGroups(
209
- allColumns,
210
- orderedLeafColumns,
211
- table,
212
- 'right'
213
- )
214
- },
215
- {
216
- key: process.env.NODE_ENV === 'development' && 'getRightHeaderGroups',
217
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
218
- }
219
- ),
220
-
221
- // Footer Groups
222
-
223
- getFooterGroups: memo(
224
- () => [table.getHeaderGroups()],
225
- headerGroups => {
226
- return [...headerGroups].reverse()
227
- },
228
- {
229
- key: process.env.NODE_ENV === 'development' && 'getFooterGroups',
230
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
231
- }
232
- ),
233
-
234
- getLeftFooterGroups: memo(
235
- () => [table.getLeftHeaderGroups()],
236
- headerGroups => {
237
- return [...headerGroups].reverse()
238
- },
239
- {
240
- key: process.env.NODE_ENV === 'development' && 'getLeftFooterGroups',
241
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
242
- }
243
- ),
244
-
245
- getCenterFooterGroups: memo(
246
- () => [table.getCenterHeaderGroups()],
247
- headerGroups => {
248
- return [...headerGroups].reverse()
249
- },
250
- {
251
- key:
252
- process.env.NODE_ENV === 'development' && 'getCenterFooterGroups',
253
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
254
- }
255
- ),
256
-
257
- getRightFooterGroups: memo(
258
- () => [table.getRightHeaderGroups()],
259
- headerGroups => {
260
- return [...headerGroups].reverse()
261
- },
262
- {
263
- key: process.env.NODE_ENV === 'development' && 'getRightFooterGroups',
264
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
265
- }
266
- ),
267
-
268
- // Flat Headers
269
-
270
- getFlatHeaders: memo(
271
- () => [table.getHeaderGroups()],
272
- headerGroups => {
273
- return headerGroups
274
- .map(headerGroup => {
275
- return headerGroup.headers
276
- })
277
- .flat()
278
- },
279
- {
280
- key: process.env.NODE_ENV === 'development' && 'getFlatHeaders',
281
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
282
- }
283
- ),
284
-
285
- getLeftFlatHeaders: memo(
286
- () => [table.getLeftHeaderGroups()],
287
- left => {
288
- return left
289
- .map(headerGroup => {
290
- return headerGroup.headers
291
- })
292
- .flat()
293
- },
294
- {
295
- key: process.env.NODE_ENV === 'development' && 'getLeftFlatHeaders',
296
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
297
- }
298
- ),
299
-
300
- getCenterFlatHeaders: memo(
301
- () => [table.getCenterHeaderGroups()],
302
- left => {
303
- return left
304
- .map(headerGroup => {
305
- return headerGroup.headers
306
- })
307
- .flat()
308
- },
309
- {
310
- key: process.env.NODE_ENV === 'development' && 'getCenterFlatHeaders',
311
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
312
- }
313
- ),
314
-
315
- getRightFlatHeaders: memo(
316
- () => [table.getRightHeaderGroups()],
317
- left => {
318
- return left
319
- .map(headerGroup => {
320
- return headerGroup.headers
321
- })
322
- .flat()
323
- },
324
- {
325
- key: process.env.NODE_ENV === 'development' && 'getRightFlatHeaders',
326
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
327
- }
328
- ),
329
-
330
- // Leaf Headers
331
-
332
- getCenterLeafHeaders: memo(
333
- () => [table.getCenterFlatHeaders()],
334
- flatHeaders => {
335
- return flatHeaders.filter(header => !header.subHeaders?.length)
336
- },
337
- {
338
- key: process.env.NODE_ENV === 'development' && 'getCenterLeafHeaders',
339
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
340
- }
341
- ),
342
-
343
- getLeftLeafHeaders: memo(
344
- () => [table.getLeftFlatHeaders()],
345
- flatHeaders => {
346
- return flatHeaders.filter(header => !header.subHeaders?.length)
347
- },
348
- {
349
- key: process.env.NODE_ENV === 'development' && 'getLeftLeafHeaders',
350
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
351
- }
352
- ),
353
-
354
- getRightLeafHeaders: memo(
355
- () => [table.getRightFlatHeaders()],
356
- flatHeaders => {
357
- return flatHeaders.filter(header => !header.subHeaders?.length)
358
- },
359
- {
360
- key: process.env.NODE_ENV === 'development' && 'getRightLeafHeaders',
361
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
362
- }
363
- ),
364
-
365
- getLeafHeaders: memo(
366
- () => [
367
- table.getLeftHeaderGroups(),
368
- table.getCenterHeaderGroups(),
369
- table.getRightHeaderGroups(),
370
- ],
371
- (left, center, right) => {
372
- return [
373
- ...(left[0]?.headers ?? []),
374
- ...(center[0]?.headers ?? []),
375
- ...(right[0]?.headers ?? []),
376
- ]
377
- .map(header => {
378
- return header.getLeafHeaders()
379
- })
380
- .flat()
381
- },
382
- {
383
- key: process.env.NODE_ENV === 'development' && 'getLeafHeaders',
384
- debug: () => table.options.debugAll ?? table.options.debugHeaders,
385
- }
386
- ),
387
- }
109
+ createTable: <TData extends RowData>(table: Table<TData>): void => {
110
+ // Header Groups
111
+
112
+ table.getHeaderGroups = memo(
113
+ () => [
114
+ table.getAllColumns(),
115
+ table.getVisibleLeafColumns(),
116
+ table.getState().columnPinning.left,
117
+ table.getState().columnPinning.right,
118
+ ],
119
+ (allColumns, leafColumns, left, right) => {
120
+ const leftColumns =
121
+ left
122
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
123
+ .filter(Boolean) ?? []
124
+
125
+ const rightColumns =
126
+ right
127
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
128
+ .filter(Boolean) ?? []
129
+
130
+ const centerColumns = leafColumns.filter(
131
+ column => !left?.includes(column.id) && !right?.includes(column.id)
132
+ )
133
+
134
+ const headerGroups = buildHeaderGroups(
135
+ allColumns,
136
+ [...leftColumns, ...centerColumns, ...rightColumns],
137
+ table
138
+ )
139
+
140
+ return headerGroups
141
+ },
142
+ {
143
+ key: process.env.NODE_ENV === 'development' && 'getHeaderGroups',
144
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
145
+ }
146
+ )
147
+
148
+ table.getCenterHeaderGroups = memo(
149
+ () => [
150
+ table.getAllColumns(),
151
+ table.getVisibleLeafColumns(),
152
+ table.getState().columnPinning.left,
153
+ table.getState().columnPinning.right,
154
+ ],
155
+ (allColumns, leafColumns, left, right) => {
156
+ leafColumns = leafColumns.filter(
157
+ column => !left?.includes(column.id) && !right?.includes(column.id)
158
+ )
159
+ return buildHeaderGroups(allColumns, leafColumns, table, 'center')
160
+ },
161
+ {
162
+ key: process.env.NODE_ENV === 'development' && 'getCenterHeaderGroups',
163
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
164
+ }
165
+ )
166
+
167
+ table.getLeftHeaderGroups = memo(
168
+ () => [
169
+ table.getAllColumns(),
170
+ table.getVisibleLeafColumns(),
171
+ table.getState().columnPinning.left,
172
+ ],
173
+ (allColumns, leafColumns, left) => {
174
+ const orderedLeafColumns =
175
+ left
176
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
177
+ .filter(Boolean) ?? []
178
+
179
+ return buildHeaderGroups(allColumns, orderedLeafColumns, table, 'left')
180
+ },
181
+ {
182
+ key: process.env.NODE_ENV === 'development' && 'getLeftHeaderGroups',
183
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
184
+ }
185
+ )
186
+
187
+ table.getRightHeaderGroups = memo(
188
+ () => [
189
+ table.getAllColumns(),
190
+ table.getVisibleLeafColumns(),
191
+ table.getState().columnPinning.right,
192
+ ],
193
+ (allColumns, leafColumns, right) => {
194
+ const orderedLeafColumns =
195
+ right
196
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
197
+ .filter(Boolean) ?? []
198
+
199
+ return buildHeaderGroups(allColumns, orderedLeafColumns, table, 'right')
200
+ },
201
+ {
202
+ key: process.env.NODE_ENV === 'development' && 'getRightHeaderGroups',
203
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
204
+ }
205
+ )
206
+
207
+ // Footer Groups
208
+
209
+ table.getFooterGroups = memo(
210
+ () => [table.getHeaderGroups()],
211
+ headerGroups => {
212
+ return [...headerGroups].reverse()
213
+ },
214
+ {
215
+ key: process.env.NODE_ENV === 'development' && 'getFooterGroups',
216
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
217
+ }
218
+ )
219
+
220
+ table.getLeftFooterGroups = memo(
221
+ () => [table.getLeftHeaderGroups()],
222
+ headerGroups => {
223
+ return [...headerGroups].reverse()
224
+ },
225
+ {
226
+ key: process.env.NODE_ENV === 'development' && 'getLeftFooterGroups',
227
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
228
+ }
229
+ )
230
+
231
+ table.getCenterFooterGroups = memo(
232
+ () => [table.getCenterHeaderGroups()],
233
+ headerGroups => {
234
+ return [...headerGroups].reverse()
235
+ },
236
+ {
237
+ key: process.env.NODE_ENV === 'development' && 'getCenterFooterGroups',
238
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
239
+ }
240
+ )
241
+
242
+ table.getRightFooterGroups = memo(
243
+ () => [table.getRightHeaderGroups()],
244
+ headerGroups => {
245
+ return [...headerGroups].reverse()
246
+ },
247
+ {
248
+ key: process.env.NODE_ENV === 'development' && 'getRightFooterGroups',
249
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
250
+ }
251
+ )
252
+
253
+ // Flat Headers
254
+
255
+ table.getFlatHeaders = memo(
256
+ () => [table.getHeaderGroups()],
257
+ headerGroups => {
258
+ return headerGroups
259
+ .map(headerGroup => {
260
+ return headerGroup.headers
261
+ })
262
+ .flat()
263
+ },
264
+ {
265
+ key: process.env.NODE_ENV === 'development' && 'getFlatHeaders',
266
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
267
+ }
268
+ )
269
+
270
+ table.getLeftFlatHeaders = memo(
271
+ () => [table.getLeftHeaderGroups()],
272
+ left => {
273
+ return left
274
+ .map(headerGroup => {
275
+ return headerGroup.headers
276
+ })
277
+ .flat()
278
+ },
279
+ {
280
+ key: process.env.NODE_ENV === 'development' && 'getLeftFlatHeaders',
281
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
282
+ }
283
+ )
284
+
285
+ table.getCenterFlatHeaders = memo(
286
+ () => [table.getCenterHeaderGroups()],
287
+ left => {
288
+ return left
289
+ .map(headerGroup => {
290
+ return headerGroup.headers
291
+ })
292
+ .flat()
293
+ },
294
+ {
295
+ key: process.env.NODE_ENV === 'development' && 'getCenterFlatHeaders',
296
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
297
+ }
298
+ )
299
+
300
+ table.getRightFlatHeaders = memo(
301
+ () => [table.getRightHeaderGroups()],
302
+ left => {
303
+ return left
304
+ .map(headerGroup => {
305
+ return headerGroup.headers
306
+ })
307
+ .flat()
308
+ },
309
+ {
310
+ key: process.env.NODE_ENV === 'development' && 'getRightFlatHeaders',
311
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
312
+ }
313
+ )
314
+
315
+ // Leaf Headers
316
+
317
+ table.getCenterLeafHeaders = memo(
318
+ () => [table.getCenterFlatHeaders()],
319
+ flatHeaders => {
320
+ return flatHeaders.filter(header => !header.subHeaders?.length)
321
+ },
322
+ {
323
+ key: process.env.NODE_ENV === 'development' && 'getCenterLeafHeaders',
324
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
325
+ }
326
+ )
327
+
328
+ table.getLeftLeafHeaders = memo(
329
+ () => [table.getLeftFlatHeaders()],
330
+ flatHeaders => {
331
+ return flatHeaders.filter(header => !header.subHeaders?.length)
332
+ },
333
+ {
334
+ key: process.env.NODE_ENV === 'development' && 'getLeftLeafHeaders',
335
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
336
+ }
337
+ )
338
+
339
+ table.getRightLeafHeaders = memo(
340
+ () => [table.getRightFlatHeaders()],
341
+ flatHeaders => {
342
+ return flatHeaders.filter(header => !header.subHeaders?.length)
343
+ },
344
+ {
345
+ key: process.env.NODE_ENV === 'development' && 'getRightLeafHeaders',
346
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
347
+ }
348
+ )
349
+
350
+ table.getLeafHeaders = memo(
351
+ () => [
352
+ table.getLeftHeaderGroups(),
353
+ table.getCenterHeaderGroups(),
354
+ table.getRightHeaderGroups(),
355
+ ],
356
+ (left, center, right) => {
357
+ return [
358
+ ...(left[0]?.headers ?? []),
359
+ ...(center[0]?.headers ?? []),
360
+ ...(right[0]?.headers ?? []),
361
+ ]
362
+ .map(header => {
363
+ return header.getLeafHeaders()
364
+ })
365
+ .flat()
366
+ },
367
+ {
368
+ key: process.env.NODE_ENV === 'development' && 'getLeafHeaders',
369
+ debug: () => table.options.debugAll ?? table.options.debugHeaders,
370
+ }
371
+ )
388
372
  },
389
373
  }
390
374
 
package/src/core/row.ts CHANGED
@@ -127,7 +127,7 @@ export const createRow = <TData extends RowData>(
127
127
 
128
128
  for (let i = 0; i < table._features.length; i++) {
129
129
  const feature = table._features[i]
130
- Object.assign(row, feature?.createRow?.(row, table))
130
+ feature?.createRow?.(row, table)
131
131
  }
132
132
 
133
133
  return row as Row<TData>
package/src/core/table.ts CHANGED
@@ -347,9 +347,10 @@ export function createTable<TData extends RowData>(
347
347
 
348
348
  Object.assign(table, coreInstance)
349
349
 
350
- table._features.forEach(feature => {
351
- return Object.assign(table, feature.createTable?.(table))
352
- })
350
+ for (let index = 0; index < table._features.length; index++) {
351
+ const feature = table._features[index]
352
+ feature?.createTable?.(table)
353
+ }
353
354
 
354
355
  return table
355
356
  }