Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
Merge pull request #704 from OpenClinica/revert-697-revert-694-revert…
Browse files Browse the repository at this point in the history
…-691-merge/6.2.0

Revert "Revert "Revert "Merge/6.2.0"""
  • Loading branch information
kkrumlian authored Oct 13, 2023
2 parents ca3d6ac + 1e9135d commit eb3b67b
Show file tree
Hide file tree
Showing 110 changed files with 1,193 additions and 2,826 deletions.
20 changes: 2 additions & 18 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,12 @@
"structuredClone": true
},
"extends": ["airbnb", "prettier"],
"plugins": [
"chai-friendly",
"jsdoc",
"prettier",
"unicorn",
"@typescript-eslint"
],
"parser": "@typescript-eslint/parser",
"plugins": ["chai-friendly", "jsdoc", "prettier", "unicorn"],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2021
},
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".js", ".ts", ".tsx"]
},
"import/resolver": {
"typescript": {
"alwaysTryTypes": true
}
},
"jsdoc": {
"tagNamePreference": {
"returns": "return"
Expand All @@ -46,8 +31,7 @@
"enketo/widgets",
"enketo/translator",
"enketo/dialog",
"enketo/file-manager",
"enketo-transformer/web"
"enketo/file-manager"
]
}
],
Expand Down
29 changes: 0 additions & 29 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,6 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## 6.2.0 - 2023-07-03

- Make pdf generation timeout configurable (#560)
- Added the Ukrainian translation (#569)
- Optimizations: do less redundant work, part 2 (enketo-core#976)
- Fix: gracefully handle undefined key (enketo-core#978)
- Fix: TOC navigation in pages theme (enketo-core#983)
- Fix: Respect existing val of type='time' (enketo-core#980)

## 6.1.0 - 2023-05-10

- removed: analog-scale widget (#525) _Note: now maintained by OpenClinica (https://github.com/OpenClinica/enketo-express-oc/tree/master/widget/analog-scale). Not considered a breaking change because usage outside of OpenClinica is not known_
- fixed: The app UI strings in newly created repeats are not translated (#527)
- Fix: validate CSV header names according to XML spec (#530)
- Use pm2-runtime on docker/start.sh (#533)
- Fix: revert jQuery upgrade (#539)
- Use client-side transform for preview-by-URL (#540)
- changed: updated Slovak translation (#542)
- Use exponential backoff for submission attempts in offline mode (#543)
- feat(app): add enketo namespace to all debug statements (#547)
- Add support for LineString and Polygon GeoJSON types (#554)
- Fix: further simplify geopicker widget selector (#954)
- Fix: undesired newlines in print view in select/select1 labels (#957)
- Add browser-based transformation (#171)
- Reimplement draw/signature/annotate widget to preserve original image size when annotating and improve resize performance (#960)
- Fix: focus first active input/widget on load, page navigation, user-added repeat (#969)
- Performance improvements: NumberInput widgets, `excludeNonRelevant` (#971)
- Fix: localized numeral entry by keyboard in number input widgets (#973)

## 6.0.0 - 2023-02-08

- **BREAKING CHANGE**: Removed IE11 support (enketo-core#946)
Expand Down
4 changes: 2 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = (grunt) => {
'!.nyc_output',
'!**/node_modules/**',
'!test/client/forms/forms.js',
'!public/js/build/**',
'!public/js/build/*',
'!docs/**',
'!test-coverage/**',
];
Expand Down Expand Up @@ -105,7 +105,7 @@ module.exports = (grunt) => {
'find locales -name "translation-combined.json" -delete && rm -fr locales/??',
},
'clean-js': {
command: 'rm -rf public/js/build/* && rm -f public/js/*.js',
command: 'rm -f public/js/build/* && rm -f public/js/*.js',
},
translation: {
command:
Expand Down
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ OpenClinica users, in addition to the configuration documentation linked above,

Enketo was initiated in 2009 by Martijn van de Rijdt as a web-based alternative or complement to [ODK Collect](https://docs.getodk.org/collect-intro/). It has become a core component of the ODK ecosystem and been adopted by several organizations beyond that ecosystem.

As of 2022, Enketo is maintained by the [ODK team](https://getodk.org/about/team.html) (primarily [Trevor Schmidt](https://github.com/eyelidlessness/)). Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its [Technical Advisory Board](https://getodk.org/about/ecosystem.html).
As of 2022, Enketo is maintained by [Trevor Schmidt](https://github.com/eyelidlessness/) and [the ODK team](https://getodk.org/about/team.html). Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its [Technical Advisory Board](https://getodk.org/about/ecosystem.html).

Our current primary goals are:

Expand All @@ -49,7 +49,7 @@ Feature requests and project discussion are welcome on the [ODK forum](https://f

### Translation

The user interface was translated by: Oleg Zhyliak (Ukrainian), Karol Kozyra (Swedish), Badisches Rotes Kreuz (German), Serkan Tümbaş (Turkish), Hélène Martin (French), Gurjot Sidhu(Hindi, Panjabi), "Abcmen" (Turkish), Otto Saldadze, Makhare Atchaidze, David Sichinava, Elene Ergeshidze (Georgian), Nancy Shapsough (Arabic), Noel O'Boyle (French), Miguel Moreno (Spanish), Tortue Torche (French), Bekim Kajtazi (Albanian), Marc Kreidler (German), Darío Hereñú (Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch).
The user interface was translated by: Karol Kozyra (Swedish), Badisches Rotes Kreuz (German), Serkan Tümbaş (Turkish), Hélène Martin (French), Gurjot Sidhu(Hindi, Panjabi), "Abcmen" (Turkish), Otto Saldadze, Makhare Atchaidze, David Sichinava, Elene Ergeshidze (Georgian), Nancy Shapsough (Arabic), Noel O'Boyle (French), Miguel Moreno (Spanish), Tortue Torche (French), Bekim Kajtazi (Albanian), Marc Kreidler (German), Darío Hereñú (Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch).

_Send a message if you'd like to contribute! We use an easy web interface provided by [Transifex](https://www.transifex.com/projects/p/enketo-express/)._

Expand Down Expand Up @@ -80,15 +80,13 @@ OpenClinica has a few [additional text strings](./locales/src/en/translation-add

### Funding

The development of this application is now led by [ODK](https://getodk.org) and funded by customers of the ODK Cloud hosted service.

Past funders include [KoBo Toolbox (Harvard Humanitarian Initiative)](http://www.kobotoolbox.org), [iMMAP](http://immap.org), [OpenClinica](https://openclinica.com), [London School of Hygiene and Tropical Medicine](https://opendatakit.lshtm.ac.uk/), [DIAL Open Source Center](https://www.osc.dial.community/) and [Enketo LLC](https://www.linkedin.com/company/enketo-llc). Also see [Enketo Core sponsors](https://github.com/enketo/enketo-core#sponsors).
The development of this application was funded by [KoBo Toolbox (Harvard Humanitarian Initiative)](http://www.kobotoolbox.org), [iMMAP](http://immap.org), [OpenClinica](https://openclinica.com), [London School of Hygiene and Tropical Medicine](https://opendatakit.lshtm.ac.uk/), [DIAL Open Source Center](https://www.osc.dial.community/) and [Enketo LLC](https://www.linkedin.com/company/enketo-llc). The [Enketo-core](https://github.com/enketo/enketo-core) library (the form engine + themes) used in this application obtained significant funding from [SEL (Columbia University)](http://modi.mech.columbia.edu/), the [Santa Fe Institute](http://www.santafe.edu/), [Ona](https://ona.io) and the [HRP project](http://www.who.int/reproductivehealth/topics/mhealth/en/).

### License

See [the license document](https://github.com/enketo/enketo-express/blob/master/LICENSE) for this application's license.

Note that some of the libraries used in this app have a different license.
Note that some of the libraries used in this app have a different license. In particular note [this one](https://github.com/enketo/enketo-xpathjs).

Note the 'Powered by Enketo' footer requirement as explained in [enketo-core](https://github.com/enketo/enketo-core#license). This requirement is applicable to all Enketo apps, including this one, unless an exemption was granted.

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/media-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const request = require('request');
const express = require('express');

const router = express.Router();
const debug = require('debug')('enketo:media-controller');
const debug = require('debug')('media-controller');
const {
RequestFilteringHttpAgent,
RequestFilteringHttpsAgent,
Expand Down
79 changes: 65 additions & 14 deletions app/controllers/transformation-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

const transformer = require('enketo-transformer');
const communicator = require('../lib/communicator');
const { ResponseError, TranslatedError } = require('../lib/custom-error');
const { TranslatedError } = require('../lib/custom-error');
const surveyModel = require('../models/survey-model');
const cacheModel = require('../models/cache-model');
const account = require('../models/account-model');
Expand All @@ -13,6 +13,7 @@ const config = require('../models/config-model').server;
const utils = require('../lib/utils');
const routerUtils = require('../lib/router-utils');
const express = require('express');
const url = require('url');
const mediaLib = require('../lib/media');

const router = express.Router();
Expand Down Expand Up @@ -100,15 +101,27 @@ async function getSurveyParts(req, res, next) {
/** @type {string | null} */
let formId = null;

/** @type {string | null} */
let formFileName = null;

try {
let survey = await _getSurveyParams(req);

formId = survey.openRosaId;
// A request with "xformUrl" body parameter was used (unlaunched form)
if (survey.info != null) {
formFileName = survey.info.downloadUrl.replace(
/.*\/([^/]+)$/,
'$1'
);
survey = await _getFormDirectly(survey);

_respond(res, survey);

if (formId == null) {
throw new ResponseError(404);
return;
}

formId = survey.openRosaId;

const authenticated = await _authenticate(survey);
const cached = await _getFormFromCache(authenticated);

Expand All @@ -129,10 +142,14 @@ async function getSurveyParts(req, res, next) {
});
} catch (error) {
if (error.status === 403) {
const notFoundError = new TranslatedError(
'error.notfoundinformlist',
{ formId }
);
const notFoundError =
formId == null
? new TranslatedError('error.notfounddirectformurl', {
formFileName,
})
: new TranslatedError('error.notfoundinformlist', {
formId,
});

notFoundError.status = 404;

Expand Down Expand Up @@ -166,6 +183,17 @@ function getSurveyHash(req, res, next) {
.catch(next);
}

/**
* @param {module:survey-model~SurveyObject} survey - survey object
*
* @return { Promise<module:survey-model~SurveyObject> } a Promise resolving with survey object with form transformation result
*
*/
function _getFormDirectly(survey) {
survey.openclinica = true;
return communicator.getXForm(survey).then(transformer.transform);
}

/**
* @param {module:survey-model~SurveyObject} survey - survey object
*
Expand Down Expand Up @@ -205,11 +233,8 @@ function _updateCache(survey) {
delete survey.mediaHash;
delete survey.mediaUrlHash;
delete survey.formHash;
survey.openclinica = true;
return communicator
.getXForm(survey)
.then(transformer.transform)
.then(cacheModel.set);

return _getFormDirectly(survey).then(cacheModel.set);
}

return survey;
Expand Down Expand Up @@ -334,6 +359,7 @@ function _setCookieAndCredentials(survey, req) {
* @return { Promise<module:survey-model~SurveyObject> } a Promise resolving with survey object
*/
function _getSurveyParams(req) {
const params = req.body;
const customParamName = req.app.get(
'query parameter to pass to submission'
);
Expand All @@ -350,7 +376,32 @@ function _getSurveyParams(req) {
return _setCookieAndCredentials(survey, req);
});
}

if (params.xformUrl) {
const urlObj = url.parse(params.xformUrl);
if (!urlObj || !urlObj.protocol || !urlObj.host) {
const error = new Error('Bad Request. Form URL is invalid.');
error.status = 400;
throw error;
}
const xUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;

return account
.check({
openRosaServer: xUrl,
})
.then(
(
survey // no need to check quota
) =>
Promise.resolve({
info: {
downloadUrl: params.xformUrl,
},
account: survey.account,
})
)
.then((survey) => _setCookieAndCredentials(survey, req));
}
const error = new Error('Bad Request. Survey information not complete.');
error.status = 400;
throw error;
Expand Down
2 changes: 1 addition & 1 deletion app/lib/communicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const request = require('request');
const { Auth } = require('request/lib/auth');
const TError = require('./custom-error').TranslatedError;
const config = require('../models/config-model').server;
const debug = require('debug')('enketo:openrosa-communicator');
const debug = require('debug')('openrosa-communicator');
const Xml2Js = require('xml2js');

const parser = new Xml2Js.Parser();
Expand Down
1 change: 0 additions & 1 deletion app/lib/pdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ async function get(
},
scale,
printBackground: true,
timeout,
});
} catch (e) {
e.status = e.status || 400;
Expand Down
2 changes: 1 addition & 1 deletion app/models/cache-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const utils = require('../lib/utils');

const prefix = 'ca:';
const expiry = 30 * 24 * 60 * 60;
const debug = require('debug')('enketo:cache-model');
const debug = require('debug')('cache-model');

const clientGet = promisify(cacheClient.get).bind(cacheClient);
const clientSet = promisify(cacheClient.set).bind(cacheClient);
Expand Down
2 changes: 1 addition & 1 deletion app/models/survey-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const TError = require('../lib/custom-error').TranslatedError;
const config = require('./config-model').server;

const pending = {};
const debug = require('debug')('enketo:survey-model');
const debug = require('debug')('survey-model');

/**
* @typedef {import('./account-model').AccountObj} AccountObj
Expand Down
2 changes: 0 additions & 2 deletions app/views/index.pug
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ block content
li= t("langs.sv")
when "lo"
li= t("langs.lo")
when "uk"
li= t("langs.uk")
when "sk"
li= t("langs.sk")
when "tr"
Expand Down
2 changes: 1 addition & 1 deletion app/views/surveys/webform.pug
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ block style

block script
- var suffix = (type && type !== 'single') ? '-' + (type === 'full' || type === 'preview' || type === 'fieldsubmission' ? 'oc' : type): ''
script#main-script(defer, type='module', src=`${basePath}${offlinePath || ''}/js/build/enketo-webform${suffix}.js`)
script#main-script(defer, module, src=`${basePath}${offlinePath || ''}/js/build/enketo-webform${suffix}.js`)

-// load jini stuff asynchronously (OC)
if jini && !headless
Expand Down
35 changes: 18 additions & 17 deletions config/build.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
// @ts-check

const alias = require('esbuild-plugin-alias');
const path = require('path');
const pkg = require('../package.json');

const cwd = process.cwd();

const entryPoints = pkg.entries.map((entry) => path.resolve(cwd, entry));

module.exports = /** @satisfies {import('esbuild').BuildOptions} */ ({
alias: Object.fromEntries(
Object.entries(pkg.browser).map(([key, value]) => [
key,
path.resolve(cwd, `${value}.js`),
])
),
const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
bundle: true,
chunkNames: 'chunks/[name]-[hash]',
entryPoints,
entryNames: '[name]',
external: ['crypto', 'libxslt'],
format: 'esm',
minify: true,
format: 'iife',
minify: isProduction,
outdir: path.resolve(cwd, './public/js/build'),
sourcemap: true,
splitting: true,
plugins: [
alias(
Object.fromEntries(
Object.entries(pkg.browser).map(([key, value]) => [
key,
path.resolve(cwd, `${value}.js`),
])
)
),
],
sourcemap: isProduction ? false : 'inline',
target: ['chrome89', 'edge89', 'firefox90', 'safari13'],
});
};
2 changes: 1 addition & 1 deletion config/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const errorHandler = require('../app/controllers/error-handler');

const controllersPath = path.join(__dirname, '../app/controllers');
const app = express();
const debug = require('debug')('enketo:express');
const debug = require('debug')('express');
const config = require('../app/models/config-model');

// general
Expand Down
2 changes: 1 addition & 1 deletion docs/app_controllers_api-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_api-v1-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_api-v2-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_authentication-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_error-handler.js.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/app_controllers_media-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_offline-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_pages-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_submission-controller.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_controllers_survey-controller.js.html

Large diffs are not rendered by default.

78 changes: 64 additions & 14 deletions docs/app_controllers_transformation-controller.js.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/app_lib_communicator.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_lib_custom-error.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_lib_media.js.html

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions docs/app_lib_pdf.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_lib_router-utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_lib_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_models_account-model.js.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/app_models_cache-model.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_models_config-model.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_models_instance-model.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_models_record-model.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_models_submission-model.js.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/app_models_survey-model.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/app_models_user-model.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/global.html

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions docs/index.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-account-model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-api-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-api-v1-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-api-v2-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-authentication-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-cache-model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-communicator.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-config-model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-custom-error.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-duplicates.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-error-handler.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-instance-model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-media-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-offline-resources-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-pages-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-pdf.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-router-utils.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-submission-model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-submissions-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-survey-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-survey-model.html

Large diffs are not rendered by default.

178 changes: 166 additions & 12 deletions docs/module-transformation-controller.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-user-model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-utils.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tools_duplicates.js.html

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions docs/tutorial-00-getting-started.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-02-heroku.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-10-configure.html

Large diffs are not rendered by default.

Loading

0 comments on commit eb3b67b

Please sign in to comment.