├── .dockerignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ └── ui-for-new-step.md ├── PULL_REQUEST_TEMPLATE │ └── new-step.md ├── renovate.json5 └── workflows │ ├── ci-server.yml │ ├── ci-ui.yml │ └── npm-publish.yml ├── .gitignore ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── codecov.yml ├── docs ├── .editorconfig ├── .gitignore ├── 404.html ├── CNAME ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── _config.yml ├── _data │ └── docs.yml ├── _docs │ ├── contributing │ │ └── new-step.md │ ├── tech │ │ ├── custom-code-editor.md │ │ ├── dates.md │ │ ├── known_limitations.md │ │ ├── packages.md │ │ ├── python-package.md │ │ ├── sql-pipeline.md │ │ ├── sql-steps │ │ │ ├── aggregate.md │ │ │ └── filter.md │ │ ├── steps.md │ │ ├── translators.md │ │ └── variables.md │ └── user-interface │ │ ├── absolutevalue.md │ │ ├── addmissingdates.md │ │ ├── aggregate.md │ │ ├── append.md │ │ ├── argmax.md │ │ ├── argmin.md │ │ ├── comparetext.md │ │ ├── concatenate.md │ │ ├── convert.md │ │ ├── cumsum.md │ │ ├── custom.md │ │ ├── dateextract.md │ │ ├── delete.md │ │ ├── dissolve.md │ │ ├── duplicate.md │ │ ├── duration.md │ │ ├── evolution.md │ │ ├── fillna.md │ │ ├── filter.md │ │ ├── formula.md │ │ ├── fromdate.md │ │ ├── general-principles.md │ │ ├── hierarchy.md │ │ ├── ifthenelse.md │ │ ├── join.md │ │ ├── keep.md │ │ ├── lowercase.md │ │ ├── movingaverage.md │ │ ├── percentage.md │ │ ├── pivot.md │ │ ├── rank.md │ │ ├── rename.md │ │ ├── replace.md │ │ ├── rollup.md │ │ ├── simplify.md │ │ ├── sort.md │ │ ├── split.md │ │ ├── statistics.md │ │ ├── substring.md │ │ ├── text.md │ │ ├── todate.md │ │ ├── top.md │ │ ├── totals.md │ │ ├── trim.md │ │ ├── uniquegroups.md │ │ ├── unpivot.md │ │ ├── uppercase.md │ │ └── waterfall.md ├── _includes │ ├── docs_nav.html │ ├── footer.html │ ├── head.html │ ├── js_files.html │ ├── section_nav.html │ └── topnav.html ├── _layouts │ ├── default.html │ ├── docs.html │ └── page.html ├── _sass │ ├── _bootstrap.scss │ ├── _syntax-highlighting.scss │ ├── _typeahead.scss │ ├── bootstrap │ │ ├── _alerts.scss │ │ ├── _badges.scss │ │ ├── _breadcrumbs.scss │ │ ├── _button-groups.scss │ │ ├── _buttons.scss │ │ ├── _carousel.scss │ │ ├── _close.scss │ │ ├── _code.scss │ │ ├── _component-animations.scss │ │ ├── _dropdowns.scss │ │ ├── _forms.scss │ │ ├── _glyphicons.scss │ │ ├── _grid.scss │ │ ├── _input-groups.scss │ │ ├── _jumbotron.scss │ │ ├── _labels.scss │ │ ├── _list-group.scss │ │ ├── _media.scss │ │ ├── _mixins.scss │ │ ├── _modals.scss │ │ ├── _navbar.scss │ │ ├── _navs.scss │ │ ├── _normalize.scss │ │ ├── _pager.scss │ │ ├── _pagination.scss │ │ ├── _panels.scss │ │ ├── _popovers.scss │ │ ├── _print.scss │ │ ├── _progress-bars.scss │ │ ├── _responsive-embed.scss │ │ ├── _responsive-utilities.scss │ │ ├── _scaffolding.scss │ │ ├── _tables.scss │ │ ├── _theme.scss │ │ ├── _thumbnails.scss │ │ ├── _tooltip.scss │ │ ├── _type.scss │ │ ├── _utilities.scss │ │ ├── _variables.scss │ │ ├── _wells.scss │ │ └── mixins │ │ │ ├── _alerts.scss │ │ │ ├── _background-variant.scss │ │ │ ├── _border-radius.scss │ │ │ ├── _buttons.scss │ │ │ ├── _center-block.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _forms.scss │ │ │ ├── _gradients.scss │ │ │ ├── _grid-framework.scss │ │ │ ├── _grid.scss │ │ │ ├── _hide-text.scss │ │ │ ├── _image.scss │ │ │ ├── _labels.scss │ │ │ ├── _list-group.scss │ │ │ ├── _nav-divider.scss │ │ │ ├── _nav-vertical-align.scss │ │ │ ├── _opacity.scss │ │ │ ├── _pagination.scss │ │ │ ├── _panels.scss │ │ │ ├── _progress-bar.scss │ │ │ ├── _reset-filter.scss │ │ │ ├── _reset-text.scss │ │ │ ├── _resize.scss │ │ │ ├── _responsive-visibility.scss │ │ │ ├── _size.scss │ │ │ ├── _tab-focus.scss │ │ │ ├── _table-row.scss │ │ │ ├── _text-emphasis.scss │ │ │ ├── _text-overflow.scss │ │ │ └── _vendor-prefixes.scss │ └── bootswatch │ │ ├── LICENSE │ │ ├── cerulean │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── cosmo │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── custom │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── cyborg │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── darkly │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── flatly │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── journal │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── lumen │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── paper │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── readable │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── sandstone │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── simplex │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── slate │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── solar │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── spacelab │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── superhero │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── united │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ └── yeti │ │ ├── _bootswatch.scss │ │ └── _variables.scss ├── about.html ├── css │ ├── font-awesome.min.css │ └── main.scss ├── favicon.ico ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── img │ ├── StepFormButtonbar.png │ ├── StepFormHeader.png │ ├── bg.jpg │ ├── docs │ │ └── user-interface │ │ │ ├── absolutevalue_example_conf.jpg │ │ │ ├── absolutevalue_example_result.jpg │ │ │ ├── addmissingdates_example_conf_1.png │ │ │ ├── addmissingdates_example_conf_2.png │ │ │ ├── addmissingdates_example_conf_3.png │ │ │ ├── addmissingdates_example_result_1.png │ │ │ ├── addmissingdates_example_result_2.png │ │ │ ├── addmissingdates_example_result_3.png │ │ │ ├── addmissingdates_step_form.png │ │ │ ├── aggregate_example_conf_1.jpg │ │ │ ├── aggregate_example_conf_2.jpg │ │ │ ├── aggregate_example_result_1.jpg │ │ │ ├── aggregate_example_result_2.jpg │ │ │ ├── aggregate_step_form.jpg │ │ │ ├── append_example_conf.jpg │ │ │ ├── append_example_current_dataset.jpg │ │ │ ├── append_example_dataset1.jpg │ │ │ ├── append_example_dataset2.jpg │ │ │ ├── append_example_result.jpg │ │ │ ├── append_step_form.jpg │ │ │ ├── argmax_example_conf.jpg │ │ │ ├── argmax_example_result.jpg │ │ │ ├── argmax_step_form.jpg │ │ │ ├── argmin_example_conf.jpg │ │ │ ├── argmin_example_result.jpg │ │ │ ├── argmin_step_form.jpg │ │ │ ├── column_header_menu.jpg │ │ │ ├── comparetext_example_conf.jpg │ │ │ ├── comparetext_example_result.jpg │ │ │ ├── comparetext_step_form.jpg │ │ │ ├── concatenate_example_conf.jpg │ │ │ ├── concatenate_example_result.jpg │ │ │ ├── concatenate_step_form.jpg │ │ │ ├── convert_example_conf.jpg │ │ │ ├── convert_example_result.jpg │ │ │ ├── convert_step_form.jpg │ │ │ ├── cumsum_example_conf_1.png │ │ │ ├── cumsum_example_conf_2.png │ │ │ ├── cumsum_example_result_1.jpg │ │ │ ├── cumsum_example_result_2.jpg │ │ │ ├── cumsum_step_form.jpg │ │ │ ├── custom_example_conf.jpg │ │ │ ├── custom_example_result.jpg │ │ │ ├── custom_step_form.jpg │ │ │ ├── data_type_icon.jpg │ │ │ ├── dateextract_example_conf.jpg │ │ │ ├── dateextract_example_result.jpg │ │ │ ├── dateextract_step_form.jpg │ │ │ ├── delete_step_form.jpg │ │ │ ├── dissolve_step_form.jpg │ │ │ ├── duplicate_example_conf.jpg │ │ │ ├── duplicate_example_result.jpg │ │ │ ├── duplicate_step_form.jpg │ │ │ ├── duration_example_conf_1.png │ │ │ ├── duration_example_conf_2.png │ │ │ ├── duration_example_result_1.png │ │ │ ├── duration_example_result_2.png │ │ │ ├── duration_step_form.png │ │ │ ├── evolution_example_conf_1.jpg │ │ │ ├── evolution_example_conf_1.png │ │ │ ├── evolution_example_conf_2.jpg │ │ │ ├── evolution_example_conf_2.png │ │ │ ├── evolution_example_conf_3.jpg │ │ │ ├── evolution_example_conf_3.png │ │ │ ├── evolution_example_result_1.jpg │ │ │ ├── evolution_example_result_1.png │ │ │ ├── evolution_example_result_2.jpg │ │ │ ├── evolution_example_result_2.png │ │ │ ├── evolution_example_result_3.jpg │ │ │ ├── evolution_example_result_3.png │ │ │ ├── evolution_step_form.jpg │ │ │ ├── evolution_step_form.png │ │ │ ├── fillna_example_conf.jpg │ │ │ ├── fillna_example_result.jpg │ │ │ ├── fillna_step_form.jpg │ │ │ ├── filter_example_conf.jpg │ │ │ ├── filter_example_result.jpg │ │ │ ├── filter_step_form.jpg │ │ │ ├── formula_example_conf_1.jpg │ │ │ ├── formula_example_conf_2.jpg │ │ │ ├── formula_example_result_1.jpg │ │ │ ├── formula_example_result_2.jpg │ │ │ ├── formula_step_form.jpg │ │ │ ├── fromdate_example_conf.jpg │ │ │ ├── fromdate_example_result.jpg │ │ │ ├── fromdate_step_form.jpg │ │ │ ├── fromdate_step_form_custom.jpg │ │ │ ├── fromdate_step_form_presets.jpg │ │ │ ├── general_interface.jpg │ │ │ ├── hierarchy_step_form.jpg │ │ │ ├── ifthenelse_example_conf.jpg │ │ │ ├── ifthenelse_example_result.jpg │ │ │ ├── ifthenelse_step_form.jpg │ │ │ ├── join_example_conf_1.jpg │ │ │ ├── join_example_conf_2.jpg │ │ │ ├── join_example_conf_3.jpg │ │ │ ├── join_example_current_dataset.jpg │ │ │ ├── join_example_result_1.jpg │ │ │ ├── join_example_result_2.jpg │ │ │ ├── join_example_result_3.jpg │ │ │ ├── join_example_right_dataset_1.jpg │ │ │ ├── join_example_right_dataset_2.jpg │ │ │ ├── join_step_form.jpg │ │ │ ├── lowercase_example_conf.jpg │ │ │ ├── lowercase_example_result.jpg │ │ │ ├── lowercase_step_form.jpg │ │ │ ├── middle_step_selected.jpg │ │ │ ├── movingaverage_example_conf_1.png │ │ │ ├── movingaverage_example_conf_2.png │ │ │ ├── movingaverage_example_result_1.png │ │ │ ├── movingaverage_example_result_2.png │ │ │ ├── movingaverage_step_form.png │ │ │ ├── percentage_example_conf.jpg │ │ │ ├── percentage_example_result.jpg │ │ │ ├── percentage_step_form.jpg │ │ │ ├── pivot_example_conf.jpg │ │ │ ├── pivot_example_result.jpg │ │ │ ├── pivot_step_form.jpg │ │ │ ├── rank_example_conf_1.jpg │ │ │ ├── rank_example_conf_2.jpg │ │ │ ├── rank_example_result_1.jpg │ │ │ ├── rank_example_result_2.jpg │ │ │ ├── rank_step_form.jpg │ │ │ ├── rename_example_conf.jpg │ │ │ ├── rename_example_result.jpg │ │ │ ├── rename_step_form.jpg │ │ │ ├── replace_example_conf.jpg │ │ │ ├── replace_example_result.jpg │ │ │ ├── replace_step_form.jpg │ │ │ ├── rollup_example_conf_1.jpg │ │ │ ├── rollup_example_conf_2.jpg │ │ │ ├── rollup_example_result_1.jpg │ │ │ ├── rollup_example_result_2.jpg │ │ │ ├── rollup_step_form.jpg │ │ │ ├── search_bar_menu.jpg │ │ │ ├── select_step_form.jpg │ │ │ ├── simplify_step_form.jpg │ │ │ ├── sort_example_conf.jpg │ │ │ ├── sort_example_result.jpg │ │ │ ├── sort_step_form.jpg │ │ │ ├── split_example_conf.jpg │ │ │ ├── split_example_result.jpg │ │ │ ├── split_step_form.jpg │ │ │ ├── statistics_form_1.jpg │ │ │ ├── statistics_form_2.jpg │ │ │ ├── statistics_form_3.jpg │ │ │ ├── statistics_result_1.jpg │ │ │ ├── statistics_result_2.jpg │ │ │ ├── statistics_result_3.jpg │ │ │ ├── step_edition_mode.jpg │ │ │ ├── substring_example_conf_1.jpg │ │ │ ├── substring_example_conf_2.jpg │ │ │ ├── substring_example_result.jpg │ │ │ ├── substring_step_form.jpg │ │ │ ├── text_example_conf.jpg │ │ │ ├── text_example_result.jpg │ │ │ ├── text_step_form.jpg │ │ │ ├── todate_example_conf.jpg │ │ │ ├── todate_example_result.jpg │ │ │ ├── todate_step_form.jpg │ │ │ ├── todate_step_form_custom.jpg │ │ │ ├── todate_step_form_presets.jpg │ │ │ ├── top_example_conf.jpg │ │ │ ├── top_example_result.jpg │ │ │ ├── top_step_form.jpg │ │ │ ├── totals_example_conf_1.png │ │ │ ├── totals_example_conf_2.png │ │ │ ├── totals_example_result_1.png │ │ │ ├── totals_example_result_2.png │ │ │ ├── totals_step_form.png │ │ │ ├── trim-step-form.png │ │ │ ├── uniquegroups_example_conf.jpg │ │ │ ├── uniquegroups_example_result.jpg │ │ │ ├── uniquegroups_step_form.jpg │ │ │ ├── unpivot_example_conf.jpg │ │ │ ├── unpivot_example_result.jpg │ │ │ ├── unpivot_step_form.jpg │ │ │ ├── uppercase_example_conf.jpg │ │ │ ├── uppercase_example_result.jpg │ │ │ ├── uppercase_step_form.jpg │ │ │ ├── waterfall_example_conf_1.jpg │ │ │ ├── waterfall_example_conf_2.jpg │ │ │ ├── waterfall_example_result_1.jpg │ │ │ ├── waterfall_example_result_2.jpg │ │ │ ├── waterfall_step_form.jpg │ │ │ └── widget_menu.jpg │ ├── jekyll-dark.png │ ├── jekyll.png │ ├── logonav.png │ ├── readme_screenshot.png │ └── weaverbird-404.jpg ├── index.html ├── js │ ├── bootstrap.min.js │ ├── main.js │ └── typeahead.bundle.min.js ├── nginx.conf └── search.json ├── server ├── .coveragerc ├── .editorconfig ├── .gitignore ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── Makefile ├── README.md ├── __init__.py ├── doc │ ├── README.md │ └── sql_pipeline.png ├── pyproject.toml ├── src │ └── weaverbird │ │ ├── __init__.py │ │ ├── backends │ │ ├── __init__.py │ │ ├── mongo_translator │ │ │ ├── __init__.py │ │ │ ├── date_extractors.py │ │ │ ├── mongo_pipeline_translator.py │ │ │ ├── steps │ │ │ │ ├── __init__.py │ │ │ │ ├── absolutevalue.py │ │ │ │ ├── addmissingdates.py │ │ │ │ ├── aggregate.py │ │ │ │ ├── append.py │ │ │ │ ├── argmax.py │ │ │ │ ├── argmin.py │ │ │ │ ├── comparetext.py │ │ │ │ ├── concatenate.py │ │ │ │ ├── convert.py │ │ │ │ ├── cumsum.py │ │ │ │ ├── custom.py │ │ │ │ ├── date_extract.py │ │ │ │ ├── date_granularity.py │ │ │ │ ├── delete.py │ │ │ │ ├── domain.py │ │ │ │ ├── duplicate.py │ │ │ │ ├── duration.py │ │ │ │ ├── evolution.py │ │ │ │ ├── fillna.py │ │ │ │ ├── filter.py │ │ │ │ ├── formula.py │ │ │ │ ├── fromdate.py │ │ │ │ ├── ifthenelse.py │ │ │ │ ├── join.py │ │ │ │ ├── lowercase.py │ │ │ │ ├── moving_average.py │ │ │ │ ├── percentage.py │ │ │ │ ├── pivot.py │ │ │ │ ├── rank.py │ │ │ │ ├── rename.py │ │ │ │ ├── replace.py │ │ │ │ ├── replacetext.py │ │ │ │ ├── rollup.py │ │ │ │ ├── select.py │ │ │ │ ├── sort.py │ │ │ │ ├── split.py │ │ │ │ ├── statistics.py │ │ │ │ ├── substring.py │ │ │ │ ├── text.py │ │ │ │ ├── todate.py │ │ │ │ ├── top.py │ │ │ │ ├── totals.py │ │ │ │ ├── trim.py │ │ │ │ ├── types.py │ │ │ │ ├── uniquegroups.py │ │ │ │ ├── unpivot.py │ │ │ │ ├── uppercase.py │ │ │ │ └── waterfall.py │ │ │ └── utils.py │ │ ├── pandas_executor │ │ │ ├── __init__.py │ │ │ ├── date_extractors.py │ │ │ ├── geo_utils.py │ │ │ ├── pipeline_executor.py │ │ │ ├── steps │ │ │ │ ├── __init__.py │ │ │ │ ├── absolutevalue.py │ │ │ │ ├── addmissingdates.py │ │ │ │ ├── aggregate.py │ │ │ │ ├── append.py │ │ │ │ ├── argmax.py │ │ │ │ ├── argmin.py │ │ │ │ ├── comparetext.py │ │ │ │ ├── concatenate.py │ │ │ │ ├── convert.py │ │ │ │ ├── cumsum.py │ │ │ │ ├── date_extract.py │ │ │ │ ├── date_granularity.py │ │ │ │ ├── delete.py │ │ │ │ ├── dissolve.py │ │ │ │ ├── domain.py │ │ │ │ ├── duplicate.py │ │ │ │ ├── duration.py │ │ │ │ ├── evolution.py │ │ │ │ ├── fillna.py │ │ │ │ ├── filter.py │ │ │ │ ├── formula.py │ │ │ │ ├── fromdate.py │ │ │ │ ├── hierarchy.py │ │ │ │ ├── ifthenelse.py │ │ │ │ ├── join.py │ │ │ │ ├── lowercase.py │ │ │ │ ├── moving_average.py │ │ │ │ ├── percentage.py │ │ │ │ ├── pivot.py │ │ │ │ ├── rank.py │ │ │ │ ├── rename.py │ │ │ │ ├── replace.py │ │ │ │ ├── replacetext.py │ │ │ │ ├── rollup.py │ │ │ │ ├── select.py │ │ │ │ ├── simplify.py │ │ │ │ ├── sort.py │ │ │ │ ├── split.py │ │ │ │ ├── statistics.py │ │ │ │ ├── substring.py │ │ │ │ ├── text.py │ │ │ │ ├── todate.py │ │ │ │ ├── top.py │ │ │ │ ├── totals.py │ │ │ │ ├── trim.py │ │ │ │ ├── uniquegroups.py │ │ │ │ ├── unpivot.py │ │ │ │ ├── uppercase.py │ │ │ │ ├── utils │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── cast.py │ │ │ │ │ ├── cleaning.py │ │ │ │ │ ├── combination.py │ │ │ │ │ ├── condition.py │ │ │ │ │ ├── dates.py │ │ │ │ │ └── formula.py │ │ │ │ └── waterfall.py │ │ │ └── types.py │ │ └── pypika_translator │ │ │ ├── __init__.py │ │ │ ├── dialects.py │ │ │ ├── operators.py │ │ │ ├── translate.py │ │ │ ├── translators │ │ │ ├── __init__.py │ │ │ ├── athena.py │ │ │ ├── base.py │ │ │ ├── exceptions.py │ │ │ ├── googlebigquery.py │ │ │ ├── mysql.py │ │ │ ├── postgresql.py │ │ │ ├── redshift.py │ │ │ └── snowflake.py │ │ │ └── utils │ │ │ ├── __init__.py │ │ │ └── formula.py │ │ ├── exceptions.py │ │ ├── pipeline │ │ ├── __init__.py │ │ ├── conditions.py │ │ ├── dates.py │ │ ├── formula_ast │ │ │ ├── __init__.py │ │ │ ├── eval.py │ │ │ ├── types.py │ │ │ └── utils.py │ │ ├── pipeline.py │ │ ├── steps │ │ │ ├── __init__.py │ │ │ ├── absolutevalue.py │ │ │ ├── addmissingdates.py │ │ │ ├── aggregate.py │ │ │ ├── append.py │ │ │ ├── argmax.py │ │ │ ├── argmin.py │ │ │ ├── comparetext.py │ │ │ ├── concatenate.py │ │ │ ├── convert.py │ │ │ ├── cumsum.py │ │ │ ├── custom.py │ │ │ ├── customsql.py │ │ │ ├── date_extract.py │ │ │ ├── date_granularity.py │ │ │ ├── delete.py │ │ │ ├── dissolve.py │ │ │ ├── domain.py │ │ │ ├── duplicate.py │ │ │ ├── duration.py │ │ │ ├── evolution.py │ │ │ ├── fillna.py │ │ │ ├── filter.py │ │ │ ├── formula.py │ │ │ ├── fromdate.py │ │ │ ├── hierarchy.py │ │ │ ├── ifthenelse.py │ │ │ ├── join.py │ │ │ ├── lowercase.py │ │ │ ├── moving_average.py │ │ │ ├── percentage.py │ │ │ ├── pivot.py │ │ │ ├── rank.py │ │ │ ├── rename.py │ │ │ ├── replace.py │ │ │ ├── replacetext.py │ │ │ ├── rollup.py │ │ │ ├── select.py │ │ │ ├── simplify.py │ │ │ ├── sort.py │ │ │ ├── split.py │ │ │ ├── statistics.py │ │ │ ├── substring.py │ │ │ ├── table.py │ │ │ ├── text.py │ │ │ ├── todate.py │ │ │ ├── top.py │ │ │ ├── totals.py │ │ │ ├── trim.py │ │ │ ├── uniquegroups.py │ │ │ ├── unpivot.py │ │ │ ├── uppercase.py │ │ │ ├── utils │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── combination.py │ │ │ │ └── render_variables.py │ │ │ └── waterfall.py │ │ └── types.py │ │ └── utils │ │ ├── __init__.py │ │ ├── iter.py │ │ ├── size.py │ │ ├── stopwatch.py │ │ └── toucan_connectors.py ├── static ├── tests │ ├── __init__.py │ ├── backends │ │ ├── __init__.py │ │ ├── fixtures │ │ │ ├── HOWTO-create-fixtures.md │ │ │ ├── absolutevalue │ │ │ │ └── simple.json │ │ │ ├── addmissingdates │ │ │ │ ├── simple.json │ │ │ │ └── simple_with_tz.yaml │ │ │ ├── aggregate │ │ │ │ ├── count.json │ │ │ │ ├── count_distinct.json │ │ │ │ ├── count_distinct_pypika.json │ │ │ │ ├── count_nulls.yaml │ │ │ │ ├── count_nulls_false.yaml │ │ │ │ ├── count_nulls_false_pypika.yaml │ │ │ │ ├── count_nulls_pypika.yaml │ │ │ │ ├── count_pypika.json │ │ │ │ ├── count_with_null.json │ │ │ │ ├── first.json │ │ │ │ ├── first_avg_pypika.json │ │ │ │ ├── first_avg_sum_pypika.json │ │ │ │ ├── first_pypika.json │ │ │ │ ├── first_two_aggs_avg_pypika.json │ │ │ │ ├── first_two_aggs_pypika.json │ │ │ │ ├── first_two_cols_pypika.json │ │ │ │ ├── first_with_special_column_name_mongo.json │ │ │ │ ├── keep_original_granularity_empty_on.json │ │ │ │ ├── last.json │ │ │ │ ├── last_pypika.json │ │ │ │ ├── last_step_no_group_with_granularity.yaml │ │ │ │ ├── legacy_syntax.json │ │ │ │ ├── multiple_aggregations_with_same_columns.yaml │ │ │ │ ├── multiple_aggregations_with_window_func_pypika.json │ │ │ │ ├── multiple_aggregations_with_window_func_without_on_pypika.json │ │ │ │ ├── simple.json │ │ │ │ ├── simple_aggregate_with_null.json │ │ │ │ ├── with_original_granularity.json │ │ │ │ ├── with_original_granularity_multiple_aggregations.json │ │ │ │ ├── with_original_granularity_multiple_aggregations_multiple_columns.json │ │ │ │ ├── with_original_granularity_multiple_aggregations_with_window_func_pypika.json │ │ │ │ ├── with_original_granularity_multiple_window_func_pypika.json │ │ │ │ ├── with_original_granularity_pypika.json │ │ │ │ ├── without_on.json │ │ │ │ ├── without_on.yaml │ │ │ │ └── without_on_pypika.json │ │ │ ├── append │ │ │ │ ├── different_columns_pypika.yaml │ │ │ │ ├── different_columns_tricky_pypika.yaml │ │ │ │ ├── domain_name_only.json │ │ │ │ ├── multi_pipeline_with_join_pypika.yaml │ │ │ │ ├── multi_pipeline_with_join_pypika_bigquery.yaml │ │ │ │ ├── multiple_pypika.yaml │ │ │ │ ├── nested_pypika.yaml │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.yaml │ │ │ │ └── with_domain_name.json │ │ │ ├── argmax │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ ├── with_group.json │ │ │ │ └── with_group_pypika.json │ │ │ ├── argmin │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ ├── with_group.json │ │ │ │ └── with_group_pypika.json │ │ │ ├── comparetext │ │ │ │ └── simple.json │ │ │ ├── concatenate │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.yaml │ │ │ ├── convert │ │ │ │ ├── from_datetime_to_text_athena_bq.json │ │ │ │ ├── from_datetime_to_text_pypika.json │ │ │ │ ├── to_bool.json │ │ │ │ ├── to_bool_pypika.json │ │ │ │ ├── to_datetime.json │ │ │ │ ├── to_datetime_from_timestamp.json │ │ │ │ ├── to_float.json │ │ │ │ ├── to_float_pypika.json │ │ │ │ ├── to_integer.json │ │ │ │ ├── to_integer_from_datetime.json │ │ │ │ ├── to_integer_only_floats.json │ │ │ │ ├── to_integer_only_strings.json │ │ │ │ ├── to_text.json │ │ │ │ └── to_text_pypika.json │ │ │ ├── cumsum │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ ├── with_groups.json │ │ │ │ ├── with_groups_pypika.json │ │ │ │ ├── with_multiple_values.json │ │ │ │ └── with_multiple_values_pypika.json │ │ │ ├── custom │ │ │ │ └── simple.json │ │ │ ├── customsql │ │ │ │ └── simple.json │ │ │ ├── dateextract │ │ │ │ ├── after_add_missing_dates_duplicate_values.json │ │ │ │ ├── all_cases.json │ │ │ │ ├── first_day_of_previous_month_pypika.yaml │ │ │ │ ├── google_big_query_datetimes.yaml │ │ │ │ ├── google_big_query_timestamps.yaml │ │ │ │ ├── legacy_config.json │ │ │ │ ├── legacy_config_without_column.json │ │ │ │ ├── mongo_all_cases.json │ │ │ │ └── pypika_all_cases.json │ │ │ ├── dategranularity │ │ │ │ ├── all_cases_in_new_columns.yaml │ │ │ │ └── week_without_new_column.yaml │ │ │ ├── delete │ │ │ │ ├── non_existing_column.json │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── dissolve │ │ │ │ ├── pandas_advanced.json │ │ │ │ ├── pandas_no_aggs.json │ │ │ │ └── pandas_simple.json │ │ │ ├── duplicate │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── duration │ │ │ │ ├── all_cases_pypika.yaml │ │ │ │ └── simple.json │ │ │ ├── evolution │ │ │ │ ├── abs_nogroups.json │ │ │ │ ├── abs_nogroups_multirow_lag.yaml │ │ │ │ ├── abs_nogroups_pypika.json │ │ │ │ ├── abs_with_same_group.yml │ │ │ │ ├── multiple_evolutions_with_groups.yaml │ │ │ │ ├── perc_groups.json │ │ │ │ ├── perc_groups_pypika.json │ │ │ │ ├── perc_nogroups.json │ │ │ │ ├── perc_nogroups_integers_pypika.yaml │ │ │ │ ├── perc_nogroups_negatives.yaml │ │ │ │ ├── perc_nogroups_negatives_pypika.yaml │ │ │ │ └── perc_nogroups_pypika.json │ │ │ ├── fillna │ │ │ │ ├── date.json │ │ │ │ ├── fillinteger.json │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.yaml │ │ │ ├── filter │ │ │ │ ├── date_eq_pypika.yaml │ │ │ │ ├── date_in_pypika.yaml │ │ │ │ ├── date_in_with_null_pypika.yaml │ │ │ │ ├── dates.json │ │ │ │ ├── dates_from_until.json │ │ │ │ ├── dates_from_until_pypika.json │ │ │ │ ├── dates_from_until_strip_hours.json │ │ │ │ ├── dates_from_until_too_wide.json │ │ │ │ ├── dates_from_until_tz_offset_pypika.json │ │ │ │ ├── eq.json │ │ │ │ ├── eq_pypika.json │ │ │ │ ├── eq_with_null_and_filter_step_last_pypika.yaml │ │ │ │ ├── eq_with_null_pypika.yaml │ │ │ │ ├── isin_with_null_pypika.yaml │ │ │ │ ├── join_geojson_null_values.yaml │ │ │ │ ├── matches_with_float_pypika.yaml │ │ │ │ ├── notmatches_pypika.yaml │ │ │ │ ├── notmatches_with_float_pypika.yaml │ │ │ │ ├── relative_dates.json │ │ │ │ └── relative_dates_pypika.json │ │ │ ├── formula │ │ │ │ ├── division.json │ │ │ │ ├── division_pypika.json │ │ │ │ ├── division_zero.json │ │ │ │ ├── division_zero_pypika.json │ │ │ │ ├── nested.json │ │ │ │ ├── nested_divisions.json │ │ │ │ ├── nested_divisions_pypika.yaml │ │ │ │ ├── nested_pypika.json │ │ │ │ ├── priorities_pypika.yaml │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ ├── special_brackets_pypika.yaml │ │ │ │ ├── special_col.json │ │ │ │ └── text_quotes.json │ │ │ ├── fromdate │ │ │ │ ├── day_longmonth_year_space.json │ │ │ │ ├── day_longmonth_year_space_pypika.yaml │ │ │ │ ├── day_shortmonth_year_dash.json │ │ │ │ ├── day_shortmonth_year_dash_pypika.yaml │ │ │ │ ├── day_shortmonth_year_space.json │ │ │ │ ├── day_shortmonth_year_space_pypika.yaml │ │ │ │ ├── longmonth_only_custom.json │ │ │ │ ├── longmonth_year_space.json │ │ │ │ ├── longmonth_year_space_pypika.yaml │ │ │ │ ├── shortmonth_year_dash.json │ │ │ │ ├── shortmonth_year_dash_pypika.yaml │ │ │ │ ├── shortmonth_year_space.json │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.yaml │ │ │ │ └── simple_with_null.json │ │ │ ├── hierarchy │ │ │ │ └── pandas_advanced.json │ │ │ ├── ifthenelse │ │ │ │ ├── after_join.yaml │ │ │ │ ├── combination_or.json │ │ │ │ ├── combinations.json │ │ │ │ ├── combinations_pypika.json │ │ │ │ ├── dates_conditions.json │ │ │ │ ├── dates_conditions_pypika.json │ │ │ │ ├── formula_and_value.yaml │ │ │ │ ├── nested.json │ │ │ │ ├── nested_pypika.json │ │ │ │ ├── number_values.json │ │ │ │ ├── number_values_pypika.json │ │ │ │ ├── override_column_name_pypika.yaml │ │ │ │ ├── overwrite_column_pypika.yaml │ │ │ │ ├── quotes.json │ │ │ │ ├── quotes_pypika.yaml │ │ │ │ ├── regex.json │ │ │ │ ├── regex_pypika.json │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ ├── simple_with_dates_and_nulls.yaml │ │ │ │ └── simple_with_dates_and_nulls_pypika.yaml │ │ │ ├── join │ │ │ │ ├── domain_name_only.json │ │ │ │ ├── inner.json │ │ │ │ ├── inner_geo_left.json │ │ │ │ ├── inner_geo_right.json │ │ │ │ ├── inner_nested_pypika.yaml │ │ │ │ ├── inner_simple_pypika.yaml │ │ │ │ ├── last_position_with_nested_append_pypika.yaml │ │ │ │ ├── last_position_with_nested_append_pypika_bigquery.yaml │ │ │ │ ├── left.json │ │ │ │ ├── left_customsql_pypika.yaml │ │ │ │ ├── left_customsql_pypika_bigquery.yaml │ │ │ │ ├── left_geo_left.json │ │ │ │ ├── left_geo_right.json │ │ │ │ ├── left_outer.json │ │ │ │ ├── left_weird_name.json │ │ │ │ ├── not_last_position_with_nested_append_pypika.yaml │ │ │ │ └── not_last_position_with_nested_append_pypika_bigquery.yaml │ │ │ ├── lowercase │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ └── simple_pypika_null.json │ │ │ ├── movingaverage │ │ │ │ ├── simple.json │ │ │ │ └── with_groups.json │ │ │ ├── percentage │ │ │ │ ├── advanced.json │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.yaml │ │ │ │ └── with_groups_pypika.yaml │ │ │ ├── pivot │ │ │ │ ├── columns_cleaning.json │ │ │ │ ├── simple.json │ │ │ │ └── with_nulls.yaml │ │ │ ├── rank │ │ │ │ ├── group_by.json │ │ │ │ ├── grouped_standard_pypika.yaml │ │ │ │ ├── simple.json │ │ │ │ ├── simple_dense_pypika.yaml │ │ │ │ └── simple_standard_pypika.yaml │ │ │ ├── rename │ │ │ │ ├── edge_case.json │ │ │ │ ├── edge_case_pypika.json │ │ │ │ ├── multiple.json │ │ │ │ ├── multiple_pypika.json │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── replace │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ └── with_substrings.yaml │ │ │ ├── replacetext │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── rollup │ │ │ │ ├── datetime_followed_by_dateextract.yaml │ │ │ │ ├── groupby.json │ │ │ │ ├── groupby_and_limit.yaml │ │ │ │ ├── groupby_with_special_column_name.json │ │ │ │ ├── no_aggregation.json │ │ │ │ ├── no_aggs_single_label.yaml │ │ │ │ └── simple.json │ │ │ ├── select │ │ │ │ └── simple.yaml │ │ │ ├── simplify │ │ │ │ └── pandas_simple.json │ │ │ ├── sort │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── split │ │ │ │ ├── followed_by_rename_pypika.yaml │ │ │ │ ├── followed_by_replace_and_text_pypika.yaml │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ └── with_delimiter_pypika.yaml │ │ │ ├── statistics │ │ │ │ ├── all.json │ │ │ │ └── median_odd.yaml │ │ │ ├── substring │ │ │ │ ├── implicit_conversion.yaml │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── text │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ └── single_quote_pypika.yaml │ │ │ ├── todate │ │ │ │ ├── automatic_guess.json │ │ │ │ ├── custom_formats_with_nulls.yaml │ │ │ │ ├── from_timestamp.json │ │ │ │ ├── int_as_year_with_automatic_guess.json │ │ │ │ ├── simple.json │ │ │ │ ├── simple_gbq_pypika.yaml │ │ │ │ ├── simple_non_percent_formatting_pypika.yaml │ │ │ │ ├── simple_percent_formatting_pypika.yaml │ │ │ │ ├── simple_two_digit_year.yaml │ │ │ │ └── str_as_year_with_automatic_guess.json │ │ │ ├── top │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ ├── simple_strings.json │ │ │ │ ├── with_groups.json │ │ │ │ ├── with_groups_and_dates.json │ │ │ │ └── with_groups_pypika.json │ │ │ ├── totals │ │ │ │ ├── simple-pandas.json │ │ │ │ └── simple.json │ │ │ ├── trim │ │ │ │ ├── multiple_columns.json │ │ │ │ ├── multiple_columns_pypika.json │ │ │ │ ├── single_column.json │ │ │ │ └── single_column_pypika.json │ │ │ ├── uniquegroups │ │ │ │ ├── simple.json │ │ │ │ └── simple_pypika.json │ │ │ ├── unpivot │ │ │ │ ├── pandas.json │ │ │ │ └── simple_pypika.json │ │ │ ├── uppercase │ │ │ │ ├── simple.json │ │ │ │ ├── simple_pypika.json │ │ │ │ └── simple_pypika_null.json │ │ │ └── waterfall │ │ │ │ ├── simple.json │ │ │ │ ├── with_aggregation.json │ │ │ │ ├── with_backfill.yaml │ │ │ │ ├── with_groups.json │ │ │ │ └── without_backfill.yaml │ │ ├── mongo_translator │ │ │ ├── __init__.py │ │ │ ├── steps │ │ │ │ ├── __init__.py │ │ │ │ ├── test_addmissingdates.py │ │ │ │ ├── test_evolution.py │ │ │ │ ├── test_filter.py │ │ │ │ ├── test_formula.py │ │ │ │ └── test_ifthenelse.py │ │ │ └── test_mongo_translator_steps.py │ │ ├── mongo_translator_unit_tests │ │ │ ├── __init__.py │ │ │ ├── test_fromdate_separators.py │ │ │ └── test_ifthenelse_errors.py │ │ ├── pandas_executor │ │ │ ├── __init__.py │ │ │ ├── test_pandas_executor_steps.py │ │ │ └── utils │ │ │ │ ├── __init__.py │ │ │ │ └── test_dates.py │ │ ├── sql_translator │ │ │ └── common.py │ │ ├── sql_translator_integration_tests │ │ │ ├── __init__.py │ │ │ ├── beers.csv │ │ │ ├── test_sql_athena_translator_steps.py │ │ │ ├── test_sql_bigquery_translator_steps.py │ │ │ ├── test_sql_mysql_translator_steps.py │ │ │ ├── test_sql_postgres_translator_steps.py │ │ │ ├── test_sql_redshift_translator_steps.py │ │ │ └── test_sql_snowflake_translator_steps.py │ │ └── sql_translator_unit_tests │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_adapt_date_format.py │ │ │ ├── test_base_translator.py │ │ │ ├── test_base_translator_strings.py │ │ │ ├── test_date_format_translators.py │ │ │ ├── test_filter_translators.py │ │ │ ├── test_google_big_query.py │ │ │ ├── test_offset_limit_behaviour.py │ │ │ ├── test_redshift_translator.py │ │ │ ├── test_row_number_translators.py │ │ │ ├── test_snowflake_translator.py │ │ │ ├── test_split_part_translators.py │ │ │ ├── test_translation_last_step_unwrapping.py │ │ │ ├── test_translation_with_mergeable_first_step.py │ │ │ └── test_type_mapping_translators.py │ ├── conftest.py │ ├── fixtures │ │ ├── domain_a.csv │ │ ├── fixtures_templating │ │ │ ├── addmissingdate.json │ │ │ ├── aggregate.json │ │ │ ├── append.json │ │ │ ├── argmax.json │ │ │ ├── argmin.json │ │ │ ├── comparetext.json │ │ │ ├── concatenate.json │ │ │ ├── cumsum.json │ │ │ ├── dateextract.json │ │ │ ├── duration.json │ │ │ ├── evolution.json │ │ │ ├── fillna.json │ │ │ ├── formula.json │ │ │ ├── ifthenelse.json │ │ │ ├── join.json │ │ │ ├── pivot.json │ │ │ ├── rank.json │ │ │ ├── rename.json │ │ │ ├── replace.json │ │ │ ├── replacetext.json │ │ │ ├── rollup.json │ │ │ ├── split.json │ │ │ ├── text.json │ │ │ ├── top.json │ │ │ ├── top_filter.json │ │ │ ├── totals.json │ │ │ ├── uniquegroups.json │ │ │ ├── unpivot.json │ │ │ └── waterfall.json │ │ └── world.sql │ ├── pipeline │ │ ├── formula_ast │ │ │ └── test_utils.py │ │ ├── steps │ │ │ └── utils │ │ │ │ └── test_combination.py │ │ └── test_references.py │ ├── steps │ │ ├── __init__.py │ │ ├── fixtures │ │ │ └── sales_df.json │ │ ├── test_addmissingdates.py │ │ ├── test_aggregate.py │ │ ├── test_append.py │ │ ├── test_argmax.py │ │ ├── test_argmin.py │ │ ├── test_comparetext.py │ │ ├── test_concatenate.py │ │ ├── test_convert.py │ │ ├── test_cumstomsql.py │ │ ├── test_cumsum.py │ │ ├── test_date_extract.py │ │ ├── test_delete.py │ │ ├── test_domain.py │ │ ├── test_duplicate.py │ │ ├── test_duration.py │ │ ├── test_evolution.py │ │ ├── test_fillna.py │ │ ├── test_filter.py │ │ ├── test_formula.py │ │ ├── test_fromdate.py │ │ ├── test_ifthenelse.py │ │ ├── test_join.py │ │ ├── test_lowercase.py │ │ ├── test_moving_average.py │ │ ├── test_percentage.py │ │ ├── test_pivot.py │ │ ├── test_rank.py │ │ ├── test_rename.py │ │ ├── test_replace.py │ │ ├── test_replacetext.py │ │ ├── test_rollup.py │ │ ├── test_select.py │ │ ├── test_sort.py │ │ ├── test_split.py │ │ ├── test_statistics.py │ │ ├── test_substring.py │ │ ├── test_text.py │ │ ├── test_todate.py │ │ ├── test_top.py │ │ ├── test_totals.py │ │ ├── test_trim.py │ │ ├── test_uniquegroups.py │ │ ├── test_unpivot.py │ │ ├── test_uppercase.py │ │ └── test_waterfall.py │ ├── test_pipeline.py │ ├── test_pipeline_executor.py │ ├── test_utils.py │ └── utils.py └── uv.lock └── ui ├── .editorconfig ├── .eslintignore ├── .eslintrc.cjs ├── .gitignore ├── .npmignore ├── .prettierrc.cjs ├── .storybook ├── main.ts └── preview-head.html ├── CHANGELOG.md ├── build-types.sh ├── index.html ├── package.json ├── sonar-project.properties ├── src ├── assets │ ├── FA-ICONS.ts │ ├── internationalization.json │ └── reshape-icon.png ├── components │ ├── ConditionsEditor │ │ ├── ConditionsEditor.vue │ │ ├── ConditionsGroup.vue │ │ └── tree-types.ts │ ├── DatePicker │ │ ├── Calendar.vue │ │ ├── CustomGranularityCalendar.vue │ │ ├── GranularityConfigs.ts │ │ ├── RangeCalendar.vue │ │ ├── __mocks__ │ │ │ └── Calendar.vue │ │ └── transform-value-to-date-or-range.ts │ ├── FAIcon.vue │ ├── FilterEditor.vue │ ├── Popover.vue │ ├── Tabs.vue │ ├── __mocks__ │ │ └── FAIcon.vue │ ├── code-editor.ts │ ├── constants.ts │ ├── convert-if-then-else-to-human-format.ts │ ├── domutil.ts │ └── stepforms │ │ ├── AbsoluteValueStepForm.vue │ │ ├── AddMissingDatesStepForm.vue │ │ ├── AddTextColumnStepForm.vue │ │ ├── AddTotalRowsStepForm.vue │ │ ├── AggregateStepForm.vue │ │ ├── AppendStepForm.vue │ │ ├── ArgmaxStepForm.vue │ │ ├── ArgminStepForm.vue │ │ ├── ColumnPicker.vue │ │ ├── CompareTextStepForm.vue │ │ ├── ComputeDurationStepForm.vue │ │ ├── ConcatenateStepForm.vue │ │ ├── ConvertStepForm.vue │ │ ├── CumSumStepForm.vue │ │ ├── CustomSqlStepForm.vue │ │ ├── CustomStepForm.vue │ │ ├── DateExtractStepForm.vue │ │ ├── DateGranularityStepForm.vue │ │ ├── DeleteColumnStepForm.vue │ │ ├── DissolveStepForm.vue │ │ ├── DomainStepForm.vue │ │ ├── DuplicateColumnStepForm.vue │ │ ├── EvolutionStepForm.vue │ │ ├── FillnaStepForm.vue │ │ ├── FilterStepForm.vue │ │ ├── FormulaStepForm.vue │ │ ├── FromDateStepForm.vue │ │ ├── HierarchyStepForm.vue │ │ ├── IfThenElseStepForm.vue │ │ ├── JoinStepForm.vue │ │ ├── MovingAverageStepForm.vue │ │ ├── PercentageStepForm.vue │ │ ├── PivotStepForm.vue │ │ ├── RankStepForm.vue │ │ ├── RenameStepForm.vue │ │ ├── ReplaceStepForm.vue │ │ ├── ReplaceTextStepForm.vue │ │ ├── RollupStepForm.vue │ │ ├── SelectColumnStepForm.vue │ │ ├── SimplifyStepForm.vue │ │ ├── SortStepForm.vue │ │ ├── SplitStepForm.vue │ │ ├── StatisticsStepForm.vue │ │ ├── StepForm.vue │ │ ├── StepFormButtonbar.vue │ │ ├── StepFormComponent.vue │ │ ├── StepFormHeader.vue │ │ ├── SubstringStepForm.vue │ │ ├── ToDateStepForm.vue │ │ ├── ToLowerStepForm.vue │ │ ├── ToUpperStepForm.vue │ │ ├── TopStepForm.vue │ │ ├── TrimStepForm.vue │ │ ├── UniqueGroupsStepForm.vue │ │ ├── UnpivotStepForm.vue │ │ ├── WaterfallStepForm.vue │ │ ├── convert-filter-step-tree.ts │ │ ├── index.ts │ │ ├── schemas │ │ ├── absolutevalue.ts │ │ ├── addmissingdates.ts │ │ ├── aggregate.ts │ │ ├── aggregations.ts │ │ ├── append.ts │ │ ├── argmax.ts │ │ ├── argmin.ts │ │ ├── comparetext.ts │ │ ├── concatenate.ts │ │ ├── convert.ts │ │ ├── cumsum.ts │ │ ├── custom.ts │ │ ├── customsql.ts │ │ ├── dateextract.ts │ │ ├── dategranularity.ts │ │ ├── delete.ts │ │ ├── dissolve.ts │ │ ├── domain.ts │ │ ├── duplicate.ts │ │ ├── duration.ts │ │ ├── evolution.ts │ │ ├── fillna.ts │ │ ├── filter.ts │ │ ├── formula.ts │ │ ├── fromdate.ts │ │ ├── hierarchy.ts │ │ ├── ifthenelse.ts │ │ ├── index.ts │ │ ├── join.ts │ │ ├── movingaverage.ts │ │ ├── percentage.ts │ │ ├── pivot.ts │ │ ├── rank.ts │ │ ├── rename.ts │ │ ├── replace.ts │ │ ├── replaceText.ts │ │ ├── rollup.ts │ │ ├── select.ts │ │ ├── simplify.ts │ │ ├── sort.ts │ │ ├── split.ts │ │ ├── statistics.ts │ │ ├── substring.ts │ │ ├── text.ts │ │ ├── todate.ts │ │ ├── tolower.ts │ │ ├── top.ts │ │ ├── totals.ts │ │ ├── toupper.ts │ │ ├── trim.ts │ │ ├── uniquegroups.ts │ │ ├── unpivot.ts │ │ ├── utils.ts │ │ └── waterfall.ts │ │ ├── utils.ts │ │ └── widgets │ │ ├── Aggregation.vue │ │ ├── Autocomplete.vue │ │ ├── Checkbox.vue │ │ ├── CodeEditorWidget.vue │ │ ├── CumSum.vue │ │ ├── DateComponents │ │ ├── CustomVariableList.vue │ │ ├── DateRangeInput.vue │ │ ├── NewDateInput.vue │ │ ├── RelativeDateForm.vue │ │ └── TabbedRangeCalendars.vue │ │ ├── DefaultCodeEditor.vue │ │ ├── FilterSimpleCondition.vue │ │ ├── FormWidget.vue │ │ ├── IfThenElseWidget.vue │ │ ├── InputDate.vue │ │ ├── InputNumber.vue │ │ ├── InputText.vue │ │ ├── JoinColumns.vue │ │ ├── List.vue │ │ ├── MultiInputText.vue │ │ ├── MultiVariableInput.vue │ │ ├── Multiselect.vue │ │ ├── Rename.vue │ │ ├── Replace.vue │ │ ├── SortColumn.vue │ │ ├── TotalDimensions.vue │ │ ├── VariableInput.vue │ │ └── VariableInputs │ │ ├── AdvancedVariableModal.vue │ │ ├── VariableChooser.vue │ │ ├── VariableInputBase.vue │ │ ├── VariableList.vue │ │ ├── VariableListOption.vue │ │ └── VariableTag.vue ├── lib │ ├── backend.ts │ ├── clipboard.ts │ ├── dataset │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── mongo.ts │ │ ├── pagination.ts │ │ └── pandas.ts │ ├── dates.ts │ ├── helpers.ts │ ├── icons.ts │ ├── internationalization.ts │ ├── labeller.ts │ ├── matcher.ts │ ├── pipeline.ts │ ├── send-analytics.ts │ ├── steps.ts │ ├── templating.ts │ ├── translators │ │ ├── athena.ts │ │ ├── base.ts │ │ ├── empty.ts │ │ ├── google-big-query.ts │ │ ├── index.ts │ │ ├── mongo-dates.ts │ │ ├── mongo.ts │ │ ├── mongo4.ts │ │ ├── mongo42.ts │ │ ├── mongo5.ts │ │ ├── mysql.ts │ │ ├── pandas-no_joins.ts │ │ ├── pandas.ts │ │ ├── postgresql.ts │ │ ├── pypika.ts │ │ ├── redshift.ts │ │ └── snowflake.ts │ └── variables.ts ├── main.ts ├── styles │ ├── _variables.scss │ └── utils │ │ └── v-tooltip.scss └── types.ts ├── stories ├── AddTotalRowsStepForm.stories.ts ├── AggregateStepForm.stories.ts ├── Autocomplete.stories.ts ├── ColumnPicker.stories.ts ├── ConditionsEditor.stories.ts ├── FilterEditor.stories.ts ├── JoinStepForm.stories.ts ├── Multiselect.stories.ts ├── StepForm.stories.ts └── dates │ ├── Calendar.stories.ts │ ├── CustomGranularityCalendar.stories.ts │ ├── CustomVariableList.stories.ts │ ├── DateRangeInput.stories.ts │ ├── NewDateInput.stories.ts │ ├── RangeCalendar.stories.ts │ └── RelativeDateForm.stories.ts ├── tests └── unit │ ├── FAicon.spec.ts │ ├── absolutevalue-step-form.spec.ts │ ├── add-missing-dates-step-form.spec.ts │ ├── add-text-column.spec.ts │ ├── advanced-variable-modal.spec.ts │ ├── aggregate-step-form.spec.ts │ ├── aggregation-widget.spec.ts │ ├── append-step-form.spec.ts │ ├── argmax-step-form.spec.ts │ ├── argmin-step-form.spec.ts │ ├── autocomplete-widget.spec.ts │ ├── calendar.spec.ts │ ├── checkbox-widget.spec.ts │ ├── code-editor-widget.spec.ts │ ├── column-picker.spec.ts │ ├── compare-text.spec.ts │ ├── compute-duration.spec.ts │ ├── concatenate-step-form.spec.ts │ ├── conditions-editor.spec.ts │ ├── conditions-group.spec.ts │ ├── convert-filter-step-tree.spec.ts │ ├── convert-if-then-else-to-human-format.spec.ts │ ├── convert-step.spec.ts │ ├── cumsum-step-form.spec.ts │ ├── cumsum-widget.spec.ts │ ├── custom-granularity-calendar.spec.ts │ ├── custom-step-form.spec.ts │ ├── custom-variable-list.spec.ts │ ├── customsql-step-form.spec.ts │ ├── dataset.spec.ts │ ├── date-range-input.spec.ts │ ├── dateextract-step-form.spec.ts │ ├── dategranularity-step-form.spec.ts │ ├── delete-column-step-form.spec.ts │ ├── dissolve-step-form.spec.ts │ ├── domain-step-form.spec.ts │ ├── domutil.spec.ts │ ├── duplicate-column-step-form.spec.ts │ ├── evolution-step-form.spec.ts │ ├── fillna-step-form.spec.ts │ ├── filter-editor.spec.ts │ ├── filter-simple-condition-widget.spec.ts │ ├── filter-step-form.spec.ts │ ├── form-widget.spec.ts │ ├── formula-step-form.spec.ts │ ├── fromdate-step-form.spec.ts │ ├── helpers.spec.ts │ ├── hierarchy-step-form.spec.ts │ ├── ifthenelse-step-form.spec.ts │ ├── ifthenelse-widget.spec.ts │ ├── input-date-widget.spec.ts │ ├── input-number-widget.spec.ts │ ├── input-text-widget.spec.ts │ ├── join-columns.spec.ts │ ├── join-step-form.spec.ts │ ├── labeller.spec.ts │ ├── lib │ ├── clipboard.spec.ts │ ├── dataset │ │ └── pandas.spec.ts │ ├── dates.spec.ts │ ├── internationalization.spec.ts │ └── send-analytics.spec.ts │ ├── list-widget.spec.ts │ ├── moving-average-step-form.spec.ts │ ├── multi-input-text-widget.spec.ts │ ├── multi-variable-input.spec.ts │ ├── multiselect-widget.spec.ts │ ├── new-date-input.spec.ts │ ├── percentage-step-form.spec.ts │ ├── pipebuild.spec.ts │ ├── pivot-step-form.spec.ts │ ├── popover.spec.ts │ ├── range-calendar.spec.ts │ ├── rank-step-form.spec.ts │ ├── relative-date-form-widget.spec.ts │ ├── rename-step-form.spec.ts │ ├── rename-widget.spec.ts │ ├── replace-step-form.spec.ts │ ├── replace-text-step-form.spec.ts │ ├── replace-widget.spec.ts │ ├── rollup-step-form.spec.ts │ ├── select-column-step-form.spec.ts │ ├── set-code-editor.spec.ts │ ├── simplify-step-form.spec.ts │ ├── sort-column-widget.spec.ts │ ├── sort-step-form.spec.ts │ ├── split-step-form.spec.ts │ ├── statistics-step-form.spec.ts │ ├── step-form-header.spec.ts │ ├── substring-step-form.spec.ts │ ├── tabbed-range-calendars.spec.ts │ ├── tabs.spec.ts │ ├── templating.spec.ts │ ├── todate-step-form.spec.ts │ ├── tolower-step-form.spec.ts │ ├── top-step-form.spec.ts │ ├── total-dimensions.spec.ts │ ├── totals-step-form.spec.ts │ ├── toupper-step-form.spec.ts │ ├── transform-value-to-date-or-range.spec.ts │ ├── translator.spec.ts │ ├── trim-step-form.spec.ts │ ├── uniquegroups-step-form.spec.ts │ ├── unpivot-step-form.spec.ts │ ├── utils.ts │ ├── variable-chooser.spec.ts │ ├── variable-input-base.spec.ts │ ├── variable-input.spec.ts │ ├── variable-list-option.spec.ts │ ├── variable-list.spec.ts │ ├── variable-tag.spec.ts │ ├── variables.spec.ts │ └── waterfall-step-form.spec.ts ├── tsconfig.app.json ├── tsconfig.config.json ├── tsconfig.json ├── tsconfig.types.json ├── vite.config.ts ├── vitest.config.ts ├── vitest.setup.ts └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | docs 2 | 3 | .git 4 | .idea 5 | .vscode 6 | .circleci 7 | .github 8 | 9 | ui/.storybook 10 | ui/dist 11 | ui/node_modules 12 | ui/stories 13 | ui/tests 14 | 15 | server/.mypy_cache 16 | server/.pytest_cache 17 | server/tests 18 | server/static 19 | 20 | Dockerfile 21 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | server/* @ToucanToco/build_back 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/new-step.md: -------------------------------------------------------------------------------- 1 | ## New step to-do list 2 | 3 | - [ ] implement the pipeline / translation logic itself in the `lib` directory 4 | - [ ] define the step interface 5 | - [ ] implement a translation function for all supported back-ends 6 | - [ ] define a "human readable" label for this step (e.g. "duplicate column 'foo'") 7 | - [ ] define which fields of the step supports interpolation 8 | 9 | - [ ] implement the UI part 10 | - [ ] implement a form to configure the step 11 | - [ ] make it accessible through top bar widgets and/or columns contextual menus 12 | - [ ] make it accessible through search 13 | 14 | - [ ] add documentation 15 | - [ ] add UI documentation 16 | - [ ] add technical documentation 17 | 18 | - [ ] update the changelog 19 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: npm publish 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | 11 | defaults: 12 | run: 13 | working-directory: ui 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/setup-node@v4 18 | with: 19 | node-version: 22 20 | registry-url: 'https://registry.npmjs.org' 21 | scope: '@toucantoco' 22 | - run: yarn install --non-interactive --frozen-lockfile 23 | - run: yarn build 24 | - run: npm publish --access public 25 | env: 26 | NODE_AUTH_TOKEN: ${{ secrets.npm_token }} 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editors 2 | .idea 3 | .vscode 4 | !.vscode/extensions.json 5 | *.swp 6 | 7 | # Secrets 8 | bigquery-credentials.json 9 | .env 10 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "dbaeumer.vscode-eslint" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | threshold: 5% 6 | patch: 7 | default: 8 | enabled: yes 9 | target: 100% 10 | ignore: 11 | - 'tests/unit/*.spec.ts' 12 | -------------------------------------------------------------------------------- /docs/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | 17 | [COMMIT_EDITMSG] 18 | max_line_length = 0 19 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .sass-cache 3 | .jekyll-metadata 4 | *.gem 5 | .bundle 6 | vendor/bundle 7 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
The page you are looking for cannot be found.
7 |