@svgrid/enterprise 3.0.1 → 3.0.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/LICENSE +94 -24
- package/README.md +36 -4
- package/dist/SvAdvancedFilter.svelte +1 -1
- package/dist/SvAlertsManager.svelte +2 -1
- package/dist/SvBoard.svelte +2 -1
- package/dist/SvExportMenu.svelte +4 -1
- package/dist/SvExportMenu.svelte.d.ts +0 -13
- package/dist/SvExpressionEditor.svelte +3 -3
- package/dist/SvFormulaBar.svelte +680 -0
- package/dist/SvFormulaBar.svelte.d.ts +69 -0
- package/dist/SvGridAlerts.svelte +49 -9
- package/dist/SvGridBoard.svelte +13 -8
- package/dist/SvGridBulkEditDrawer.svelte +26 -2
- package/dist/SvGridEditPanel.svelte +3 -0
- package/dist/SvGridScheduler.svelte +69 -40
- package/dist/SvGridSelectionBar.svelte +10 -3
- package/dist/SvPivotDesigner.svelte +263 -54
- package/dist/SvPivotDesigner.svelte.d.ts +27 -20
- package/dist/SvRibbonIcon.svelte +46 -0
- package/dist/SvRibbonIcon.svelte.d.ts +17 -0
- package/dist/SvSchemaChart.svelte +4 -2
- package/dist/SvSheet.svelte +7914 -0
- package/dist/SvSheet.svelte.d.ts +215 -0
- package/dist/SvSheetChartSetup.svelte +151 -0
- package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
- package/dist/SvSheetComment.svelte +283 -0
- package/dist/SvSheetComment.svelte.d.ts +22 -0
- package/dist/SvSheetConditionalFormat.svelte +159 -0
- package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
- package/dist/SvSheetDataValidation.svelte +273 -0
- package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
- package/dist/SvSheetEditRanges.svelte +217 -0
- package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
- package/dist/SvSheetErrors.svelte +125 -0
- package/dist/SvSheetErrors.svelte.d.ts +20 -0
- package/dist/SvSheetEvaluate.svelte +133 -0
- package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
- package/dist/SvSheetFilterMenu.svelte +320 -0
- package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
- package/dist/SvSheetFindReplace.svelte +132 -0
- package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
- package/dist/SvSheetFormatCells.svelte +465 -0
- package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
- package/dist/SvSheetGoalSeek.svelte +145 -0
- package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
- package/dist/SvSheetInsertFunction.svelte +149 -0
- package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
- package/dist/SvSheetIteration.svelte +81 -0
- package/dist/SvSheetIteration.svelte.d.ts +10 -0
- package/dist/SvSheetLink.svelte +99 -0
- package/dist/SvSheetLink.svelte.d.ts +17 -0
- package/dist/SvSheetListPicker.svelte +91 -0
- package/dist/SvSheetListPicker.svelte.d.ts +10 -0
- package/dist/SvSheetManageRules.svelte +187 -0
- package/dist/SvSheetManageRules.svelte.d.ts +16 -0
- package/dist/SvSheetNameManager.svelte +227 -0
- package/dist/SvSheetNameManager.svelte.d.ts +11 -0
- package/dist/SvSheetPageSetup.svelte +159 -0
- package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
- package/dist/SvSheetPasteSpecial.svelte +107 -0
- package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
- package/dist/SvSheetPivot.svelte +220 -0
- package/dist/SvSheetPivot.svelte.d.ts +21 -0
- package/dist/SvSheetProtectSheet.svelte +81 -0
- package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
- package/dist/SvSheetRemoveDuplicates.svelte +152 -0
- package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
- package/dist/SvSheetRibbon.svelte +1254 -0
- package/dist/SvSheetRibbon.svelte.d.ts +34 -0
- package/dist/SvSheetSizeDialog.svelte +60 -0
- package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
- package/dist/SvSheetSort.svelte +218 -0
- package/dist/SvSheetSort.svelte.d.ts +28 -0
- package/dist/SvSheetSparklines.svelte +135 -0
- package/dist/SvSheetSparklines.svelte.d.ts +14 -0
- package/dist/SvSheetTable.svelte +160 -0
- package/dist/SvSheetTable.svelte.d.ts +24 -0
- package/dist/SvSheetTabs.svelte +571 -0
- package/dist/SvSheetTabs.svelte.d.ts +50 -0
- package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
- package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
- package/dist/SvSheetTextToColumns.svelte +172 -0
- package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
- package/dist/SvSheetValidationAlert.svelte +85 -0
- package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
- package/dist/advanced-filter-enable.js +1 -1
- package/dist/alerts/alert-engine.d.ts +6 -0
- package/dist/alerts/alert-engine.js +21 -4
- package/dist/alerts/alert-formats.js +2 -0
- package/dist/alerts/alert-types.d.ts +1 -1
- package/dist/alerts.d.ts +1 -1
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/bulk-edit.d.ts +3 -1
- package/dist/bulk-edit.js +1 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
- package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
- package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
- package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
- package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
- package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
- package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
- package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
- package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
- package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
- package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
- package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
- package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
- package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
- package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
- package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
- package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
- package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
- package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
- package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
- package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
- package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
- package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
- package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
- package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
- package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
- package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
- package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
- package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
- package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
- package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
- package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
- package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
- package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
- package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
- package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
- package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
- package/dist/designer/assets/index-_JVFxt02.css +1 -0
- package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
- package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
- package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
- package/dist/designer/assets/src-CITpcm6b.js +1 -0
- package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
- package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
- package/dist/designer/index.html +29 -19
- package/dist/export-pdf.d.ts +164 -0
- package/dist/export-pdf.js +346 -15
- package/dist/export.js +25 -10
- package/dist/gantt/SvGridGantt.svelte +2890 -0
- package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
- package/dist/gantt/gantt-config.d.ts +73 -0
- package/dist/gantt/gantt-config.js +1 -0
- package/dist/gantt/gantt-critical-path.d.ts +67 -0
- package/dist/gantt/gantt-critical-path.js +207 -0
- package/dist/gantt/gantt-model.d.ts +257 -0
- package/dist/gantt/gantt-model.js +651 -0
- package/dist/gantt/gantt-resources.d.ts +59 -0
- package/dist/gantt/gantt-resources.js +71 -0
- package/dist/gantt/gantt.d.ts +7 -0
- package/dist/gantt/gantt.js +36 -0
- package/dist/gantt/index.d.ts +15 -0
- package/dist/gantt/index.js +22 -0
- package/dist/gantt/timeline-arrows.d.ts +102 -0
- package/dist/gantt/timeline-arrows.js +181 -0
- package/dist/import.d.ts +2 -2
- package/dist/import.js +1 -1
- package/dist/index.d.ts +93 -3
- package/dist/index.js +107 -3
- package/dist/install.js +13 -1
- package/dist/license-core.d.ts +17 -1
- package/dist/license-core.js +16 -5
- package/dist/license.d.ts +18 -2
- package/dist/license.js +71 -6
- package/dist/node/studio.js +203 -9
- package/dist/pivot-chart.d.ts +25 -1
- package/dist/pivot-chart.js +25 -69
- package/dist/pivot-enable.js +2 -2
- package/dist/scheduler-dependencies.d.ts +35 -0
- package/dist/scheduler-dependencies.js +36 -1
- package/dist/scheduler.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/server/SvGroupCell.svelte +213 -0
- package/dist/server/SvGroupCell.svelte.d.ts +62 -0
- package/dist/server/SvRowGroupPanel.svelte +322 -0
- package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
- package/dist/server/enable.d.ts +17 -0
- package/dist/server/enable.js +49 -0
- package/dist/server/index.d.ts +22 -0
- package/dist/server/index.js +24 -0
- package/dist/server/messages.d.ts +45 -0
- package/dist/server/messages.js +35 -0
- package/dist/server/server-group-model.d.ts +104 -0
- package/dist/server/server-group-model.js +272 -0
- package/dist/server/server-pivot.d.ts +46 -0
- package/dist/server/server-pivot.js +57 -0
- package/dist/server/server-row-model.d.ts +547 -0
- package/dist/server/server-row-model.js +1551 -0
- package/dist/server/server-selection.d.ts +99 -0
- package/dist/server/server-selection.js +215 -0
- package/dist/server/svgrid-adapter.d.ts +155 -0
- package/dist/server/svgrid-adapter.js +202 -0
- package/dist/sheet/address.d.ts +43 -0
- package/dist/sheet/address.js +81 -0
- package/dist/sheet/ast.d.ts +138 -0
- package/dist/sheet/ast.js +70 -0
- package/dist/sheet/auto-filter.d.ts +120 -0
- package/dist/sheet/auto-filter.js +295 -0
- package/dist/sheet/autocomplete.d.ts +51 -0
- package/dist/sheet/autocomplete.js +248 -0
- package/dist/sheet/cell-images.d.ts +39 -0
- package/dist/sheet/cell-images.js +90 -0
- package/dist/sheet/cell-types.d.ts +58 -0
- package/dist/sheet/cell-types.js +96 -0
- package/dist/sheet/coerce.d.ts +71 -0
- package/dist/sheet/coerce.js +289 -0
- package/dist/sheet/commands.d.ts +89 -0
- package/dist/sheet/commands.js +230 -0
- package/dist/sheet/comments.d.ts +63 -0
- package/dist/sheet/comments.js +131 -0
- package/dist/sheet/conditional-formats.d.ts +167 -0
- package/dist/sheet/conditional-formats.js +341 -0
- package/dist/sheet/csv.d.ts +32 -0
- package/dist/sheet/csv.js +158 -0
- package/dist/sheet/culture.d.ts +87 -0
- package/dist/sheet/culture.js +247 -0
- package/dist/sheet/delta.d.ts +102 -0
- package/dist/sheet/delta.js +203 -0
- package/dist/sheet/deps.d.ts +104 -0
- package/dist/sheet/deps.js +274 -0
- package/dist/sheet/document.d.ts +252 -0
- package/dist/sheet/document.js +465 -0
- package/dist/sheet/edit-keys.d.ts +14 -0
- package/dist/sheet/edit-keys.js +40 -0
- package/dist/sheet/engine.d.ts +67 -0
- package/dist/sheet/engine.js +19 -0
- package/dist/sheet/entry.d.ts +35 -0
- package/dist/sheet/entry.js +226 -0
- package/dist/sheet/error-check.d.ts +49 -0
- package/dist/sheet/error-check.js +83 -0
- package/dist/sheet/evaluate-steps.d.ts +48 -0
- package/dist/sheet/evaluate-steps.js +196 -0
- package/dist/sheet/evaluate.d.ts +128 -0
- package/dist/sheet/evaluate.js +1049 -0
- package/dist/sheet/filter-files.d.ts +37 -0
- package/dist/sheet/filter-files.js +465 -0
- package/dist/sheet/find-replace.d.ts +62 -0
- package/dist/sheet/find-replace.js +152 -0
- package/dist/sheet/format-store.d.ts +114 -0
- package/dist/sheet/format-store.js +243 -0
- package/dist/sheet/freeze.d.ts +54 -0
- package/dist/sheet/freeze.js +58 -0
- package/dist/sheet/from-rows.d.ts +14 -0
- package/dist/sheet/from-rows.js +50 -0
- package/dist/sheet/function-catalog.d.ts +10 -0
- package/dist/sheet/function-catalog.js +385 -0
- package/dist/sheet/functions.d.ts +28 -0
- package/dist/sheet/functions.js +634 -0
- package/dist/sheet/goal-seek.d.ts +73 -0
- package/dist/sheet/goal-seek.js +153 -0
- package/dist/sheet/index.d.ts +80 -0
- package/dist/sheet/index.js +80 -0
- package/dist/sheet/links.d.ts +57 -0
- package/dist/sheet/links.js +174 -0
- package/dist/sheet/merges.d.ts +71 -0
- package/dist/sheet/merges.js +137 -0
- package/dist/sheet/messages.d.ts +778 -0
- package/dist/sheet/messages.js +806 -0
- package/dist/sheet/names.d.ts +31 -0
- package/dist/sheet/names.js +87 -0
- package/dist/sheet/navigate.d.ts +52 -0
- package/dist/sheet/navigate.js +135 -0
- package/dist/sheet/number-format.d.ts +110 -0
- package/dist/sheet/number-format.js +905 -0
- package/dist/sheet/objects.d.ts +106 -0
- package/dist/sheet/objects.js +149 -0
- package/dist/sheet/ods-document.d.ts +44 -0
- package/dist/sheet/ods-document.js +1275 -0
- package/dist/sheet/open-file.d.ts +26 -0
- package/dist/sheet/open-file.js +56 -0
- package/dist/sheet/outline.d.ts +82 -0
- package/dist/sheet/outline.js +228 -0
- package/dist/sheet/packs/array.d.ts +16 -0
- package/dist/sheet/packs/array.js +172 -0
- package/dist/sheet/packs/database.d.ts +42 -0
- package/dist/sheet/packs/database.js +142 -0
- package/dist/sheet/packs/engineering.d.ts +2 -0
- package/dist/sheet/packs/engineering.js +296 -0
- package/dist/sheet/packs/financial.d.ts +5 -0
- package/dist/sheet/packs/financial.js +220 -0
- package/dist/sheet/packs/math-stats.d.ts +2 -0
- package/dist/sheet/packs/math-stats.js +372 -0
- package/dist/sheet/packs/special.d.ts +44 -0
- package/dist/sheet/packs/special.js +187 -0
- package/dist/sheet/packs/stats-dist.d.ts +2 -0
- package/dist/sheet/packs/stats-dist.js +785 -0
- package/dist/sheet/packs/text-date.d.ts +2 -0
- package/dist/sheet/packs/text-date.js +332 -0
- package/dist/sheet/packs/trig.d.ts +2 -0
- package/dist/sheet/packs/trig.js +73 -0
- package/dist/sheet/page-setup.d.ts +73 -0
- package/dist/sheet/page-setup.js +73 -0
- package/dist/sheet/palette.d.ts +19 -0
- package/dist/sheet/palette.js +84 -0
- package/dist/sheet/parse.d.ts +13 -0
- package/dist/sheet/parse.js +140 -0
- package/dist/sheet/paste-special.d.ts +186 -0
- package/dist/sheet/paste-special.js +601 -0
- package/dist/sheet/pivot-range.d.ts +160 -0
- package/dist/sheet/pivot-range.js +333 -0
- package/dist/sheet/presence.d.ts +73 -0
- package/dist/sheet/presence.js +79 -0
- package/dist/sheet/print.d.ts +104 -0
- package/dist/sheet/print.js +169 -0
- package/dist/sheet/protection.d.ts +75 -0
- package/dist/sheet/protection.js +101 -0
- package/dist/sheet/rects.d.ts +45 -0
- package/dist/sheet/rects.js +112 -0
- package/dist/sheet/refs.d.ts +130 -0
- package/dist/sheet/refs.js +413 -0
- package/dist/sheet/ribbon-icons.d.ts +31 -0
- package/dist/sheet/ribbon-icons.js +536 -0
- package/dist/sheet/ribbon.d.ts +173 -0
- package/dist/sheet/ribbon.js +1054 -0
- package/dist/sheet/sheet-kinds.d.ts +74 -0
- package/dist/sheet/sheet-kinds.js +91 -0
- package/dist/sheet/shortcuts.d.ts +174 -0
- package/dist/sheet/shortcuts.js +674 -0
- package/dist/sheet/sort.d.ts +51 -0
- package/dist/sheet/sort.js +107 -0
- package/dist/sheet/sparklines.d.ts +111 -0
- package/dist/sheet/sparklines.js +204 -0
- package/dist/sheet/structure.d.ts +87 -0
- package/dist/sheet/structure.js +166 -0
- package/dist/sheet/table-styles.d.ts +74 -0
- package/dist/sheet/table-styles.js +152 -0
- package/dist/sheet/tables.d.ts +89 -0
- package/dist/sheet/tables.js +178 -0
- package/dist/sheet/tokenize.d.ts +71 -0
- package/dist/sheet/tokenize.js +355 -0
- package/dist/sheet/transforms.d.ts +76 -0
- package/dist/sheet/transforms.js +154 -0
- package/dist/sheet/validation.d.ts +108 -0
- package/dist/sheet/validation.js +278 -0
- package/dist/sheet/workbook.d.ts +217 -0
- package/dist/sheet/workbook.js +1120 -0
- package/dist/sheet/xls-cfb.d.ts +32 -0
- package/dist/sheet/xls-cfb.js +290 -0
- package/dist/sheet/xls-document.d.ts +10 -0
- package/dist/sheet/xls-document.js +1243 -0
- package/dist/sheet/xls-formula.d.ts +40 -0
- package/dist/sheet/xls-formula.js +569 -0
- package/dist/sheet/xlsx-document.d.ts +108 -0
- package/dist/sheet/xlsx-document.js +1849 -0
- package/dist/sheet/xlsx-drawing.d.ts +99 -0
- package/dist/sheet/xlsx-drawing.js +420 -0
- package/dist/sheet-enable.d.ts +6 -0
- package/dist/sheet-enable.js +45 -0
- package/dist/sheet-text.d.ts +7 -0
- package/dist/sheet-text.js +29 -0
- package/dist/sources/auth-supabase.js +2 -2
- package/dist/sources/realtime-supabase.js +2 -2
- package/dist/sources/rest.d.ts +6 -2
- package/dist/sources/rest.js +42 -7
- package/dist/sources/supabase.d.ts +10 -1
- package/dist/sources/supabase.js +73 -40
- package/dist/studio/emit-project.js +14 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio/project.d.ts +11 -2
- package/dist/studio/project.js +5 -2
- package/dist/studio/ui-components.generated.js +170 -3
- package/dist/sveltekit/in-memory.d.ts +2 -2
- package/dist/sveltekit/in-memory.js +125 -4
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/query-plan.d.ts +50 -4
- package/dist/sveltekit/query-plan.js +25 -3
- package/dist/sveltekit/sql-source.d.ts +6 -0
- package/dist/sveltekit/sql-source.js +34 -6
- package/dist/sveltekit/sql.d.ts +31 -0
- package/dist/sveltekit/sql.js +135 -25
- package/dist/sveltekit/transport.d.ts +10 -2
- package/dist/sveltekit/transport.js +30 -6
- package/dist/upgrade-prompt.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watermark.js +35 -2
- package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
- package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
- package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
- package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
- package/dist/wc/SvField-B_kurx_P.js +149 -0
- package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
- package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
- package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
- package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
- package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
- package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
- package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
- package/dist/wc/SvModal-DrfOYYyX.js +189 -0
- package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
- package/dist/wc/chart-6OXlybVT.js +4341 -0
- package/dist/wc/chart-export-CeSADGfi.js +135 -0
- package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
- package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
- package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
- package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
- package/dist/wc/client-DQIzjDBG.js +3064 -0
- package/dist/wc/column-resize-DUPgynvc.js +101 -0
- package/dist/wc/date-format-DS-z_h9v.js +1130 -0
- package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
- package/dist/wc/editor-contract-peBDxir_.js +22 -0
- package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
- package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
- package/dist/wc/list-option-DrRyivWp.js +82 -0
- package/dist/wc/popover-WsGlvtQv.js +69 -0
- package/dist/wc/positioning-BiKLfu1E.js +112 -0
- package/dist/wc/react.d.ts +41 -0
- package/dist/wc/react.js +90 -0
- package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
- package/dist/wc/row-resize-limG_N1z.js +111 -0
- package/dist/wc/sv-sheet-element.d.ts +97 -0
- package/dist/wc/sv-sheet-element.js +44213 -0
- package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
- package/dist/wc/validate-BqDthkNr.js +88 -0
- package/dist/wc/vue.d.ts +31 -0
- package/dist/wc/vue.js +75 -0
- package/package.json +36 -6
- package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
- package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
- package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
- package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
- package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
- package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
- package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
- package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
- package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
- package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
- package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
- package/dist/designer/assets/chart-DXFganU8.js +0 -1
- package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
- package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
- package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
- package/dist/designer/assets/easing-zaypKrr0.js +0 -3
- package/dist/designer/assets/index-k2stW6L8.css +0 -1
- package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
- package/dist/designer/assets/src-D9p27OGC.js +0 -58
- package/dist/designer/assets/validate-h-aslRV9.js +0 -1
|
@@ -0,0 +1,785 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excel's statistical distributions, their inverses, the hypothesis tests
|
|
3
|
+
* built on them, and the descriptive measures that sit alongside.
|
|
4
|
+
*
|
|
5
|
+
* Every distribution here is the same two questions with different
|
|
6
|
+
* parameters, so they share one shape: a density and a cumulative, with
|
|
7
|
+
* `cumulative` picking between them, and an inverse found by bisecting the
|
|
8
|
+
* cumulative (see `invertCdf` in `./special`).
|
|
9
|
+
*
|
|
10
|
+
* Excel renamed this whole family in 2010 and kept the old names working.
|
|
11
|
+
* Both spellings are registered, and where the two disagree the comment
|
|
12
|
+
* says so, because the disagreements are real and they are traps:
|
|
13
|
+
*
|
|
14
|
+
* - `CHIDIST` is the RIGHT tail; `CHISQ.DIST` is the left. The old name
|
|
15
|
+
* is not the new one with a dot in it.
|
|
16
|
+
* - `TDIST` takes a tail COUNT (1 or 2) and refuses a negative x;
|
|
17
|
+
* `T.DIST` takes a boolean and accepts any x.
|
|
18
|
+
* - `FDIST` and `FINV` are right-tailed; `F.DIST` and `F.INV` are left.
|
|
19
|
+
* - `BETADIST` and `BETA.DIST` order their optional bounds the same, but
|
|
20
|
+
* `BETA.DIST` alone requires `cumulative`.
|
|
21
|
+
*
|
|
22
|
+
* Factorials and binomial coefficients go through `lgamma` rather than a
|
|
23
|
+
* product, so `COMBIN`-sized arguments do not overflow to Infinity on the
|
|
24
|
+
* way to a probability that is perfectly representable.
|
|
25
|
+
*/
|
|
26
|
+
import { err } from '../ast.js';
|
|
27
|
+
import { toNumber, toBool, numericOnly, isBlank } from '../coerce.js';
|
|
28
|
+
import { lgamma, gammaFn, gammaP, gammaQ, betaI, normalCdf, normalPdf, invertCdf, } from './special.js';
|
|
29
|
+
const nth = (a, i) => a.args[i]?.[0] ?? '';
|
|
30
|
+
const num = (a, i) => toNumber(nth(a, i));
|
|
31
|
+
const flag = (a, i) => toBool(nth(a, i));
|
|
32
|
+
const has = (a, i) => {
|
|
33
|
+
const v = a.args[i]?.[0];
|
|
34
|
+
return v !== undefined && v !== '';
|
|
35
|
+
};
|
|
36
|
+
const opt = (a, i, fallback) => (has(a, i) ? num(a, i) : fallback);
|
|
37
|
+
/** log of n choose k, which stays finite where the value itself would not. */
|
|
38
|
+
const lchoose = (n, k) => lgamma(n + 1) - lgamma(k + 1) - lgamma(n - k + 1);
|
|
39
|
+
const choose = (n, k) => Math.exp(lchoose(n, k));
|
|
40
|
+
// ---- Normal ------------------------------------------------------------
|
|
41
|
+
const normDist = (x, mean, sd, cumulative) => {
|
|
42
|
+
if (sd <= 0)
|
|
43
|
+
return err('#NUM!');
|
|
44
|
+
const z = (x - mean) / sd;
|
|
45
|
+
return cumulative ? normalCdf(z) : normalPdf(z) / sd;
|
|
46
|
+
};
|
|
47
|
+
const normInv = (p, mean, sd) => {
|
|
48
|
+
if (sd <= 0 || p <= 0 || p >= 1)
|
|
49
|
+
return err('#NUM!');
|
|
50
|
+
return mean + sd * invertCdf(normalCdf, p, -8, 8);
|
|
51
|
+
};
|
|
52
|
+
// ---- Student t ---------------------------------------------------------
|
|
53
|
+
/** The left-tailed t cumulative, through the incomplete beta. */
|
|
54
|
+
function tCdf(x, df) {
|
|
55
|
+
const half = betaI(df / 2, 0.5, df / (df + x * x)) / 2;
|
|
56
|
+
return x > 0 ? 1 - half : half;
|
|
57
|
+
}
|
|
58
|
+
function tPdf(x, df) {
|
|
59
|
+
return Math.exp(lgamma((df + 1) / 2) - lgamma(df / 2) - 0.5 * Math.log(df * Math.PI)
|
|
60
|
+
- ((df + 1) / 2) * Math.log(1 + (x * x) / df));
|
|
61
|
+
}
|
|
62
|
+
// ---- Chi-square --------------------------------------------------------
|
|
63
|
+
const chiCdf = (x, df) => (x <= 0 ? 0 : gammaP(df / 2, x / 2));
|
|
64
|
+
function chiPdf(x, df) {
|
|
65
|
+
if (x < 0)
|
|
66
|
+
return 0;
|
|
67
|
+
if (x === 0)
|
|
68
|
+
return df === 2 ? 0.5 : 0;
|
|
69
|
+
return Math.exp((df / 2 - 1) * Math.log(x) - x / 2 - lgamma(df / 2) - (df / 2) * Math.LN2);
|
|
70
|
+
}
|
|
71
|
+
// ---- F -----------------------------------------------------------------
|
|
72
|
+
const fCdf = (x, d1, d2) => (x <= 0 ? 0 : betaI(d1 / 2, d2 / 2, (d1 * x) / (d1 * x + d2)));
|
|
73
|
+
function fPdf(x, d1, d2) {
|
|
74
|
+
if (x <= 0)
|
|
75
|
+
return 0;
|
|
76
|
+
const logNum = (d1 / 2) * Math.log(d1 / d2) + (d1 / 2 - 1) * Math.log(x);
|
|
77
|
+
const logDen = ((d1 + d2) / 2) * Math.log(1 + (d1 * x) / d2)
|
|
78
|
+
+ lgamma(d1 / 2) + lgamma(d2 / 2) - lgamma((d1 + d2) / 2);
|
|
79
|
+
return Math.exp(logNum - logDen);
|
|
80
|
+
}
|
|
81
|
+
// ---- Discrete ----------------------------------------------------------
|
|
82
|
+
function binomPmf(k, n, p) {
|
|
83
|
+
if (p === 0)
|
|
84
|
+
return k === 0 ? 1 : 0;
|
|
85
|
+
if (p === 1)
|
|
86
|
+
return k === n ? 1 : 0;
|
|
87
|
+
return Math.exp(lchoose(n, k) + k * Math.log(p) + (n - k) * Math.log(1 - p));
|
|
88
|
+
}
|
|
89
|
+
function binomCdf(k, n, p) {
|
|
90
|
+
let total = 0;
|
|
91
|
+
for (let i = 0; i <= k; i += 1)
|
|
92
|
+
total += binomPmf(i, n, p);
|
|
93
|
+
return Math.min(total, 1);
|
|
94
|
+
}
|
|
95
|
+
const poissonPmf = (k, mean) => Math.exp(-mean + k * Math.log(mean) - lgamma(k + 1));
|
|
96
|
+
/** The Poisson cumulative is the upper incomplete gamma at k + 1. */
|
|
97
|
+
const poissonCdf = (k, mean) => (mean === 0 ? 1 : gammaQ(k + 1, mean));
|
|
98
|
+
function hypgeomPmf(x, n, m, N) {
|
|
99
|
+
return Math.exp(lchoose(m, x) + lchoose(N - m, n - x) - lchoose(N, n));
|
|
100
|
+
}
|
|
101
|
+
// ---- The *A variants, which read text and booleans as numbers ----------
|
|
102
|
+
/** AVERAGEA and friends count text as 0 and a boolean as 1 or 0. */
|
|
103
|
+
function valuesA(values) {
|
|
104
|
+
const out = [];
|
|
105
|
+
for (const v of values) {
|
|
106
|
+
if (isBlank(v))
|
|
107
|
+
continue;
|
|
108
|
+
if (typeof v === 'number')
|
|
109
|
+
out.push(v);
|
|
110
|
+
else if (typeof v === 'boolean')
|
|
111
|
+
out.push(v ? 1 : 0);
|
|
112
|
+
else if (typeof v === 'string')
|
|
113
|
+
out.push(Number(v) || 0);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
function variance(values, sample) {
|
|
118
|
+
const n = values.length;
|
|
119
|
+
if (n < (sample ? 2 : 1))
|
|
120
|
+
return err('#DIV/0!');
|
|
121
|
+
const mean = values.reduce((x, y) => x + y, 0) / n;
|
|
122
|
+
const ss = values.reduce((acc, v) => acc + (v - mean) ** 2, 0);
|
|
123
|
+
return ss / (sample ? n - 1 : n);
|
|
124
|
+
}
|
|
125
|
+
const stdev = (values, sample) => {
|
|
126
|
+
const v = variance(values, sample);
|
|
127
|
+
return typeof v === 'number' ? Math.sqrt(v) : v;
|
|
128
|
+
};
|
|
129
|
+
const mean = (ns) => ns.reduce((x, y) => x + y, 0) / ns.length;
|
|
130
|
+
/** The (x, y) pairs where both sides are numbers. */
|
|
131
|
+
function pairs(ys, xs) {
|
|
132
|
+
if (ys.length !== xs.length)
|
|
133
|
+
return null;
|
|
134
|
+
const out = [];
|
|
135
|
+
for (let i = 0; i < ys.length; i += 1) {
|
|
136
|
+
const y = ys[i];
|
|
137
|
+
const x = xs[i];
|
|
138
|
+
if (typeof y === 'number' && typeof x === 'number')
|
|
139
|
+
out.push([x, y]);
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
export const STATS_DIST_FUNCTIONS = {
|
|
144
|
+
// ---- Normal ----------------------------------------------------------
|
|
145
|
+
'NORM.DIST': (a) => normDist(num(a, 0), num(a, 1), num(a, 2), flag(a, 3)),
|
|
146
|
+
NORMDIST: (a) => normDist(num(a, 0), num(a, 1), num(a, 2), flag(a, 3)),
|
|
147
|
+
'NORM.INV': (a) => normInv(num(a, 0), num(a, 1), num(a, 2)),
|
|
148
|
+
NORMINV: (a) => normInv(num(a, 0), num(a, 1), num(a, 2)),
|
|
149
|
+
'NORM.S.DIST': (a) => (has(a, 1) && !flag(a, 1) ? normalPdf(num(a, 0)) : normalCdf(num(a, 0))),
|
|
150
|
+
// The legacy NORMSDIST is cumulative only and takes one argument.
|
|
151
|
+
NORMSDIST: (a) => normalCdf(num(a, 0)),
|
|
152
|
+
'NORM.S.INV': (a) => normInv(num(a, 0), 0, 1),
|
|
153
|
+
NORMSINV: (a) => normInv(num(a, 0), 0, 1),
|
|
154
|
+
STANDARDIZE: (a) => {
|
|
155
|
+
const sd = num(a, 2);
|
|
156
|
+
return sd <= 0 ? err('#NUM!') : (num(a, 0) - num(a, 1)) / sd;
|
|
157
|
+
},
|
|
158
|
+
PHI: (a) => normalPdf(num(a, 0)),
|
|
159
|
+
GAUSS: (a) => normalCdf(num(a, 0)) - 0.5,
|
|
160
|
+
FISHER: (a) => {
|
|
161
|
+
const x = num(a, 0);
|
|
162
|
+
return x <= -1 || x >= 1 ? err('#NUM!') : 0.5 * Math.log((1 + x) / (1 - x));
|
|
163
|
+
},
|
|
164
|
+
FISHERINV: (a) => Math.tanh(num(a, 0)),
|
|
165
|
+
// ---- Student t -------------------------------------------------------
|
|
166
|
+
'T.DIST': (a) => {
|
|
167
|
+
const df = Math.trunc(num(a, 1));
|
|
168
|
+
if (df < 1)
|
|
169
|
+
return err('#NUM!');
|
|
170
|
+
return flag(a, 2) ? tCdf(num(a, 0), df) : tPdf(num(a, 0), df);
|
|
171
|
+
},
|
|
172
|
+
'T.DIST.RT': (a) => {
|
|
173
|
+
const df = Math.trunc(num(a, 1));
|
|
174
|
+
return df < 1 ? err('#NUM!') : 1 - tCdf(num(a, 0), df);
|
|
175
|
+
},
|
|
176
|
+
'T.DIST.2T': (a) => {
|
|
177
|
+
const x = num(a, 0);
|
|
178
|
+
const df = Math.trunc(num(a, 1));
|
|
179
|
+
if (df < 1 || x < 0)
|
|
180
|
+
return err('#NUM!');
|
|
181
|
+
return 2 * (1 - tCdf(x, df));
|
|
182
|
+
},
|
|
183
|
+
// The legacy TDIST takes a tail count and refuses a negative x.
|
|
184
|
+
TDIST: (a) => {
|
|
185
|
+
const x = num(a, 0);
|
|
186
|
+
const df = Math.trunc(num(a, 1));
|
|
187
|
+
const tails = Math.trunc(num(a, 2));
|
|
188
|
+
if (df < 1 || x < 0 || (tails !== 1 && tails !== 2))
|
|
189
|
+
return err('#NUM!');
|
|
190
|
+
const right = 1 - tCdf(x, df);
|
|
191
|
+
return tails === 1 ? right : 2 * right;
|
|
192
|
+
},
|
|
193
|
+
'T.INV': (a) => {
|
|
194
|
+
const p = num(a, 0);
|
|
195
|
+
const df = Math.trunc(num(a, 1));
|
|
196
|
+
if (df < 1 || p <= 0 || p >= 1)
|
|
197
|
+
return err('#NUM!');
|
|
198
|
+
return invertCdf((x) => tCdf(x, df), p, -10, 10);
|
|
199
|
+
},
|
|
200
|
+
'T.INV.2T': (a) => {
|
|
201
|
+
const p = num(a, 0);
|
|
202
|
+
const df = Math.trunc(num(a, 1));
|
|
203
|
+
if (df < 1 || p <= 0 || p > 1)
|
|
204
|
+
return err('#NUM!');
|
|
205
|
+
return invertCdf((x) => tCdf(x, df), 1 - p / 2, -10, 10);
|
|
206
|
+
},
|
|
207
|
+
// TINV is the two-tailed inverse, so it matches T.INV.2T and not T.INV.
|
|
208
|
+
TINV: (a) => {
|
|
209
|
+
const p = num(a, 0);
|
|
210
|
+
const df = Math.trunc(num(a, 1));
|
|
211
|
+
if (df < 1 || p <= 0 || p > 1)
|
|
212
|
+
return err('#NUM!');
|
|
213
|
+
return invertCdf((x) => tCdf(x, df), 1 - p / 2, -10, 10);
|
|
214
|
+
},
|
|
215
|
+
// ---- Chi-square ------------------------------------------------------
|
|
216
|
+
'CHISQ.DIST': (a) => {
|
|
217
|
+
const x = num(a, 0);
|
|
218
|
+
const df = Math.trunc(num(a, 1));
|
|
219
|
+
if (df < 1 || x < 0)
|
|
220
|
+
return err('#NUM!');
|
|
221
|
+
return flag(a, 2) ? chiCdf(x, df) : chiPdf(x, df);
|
|
222
|
+
},
|
|
223
|
+
'CHISQ.DIST.RT': (a) => {
|
|
224
|
+
const x = num(a, 0);
|
|
225
|
+
const df = Math.trunc(num(a, 1));
|
|
226
|
+
return df < 1 || x < 0 ? err('#NUM!') : 1 - chiCdf(x, df);
|
|
227
|
+
},
|
|
228
|
+
// CHIDIST is the RIGHT tail, which CHISQ.DIST is not.
|
|
229
|
+
CHIDIST: (a) => {
|
|
230
|
+
const x = num(a, 0);
|
|
231
|
+
const df = Math.trunc(num(a, 1));
|
|
232
|
+
return df < 1 || x < 0 ? err('#NUM!') : 1 - chiCdf(x, df);
|
|
233
|
+
},
|
|
234
|
+
'CHISQ.INV': (a) => {
|
|
235
|
+
const p = num(a, 0);
|
|
236
|
+
const df = Math.trunc(num(a, 1));
|
|
237
|
+
if (df < 1 || p < 0 || p >= 1)
|
|
238
|
+
return err('#NUM!');
|
|
239
|
+
return invertCdf((x) => chiCdf(x, df), p, 0, df * 4 + 10);
|
|
240
|
+
},
|
|
241
|
+
'CHISQ.INV.RT': (a) => {
|
|
242
|
+
const p = num(a, 0);
|
|
243
|
+
const df = Math.trunc(num(a, 1));
|
|
244
|
+
if (df < 1 || p <= 0 || p > 1)
|
|
245
|
+
return err('#NUM!');
|
|
246
|
+
return invertCdf((x) => chiCdf(x, df), 1 - p, 0, df * 4 + 10);
|
|
247
|
+
},
|
|
248
|
+
CHIINV: (a) => {
|
|
249
|
+
const p = num(a, 0);
|
|
250
|
+
const df = Math.trunc(num(a, 1));
|
|
251
|
+
if (df < 1 || p <= 0 || p > 1)
|
|
252
|
+
return err('#NUM!');
|
|
253
|
+
return invertCdf((x) => chiCdf(x, df), 1 - p, 0, df * 4 + 10);
|
|
254
|
+
},
|
|
255
|
+
// ---- F ---------------------------------------------------------------
|
|
256
|
+
'F.DIST': (a) => {
|
|
257
|
+
const x = num(a, 0);
|
|
258
|
+
const d1 = Math.trunc(num(a, 1));
|
|
259
|
+
const d2 = Math.trunc(num(a, 2));
|
|
260
|
+
if (x < 0 || d1 < 1 || d2 < 1)
|
|
261
|
+
return err('#NUM!');
|
|
262
|
+
return flag(a, 3) ? fCdf(x, d1, d2) : fPdf(x, d1, d2);
|
|
263
|
+
},
|
|
264
|
+
'F.DIST.RT': (a) => {
|
|
265
|
+
const x = num(a, 0);
|
|
266
|
+
const d1 = Math.trunc(num(a, 1));
|
|
267
|
+
const d2 = Math.trunc(num(a, 2));
|
|
268
|
+
return x < 0 || d1 < 1 || d2 < 1 ? err('#NUM!') : 1 - fCdf(x, d1, d2);
|
|
269
|
+
},
|
|
270
|
+
FDIST: (a) => {
|
|
271
|
+
const x = num(a, 0);
|
|
272
|
+
const d1 = Math.trunc(num(a, 1));
|
|
273
|
+
const d2 = Math.trunc(num(a, 2));
|
|
274
|
+
return x < 0 || d1 < 1 || d2 < 1 ? err('#NUM!') : 1 - fCdf(x, d1, d2);
|
|
275
|
+
},
|
|
276
|
+
'F.INV': (a) => {
|
|
277
|
+
const p = num(a, 0);
|
|
278
|
+
const d1 = Math.trunc(num(a, 1));
|
|
279
|
+
const d2 = Math.trunc(num(a, 2));
|
|
280
|
+
if (p < 0 || p >= 1 || d1 < 1 || d2 < 1)
|
|
281
|
+
return err('#NUM!');
|
|
282
|
+
return invertCdf((x) => fCdf(x, d1, d2), p, 0, 100);
|
|
283
|
+
},
|
|
284
|
+
'F.INV.RT': (a) => {
|
|
285
|
+
const p = num(a, 0);
|
|
286
|
+
const d1 = Math.trunc(num(a, 1));
|
|
287
|
+
const d2 = Math.trunc(num(a, 2));
|
|
288
|
+
if (p <= 0 || p > 1 || d1 < 1 || d2 < 1)
|
|
289
|
+
return err('#NUM!');
|
|
290
|
+
return invertCdf((x) => fCdf(x, d1, d2), 1 - p, 0, 100);
|
|
291
|
+
},
|
|
292
|
+
FINV: (a) => {
|
|
293
|
+
const p = num(a, 0);
|
|
294
|
+
const d1 = Math.trunc(num(a, 1));
|
|
295
|
+
const d2 = Math.trunc(num(a, 2));
|
|
296
|
+
if (p <= 0 || p > 1 || d1 < 1 || d2 < 1)
|
|
297
|
+
return err('#NUM!');
|
|
298
|
+
return invertCdf((x) => fCdf(x, d1, d2), 1 - p, 0, 100);
|
|
299
|
+
},
|
|
300
|
+
// ---- Discrete --------------------------------------------------------
|
|
301
|
+
'BINOM.DIST': (a) => {
|
|
302
|
+
const k = Math.trunc(num(a, 0));
|
|
303
|
+
const n = Math.trunc(num(a, 1));
|
|
304
|
+
const p = num(a, 2);
|
|
305
|
+
if (k < 0 || k > n || p < 0 || p > 1)
|
|
306
|
+
return err('#NUM!');
|
|
307
|
+
return flag(a, 3) ? binomCdf(k, n, p) : binomPmf(k, n, p);
|
|
308
|
+
},
|
|
309
|
+
BINOMDIST: (a) => {
|
|
310
|
+
const k = Math.trunc(num(a, 0));
|
|
311
|
+
const n = Math.trunc(num(a, 1));
|
|
312
|
+
const p = num(a, 2);
|
|
313
|
+
if (k < 0 || k > n || p < 0 || p > 1)
|
|
314
|
+
return err('#NUM!');
|
|
315
|
+
return flag(a, 3) ? binomCdf(k, n, p) : binomPmf(k, n, p);
|
|
316
|
+
},
|
|
317
|
+
'BINOM.INV': (a) => {
|
|
318
|
+
const n = Math.trunc(num(a, 0));
|
|
319
|
+
const p = num(a, 1);
|
|
320
|
+
const alpha = num(a, 2);
|
|
321
|
+
if (p < 0 || p > 1 || alpha <= 0 || alpha >= 1)
|
|
322
|
+
return err('#NUM!');
|
|
323
|
+
let total = 0;
|
|
324
|
+
for (let k = 0; k <= n; k += 1) {
|
|
325
|
+
total += binomPmf(k, n, p);
|
|
326
|
+
if (total >= alpha)
|
|
327
|
+
return k;
|
|
328
|
+
}
|
|
329
|
+
return n;
|
|
330
|
+
},
|
|
331
|
+
CRITBINOM: (a) => STATS_DIST_FUNCTIONS['BINOM.INV'](a),
|
|
332
|
+
'NEGBINOM.DIST': (a) => {
|
|
333
|
+
const f = Math.trunc(num(a, 0));
|
|
334
|
+
const s = Math.trunc(num(a, 1));
|
|
335
|
+
const p = num(a, 2);
|
|
336
|
+
if (f < 0 || s < 1 || p <= 0 || p > 1)
|
|
337
|
+
return err('#NUM!');
|
|
338
|
+
const pmf = (k) => choose(k + s - 1, s - 1) * Math.pow(p, s) * Math.pow(1 - p, k);
|
|
339
|
+
if (!flag(a, 3))
|
|
340
|
+
return pmf(f);
|
|
341
|
+
let total = 0;
|
|
342
|
+
for (let k = 0; k <= f; k += 1)
|
|
343
|
+
total += pmf(k);
|
|
344
|
+
return Math.min(total, 1);
|
|
345
|
+
},
|
|
346
|
+
NEGBINOMDIST: (a) => {
|
|
347
|
+
const f = Math.trunc(num(a, 0));
|
|
348
|
+
const s = Math.trunc(num(a, 1));
|
|
349
|
+
const p = num(a, 2);
|
|
350
|
+
if (f < 0 || s < 1 || p <= 0 || p > 1)
|
|
351
|
+
return err('#NUM!');
|
|
352
|
+
return choose(f + s - 1, s - 1) * Math.pow(p, s) * Math.pow(1 - p, f);
|
|
353
|
+
},
|
|
354
|
+
'POISSON.DIST': (a) => {
|
|
355
|
+
const k = Math.trunc(num(a, 0));
|
|
356
|
+
const m = num(a, 1);
|
|
357
|
+
if (k < 0 || m < 0)
|
|
358
|
+
return err('#NUM!');
|
|
359
|
+
return flag(a, 2) ? poissonCdf(k, m) : poissonPmf(k, m);
|
|
360
|
+
},
|
|
361
|
+
POISSON: (a) => STATS_DIST_FUNCTIONS['POISSON.DIST'](a),
|
|
362
|
+
'HYPGEOM.DIST': (a) => {
|
|
363
|
+
const x = Math.trunc(num(a, 0));
|
|
364
|
+
const n = Math.trunc(num(a, 1));
|
|
365
|
+
const m = Math.trunc(num(a, 2));
|
|
366
|
+
const N = Math.trunc(num(a, 3));
|
|
367
|
+
if (x < 0 || x > n || n > N || m > N || m < 0)
|
|
368
|
+
return err('#NUM!');
|
|
369
|
+
if (!has(a, 4) || !flag(a, 4))
|
|
370
|
+
return hypgeomPmf(x, n, m, N);
|
|
371
|
+
let total = 0;
|
|
372
|
+
for (let k = Math.max(0, n - (N - m)); k <= x; k += 1)
|
|
373
|
+
total += hypgeomPmf(k, n, m, N);
|
|
374
|
+
return Math.min(total, 1);
|
|
375
|
+
},
|
|
376
|
+
HYPGEOMDIST: (a) => {
|
|
377
|
+
const x = Math.trunc(num(a, 0));
|
|
378
|
+
const n = Math.trunc(num(a, 1));
|
|
379
|
+
const m = Math.trunc(num(a, 2));
|
|
380
|
+
const N = Math.trunc(num(a, 3));
|
|
381
|
+
if (x < 0 || x > n || n > N || m > N || m < 0)
|
|
382
|
+
return err('#NUM!');
|
|
383
|
+
return hypgeomPmf(x, n, m, N);
|
|
384
|
+
},
|
|
385
|
+
// ---- Continuous, the rest --------------------------------------------
|
|
386
|
+
'EXPON.DIST': (a) => {
|
|
387
|
+
const x = num(a, 0);
|
|
388
|
+
const lambda = num(a, 1);
|
|
389
|
+
if (x < 0 || lambda <= 0)
|
|
390
|
+
return err('#NUM!');
|
|
391
|
+
return flag(a, 2) ? 1 - Math.exp(-lambda * x) : lambda * Math.exp(-lambda * x);
|
|
392
|
+
},
|
|
393
|
+
EXPONDIST: (a) => STATS_DIST_FUNCTIONS['EXPON.DIST'](a),
|
|
394
|
+
'LOGNORM.DIST': (a) => {
|
|
395
|
+
const x = num(a, 0);
|
|
396
|
+
const m = num(a, 1);
|
|
397
|
+
const sd = num(a, 2);
|
|
398
|
+
if (x <= 0 || sd <= 0)
|
|
399
|
+
return err('#NUM!');
|
|
400
|
+
const z = (Math.log(x) - m) / sd;
|
|
401
|
+
return flag(a, 3) ? normalCdf(z) : normalPdf(z) / (x * sd);
|
|
402
|
+
},
|
|
403
|
+
// The legacy LOGNORMDIST is cumulative only.
|
|
404
|
+
LOGNORMDIST: (a) => {
|
|
405
|
+
const x = num(a, 0);
|
|
406
|
+
const sd = num(a, 2);
|
|
407
|
+
if (x <= 0 || sd <= 0)
|
|
408
|
+
return err('#NUM!');
|
|
409
|
+
return normalCdf((Math.log(x) - num(a, 1)) / sd);
|
|
410
|
+
},
|
|
411
|
+
'LOGNORM.INV': (a) => {
|
|
412
|
+
const p = num(a, 0);
|
|
413
|
+
const sd = num(a, 2);
|
|
414
|
+
if (p <= 0 || p >= 1 || sd <= 0)
|
|
415
|
+
return err('#NUM!');
|
|
416
|
+
return Math.exp(num(a, 1) + sd * invertCdf(normalCdf, p, -8, 8));
|
|
417
|
+
},
|
|
418
|
+
LOGINV: (a) => STATS_DIST_FUNCTIONS['LOGNORM.INV'](a),
|
|
419
|
+
'GAMMA.DIST': (a) => {
|
|
420
|
+
const x = num(a, 0);
|
|
421
|
+
const alpha = num(a, 1);
|
|
422
|
+
const beta = num(a, 2);
|
|
423
|
+
if (x < 0 || alpha <= 0 || beta <= 0)
|
|
424
|
+
return err('#NUM!');
|
|
425
|
+
if (flag(a, 3))
|
|
426
|
+
return gammaP(alpha, x / beta);
|
|
427
|
+
return Math.exp((alpha - 1) * Math.log(x) - x / beta - lgamma(alpha) - alpha * Math.log(beta));
|
|
428
|
+
},
|
|
429
|
+
GAMMADIST: (a) => STATS_DIST_FUNCTIONS['GAMMA.DIST'](a),
|
|
430
|
+
'GAMMA.INV': (a) => {
|
|
431
|
+
const p = num(a, 0);
|
|
432
|
+
const alpha = num(a, 1);
|
|
433
|
+
const beta = num(a, 2);
|
|
434
|
+
if (p < 0 || p >= 1 || alpha <= 0 || beta <= 0)
|
|
435
|
+
return err('#NUM!');
|
|
436
|
+
return invertCdf((x) => gammaP(alpha, x / beta), p, 0, alpha * beta * 10 + 10);
|
|
437
|
+
},
|
|
438
|
+
GAMMAINV: (a) => STATS_DIST_FUNCTIONS['GAMMA.INV'](a),
|
|
439
|
+
GAMMA: (a) => {
|
|
440
|
+
const x = num(a, 0);
|
|
441
|
+
// Gamma has poles at zero and the negative integers.
|
|
442
|
+
if (x <= 0 && Number.isInteger(x))
|
|
443
|
+
return err('#NUM!');
|
|
444
|
+
return gammaFn(x);
|
|
445
|
+
},
|
|
446
|
+
GAMMALN: (a) => {
|
|
447
|
+
const x = num(a, 0);
|
|
448
|
+
return x <= 0 ? err('#NUM!') : lgamma(x);
|
|
449
|
+
},
|
|
450
|
+
'GAMMALN.PRECISE': (a) => {
|
|
451
|
+
const x = num(a, 0);
|
|
452
|
+
return x <= 0 ? err('#NUM!') : lgamma(x);
|
|
453
|
+
},
|
|
454
|
+
'BETA.DIST': (a) => {
|
|
455
|
+
const alpha = num(a, 1);
|
|
456
|
+
const beta = num(a, 2);
|
|
457
|
+
const lo = opt(a, 4, 0);
|
|
458
|
+
const hi = opt(a, 5, 1);
|
|
459
|
+
const x = (num(a, 0) - lo) / (hi - lo);
|
|
460
|
+
if (alpha <= 0 || beta <= 0 || hi <= lo || x < 0 || x > 1)
|
|
461
|
+
return err('#NUM!');
|
|
462
|
+
if (flag(a, 3))
|
|
463
|
+
return betaI(alpha, beta, x);
|
|
464
|
+
const density = Math.exp((alpha - 1) * Math.log(x) + (beta - 1) * Math.log(1 - x)
|
|
465
|
+
+ lgamma(alpha + beta) - lgamma(alpha) - lgamma(beta));
|
|
466
|
+
return density / (hi - lo);
|
|
467
|
+
},
|
|
468
|
+
// BETADIST is cumulative only, with the bounds one argument earlier.
|
|
469
|
+
BETADIST: (a) => {
|
|
470
|
+
const alpha = num(a, 1);
|
|
471
|
+
const beta = num(a, 2);
|
|
472
|
+
const lo = opt(a, 3, 0);
|
|
473
|
+
const hi = opt(a, 4, 1);
|
|
474
|
+
const x = (num(a, 0) - lo) / (hi - lo);
|
|
475
|
+
if (alpha <= 0 || beta <= 0 || hi <= lo || x < 0 || x > 1)
|
|
476
|
+
return err('#NUM!');
|
|
477
|
+
return betaI(alpha, beta, x);
|
|
478
|
+
},
|
|
479
|
+
'BETA.INV': (a) => {
|
|
480
|
+
const p = num(a, 0);
|
|
481
|
+
const alpha = num(a, 1);
|
|
482
|
+
const beta = num(a, 2);
|
|
483
|
+
const lo = opt(a, 3, 0);
|
|
484
|
+
const hi = opt(a, 4, 1);
|
|
485
|
+
if (p <= 0 || p > 1 || alpha <= 0 || beta <= 0 || hi <= lo)
|
|
486
|
+
return err('#NUM!');
|
|
487
|
+
return lo + (hi - lo) * invertCdf((x) => betaI(alpha, beta, x), p, 0, 1);
|
|
488
|
+
},
|
|
489
|
+
BETAINV: (a) => STATS_DIST_FUNCTIONS['BETA.INV'](a),
|
|
490
|
+
'WEIBULL.DIST': (a) => {
|
|
491
|
+
const x = num(a, 0);
|
|
492
|
+
const alpha = num(a, 1);
|
|
493
|
+
const beta = num(a, 2);
|
|
494
|
+
if (x < 0 || alpha <= 0 || beta <= 0)
|
|
495
|
+
return err('#NUM!');
|
|
496
|
+
const scaled = Math.pow(x / beta, alpha);
|
|
497
|
+
if (flag(a, 3))
|
|
498
|
+
return 1 - Math.exp(-scaled);
|
|
499
|
+
return (alpha / Math.pow(beta, alpha)) * Math.pow(x, alpha - 1) * Math.exp(-scaled);
|
|
500
|
+
},
|
|
501
|
+
WEIBULL: (a) => STATS_DIST_FUNCTIONS['WEIBULL.DIST'](a),
|
|
502
|
+
// ---- Confidence intervals -------------------------------------------
|
|
503
|
+
'CONFIDENCE.NORM': (a) => {
|
|
504
|
+
const alpha = num(a, 0);
|
|
505
|
+
const sd = num(a, 1);
|
|
506
|
+
const n = Math.trunc(num(a, 2));
|
|
507
|
+
if (alpha <= 0 || alpha >= 1 || sd <= 0 || n < 1)
|
|
508
|
+
return err('#NUM!');
|
|
509
|
+
return invertCdf(normalCdf, 1 - alpha / 2, -8, 8) * (sd / Math.sqrt(n));
|
|
510
|
+
},
|
|
511
|
+
CONFIDENCE: (a) => STATS_DIST_FUNCTIONS['CONFIDENCE.NORM'](a),
|
|
512
|
+
'CONFIDENCE.T': (a) => {
|
|
513
|
+
const alpha = num(a, 0);
|
|
514
|
+
const sd = num(a, 1);
|
|
515
|
+
const n = Math.trunc(num(a, 2));
|
|
516
|
+
if (alpha <= 0 || alpha >= 1 || sd <= 0 || n < 1)
|
|
517
|
+
return err('#NUM!');
|
|
518
|
+
if (n === 1)
|
|
519
|
+
return err('#DIV/0!');
|
|
520
|
+
const t = invertCdf((x) => tCdf(x, n - 1), 1 - alpha / 2, -10, 10);
|
|
521
|
+
return t * (sd / Math.sqrt(n));
|
|
522
|
+
},
|
|
523
|
+
// ---- Hypothesis tests ------------------------------------------------
|
|
524
|
+
'Z.TEST': (a) => {
|
|
525
|
+
const ns = numericOnly(a.args[0] ?? []);
|
|
526
|
+
if (ns.length === 0)
|
|
527
|
+
return err('#N/A');
|
|
528
|
+
const x = num(a, 1);
|
|
529
|
+
const sd = has(a, 2) ? num(a, 2) : stdev(ns, true);
|
|
530
|
+
if (!(sd > 0))
|
|
531
|
+
return err('#DIV/0!');
|
|
532
|
+
return 1 - normalCdf((mean(ns) - x) / (sd / Math.sqrt(ns.length)));
|
|
533
|
+
},
|
|
534
|
+
ZTEST: (a) => STATS_DIST_FUNCTIONS['Z.TEST'](a),
|
|
535
|
+
'CHISQ.TEST': (a) => {
|
|
536
|
+
const actual = numericOnly(a.args[0] ?? []);
|
|
537
|
+
const expected = numericOnly(a.args[1] ?? []);
|
|
538
|
+
if (actual.length !== expected.length || actual.length === 0)
|
|
539
|
+
return err('#N/A');
|
|
540
|
+
let stat = 0;
|
|
541
|
+
for (let i = 0; i < actual.length; i += 1) {
|
|
542
|
+
const e = expected[i];
|
|
543
|
+
if (e === 0)
|
|
544
|
+
return err('#DIV/0!');
|
|
545
|
+
stat += (actual[i] - e) ** 2 / e;
|
|
546
|
+
}
|
|
547
|
+
// The grid's shape decides the degrees of freedom: a single row or
|
|
548
|
+
// column is n - 1, a true table is (rows - 1) (cols - 1).
|
|
549
|
+
const grid = a.grids[0];
|
|
550
|
+
const rows = grid?.length ?? 1;
|
|
551
|
+
const cols = grid?.[0]?.length ?? actual.length;
|
|
552
|
+
const df = rows > 1 && cols > 1 ? (rows - 1) * (cols - 1) : actual.length - 1;
|
|
553
|
+
if (df < 1)
|
|
554
|
+
return err('#N/A');
|
|
555
|
+
return 1 - chiCdf(stat, df);
|
|
556
|
+
},
|
|
557
|
+
CHITEST: (a) => STATS_DIST_FUNCTIONS['CHISQ.TEST'](a),
|
|
558
|
+
'F.TEST': (a) => {
|
|
559
|
+
const x = numericOnly(a.args[0] ?? []);
|
|
560
|
+
const y = numericOnly(a.args[1] ?? []);
|
|
561
|
+
if (x.length < 2 || y.length < 2)
|
|
562
|
+
return err('#DIV/0!');
|
|
563
|
+
const vx = variance(x, true);
|
|
564
|
+
const vy = variance(y, true);
|
|
565
|
+
if (vx === 0 || vy === 0)
|
|
566
|
+
return err('#DIV/0!');
|
|
567
|
+
// Excel reports the two-tailed probability, so the larger variance
|
|
568
|
+
// goes on top and the right tail is doubled.
|
|
569
|
+
const ratio = vx > vy ? vx / vy : vy / vx;
|
|
570
|
+
const [d1, d2] = vx > vy ? [x.length - 1, y.length - 1] : [y.length - 1, x.length - 1];
|
|
571
|
+
return Math.min(2 * (1 - fCdf(ratio, d1, d2)), 1);
|
|
572
|
+
},
|
|
573
|
+
FTEST: (a) => STATS_DIST_FUNCTIONS['F.TEST'](a),
|
|
574
|
+
'T.TEST': (a) => {
|
|
575
|
+
const x = numericOnly(a.args[0] ?? []);
|
|
576
|
+
const y = numericOnly(a.args[1] ?? []);
|
|
577
|
+
const tails = Math.trunc(num(a, 2));
|
|
578
|
+
const kind = Math.trunc(num(a, 3));
|
|
579
|
+
if (tails !== 1 && tails !== 2)
|
|
580
|
+
return err('#NUM!');
|
|
581
|
+
if (kind < 1 || kind > 3)
|
|
582
|
+
return err('#NUM!');
|
|
583
|
+
let t;
|
|
584
|
+
let df;
|
|
585
|
+
if (kind === 1) {
|
|
586
|
+
// Paired: the test is a one-sample test on the differences.
|
|
587
|
+
if (x.length !== y.length || x.length < 2)
|
|
588
|
+
return err('#N/A');
|
|
589
|
+
const d = x.map((v, i) => v - y[i]);
|
|
590
|
+
const sd = stdev(d, true);
|
|
591
|
+
if (sd === 0)
|
|
592
|
+
return err('#DIV/0!');
|
|
593
|
+
t = mean(d) / (sd / Math.sqrt(d.length));
|
|
594
|
+
df = d.length - 1;
|
|
595
|
+
}
|
|
596
|
+
else if (kind === 2) {
|
|
597
|
+
// Equal variance: the pooled two-sample test.
|
|
598
|
+
const nx = x.length;
|
|
599
|
+
const ny = y.length;
|
|
600
|
+
if (nx < 2 || ny < 2)
|
|
601
|
+
return err('#DIV/0!');
|
|
602
|
+
df = nx + ny - 2;
|
|
603
|
+
const pooled = ((nx - 1) * variance(x, true)
|
|
604
|
+
+ (ny - 1) * variance(y, true)) / df;
|
|
605
|
+
if (pooled === 0)
|
|
606
|
+
return err('#DIV/0!');
|
|
607
|
+
t = (mean(x) - mean(y)) / Math.sqrt(pooled * (1 / nx + 1 / ny));
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
// Unequal variance: Welch, with its fractional degrees of freedom.
|
|
611
|
+
const nx = x.length;
|
|
612
|
+
const ny = y.length;
|
|
613
|
+
if (nx < 2 || ny < 2)
|
|
614
|
+
return err('#DIV/0!');
|
|
615
|
+
const sx = variance(x, true) / nx;
|
|
616
|
+
const sy = variance(y, true) / ny;
|
|
617
|
+
if (sx + sy === 0)
|
|
618
|
+
return err('#DIV/0!');
|
|
619
|
+
t = (mean(x) - mean(y)) / Math.sqrt(sx + sy);
|
|
620
|
+
df = (sx + sy) ** 2 / (sx ** 2 / (nx - 1) + sy ** 2 / (ny - 1));
|
|
621
|
+
}
|
|
622
|
+
const right = 1 - tCdf(Math.abs(t), df);
|
|
623
|
+
return tails === 1 ? right : 2 * right;
|
|
624
|
+
},
|
|
625
|
+
TTEST: (a) => STATS_DIST_FUNCTIONS['T.TEST'](a),
|
|
626
|
+
// ---- Descriptive -----------------------------------------------------
|
|
627
|
+
AVEDEV: (a) => {
|
|
628
|
+
const ns = numericOnly(a.flat);
|
|
629
|
+
if (ns.length === 0)
|
|
630
|
+
return err('#NUM!');
|
|
631
|
+
const m = mean(ns);
|
|
632
|
+
return ns.reduce((acc, v) => acc + Math.abs(v - m), 0) / ns.length;
|
|
633
|
+
},
|
|
634
|
+
DEVSQ: (a) => {
|
|
635
|
+
const ns = numericOnly(a.flat);
|
|
636
|
+
if (ns.length === 0)
|
|
637
|
+
return err('#NUM!');
|
|
638
|
+
const m = mean(ns);
|
|
639
|
+
return ns.reduce((acc, v) => acc + (v - m) ** 2, 0);
|
|
640
|
+
},
|
|
641
|
+
SKEW: (a) => {
|
|
642
|
+
const ns = numericOnly(a.flat);
|
|
643
|
+
const n = ns.length;
|
|
644
|
+
if (n < 3)
|
|
645
|
+
return err('#DIV/0!');
|
|
646
|
+
const m = mean(ns);
|
|
647
|
+
const sd = stdev(ns, true);
|
|
648
|
+
if (sd === 0)
|
|
649
|
+
return err('#DIV/0!');
|
|
650
|
+
const sum = ns.reduce((acc, v) => acc + ((v - m) / sd) ** 3, 0);
|
|
651
|
+
return (n / ((n - 1) * (n - 2))) * sum;
|
|
652
|
+
},
|
|
653
|
+
'SKEW.P': (a) => {
|
|
654
|
+
const ns = numericOnly(a.flat);
|
|
655
|
+
const n = ns.length;
|
|
656
|
+
if (n < 2)
|
|
657
|
+
return err('#DIV/0!');
|
|
658
|
+
const m = mean(ns);
|
|
659
|
+
const sd = stdev(ns, false);
|
|
660
|
+
if (sd === 0)
|
|
661
|
+
return err('#DIV/0!');
|
|
662
|
+
return ns.reduce((acc, v) => acc + ((v - m) / sd) ** 3, 0) / n;
|
|
663
|
+
},
|
|
664
|
+
KURT: (a) => {
|
|
665
|
+
const ns = numericOnly(a.flat);
|
|
666
|
+
const n = ns.length;
|
|
667
|
+
if (n < 4)
|
|
668
|
+
return err('#DIV/0!');
|
|
669
|
+
const m = mean(ns);
|
|
670
|
+
const sd = stdev(ns, true);
|
|
671
|
+
if (sd === 0)
|
|
672
|
+
return err('#DIV/0!');
|
|
673
|
+
const sum = ns.reduce((acc, v) => acc + ((v - m) / sd) ** 4, 0);
|
|
674
|
+
return ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sum
|
|
675
|
+
- (3 * (n - 1) ** 2) / ((n - 2) * (n - 3));
|
|
676
|
+
},
|
|
677
|
+
TRIMMEAN: (a) => {
|
|
678
|
+
const ns = numericOnly(a.args[0] ?? []).sort((x, y) => x - y);
|
|
679
|
+
const percent = num(a, 1);
|
|
680
|
+
if (percent < 0 || percent >= 1)
|
|
681
|
+
return err('#NUM!');
|
|
682
|
+
if (ns.length === 0)
|
|
683
|
+
return err('#NUM!');
|
|
684
|
+
// Excel trims an EVEN count, half off each end, rounding down.
|
|
685
|
+
const cut = Math.floor((ns.length * percent) / 2);
|
|
686
|
+
const kept = ns.slice(cut, ns.length - cut);
|
|
687
|
+
return kept.length === 0 ? err('#NUM!') : mean(kept);
|
|
688
|
+
},
|
|
689
|
+
PERMUTATIONA: (a) => {
|
|
690
|
+
const n = Math.trunc(num(a, 0));
|
|
691
|
+
const k = Math.trunc(num(a, 1));
|
|
692
|
+
return n < 0 || k < 0 ? err('#NUM!') : Math.pow(n, k);
|
|
693
|
+
},
|
|
694
|
+
MULTINOMIAL: (a) => {
|
|
695
|
+
const ns = numericOnly(a.flat).map(Math.trunc);
|
|
696
|
+
if (ns.some((v) => v < 0))
|
|
697
|
+
return err('#NUM!');
|
|
698
|
+
const total = ns.reduce((x, y) => x + y, 0);
|
|
699
|
+
return Math.round(Math.exp(lgamma(total + 1) - ns.reduce((acc, v) => acc + lgamma(v + 1), 0)));
|
|
700
|
+
},
|
|
701
|
+
// ---- The *A family ---------------------------------------------------
|
|
702
|
+
AVERAGEA: (a) => {
|
|
703
|
+
const ns = valuesA(a.flat);
|
|
704
|
+
return ns.length === 0 ? err('#DIV/0!') : mean(ns);
|
|
705
|
+
},
|
|
706
|
+
MAXA: (a) => { const ns = valuesA(a.flat); return ns.length === 0 ? 0 : Math.max(...ns); },
|
|
707
|
+
MINA: (a) => { const ns = valuesA(a.flat); return ns.length === 0 ? 0 : Math.min(...ns); },
|
|
708
|
+
STDEVA: (a) => stdev(valuesA(a.flat), true),
|
|
709
|
+
STDEVPA: (a) => stdev(valuesA(a.flat), false),
|
|
710
|
+
VARA: (a) => variance(valuesA(a.flat), true),
|
|
711
|
+
VARPA: (a) => variance(valuesA(a.flat), false),
|
|
712
|
+
// ---- Correlation and regression --------------------------------------
|
|
713
|
+
'COVARIANCE.P': (a) => {
|
|
714
|
+
const ps = pairs(a.args[0] ?? [], a.args[1] ?? []);
|
|
715
|
+
if (!ps || ps.length === 0)
|
|
716
|
+
return err('#N/A');
|
|
717
|
+
const mx = mean(ps.map(([x]) => x));
|
|
718
|
+
const my = mean(ps.map(([, y]) => y));
|
|
719
|
+
return ps.reduce((acc, [x, y]) => acc + (x - mx) * (y - my), 0) / ps.length;
|
|
720
|
+
},
|
|
721
|
+
COVAR: (a) => STATS_DIST_FUNCTIONS['COVARIANCE.P'](a),
|
|
722
|
+
'COVARIANCE.S': (a) => {
|
|
723
|
+
const ps = pairs(a.args[0] ?? [], a.args[1] ?? []);
|
|
724
|
+
if (!ps || ps.length < 2)
|
|
725
|
+
return err('#DIV/0!');
|
|
726
|
+
const mx = mean(ps.map(([x]) => x));
|
|
727
|
+
const my = mean(ps.map(([, y]) => y));
|
|
728
|
+
return ps.reduce((acc, [x, y]) => acc + (x - mx) * (y - my), 0) / (ps.length - 1);
|
|
729
|
+
},
|
|
730
|
+
PEARSON: (a) => {
|
|
731
|
+
const ps = pairs(a.args[0] ?? [], a.args[1] ?? []);
|
|
732
|
+
if (!ps || ps.length < 2)
|
|
733
|
+
return err('#DIV/0!');
|
|
734
|
+
const mx = mean(ps.map(([x]) => x));
|
|
735
|
+
const my = mean(ps.map(([, y]) => y));
|
|
736
|
+
let sxy = 0;
|
|
737
|
+
let sxx = 0;
|
|
738
|
+
let syy = 0;
|
|
739
|
+
for (const [x, y] of ps) {
|
|
740
|
+
sxy += (x - mx) * (y - my);
|
|
741
|
+
sxx += (x - mx) ** 2;
|
|
742
|
+
syy += (y - my) ** 2;
|
|
743
|
+
}
|
|
744
|
+
return sxx === 0 || syy === 0 ? err('#DIV/0!') : sxy / Math.sqrt(sxx * syy);
|
|
745
|
+
},
|
|
746
|
+
RSQ: (a) => {
|
|
747
|
+
const r = STATS_DIST_FUNCTIONS.PEARSON(a);
|
|
748
|
+
return typeof r === 'number' ? r * r : r;
|
|
749
|
+
},
|
|
750
|
+
STEYX: (a) => {
|
|
751
|
+
const ps = pairs(a.args[0] ?? [], a.args[1] ?? []);
|
|
752
|
+
if (!ps || ps.length < 3)
|
|
753
|
+
return err('#DIV/0!');
|
|
754
|
+
const mx = mean(ps.map(([x]) => x));
|
|
755
|
+
const my = mean(ps.map(([, y]) => y));
|
|
756
|
+
let sxy = 0;
|
|
757
|
+
let sxx = 0;
|
|
758
|
+
let syy = 0;
|
|
759
|
+
for (const [x, y] of ps) {
|
|
760
|
+
sxy += (x - mx) * (y - my);
|
|
761
|
+
sxx += (x - mx) ** 2;
|
|
762
|
+
syy += (y - my) ** 2;
|
|
763
|
+
}
|
|
764
|
+
if (sxx === 0)
|
|
765
|
+
return err('#DIV/0!');
|
|
766
|
+
return Math.sqrt((syy - (sxy * sxy) / sxx) / (ps.length - 2));
|
|
767
|
+
},
|
|
768
|
+
PROB: (a) => {
|
|
769
|
+
const xs = numericOnly(a.args[0] ?? []);
|
|
770
|
+
const ps = numericOnly(a.args[1] ?? []);
|
|
771
|
+
if (xs.length !== ps.length || xs.length === 0)
|
|
772
|
+
return err('#N/A');
|
|
773
|
+
const total = ps.reduce((x, y) => x + y, 0);
|
|
774
|
+
if (Math.abs(total - 1) > 1e-9 || ps.some((p) => p <= 0 || p > 1))
|
|
775
|
+
return err('#NUM!');
|
|
776
|
+
const lo = num(a, 2);
|
|
777
|
+
const hi = has(a, 3) ? num(a, 3) : lo;
|
|
778
|
+
let out = 0;
|
|
779
|
+
for (let i = 0; i < xs.length; i += 1) {
|
|
780
|
+
if (xs[i] >= lo && xs[i] <= hi)
|
|
781
|
+
out += ps[i];
|
|
782
|
+
}
|
|
783
|
+
return out;
|
|
784
|
+
},
|
|
785
|
+
};
|