{"version":3,"sources":["webpack:///./src/services/api/feathers.ts","webpack:///./src/services/api/hooks/files/getExcelJson.ts","webpack:///./src/services/api/hooks/convertJsonQuery.ts","webpack:///./src/services/api/hooks/convertResult.ts","webpack:///./src/services/api/file.ts","webpack:///./src/services/assets/ProjectBreadcrumbs.ts","webpack:///./src/services/actions/tasks/GenerateCSV.ts","webpack:///./src/services/actions/tasks/GenerateKoboURL.ts","webpack:///./src/services/actions/tasks/GeneratePDF.ts","webpack:///./src/services/actions/tasks/Populate.ts","webpack:///./src/services/actions/tasks/Query.ts","webpack:///./src/services/actions/tasks/SaveFile.ts","webpack:///./src/services/actions/tasks/EditDFPForm.ts","webpack:///./src/services/actions/tasks/ExecuteJob.ts","webpack:///./src/services/actions/ActionService.ts","webpack:///./src/services/api/authentication.ts","webpack:///./src/services/assets/ActiveAssets.ts","webpack:///./src/services/api/hooks/files/dataUriToBlob.ts","webpack:///./src/services/api/hooks/omitHiddenProps.ts","webpack:///./src/services/api/hooks/omitProps.ts","webpack:///./src/services/api/hooks/parseId.ts","webpack:///./src/services/api/hooks/idb.ts","webpack:///./src/services/api/OfflineService.ts","webpack:///./src/services/api/DatafiProAPI.ts","webpack:///./src/services/api/hooks/convertInt.ts","webpack:///./src/services/api/hooks/omitGeomIfBinary.ts","webpack:///./src/services/api/hooks/omitEmpty.ts","webpack:///./src/resources/binding-behaviors/stop-propagation.ts","webpack:///./src/resources/validation/matchesProperty.ts","webpack:///./src/resources/validation/json.ts","webpack:///./src/resources/index.ts","webpack:///./src/resources/value-converters/array.ts","webpack:///./src/resources/value-converters/date-format.ts","webpack:///./src/resources/value-converters/default.ts","webpack:///./src/resources/value-converters/file-icon.ts","webpack:///./src/resources/value-converters/group.ts","webpack:///./src/resources/value-converters/has-permission.ts","webpack:///./src/resources/value-converters/job-status.ts","webpack:///./src/resources/value-converters/json.ts","webpack:///./src/resources/value-converters/keys.ts","webpack:///./src/resources/value-converters/number.ts","webpack:///./src/resources/value-converters/object-key.ts","webpack:///./src/resources/value-converters/purify-html.ts","webpack:///./src/resources/value-converters/round.ts","webpack:///./src/resources/value-converters/title.ts","webpack:///./src/resources/value-converters/unknown.ts","webpack:///./src/services/api/util/jobs/getJobresult.ts","webpack:///./src/services/api/hooks/log.ts","webpack:///./src/services/api/hooks/files/xform/xformSchema.ts"],"names":["getLogger","createApp","config","opt","storageKey","app","TRANSPORT","configure","API_HOST","fetch","global","socket","transports","timeout","hooks","before","all","create","context","Array","isArray","data","File","Object","assign","patch","update","error","setPrototypeOf","log","getExcelJson","file","blob","uri","then","result","errors","length","rows","convertJsonQuery","params","query","keys","forEach","key","startsWith","value","getQueries","obj","parent","map","path","type","join","reduce","currentArray","concat","item","find","convertResult","hasOwnProperty","k","FileService","createFileService","base","defaultApp","axiosInstance","axios","event","debug","fileService","emit","service","set","auth","authentication","getAccessToken","headers","Authorization","items","FormData","append","id","after","ProjectBreadcrumbsService","program","excludeFieldRegex","fields","getFields","this","target","rowsField","getRows","labels","f","label","unparse","Blob","firstRow","filter","field","test","rawValue","name","format","toView","prev","current","childRows","rowItems","$root","row","getRowValue","ea","api","programSurvey","programSurveys","get","surveyId","survey","urlResult","edit","getEditUrl","getNewSurveyUrl","detail","Error","tab","window","open","url","iframe","warn","publish","src","title","targetIdField","_id","survey_type","formUrls","fileId","survey_id","instanceId","projectname","program_id","load","targetFields","actionFields","baseUrl","urlType","getUrlFragment","project_name","__expanded","fieldName","formFieldName","indexOf","split","encodeURIComponent","DatafiProAPI","ActiveProgram","GenerateKoboURL","attachments","Promise","populateAttachments","viewModel","fixObjectArrays","jobData","template","version","objects","timezone","Intl","DateTimeFormat","resolvedOptions","timeZone","jobs","job","record","attachmentsService","_attachments","att","filename","$url","catch","e","files","foundFile","arrays","arrayField","arrayValue","GeneratePDF","populate","populateObjects","queries","populateObject","populateParams","nameAs","serviceMethod","serviceArgs","getArguments","isPrimitive","resultQueries","resultData","index","param","object","childField","parentField","Populate","defaultQuery","$limit","appService","queryValues","from","Set","$in","recursive","Query","regex","match","replacedString","exec","replacement","firstTarget","date","Date","isNaN","getTime","day","getDate","toString","padStart","getMonth","getFullYear","undefined","replace","promise","resolve","dataUriToBlob","newName","customFileName","options","programId","programs","project","projectId","projects","formSubmission","formSubmissionId","formSubmissions","getDefaults","defaults","defaultsParam","URLSearchParams","encodeURI","ExecuteJob","di","subscribe","Events","APP_ACTION_START","handleAction","bind","registerSingleton","actionData","getStandardActionData","updateTargetStatus","t","__status","PENDING","getTask","task","executeTask","executeResult","status","SUCCESS","FAILED","resultEvent","APP_ACTION_SUCCESS","APP_ACTION_FAIL","logMethod","APP_ACTION_END","APP_ACTION_PENDING","dynamic","getDynamicData","ensureArray","serialize","dynamicProps","newData","info","execute","getTaskResult","newResult","next","nextAction","nextTarget","targetType","TARGET_FROM_FIRST_TARGET","TARGET_FROM_LAST_TARGET","TARGET_FROM_LAST_RESULT","nextActionData","AuthenticationService","browserStorage","flags","cookie","defaultParams","$eager","authPromise","reAuthenticate","updateAuth","creds","authenticate","logout","force","strategy","accessToken","jwtStrategy","code","res","me","updateCookie","authResult","user","updateUnleashUser","document","expires","now","toUTCString","location","hostname","ActiveAssetsService","assets","counter","r","a","metadata","id_title","createAsset","generateId","activeAsset","dataURI","mime","binary","atob","array","i","push","charCodeAt","Uint8Array","RE","omitHiddenProps","contextProps","omittables","omitProps","propsToOmit","prop","parseId","p","parseInt","setCacheData","db","storeName","serviceParts","getStoreName","$client","dataStoreName","setInterval","sync","offline_storage_enabled","connected","serviceName","online","pendingRows","$lt","pending","created","local","remove","evt","handler","on","off","DB","FeatureFlags","container","io","handleConnectionStatus","arcGISSources","events","createService","organizations","programAssets","programAssetTypes","programConfigs","omitRelations","convertArea","convertInt","projectFiles","omitGeom","geomField","pinnedId","pins","pinId","pinnedProjects","_pinned","geocode","programSecrets","programUsersRoles","programWebhooks","roles","secrets","tokens","usersRoles","omitRole","users","omitRoles","omitWhenEmpty","hasValue","omitEmpty","authManagement","AppConfig","BrowserStorage","StopPropagationBindingBehavior","binding","source","standardCallSource","callSource","stopPropagation","customRule","otherPropertyName","globalResources","JSON","parse","ArrayValueConverter","includes","DateValueConverter","toDate","DefaultValueConverter","defaultValue","FileIconValueConverter","GroupValueConverter","values","HasPermissionValueConverter","args","perm","returnValue","JobStatusValueConverter","JsonValueConverter","stringify","KeysValueConverter","Reflect","ownKeys","NumberValueConverter","parseFloat","ObjectKeyValueConverter","purifyHTMLValueConverter","RoundValueConverter","places","multiplier","Math","pow","round","TitleValueConverter","UnknownValueConverter","prototype","getJobResult","maxPollCount","reject","pollCount","interval","clearInterval","$select","jobResult","logger","props","level","method","xFormSchema","String","hint","guidance_hint","appearance","required","required_message","default","relevant","calculation","constraint","constraint_message","readonly","repeat_count","Number","image","audio","video","parameters","xformChoicesSchema","list_name"],"mappings":"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","file":"app~c714bc7b.e702ccf9587a34a08c44.chunk.js","sourcesContent":["import feathers, { Application, HookContext } from '@feathersjs/feathers';\nimport socketio from '@feathersjs/socketio-client';\nimport auth from '@feathersjs/authentication-client';\nimport io from 'socket.io-client';\nimport restClient from '@feathersjs/rest-client';\nimport { omitHiddenProps } from './hooks/omitHiddenProps';\nimport { log as logHook } from './hooks/log';\nimport omit from 'lodash.omit';\nimport { AppConfig } from '../../services/util/AppConfig';\nimport { convertJsonQuery } from './hooks/convertJsonQuery';\nimport { LogManager } from 'aurelia-framework';\nconst log = LogManager.getLogger('dfp:actions');\n\nexport type TransportType = 'rest' | 'socketio';\nexport interface AppOptions {\n    storageKey?: string;\n}\n\nexport function createApp(config: Partial<AppConfig>, opt?:AppOptions ): Application{\n\n    opt = {\n        storageKey: 'auth',\n        ...opt,\n    };\n\n    const app = feathers();\n\n    if (config.TRANSPORT === 'rest') {\n        app.configure(restClient(config.API_HOST).fetch(global.fetch));\n    } else {\n        const socket = io(config.API_HOST, {\n            transports: [\n                'websocket',\n                'polling',\n            ],\n        });\n        app.configure(socketio(socket, { timeout: 500000 }));\n    }\n\n    app.configure(auth({\n        storageKey: opt.storageKey,\n    }));\n\n    app.hooks({\n        before: {\n            // UNCOMMENT this to log all api requests\n            all: [\n                logHook('params.query', 'data'),\n                convertJsonQuery,\n            ],\n            create: [\n                omitHiddenProps('data'),\n                (context) => {\n                    // TODO handle arrays\n                    if (Array.isArray(context.data)) {\n                        return;\n                    }\n\n                    // omit processing of files\n                    if (context.data instanceof File) {\n                        return;\n                    }\n\n                    Object.assign(context.data, omit(context.data, ['id']));\n                },\n            ],\n            patch: [\n                omitHiddenProps('data'),\n            ],\n            update: [\n                omitHiddenProps('data'),\n            ],\n        },\n        error: {\n            all: [logHook('error')],\n        },\n    });\n\n    Object.setPrototypeOf(app, Object);\n\n    return app;\n}\n","import { APIFile } from '@wsb_dev/datafi-shared/lib/types/File';\nimport { dataUriToBlob } from './dataUriToBlob';\nimport readXlsxFile from 'read-excel-file';\nimport { LogManager } from 'aurelia-framework';\n\nconst log = LogManager.getLogger('dfp:xcel');\n\nexport function getExcelJson(file: APIFile, opt): Promise<Record<string, any>[]>{\n    const blob = dataUriToBlob(file.uri as string);\n    return readXlsxFile(blob as File, opt).then((result) => {\n        if(result.errors?.length){\n            log.error('xcel errors', ...result.errors);\n        }\n        return result.rows;\n    });\n}\n","import { HookContext } from '@feathersjs/feathers';\n\nfunction getQueries(obj, parent?: string) {\n    return Object.keys(obj)\n        .map((key) => {\n\n            const value = obj[key];\n            if (typeof value === 'undefined') {\n                return [];\n            }\n\n            if (key.startsWith('$')) {\n                return parent ?\n                    [{ path: parent, value: { [key]: value } }] :\n                    [{ path: key, value }];\n            }\n\n            const path = parent ? `${parent}.${key}` : key;\n\n            if (Array.isArray(value)) {\n                const type = typeof value[0];\n                if (type === 'string' || type === 'number') {\n                    return [{ path, value: value.join(',') }];\n                }\n            }\n\n            if (typeof value === 'object') {\n                return getQueries(value, path);\n            }\n            return [{ path, value }];\n        })\n        .reduce((result, currentArray) => {\n            return result.concat(currentArray);\n        }, []);\n}\n\nexport function convertJsonQuery(context: HookContext) {\n    const operators = ['$gt', '$gte', ''];\n    if (!context.params.query) {\n        return context;\n    }\n    Object.keys(context.params.query).forEach((key) => {\n        if (key.startsWith('$')) {\n            return;\n        }\n\n        const value = context.params.query[key];\n        if (typeof value !== 'object') {\n            return;\n        }\n\n        context.params.query[key] = {};\n\n        getQueries(value).forEach((item) => {\n            if (Object.keys(item.value).find((key) => key.startsWith('$'))) {\n                context.params.query[key][item.path] = {\n                    ...item.value,\n                    ...context.params.query[key][item.path],\n                };\n            } else {\n                context.params.query[key][item.path] = item.value;\n            }\n        });\n    });\n\n    return context;\n}\n","import { HookContext } from '@feathersjs/feathers';\n\n/**\n * Takes a result object and looks for an Array-like object.\n * If this is found, the result is converted to an array.\n * This happens in some cases where arrays in multi-creates get converted to\n * ```\n * {\n *      \"0\": \"...\",\n *      \"1\": \"...\",\n *      ...\n * }\n * ```\n * @param context Current hook context\n * @returns Hook context, modified if necessary\n */\nexport function convertResult(context: HookContext): HookContext {\n    // handle multi creates\n    if (context.result.hasOwnProperty('0')) {\n        context.result = Object.keys(context.result).map(\n            (k) => context.result[k],\n        );\n    }\n\n    return context;\n}\n","import { Application, HookContext } from '@feathersjs/feathers';\nimport { Service } from '@feathersjs/feathers';\nimport { APIFile } from '@wsb_dev/datafi-shared/lib/types/File';\nimport { convertResult } from './hooks/convertResult';\nimport feathers from '@feathersjs/feathers';\nimport restClient from '@feathersjs/rest-client';\nimport axios from 'axios';\nimport { LogManager } from 'aurelia-framework';\n\nconst log = LogManager.getLogger('dfp:file');\n\n/**\n * Dispatched when upload progress occurs\n *\n * @example\n *\n * ```\n * fileService.on('uploadprogress', (event) => ...);\n * ```\n * @event\n */\nexport const UPLOAD_PROGRESS = 'uploadprogress';\n/**\n  * Dispatched when download progress occurs\n  *\n  * @example\n  *\n  * ```\n  * fileService.on('downloadprogress', (event) => ...);\n  * ```\n  *\n  * @event\n  */\nexport const DOWNLOAD_PROGRESS = 'downloadprogress';\nexport interface FileService extends Service<APIFile> {}\nexport class FileService {}\n\nexport function createFileService(base: string, defaultApp: Application): FileService {\n\n    const app = feathers();\n\n    const axiosInstance = axios.create({\n        onUploadProgress(event) {\n            log.debug('upload progress', event);\n            fileService.emit(UPLOAD_PROGRESS, event);\n        },\n        onDownloadProgress(event) {\n            log.debug('download progress', event);\n            fileService.emit(DOWNLOAD_PROGRESS, event);\n        },\n    });\n\n    app.configure(restClient(base).axios(axiosInstance));\n\n    /**\n * File service for uploading files\n */\n    const fileService: FileService = app.service('api/v1/files');\n\n    const BATCH_SIZE = 4;\n    app.set('batchSize', BATCH_SIZE);\n\n    fileService.hooks({\n        before: {\n            all: [\n                async function addTokenHeader(context: HookContext) {\n                    const auth = await defaultApp.authentication.getAccessToken();\n                    context.params.headers = {\n                        ...context.params.headers,\n                        Authorization: `Bearer ${auth}`,\n                    };\n                },\n            ],\n            create: [\n                (context: HookContext) => {\n                    const items = (\n                        Array.isArray(context.data) ?\n                            context.data : [context.data]\n                    ).map((item) => {\n                        if(item instanceof File){\n                            return {file: File};\n                        }\n                        return item;\n                    });\n\n                    const data = new FormData();\n                    const formProp = 'uri';\n\n                    items.forEach((item) => {\n                        data.append(formProp, item.file);\n                        if (item.id) {\n                            data.append('id', item.id);\n                        }\n                    });\n\n                    context.data = data;\n                    context.params.headers = {\n                        ...context.params.headers,\n                        'Content-Type': 'multipart/form-data',\n                    };\n                },\n            ],\n\n        },\n        after: {\n            create: [convertResult],\n        },\n    });\n\n    return fileService;\n}\n","import { ProgramAssetType, ProgramSurvey, Project } from '@wsb_dev/datafi-shared/lib/types';\nimport { inject } from 'aurelia-dependency-injection';\nimport { ActiveProgram } from '../util/ActiveProgram';\n\n@inject(\n    ActiveProgram,\n)\n/**\n * A shared service to store actively selected surveys, projects, and assets.\n * Used to provide context to the breadcrumb links\n */\nexport class ProjectBreadcrumbsService {\n    /**\n     * The currently selected survey item.\n     * Used when the user clicks on a survey item from the survey list\n     */\n    survey?: ProgramSurvey;\n    /**\n     * Value true if the surveyList or survey have been visited.\n     */\n    surveyList?: boolean;\n    /**\n     * The currently selected project.\n     * Used when the user clicks on a project from the project list.\n     */\n    project?: Project;\n    /**\n     * Actively selected asset type - used when a user clicks on\n     * an item from the asset type list.\n     */\n    assetType?: ProgramAssetType;\n\n    constructor(private program: ActiveProgram){}\n}\n","import { GenerateCSVData } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport {Task} from './Task';\nimport papa from 'papaparse';\nimport get from 'lodash.get';\nimport { Field } from '@wsb_dev/datafi-shared/lib/types/Field';\nimport { getFields } from '@wsb_dev/datafi-shared/lib/util/fields/getFields';\nimport { DateValueConverter } from '../../../resources/value-converters/date-format';\nimport { LogManager } from 'aurelia-framework';\n\nconst log = LogManager.getLogger('dfp:actions');\n\nconst excludeFieldRegex = /(meta|uuid)/gi;\nexport default class GenerateCSVTask implements Task {\n\n    async execute(data: GenerateCSVData) {\n\n        // get the csv data\n        const fields: Field[] = getFields(data.fields) || this.getFields(data.target, data.rowsField);\n        const rows = this.getRows(data.target, data.rowsField, fields);\n        const labels = fields.map((f) => f.label);\n\n        // export blob\n        const result = papa.unparse({\n            fields: labels,\n            data: rows,\n        });\n        log.debug('csv result', result);\n        const blob = new Blob([result], { type: 'text/csv;charset=utf-8;' });\n\n        return { file: blob };\n    }\n\n    getFields(target: any[], rowsField?: string):Field[] {\n        // get fields from action data or the first row\n        if (rowsField) {\n            target = target.find((item) => !!item[rowsField])?.[rowsField];\n        }\n        const firstRow = (Array.isArray(target) ?\n            target[0] :\n            target) || {};\n\n        const fields = Object.keys(firstRow)\n            .filter((field) => {\n                // exclude if string has _ or kobo / in it\n                return !(\n                    field.startsWith('_') ||\n                    excludeFieldRegex.test(field)\n                );\n            });\n\n        return getFields(fields);\n    }\n\n    getRowValue(item: Record<string, any>, field: Field) {\n        const rawValue = get(item, field.name);\n        if(field.type === 'date'){\n            const format = field.format;\n            return new DateValueConverter().toView(rawValue, format);\n        }\n\n        return rawValue;\n    }\n\n    getRows(data: any[], rowsField: string, fields: Field[]): any[][] {\n\n        // build the csv\n        /**\n         * data: [{\n         *      id: 1,\n         *      items: [{ }]\n         * }]\n         * rowsField: 'items'\n         */\n        const items: Record<string, any>[] = data.reduce((prev: any[], current: Record<string, any>) => {\n\n            // first get child rows\n            let childRows = rowsField ?\n                get(current, rowsField) :\n                [current];\n\n            if (!childRows) childRows = [];\n            if(!Array.isArray(childRows)) childRows = [childRows];\n\n            // convert them to row items\n            const rowItems = childRows.map((item: Record<string, any>) => {\n                const result = {\n                    ...current,\n                    ...item,\n                };\n                // backwards compatibility\n                result.$root = current;\n\n                return result;\n\n            });\n\n            // reduce the result to a single array\n            return prev.concat(rowItems);\n        }, []);\n\n        log.debug('[GenerateCSV]: ', items, fields);\n\n        // iterate through each item\n        // build a row from each field\n        return items.map((row) => fields.map((field) => this.getRowValue(row, field)));\n    }\n}\n","import { EventAggregator } from 'aurelia-event-aggregator';\nimport { autoinject, LogManager } from 'aurelia-framework';\nimport { GenerateKoboURLData } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport get from 'lodash.get';\nimport defaults from 'lodash.defaults';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nimport { ActiveProgram } from '../../../services/util/ActiveProgram';\n\nconst log = LogManager.getLogger('dfp:kobo');\n\ninterface URLResult {\n    url: string;\n    name?: string;\n    detail?: string;\n}\n\n@autoinject\nexport default class GenerateKoboURLTask {\n    constructor(\n        private ea: EventAggregator,\n        private api: DatafiProAPI,\n        private program: ActiveProgram,\n    ) { }\n\n    async execute(data: GenerateKoboURLData): Promise<{ url: string }> {\n        const target = data.target[0] || {};\n\n        const programSurvey = await this.api.programSurveys.get(data.surveyId);\n        data.survey = programSurvey;\n\n        const urlResult = await (\n            data.edit ?\n                this.getEditUrl(target, data) :\n                this.getNewSurveyUrl(target, data)\n        );\n\n        if (urlResult.detail) {\n            throw new Error(urlResult.detail);\n        }\n\n        if (data.tab) {\n            window.open(urlResult.url);\n        }\n\n        //TODO remove data.open\n        else if (data.iframe || data.open) {\n            if (data.open) {\n                log.warn('GenerateKoboUrl `open` is deprecated. Use `iframe` instead');\n            }\n            // window.location.href = urlResult.url;\n            this.ea.publish('iframe', {\n                src: urlResult.url,\n                title: urlResult.name,\n            });\n        }\n        return urlResult;\n    }\n\n    async getEditUrl(target: Record<string, any>, data: GenerateKoboURLData): Promise<URLResult> {\n\n        const id = target[data.targetIdField] || target.id || target._id;\n        if (!id) {\n            throw new Error('Row is missing unique ID value');\n        }\n\n        const surveyId = data.surveyId;\n\n        if (!surveyId) {\n            throw new Error('Survey could not be found');\n        }\n\n        let urlResult;\n        if (data.survey.survey_type === 'dfp-form') {\n            urlResult = await this.api.formUrls.create({\n                fileId: data.survey.survey_id,\n                instanceId: id,\n                type: 'edit_url',\n            });\n\n        }\n\n        return {\n            ...urlResult,\n            name: `Edit form: ${target.projectname || ''} (${id})`,\n        };\n    }\n\n    async getNewSurveyUrl(target: Record<string, any>, data: GenerateKoboURLData): Promise<URLResult> {\n        // check program_id matches\n        if (this.program?.id !== data.survey?.program_id && data.survey?.program_id) {\n            log.warn(`GenerateKoboUrl: Program id ${this.program.id} doesn't not match survey id ${data.survey.program_id}. Reloading program.`);\n            await this.program.load(data.survey.program_id);\n        }\n\n        const { targetFields, actionFields } = defaults(data, {\n            program: this.program,\n            targetFields: { id: 'project_id' },\n            actionFields: {\n                'survey.id': 'survey_id',\n                [data.survey?.program_id ? 'survey.program_id' : 'program.id']: 'program_id',\n                'auth.user.email': 'email',\n                'auth.user.fullname': 'fullname',\n                'auth.user.id': 'userId',\n                'auth.user.username': 'username',\n            },\n        } as Partial<GenerateKoboURLData>);\n        let baseUrl;\n        const programSurvey = await this.api.programSurveys.get(data.surveyId);\n        if (programSurvey.survey_type === 'dfp-form') {\n            const result = await this.api.formUrls.create({\n                fileId: programSurvey.survey_id,\n                type: data.urlType || 'single_url',\n            });\n            baseUrl = result.url;\n        }\n        if (!baseUrl) {\n            throw new Error('Form URL could not be found');\n        }\n        const surveyUrl = baseUrl + '?' +\n            // get fields from app context\n            this.getUrlFragment(data, actionFields) +\n            this.getUrlFragment(target, targetFields);\n        return {\n            url: surveyUrl,\n            name: `New Form: ${data.target?.[0]?.project_name || 'Blank'}`,\n        };\n    }\n\n    getUrlFragment(context: any, fields: Record<string, string>) {\n        let url = '';\n        if (fields) {\n            delete fields.__expanded;\n            Object.keys(fields).forEach((field) => {\n                const fieldName = fields[field];\n                const formFieldName = fieldName.indexOf('.') > -1 ?\n                    fieldName.split('.')[1] :\n                    fieldName;\n                const value = get(context, field);\n                if (value) {\n                    url += `&d[${formFieldName}]=${encodeURIComponent(value)}`;\n                } else {\n                    log.warn(`Target field ${field} was undefined`);\n                }\n            });\n        }\n        return url;\n    }\n}\n","import { APIFile } from '@wsb_dev/datafi-shared/lib/types/File';\nimport { ReportJobData } from '@wsb_dev/datafi-shared/lib/types/jobs/ReportJobData';\nimport { LogManager, autoinject } from 'aurelia-framework';\nimport { Job } from '@wsb_dev/datafi-shared/lib/types/Job';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nimport { Field, GeneratePDFActionData } from '@wsb_dev/datafi-shared/lib/types';\nimport { getJobResult } from '../../../services/api/util/jobs/getJobresult';\nimport get from 'lodash.get';\nimport set from 'lodash.set';\n\nconst log = LogManager.getLogger('dfp:actions');\n\n@autoinject\nexport default class GeneratePDFTask {\n    constructor(\n        private api: DatafiProAPI,\n    ) {}\n    async execute(data: GeneratePDFActionData): Promise<APIFile|Error> {\n        if(data.attachments){\n            await Promise.all(data.target.map((item) => this.populateAttachments(item)));\n        }\n\n        if(data.viewModel.fields){\n            data.target = this.fixObjectArrays(data.target, data.viewModel.fields);\n        }\n\n        const jobData = {\n            name: data.template || data.name,\n            format: data.format,\n            version: data.version,\n            data: {\n                objects: data.target,\n                timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone,\n            },\n        };\n\n        return this.api.jobs.create({\n            name: 'report',\n            data: jobData,\n        } as Job<ReportJobData>)\n            .then((job) => getJobResult(this.api.jobs, job))\n            .then((job) => job.result);\n    }\n\n    populateAttachments(record: Record<string, any>): Promise<void>{\n        const attachmentsService = record.attachments?.length ?\n            'api/v1/files' :\n            record._attachments?.length ?\n                'api/v2/surveys-media' :\n                null;\n\n        if(!attachmentsService){\n            return;\n        }\n\n        const service = this.api.app.service(attachmentsService);\n        const attachments = record.attachments || record._attachments || [];\n\n        return Promise.all(attachments.map((att) => {\n            const fileId = attachmentsService === 'api/v1/files' ?\n                att.id :\n                att.filename;\n\n            return service.get(fileId, {query: {$url: true}})\n                .catch((e) => undefined);\n        }))\n            .then((files) => {\n                files = files.filter((f) => !!f);\n                attachments.forEach((att) => {\n                    const fileId = attachmentsService === 'api/v1/files' ?\n                        att.id :\n                        att.filename;\n\n                    const foundFile = files.find((file) => file.id === fileId);\n                    att.url = foundFile?.url;\n                });\n            });\n    }\n\n    fixObjectArrays(rows: Record<string, any>[], fields: Field[]): Record<string, any>[] {\n        const arrays = fields.filter((field) => field.type === 'array');\n\n        rows.forEach((row) => {\n            arrays.forEach((arrayField) => {\n                const arrayValue = get(row, arrayField.path);\n                if(Array.isArray(arrayValue)){\n                    return;\n                }\n\n                if(!arrayValue){\n                    return;\n                }\n\n                log.debug(`fixing invalid array field ${arrayField.path}`, arrayValue);\n                set(row, arrayField.path, [arrayValue]);\n            });\n        });\n\n        return rows;\n    }\n}\n","import { PopulateActionData } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport { PopulateDataParam } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport {Task} from './Task';\nimport { Service } from '@feathersjs/feathers';\nimport { isPrimitive } from '../../../util/objects/isPrimitive';\nimport { LogManager, inject } from 'aurelia-framework';\nimport { DatafiProAPI } from '../../api/DatafiProAPI';\nimport set from 'lodash.set';\nconst log = LogManager.getLogger('dfp:actions');\n\n@inject(\n    DatafiProAPI,\n)\nexport default class PopulateTask implements Task {\n    constructor(private api: DatafiProAPI) { }\n    execute(params: PopulateActionData) {\n        const { target, populate } = params;\n        return this.populateObjects(target, populate);\n    }\n\n    async populateObjects(objects: any[], queries: PopulateDataParam[] = []): Promise<any[]> {\n        return Promise.all(objects.map((obj) => this.populateObject(obj, queries)));\n    }\n\n    populateObject<T>(obj: any, populateParams: PopulateDataParam[]): Promise<T[]> {\n        return Promise.all(populateParams.map((params: PopulateDataParam) => {\n\n            // if key is present already, just return that data structure populated\n            if (obj[params.nameAs]) {\n                return this.populateObjects(obj[params.nameAs], params.populate);\n            }\n\n            if(!params.service){\n                return [];\n            }\n\n            // call the service method required with the required arguments\n            const service = this.api.app.service(params.service) as Service<T>;\n            const serviceMethod = params.serviceMethod || 'find';\n            const serviceArgs = this.getArguments(serviceMethod, obj, params);\n\n            // return the result and populate sub-queries\n            return service[serviceMethod](...serviceArgs).then((result: any) => {\n\n                // get data from paginated and non paginated results\n                // check for primitive types\n                let data = result.data ? result.data : result;\n                if (isPrimitive(data)) {\n                    return data;\n                }\n\n                // convert to array for consistency\n                if(!data){\n                    data = [];\n                } else if(!Array.isArray(data)){\n                    data = [data];\n                }\n                return this.populateObjects(data, params.populate);\n            })\n                .catch((e) => {\n                    log.error(e);\n                    return obj;\n                });\n\n        })).then((resultQueries) => {\n            const resultData = {\n                ...obj,\n            };\n            resultQueries.forEach((result, index) => {\n                const param = populateParams[index];\n                resultData[param.nameAs || param.service] = result;\n            });\n\n            return resultData;\n        });\n    }\n\n    getArguments(serviceMethod: string, object: any, params: PopulateDataParam) {\n        return serviceMethod === 'find' ?\n            [{\n                ...params.params,\n                query: {\n                    ...params.params?.query,\n                    ...set(params.params?.query, params.childField, object[params.parentField]),\n                },\n            }] :\n            [\n                object[params.parentField],\n                { ...params.params },\n            ];\n    }\n}\n","import { recursiveQuery } from '../../../util/query/recursive';\nimport { Query, Service } from '@feathersjs/feathers';\nimport { LogManager, autoinject } from 'aurelia-framework';\nimport { RequestData } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport {Task} from './Task';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nconst log = LogManager.getLogger('dfp:actions');\n\n@autoinject\nexport default class QueryTask implements Task<RequestData> {\n    constructor(private api: DatafiProAPI) { }\n    async execute(data: RequestData) {\n        const { parentField, childField, target, service, defaultQuery } = data;\n        const query: Query = {\n            ...defaultQuery,\n            $limit: 1000,\n        };\n\n        const appService = this.api.app.service(service) as Service<any>;\n        if (parentField && childField) {\n            const queryValues = Array.from(\n                new Set(\n                    target\n                        .map((row) => {\n                            const value = row[parentField];\n                            if (typeof value === 'undefined') {\n                                log.warn(`Row is missing parentField<${parentField}>`, row);\n                            }\n                            return value;\n                        })\n                        .filter((value) => !!value),\n                ),\n            );\n\n            query[childField] = queryValues.length === 1 ?\n                queryValues[0] :\n                { $in: queryValues };\n        }\n\n        return recursiveQuery(appService, query, []);\n    }\n}\n","import { Task } from './Task';\n\nimport * as fileSaver from 'file-saver';\nimport { SavableFile, SaveFileActionData } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport { autoinject} from 'aurelia-framework';\nimport { APIFile } from '@wsb_dev/datafi-shared/lib/types/File';\nimport { dataUriToBlob } from '../../../services/api/hooks/files/dataUriToBlob';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nimport _ from 'lodash';\n\n@autoinject\n\nexport default class SaveFile implements Task {\n    constructor(private api: DatafiProAPI) { }\n\n    customFileName(data: SaveFileActionData): string {\n        const regex = /%([^%]+)%/g;\n        let match;\n        let replacedString = data.name;\n\n        while ((match = regex.exec(data.name)) !== null) {\n            let replacement = _.get(data.firstTarget[0], match[1]);\n            const isNumber = /^[0-9]+$/.test(replacement);\n\n            if (!isNumber) {\n                const date = new Date(replacement);\n                if (!isNaN(date.getTime()) && date !== null) {\n                    const day = date.getDate().toString().padStart(2, '0');\n                    const month = (date.getMonth() + 1).toString().padStart(2, '0');\n                    const year = date.getFullYear();\n\n                    replacement = `${month}-${day}-${year}`;\n                }\n            }\n\n            if (replacement !== undefined) {\n                // Replace each template with its target name\n                replacedString = replacedString.replace(match[0], replacement);\n            }\n        }\n        return replacedString;\n    }\n\n    async execute(data: SaveFileActionData): Promise<void> {\n        const promise: Promise<SavableFile[]> = data.file ?\n            Promise.resolve([data.file]) :\n            Promise.all(data.target.map((item: any) => {\n                if (item.file) {\n                    return item.file;\n                }\n                return this.api.files\n                    .get((item as APIFile).id, { query: { $url: true } })\n                    .then((result: APIFile) => {\n                        if (result.url?.startsWith('data:')) {\n                            return dataUriToBlob(result.url);\n                        } else if (result.url?.startsWith('http')) {\n                            return fetch(result.url).then((data) => data.blob());\n                        } else {\n                            throw new Error('File could not be downloaded');\n                        }\n                    });\n            }));\n\n        const newName = this.customFileName(data);\n\n        const files = await promise;\n        files.forEach((file: any) => {\n            fileSaver.saveAs(\n                file,\n                file.name || newName,\n                data.options);\n        });\n    }\n}\n","import { EditDFPFormData } from '@wsb_dev/datafi-shared/lib/types';\nimport { Task } from './Task';\nimport { DatafiProAPI } from '../../api/DatafiProAPI';\nimport { autoinject } from 'aurelia-dependency-injection';\nimport get from 'lodash.get';\nimport { LogManager } from 'aurelia-framework';\nimport { FormSubmission } from '@wsb_dev/datafi-shared/lib/types/FormSubmission';\n\nconst log = LogManager.getLogger('dfp:actions');\ninterface URLResult {\n    url: string;\n    name?: string;\n    detail?: string;\n}\n\n@autoinject\nexport default class EditDFPForm implements Task {\n    constructor(\n        private api: DatafiProAPI,\n    ) { }\n    async execute(data: EditDFPFormData) {\n        data.program = await (data.program || (data.programId ? this.api.programs.get(data.programId) : null));\n        data.survey = await (data.survey || (data.surveyId ? this.api.programSurveys.get(data.surveyId) : null));\n        data.project = await (data.project || (data.projectId ? this.api.projects.get(data.projectId) : null));\n        data.formSubmission = await (data.formSubmission || (data.formSubmissionId ? this.api.formSubmissions.get(data.formSubmissionId) : null));\n\n        // determine if target is a formSubmission\n        if (data.target[0] as FormSubmission) {\n            // not ideal, but if the target has an attachments property, its probably a form submission\n            // when we develop editing capabilities, maybe we can get and validate an instanceId instead\n            data.formSubmission = data.target[0].attachments ? data.target[0] : null;\n        }\n        const urlResult = await ( data.formSubmission ? this.getEditUrl(data) : this.getNewSurveyUrl(data));\n        window.open(urlResult.url);\n    }\n\n    async getEditUrl(data: EditDFPFormData): Promise<URLResult> {\n\n        const baseUrl = `/dfp-form/program/${data.formSubmission.program_id || data.formSubmission.programId}/survey/${data.surveyId}`;\n        const metadataParam = `/submissionId=${data.formSubmission.id}`;\n        const surveyURL = baseUrl + metadataParam;\n\n        // url to edit existing survey\n        return {\n            url: surveyURL,\n            name: `Edit Form: ${data.target?.[0]?.project_name || 'Blank'}`,\n        };\n    }\n\n    async getNewSurveyUrl(data: EditDFPFormData): Promise<URLResult> {\n        // define base url\n        const baseUrl = `/dfp-form/program/${data.program.id || data.programId}/survey/${data.surveyId}`;\n        //get defaults as metadata url string\n        const metadataUrl = this.getDefaults(data);\n        //return url object\n        return {\n            url: baseUrl + metadataUrl,\n            name: `New Form: ${data.target?.[0]?.project_name || 'Blank'}`,\n        };\n    }\n\n    getDefaults(data: EditDFPFormData) {\n        const defaults = {};\n        if (data.actionFields) {\n            Object.keys(data.actionFields).forEach((field) => {\n                const result = get(data, data.actionFields[field]);\n                if (result) {\n                    defaults[field] = result;\n                }\n            });\n        }\n\n        log.debug('populating defaults', defaults);\n\n        const defaultsParam = new URLSearchParams(defaults).toString().replace(/\\./g, '%2e');\n        return `/${encodeURI(defaultsParam)}`;\n    }\n}\n","import { APIFile } from '@wsb_dev/datafi-shared/lib/types/File';\nimport { ExecuteJobData } from '@wsb_dev/datafi-shared/lib/types/ActionTaskTypes';\nimport { inject } from 'aurelia-framework';\nimport { DatafiProAPI } from '../../api/DatafiProAPI';\nimport { getJobResult } from '../../api/util/jobs/getJobresult';\n\n@inject(DatafiProAPI)\nexport default class ExecuteJobTask {\n\n    constructor(\n        private api: DatafiProAPI,\n    ) { }\n    execute(data: ExecuteJobData): Promise<APIFile> {\n\n        return this.api.jobs.create({\n            name: data.name,\n            data: data.data,\n        }, {query: data.query})\n            .then((job) => getJobResult(this.api.jobs, job))\n            .then((job) => job.result);\n    }\n}\n","import { isPrimitive } from '../../util/objects/isPrimitive';\nimport { EventAggregator } from 'aurelia-event-aggregator';\nimport { LogManager, autoinject } from 'aurelia-framework';\nimport { Container } from 'aurelia-dependency-injection';\nimport get from 'lodash.get';\n\nimport { ensureArray } from '../../util/array/ensureArray';\nimport { serialize } from '../../util/objects/serialize';\nimport { Task } from './tasks/Task';\nimport { Events } from '@wsb_dev/datafi-shared/lib/types/Events';\nimport { ActionModule, DefaultActionData, ActionStatus, ActionTargetType } from '@wsb_dev/datafi-shared/lib/types/ActionTypes';\nimport { DatafiProAPI } from '../../services/api/DatafiProAPI';\nimport GenerateCSVTask from './tasks/GenerateCSV';\nimport GenerateKoboURLTask from './tasks/GenerateKoboURL';\nimport GeneratePDFTask from './tasks/GeneratePDF';\nimport PopulateTask from './tasks/Populate';\nimport QueryTask from './tasks/Query';\nimport SaveFile from './tasks/SaveFile';\nimport EditDFPForm from './tasks/EditDFPForm';\nimport ExecuteJobTask from './tasks/ExecuteJob';\n\nconst log = LogManager.getLogger('dfp:actions');\n\n@autoinject\nexport class ActionService {\n    constructor(\n        private ea: EventAggregator,\n        private di: Container,\n        private api: DatafiProAPI,\n    ) {\n        this.ea.subscribe(Events.APP_ACTION_START, this.handleAction.bind(this));\n        this.di.registerSingleton('GenerateCSV', GenerateCSVTask);\n        this.di.registerSingleton('GenerateKoboURL', GenerateKoboURLTask);\n        this.di.registerSingleton('GeneratePDF', GeneratePDFTask);\n        this.di.registerSingleton('Populate', PopulateTask);\n        this.di.registerSingleton('Query', QueryTask);\n        this.di.registerSingleton('SaveFile', SaveFile);\n        this.di.registerSingleton('EditDFPForm', EditDFPForm);\n        this.di.registerSingleton('ExecuteJob', ExecuteJobTask);\n    }\n\n    handleAction(actionData: DefaultActionData): Promise<DefaultActionData> {\n        log.warn('DEPRECATED: call create instead of handleAction');\n        return this.create(actionData);\n    }\n\n    /**\n     * The action process orchestrator to import actions, run them, and publish events\n     * @param actionData {DefaultActionData} the action data to run\n     */\n    create(actionData: DefaultActionData): Promise<DefaultActionData> {\n        actionData = this.getStandardActionData(actionData);\n        if (actionData.updateTargetStatus) {\n            actionData.target.forEach((t) => t.__status = ActionStatus.PENDING);\n        }\n        const promise = this.getTask(actionData)\n            .then((task) => this.executeTask(task, actionData))\n            .then((executeResult) => ({\n                ...executeResult,\n                status: ActionStatus.SUCCESS,\n            })).catch((e) => {\n                log.error(e);\n                return {\n                    ...actionData,\n                    error: e,\n                    status: ActionStatus.FAILED,\n                };\n            });\n\n        promise.then((result) => {\n            const resultEvent = {\n                [ActionStatus.SUCCESS]: Events.APP_ACTION_SUCCESS,\n                [ActionStatus.FAILED]: Events.APP_ACTION_FAIL,\n            }[result.status];\n\n            if (actionData.updateTargetStatus) {\n                actionData.target.forEach((t) => t.__status = result.status);\n            }\n\n            const logMethod = {\n                [ActionStatus.SUCCESS]: 'info',\n                [ActionStatus.FAILED]: 'error',\n            }[result.status];\n            log[logMethod](`Action<${actionData.id}>: ${resultEvent}`, result);\n\n            this.ea.publish(resultEvent, result);\n            this.ea.publish(Events.APP_ACTION_END, result);\n        });\n\n        this.ea.publish(Events.APP_ACTION_PENDING, {\n            ...actionData,\n            promise,\n            status: ActionStatus.PENDING,\n        });\n\n        return promise;\n    }\n\n    private getStandardActionData(data: DefaultActionData): DefaultActionData {\n        const auth = this.api.auth.authentication;\n        const dynamic = this.getDynamicData(data);\n        return {\n            ...data,\n            target: ensureArray(serialize(data.target)),\n            ...dynamic,\n            auth: auth,\n        };\n    }\n\n    private getDynamicData(data: DefaultActionData) {\n        const dynamic = data.dynamicProps || {};\n        const newData = {};\n        Object.keys(dynamic).forEach((key) => {\n            const value = get(data, dynamic[key]);\n            if (typeof value === 'undefined') {\n                return;\n            }\n\n            if (isPrimitive(value)) {\n                newData[key] = value;\n            } else if (Array.isArray(value)) {\n                // if the array is empty, skip it\n                if (!value.length) {\n                    return;\n                }\n\n                newData[key] = value;\n            } else {\n                /// if its an object, mixin with existing data\n                newData[key] = {\n                    ...data[key],\n                    ...value,\n                };\n            }\n        });\n        return newData;\n    }\n\n    private async getTask(actionData: DefaultActionData): Promise<Task> {\n        return this.di.get(actionData.id);\n    }\n\n    private executeTask(task: ActionModule<DefaultActionData>, actionData: DefaultActionData): Promise<any> {\n        log.info(`Executing action<${actionData.id}> with data`, actionData);\n        if (actionData.defaultQuery) { delete actionData.defaultQuery?.__expanded; }\n        return Promise.resolve(task.execute(actionData))\n            .then((result) => this.getTaskResult(result, actionData));\n    }\n\n    private getTaskResult(result: unknown, actionData: DefaultActionData): Promise<DefaultActionData> {\n\n        // result is always an array\n        const newResult = Array.isArray(result) ? result : [result];\n        if (!actionData.next) {\n            return Promise.resolve({ ...actionData, result: newResult });\n        }\n\n        const nextAction = actionData.next;\n        const firstTarget = actionData.firstTarget || actionData.target;\n        let nextTarget;\n\n        // get target from either result or target\n        switch (nextAction.targetType) {\n        case ActionTargetType.TARGET_FROM_FIRST_TARGET:\n            nextTarget = firstTarget;\n            break;\n        case ActionTargetType.TARGET_FROM_LAST_TARGET:\n            nextTarget = actionData.target;\n            break;\n        case ActionTargetType.TARGET_FROM_LAST_RESULT:\n        default:\n            nextTarget = newResult;\n            break;\n        }\n\n        const nextActionData = {\n            ...nextAction,\n            firstTarget,\n            target: nextTarget,\n            viewModel: actionData.viewModel,\n        };\n\n        // return next action\n        return this.create(nextActionData);\n    }\n}\n","import { Params } from '@feathersjs/feathers';\nimport { EventAggregator } from 'aurelia-event-aggregator';\nimport { AuthenticationResult } from '@feathersjs/authentication';\nimport { LogManager, autoinject } from 'aurelia-framework';\nimport { AuthCreated, AuthDestroyed } from '@wsb_dev/datafi-shared/lib/types/Events';\nimport {getTopLevelDomain} from '@wsb_dev/datafi-shared/lib/util/strings/getTopLevelDomain';\nimport { ValidatedCredentials } from '../../types/Credentials';\nimport { ValidatedUser } from '../../types/Users';\nimport { AppConfig } from '../../services/util/AppConfig';\nimport { BrowserStorage } from '../../services/util/BrowserStorage';\nimport { DFPAuthResult } from '../../types/Authentication';\nimport { FeathersApplication } from '../../types/Application';\nimport { FeatureFlagsService } from '../../services/util/FeatureFlags';\nconst log = LogManager.getLogger('dfp:api');\n\n@autoinject\nexport class AuthenticationService {\n    public cookie = 'feathers-jwt';\n    public authentication?: DFPAuthResult;\n    public me?: ValidatedUser;\n    private authPromise?: Promise<AuthenticationResult | void>;\n    public defaultParams = { query: { $eager: '[roles.role, programRoles.role]' }}\n\n    constructor(\n        private app: FeathersApplication,\n        private ea: EventAggregator,\n        private config: AppConfig,\n        private browserStorage: BrowserStorage,\n        private flags: FeatureFlagsService,\n    ) {\n        this.authPromise = this.reAuthenticate()\n            .then((auth) => this.updateAuth(auth))\n            .catch((e) => {\n                log.warn('auth error', e);\n            });\n    }\n\n    get() {\n        if (this.authentication) {\n            return Promise.resolve(this.authentication);\n        }\n\n        return this.authPromise;\n    }\n\n    login(creds: ValidatedCredentials, params?: Params) {\n        params = { ...params, ...this.defaultParams };\n        return this.app.authenticate(creds, params)\n            .then((result) => this.updateAuth(result));\n    }\n\n    logout() {\n        return this.app.logout()\n            .then(() => this.updateAuth());\n    }\n\n    authenticate(data: any, params?: Params) {\n        return this.app\n            .authenticate(data, params)\n            .then((auth) => this.updateAuth(auth));\n    }\n\n    reAuthenticate(force = false, strategy?: string): Promise<AuthenticationResult | void> {\n        if (!force && this.authentication) {\n            return Promise.resolve(this.authentication);\n        }\n\n        return this.app.authentication\n            .getAccessToken()\n            .then((accessToken) => {\n                if (!accessToken) {\n                    throw new Error('No accessToken found in storage');\n                }\n\n                return this.app.authentication.authenticate({\n                    strategy: strategy || this.app.authentication.options.jwtStrategy,\n                    accessToken,\n                }, {\n                    ...this.defaultParams,\n                });\n            })\n            .catch((e) => {\n                if(e.code === 408){  // timeout error\n                    return this.browserStorage.get('dfp-auth')\n                        .then((res) => res.data);\n                }\n            });\n    }\n\n    updateAuth(auth?: AuthenticationResult | void): DFPAuthResult {\n        log.info('[authentication]: updating auth', auth);\n\n        if (!auth) {\n            this.authentication = null;\n            this.me = null;\n            this.updateCookie();\n            this.ea.publish(new AuthDestroyed());\n            return this.authentication;\n        }\n\n        // store the raw auth result\n        this.browserStorage.create({\n            id: 'dfp-auth',\n            data: auth,\n        });\n\n        const authResult: DFPAuthResult = {\n            ...auth,\n            user: auth ? new ValidatedUser(auth.user, this.app.service('api/v1/files')) : null,\n        } as DFPAuthResult;\n\n        this.authentication = authResult;\n        this.me = authResult?.user as ValidatedUser;\n        this.updateCookie(this.authentication);\n        this.ea.publish(new AuthCreated(auth as DFPAuthResult));\n        this.flags.updateUnleashUser({ auth: authResult });\n\n        return this.authentication;\n    }\n\n    updateCookie(auth?: DFPAuthResult): void {\n        if (!auth) {\n            document.cookie = `${this.cookie}=; Max-Age=0; path=/; domain=`;\n            return;\n        }\n        const expires = (new Date(Date.now() + 86400 * 1000)).toUTCString();\n        document.cookie = `${this.cookie}=${auth.accessToken}; path=/; expires=${expires}; SameSite=Strict; domain=${getTopLevelDomain(window.location.hostname)}`;\n    }\n}\n","import { ProgramAsset } from '@wsb_dev/datafi-shared/lib/types/ProgramAsset';\nimport { computedFrom } from 'aurelia-framework';\nimport { getterThrottle } from '../../util/decorators/getterThrottle';\n\nexport class ActiveAssetsService {\n    public assets: ProgramAsset[] = [];\n    public activeAsset: ProgramAsset;\n    public counter: number;\n\n    @getterThrottle(100)\n    @computedFrom('assets')\n    public get assetGroups(): Record<string, ProgramAsset[]> {\n        return this.assets.reduce((r, a) => {\n            r[a.metadata.id_title] = [...r[a.metadata.id_title] || [], a];\n            return r;\n        }, {});\n    }\n\n    constructor() {\n        this.counter = -1;\n    }\n\n    async create(createAsset: ProgramAsset): Promise<ProgramAsset> {\n        if(!createAsset.id){\n            createAsset.id = this.generateId();\n        }\n\n        this.assets = [\n            ...this.assets,\n            createAsset,\n        ];\n\n        this.activeAsset = createAsset;\n\n        return createAsset;\n    }\n\n    /**\n     * Searches for an asset by ID and returns the result,\n     * or throws error not found if it isn't found.\n     */\n    async get(id: number): Promise<ProgramAsset>{\n        const item = this.assets.find((items) => {\n            if (items.id === id) {\n                return items;\n            }\n        });\n        this.activeAsset = item;\n        return item;\n    }\n\n    generateId(): number {\n        return  this.counter --;\n    }\n\n    getAssets(): ProgramAsset[] {\n        return this.assets;\n    }\n\n    async remove(id: number): Promise<void> {\n        this.assets = this.assets.filter((items) => {\n            if (items.id !== id) {\n                return items;\n            }\n        });\n    }\n}\n","// methods to help with converting files back and forth\nexport function dataUriToBlob(dataURI: string): Blob {\n    const mime = dataURI.split(',')[0].split(':')[1].split(';')[0];\n    const binary = atob(dataURI.split(',')[1]);\n    const array = [];\n    for (let i = 0; i < binary.length; i++) {\n        array.push(binary.charCodeAt(i));\n    }\n    return new Blob([new Uint8Array(array)], { type: mime });\n}\n","import { HookContext } from '@feathersjs/feathers';\nimport omit from 'lodash.omit';\n\nconst RE = /^_/;\n\nexport function omitHiddenProps(...contextProps: string[]) {\n    return function (context: HookContext) {\n        contextProps.forEach((item) => {\n            if (!context[item]) {\n                return;\n            }\n            // don't try to omit file object types\n            // they get coerced to regular objects\n            if (context[item] instanceof File) {\n                return;\n            }\n\n            if (Array.isArray(context[item])) {\n                context[item] = context[item].map((item) => {\n                    const omittables = Object.keys(item).filter((key) => RE.test(key));\n                    return omit(item, omittables);\n                });\n            } else {\n                const omittables = Object.keys(context[item]).filter((key) => RE.test(key));\n                context[item] = omit(context[item], omittables);\n            }\n        });\n\n        return context;\n    };\n}\n","import { HookContext } from '@feathersjs/feathers';\nimport omit from 'lodash.omit';\nexport function omitProps(contextProps: string[], propsToOmit: string[]) {\n\n    return function omitHook(context: HookContext) {\n        contextProps.forEach((prop) => {\n            if (!context[prop]) {\n                return;\n            }\n            context[prop] = omit(context[prop], propsToOmit);\n        });\n\n        return context;\n    };\n}\n","\nexport function parseId (context) {\n    const props = ['data', 'result'];\n    props.forEach((p) => {\n        if (context[p]?.id) {\n            context[p].id = parseInt(context[p].id, 10);\n        }\n    });\n}\n","import { HookContext } from '@feathersjs/feathers';\nimport { DB, DataStoreOptions } from '../../../services/util/DB';\nimport camelCase from 'just-camel-case';\nimport log from '../../../services/util/Log';\n\nfunction getStoreName(context: HookContext): DataStoreOptions{\n    const serviceParts = context.path.split('/');\n    const storeName = camelCase( serviceParts[serviceParts.length - 1] );\n    return storeName as DataStoreOptions;\n}\n\nexport function setCacheData(db: DB){\n\n    return async function(context: HookContext){\n        const storeName = getStoreName(context) as DataStoreOptions;\n        if (!context.params.query?.$client) {\n            try {\n                if(Array.isArray(context.result?.data)){\n                    for(const item of context.result.data){\n                        await db.patch(item.id, item, {dataStoreName: storeName});\n                    }\n                } else if(context.result) {\n                    await db.patch(context.result.id, context.result, {dataStoreName: storeName});\n                }\n            } catch(e) {\n                log.warn(e);\n            }\n        }\n        return context;\n    };\n}\n","import { Id, Params, Service } from '@feathersjs/feathers';\nimport { LogManager, autoinject, camelCase, transient } from 'aurelia-framework';\nimport { DB, DataStoreOptions } from '../../services/util/DB';\nimport { setCacheData } from './hooks/idb';\nimport { FeatureFlagsService } from '../../services/util/FeatureFlags';\nimport {iff} from 'feathers-hooks-common/dist/index';\n\nexport type IData = Record<string, unknown>;\n\n@autoinject\n@transient()\nexport class OfflineService<T = Record<string, unknown>> {\n    service: Service<T>;\n    dataStoreName: DataStoreOptions;\n    log: LogManager.Logger;\n    timer: NodeJS.Timeout;\n    api: any;\n\n    get online(): boolean {\n        if(!this.flags.offline_storage_enabled){\n            return true;\n        }\n        return this.api.connected;\n    }\n\n    constructor(\n        private db: DB,\n        private flags: FeatureFlagsService,\n    ){\n        this.log = LogManager.getLogger('offline');\n        const timer = setInterval(() => this.sync(), 1000 * 60 * 5);\n    }\n\n    createService(api: any, serviceName: string){\n        this.api = api;\n        this.service = this.api.app.service(serviceName);\n        this.dataStoreName = this.getStoreName(serviceName);\n\n        this.service.hooks({\n            after: {\n                find: [\n                    iff(\n                        () => this.flags.offline_storage_enabled,\n                        setCacheData(this.db),\n                    ),\n                ],\n                get: [\n                    iff(\n                        () => this.flags.offline_storage_enabled,\n                        setCacheData(this.db),\n                    ),\n                ],\n            },\n        });\n\n        return this;\n    }\n\n    public async sync(){\n        this.log.debug('checking for pending data...');\n        if(this.online){\n            const pendingResults = await this.db.find({\n                dataStoreName: this.dataStoreName,\n                query: {\n                    id: {$lt: 0},\n                    __status: 'pending',\n                },\n            });\n\n            const pendingRows = pendingResults.data as any[];\n            return Promise.all(pendingRows.map(async (pending) => {\n                this.log.debug('pending row found...uploading', pending);\n                const {id, ...data} = pending;\n                const created = await this.service.create(data);\n                this.log.debug('row saved', created);\n\n                const local = await this.db.create({\n                    ...created,\n                    __status: 'saved',\n                }, {dataStoreName: this.dataStoreName});\n                await this.db.remove(pending.id, {dataStoreName: this.dataStoreName});\n\n                this.log.debug('local db updated', local);\n\n            }));\n        } else {\n            this.log.debug('app is offline, nothing to do');\n        }\n    }\n\n    find(params: Params){\n        if(this.online){\n            return this.service.find(params);\n        }\n        return this.api.db.find({\n            ...params,\n            dataStoreName: this.dataStoreName,\n        });\n    }\n\n    get(id: Id, params: Params){\n        if(this.online){\n            return this.service.get(id, params);\n        }\n\n        return this.api.db.get(id, {\n            ...params,\n            dataStoreName: this.dataStoreName,\n        });\n    }\n\n    create(data: IData|IData[], params: Params){\n        const row = Array.isArray(data) ? data[0] : data;\n\n        // use offline method if a draft state\n        if(row.__status !== 'draft'){\n            if(this.online){\n                return this.service.create(data as any, params);\n            }\n        }\n\n        return this.api.db.create( {\n            __status: 'pending',\n            ...data,\n        }, {\n            ...params,\n            dataStoreName: this.dataStoreName,\n        });\n    }\n\n    patch(id: Id, data: IData, params: Params){\n        if(this.online){\n            return this.service.patch(id, data as any, params);\n        } else {\n            throw new Error('cannot patch data while offline');\n        }\n\n        // return this.api.db.patch(id, data, {\n        //     ...params,\n        //     dataStoreName: this.dataStoreName,\n        // });\n    }\n\n    update(id: Id, data: IData, params: Params){\n        if(this.online){\n            return this.service.update(id, data as any, params);\n        }else {\n            throw new Error('cannot update data while offline');\n        }\n\n        // return this.api.db.update(id, data, {\n        //     ...params,\n        //     dataStoreName: this.dataStoreName,\n        // });\n    }\n\n    remove(id, params: Params){\n        if(this.online){\n            return this.service.remove(id, params);\n        } else {\n            throw new Error('cannot remove data while offline');\n        }\n\n        // return this.api.db.remove(id, {\n        //     ...params,\n        //     dataStoreName: this.dataStoreName,\n        // });\n    }\n\n    hooks(hooks){\n        this.service.hooks(hooks);\n    }\n\n    on(evt: string, handler: () => unknown){\n        this.service.on(evt, handler);\n    }\n\n    off(evt: string, handler: () => unknown){\n        this.service.off(evt, handler);\n    }\n\n    private getStoreName(path: string): DataStoreOptions{\n        const serviceParts = path.split('/');\n        const storeName = camelCase( serviceParts[serviceParts.length - 1] );\n        return storeName as DataStoreOptions;\n    }\n}\n","import { HookContext, Service } from '@feathersjs/feathers';\nimport {\n    APIFile,\n    DetailedSurveyItem,\n    AppEvent,\n    GeocodeResult,\n    Job,\n    Organization,\n    Program,\n    ProgramAsset,\n    ProgramAssetType,\n    ProgramConfig,\n    ProgramSecret,\n    ProgramSurvey,\n    ProgramUserRole,\n    Project,\n    ProjectFile,\n    Role,\n    Secret,\n    Token,\n    User,\n    UserRole,\n} from '@wsb_dev/datafi-shared/lib/types';\nimport { IArcGISTokenSource } from '@wsb_dev/datafi-shared/lib/types/ArcGISSource';\nimport { FormSubmission } from '@wsb_dev/datafi-shared/lib/types/FormSubmission';\nimport { IFormUrlData } from '@wsb_dev/datafi-shared/lib/types/FormUrl';\nimport { ProgramWebhook } from '@wsb_dev/datafi-shared/lib/types/ProgramWebhook';\nimport { Container, autoinject } from 'aurelia-dependency-injection';\nimport { AppConfig } from '../util/AppConfig';\nimport { FeathersApplication } from '../../types/Application';\nimport { ValidatedProject } from '../../types/Project';\nimport { AuthenticationService } from './authentication';\nimport { FileService } from './file';\nimport { convertInt } from './hooks/convertInt';\nimport { omitEmpty } from './hooks/omitEmpty';\nimport { omitGeomIfBinary } from './hooks/omitGeomIfBinary';\nimport { omitProps } from './hooks/omitProps';\nimport { parseId } from './hooks/parseId';\nimport { BrowserStorage } from '../util/BrowserStorage';\nimport { StorageItem } from '../util/_StorageBase';\nimport { DB } from '../util/DB';\nimport { OfflineService } from './OfflineService';\nimport log from '../util/Log';\n\n@autoinject\nexport class DatafiProAPI {\n    public arcGISSources: Service<IArcGISTokenSource>;\n    public authManagement;\n    public events: Service<AppEvent>;\n    public files: Service<APIFile>;\n    public formSubmissions: Service<FormSubmission>;\n    public formUrls: Service<IFormUrlData>;\n    public geocode: Service<GeocodeResult>;\n    public jobs: Service<Job<any>>;\n    public organizations: Service<Organization>\n    public programAssets: Service<ProgramAsset>;\n    public programAssetTypes: Service<ProgramAssetType>;\n    public programConfigs: Service<ProgramConfig>;\n    public programs: Service<Program>;\n    public programSecrets: Service<ProgramSecret>;\n    public programSurveys: Service<ProgramSurvey>;\n    public programUsersRoles: Service<ProgramUserRole>;\n    public programWebhooks: Service<ProgramWebhook>;\n    public projectFiles: Service<ProjectFile>;\n    public projects: Service<Project>;\n    public roles: Service<Role>;\n    public secrets: Service<Secret>;\n    public surveys: Service<ProgramSurvey|DetailedSurveyItem>;\n    public surveysMedia: Service<APIFile>;\n    public tokens: Service<Token>;\n    public users: Service<User>;\n    public usersRoles: Service<UserRole>;\n\n    public connected: boolean;\n\n    constructor(\n        public app: FeathersApplication,\n        public db: DB,\n        public auth: AuthenticationService,\n        private config: AppConfig,\n        private browserStorage: BrowserStorage,\n        private container: Container,\n    ) {\n\n        app.io.on('connect', () => this.handleConnectionStatus(true));\n        app.io.on('disconnect', () => this.handleConnectionStatus(false));\n        this.handleConnectionStatus(app.io.connected);\n        this.arcGISSources = app.service('api/v1/arcgis-sources');\n        this.events = app.service('api/v1/events');\n        this.files = this.container.get(FileService);\n        this.formSubmissions = this.container.get(OfflineService).createService(this, 'api/v1/form-submissions') as any;\n        this.organizations = app.service('api/v1/organizations');\n        this.programAssets = app.service('api/v1/programs-assets');\n        this.programAssetTypes = app.service('api/v1/programs-asset-types');\n        this.programConfigs = app.service('api/v1/programs-configs');\n        this.programs = this.container.get(OfflineService).createService(this, 'api/v1/programs') as any;\n        {\n            const omitRelations = omitProps(\n                ['data'],\n                ['assetTypes', 'roles', 'configs', 'surveys', 'templateScope'],\n            );\n            this.programs.hooks({\n                before: {\n                    create: [omitRelations],\n                    patch: [omitRelations],\n                    update: [omitRelations],\n                },\n            });\n        }\n        this.programSurveys = this.container.get(OfflineService).createService(this, 'api/v1/programs-surveys') as any;\n        {\n            const omitRelations = omitProps(['data'], ['survey']);\n            const convertArea = convertInt('groupByArea');\n            this.programSurveys.hooks({\n                before: {\n                    create: [omitRelations, convertArea],\n                    patch: [omitRelations, convertArea],\n                    update: [omitRelations, convertArea],\n                },\n            });\n        }\n        this.projectFiles = this.container.get(OfflineService).createService(this, 'api/v1/projects-files') as any;\n        {\n            const omitGeom = omitGeomIfBinary('geom');\n            this.projectFiles.hooks({\n                before: {\n                    patch: [omitGeom],\n                    update: [omitGeom],\n                },\n            });\n        }\n        this.projects = this.container.get(OfflineService).createService(this, 'api/v1/projects') as any;\n        this.projects.hooks({\n            after: {\n                update: [parseId],\n                patch: [parseId],\n                find: [\n                    async (context: HookContext) => {\n                        if (context.params.query.program_id) {\n                            const programId = context.params.query.program_id;\n                            const pinnedId = `pinned_projects-${programId}`;\n                            await this.browserStorage.get(pinnedId).then((pins) => {\n                                if (pins.data && context) {\n                                    pins.data.forEach((pinId: number) => {\n                                        const pinnedProjects = context.result.data.find((project: ValidatedProject) => project.id === pinId);\n                                        if (pinnedProjects) {\n                                            pinnedProjects._pinned = true;\n                                        }\n                                    });\n                                }\n                            }).catch((e) => ({ id: pinnedId, data: {} } as StorageItem));\n                        }\n                    },\n                ],\n\n            },\n        });\n\n        this.formUrls = app.service('api/v1/form-urls');\n        this.geocode = app.service('api/v1/geocode');\n        this.jobs = app.service('api/v1/jobs');\n        this.jobs.hooks({\n            after: {\n                update: [parseId],\n                patch: [parseId],\n            },\n        });\n        this.programSecrets = app.service('api/v1/programs-secrets');\n        this.programUsersRoles = app.service('api/v1/programs-users-roles');\n        this.programWebhooks = app.service('api/v1/programs-webhooks');\n        this.roles = app.service('api/v1/roles');\n        this.roles.hooks({\n            after: {\n                update: [parseId],\n                patch: [parseId],\n            },\n        });\n\n        this.secrets = app.service('api/v1/secrets');\n        {\n            const omitRelations = omitProps(['data'], ['user']);\n            this.secrets.hooks({\n                before: {\n                    patch: [omitRelations],\n                    create: [omitRelations],\n                    update: [omitRelations],\n                },\n            });\n        }\n        this.tokens = app.service('api/v1/tokens');\n        this.usersRoles = app.service('api/v1/users-roles');\n        {\n            const omitRole = omitProps(['data'], ['role']);\n            this.usersRoles.hooks({\n                before: {\n                    create: [omitRole],\n                    patch: [omitRole],\n                    update: [omitRole],\n                },\n                after: {\n                    update: [parseId],\n                    patch: [parseId],\n                },\n            });\n        }\n\n        this.users = app.service('api/v1/users');\n        {\n            const omitRoles = omitProps(['data'], ['roles', 'programRoles']);\n            const omitWhenEmpty = omitEmpty('password');\n            this.users.hooks({\n                before: {\n                    create: [omitRoles],\n                    patch: [omitRoles, omitWhenEmpty],\n                    update: [omitRoles],\n                },\n                after: {\n                    update: [parseId],\n                    patch: [parseId],\n                },\n            });\n        }\n\n        this.authManagement = app.service('/api/v1/account-management');\n    }\n\n    handleConnectionStatus(online: boolean){\n        this.connected = online;\n        if(online){\n            this.auth.reAuthenticate(true);\n        }\n        log.info(online ? 'Application is now online' : 'Application is now offline');\n    }\n}\n","\nexport function convertInt(...fields: string[]) {\n    return function (context) {\n        fields.forEach((field) => {\n            if(typeof context.data[field] === 'undefined'){\n                return;\n            }\n            context.data[field] = parseInt(context.data[field], 10);\n        });\n    };\n}\n","import { HookContext } from '@feathersjs/feathers';\nimport omit from 'lodash.omit';\n\nexport function omitGeomIfBinary(geomField: string){\n    return function omitGeom(context: HookContext): HookContext {\n        if(typeof context.data?.[geomField] === 'string'){\n            context.data = omit(context.data, geomField);\n        }\n\n        return context;\n    };\n}\n","import { HookContext } from '@feathersjs/feathers';\nimport { hasValue } from '@wsb_dev/datafi-shared/lib/util/types/hasValue';\nimport omit from 'lodash.omit';\n\nexport function omitEmpty(...contextProps: string[]) {\n    return function omitEmptyHook(context: HookContext): HookContext {\n        const propsToOmit = Object.keys(context.data).filter((k) => {\n            return contextProps.indexOf(k) && !hasValue(context.data[k]);\n        });\n\n        context.data = omit(context.data, propsToOmit);\n        return context;\n    };\n}\n","export class StopPropagationBindingBehavior {\n    bind(binding, source) {\n        binding.standardCallSource = binding.callSource;\n        binding.callSource = function (event) {\n            this.standardCallSource(event);\n            event.stopPropagation();\n        };\n    }\n\n    unbind(binding, source) {\n        binding.callSource = binding.standardCallSource;\n        binding.standardCallSource = null;\n    }\n}\n","import { ValidationRules } from 'aurelia-validation';\n\nValidationRules.customRule(\n    'matchesProperty',\n    (value, obj, otherPropertyName) =>\n        value === null\n      || value === undefined\n      || value === ''\n      || obj[otherPropertyName] === null\n      || obj[otherPropertyName] === undefined\n      || obj[otherPropertyName] === ''\n      || value === obj[otherPropertyName],\n    '${$displayName} must match ${$getDisplayName($config.otherPropertyName)}',\n    (otherPropertyName) => ({ otherPropertyName }),\n);\n","import { LogManager } from 'aurelia-framework';\nimport { ValidationRules } from 'aurelia-validation';\nconst log = LogManager.getLogger('dfp:json');\n\nValidationRules.customRule(\n    'json',\n    (value) => {\n        log.debug('json value: ', value);\n        try {\n            JSON.parse(value);\n            return true;\n        } catch (e) {\n            log.warn(e);\n            return false;\n        }\n    },\n    '${$displayName} must contain valid json',\n);\n","import { FrameworkConfiguration, PLATFORM } from 'aurelia-framework';\nimport './validation/matchesProperty';\nimport './validation/json';\n\nexport function configure(config: FrameworkConfiguration): void {\n    config.globalResources([\n        PLATFORM.moduleName('resources/value-converters/array'),\n        PLATFORM.moduleName('resources/value-converters/json'),\n        PLATFORM.moduleName('resources/value-converters/date-format'),\n        PLATFORM.moduleName('resources/value-converters/file-icon'),\n        PLATFORM.moduleName('resources/value-converters/has-permission'),\n        PLATFORM.moduleName('resources/value-converters/round'),\n        PLATFORM.moduleName('resources/value-converters/group'),\n        PLATFORM.moduleName('resources/value-converters/title'),\n        PLATFORM.moduleName('resources/value-converters/object-key'),\n        PLATFORM.moduleName('resources/value-converters/keys'),\n        PLATFORM.moduleName('resources/value-converters/number'),\n        PLATFORM.moduleName('resources/value-converters/unknown'),\n        PLATFORM.moduleName('resources/value-converters/default'),\n        PLATFORM.moduleName('resources/value-converters/job-status'),\n        PLATFORM.moduleName('resources/value-converters/purify-html'),\n\n        PLATFORM.moduleName('resources/binding-behaviors/stop-propagation'),\n\n    ]);\n}\n","export class ArrayValueConverter {\n    toView(value: any[]) {\n        if(['string', 'number', 'boolean'].includes(typeof value[0])){\n            return value.join(', ');\n        }\n\n        return value.length;\n    }\n\n    fromView(value) {\n    //\n    }\n}\n","import dayjs from 'dayjs';\n\nexport class DateValueConverter {\n    toView(value, format = 'YYYY-MM-DD h:mm A') {\n        if (!value) {\n            return value;\n        }\n        return dayjs(value).format(format);\n    }\n    fromView(value) {\n        if(!value){\n            return value;\n        }\n        return dayjs(value).toDate();\n    }\n}\n","\nexport class DefaultValueConverter {\n    toView(value: any|undefined, defaultValue = true) {\n        if (typeof value === 'undefined') {\n            return defaultValue;\n        }\n        return value;\n    }\n}\n","import { getFileIcon } from '@wsb_dev/datafi-shared/lib/types/FileTypes';\n\nexport class FileIconValueConverter {\n    toView(value) {\n        return getFileIcon(value);\n    }\n\n    fromView(value) {\n    //\n    }\n}\n","export interface Group {\n    key: string;\n    values: any[];\n}\n\nexport class GroupValueConverter {\n    toView(items: any[], key: string): Group[] {\n        if (!items) {\n            return [];\n        }\n        const values = {};\n        items.forEach((i) => {\n            const prop = i[key];\n            if (!values[prop]) {\n                values[prop] = [];\n            }\n            values[prop].push(i);\n        });\n\n        return Object.keys(values).map((key) => ({ key, values: values[key] }));\n    }\n}\n","import { Program } from '@wsb_dev/datafi-shared/lib/types/Program';\nimport { PermissionType } from '@wsb_dev/datafi-shared/lib/types/Roles';\nimport { User } from '@wsb_dev/datafi-shared/lib/types/Users';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\nimport { LogManager } from 'aurelia-framework';\n\nconst log = LogManager.getLogger('dfp:permission');\n\nexport class HasPermissionValueConverter {\n    toView(...args) {\n        let program: null | Program | number, user: User, service: string, perm: PermissionType;\n\n        // handle arguments - we can accept the following:\n        // - user, program, service, perm -> program roles\n        // - user, service, perm  -> user roles\n        if (args.length === 4) {\n            [user, program, service, perm] = args;\n        } else {\n            [user, service, perm] = args;\n        }\n\n        if (!user) {\n            log.debug('user not provided', args);\n            return false;\n        }\n\n        const programId: number = typeof program === 'number' ?\n            program :\n            program?.id;\n\n        const returnValue = programId ?\n            userHasPermission(user, service, perm, programId) :\n            userHasPermission(user, service, perm);\n\n        log.debug(`permission valid: ${returnValue}`, args);\n        return returnValue;\n    }\n}\n","export class JobStatusValueConverter {\n    toView(value: any) {\n        return value;\n        // return titleize( Object.keys(JobStatus).find((key) => JobStatus[key] === value) || 'None' );\n    }\n}\n","export class JsonValueConverter {\n    toView(value) {\n        return JSON.stringify(value, undefined, 4);\n    }\n\n    fromView(value) {\n        value = value || '{}';\n        return JSON.parse(value);\n    }\n}\n","export class KeysValueConverter {\n    toView(value) {\n        return Reflect.ownKeys(value || {});\n    }\n}\n","import * as format from 'd3-format/dist/d3-format';\n/**\n * Number formatter\n * @url https://www.npmjs.com/package/d3-format\n */\nexport class NumberValueConverter {\n    toView(value, f = ',') {\n        if (f === '' || isNaN(parseFloat(value))) {\n            return value;\n        } else {\n            return format.format(f)(value);\n        }\n    }\n\n    fromView(value){\n        if(!value){\n            return 0;\n        }\n        return parseFloat(value);\n    }\n}\n","import get from 'lodash.get';\n\nexport class ObjectKeyValueConverter {\n    toView(obj: Record<string, any>, key: string) {\n        return get(obj, key);\n    }\n}\n","import * as DOMPurify from 'dompurify';\n\nexport class purifyHTMLValueConverter {\n    toView(value) {\n        return DOMPurify.sanitize(value);\n    }\n\n}\n","export class RoundValueConverter {\n    toView(value, places = 1) {\n        const multiplier = Math.pow(10, places);\n        return Math.round(multiplier * value) / multiplier;\n    }\n\n    fromView(value) {\n        return parseFloat(value);\n    }\n}\n","import { titleize } from '@wsb_dev/datafi-shared/lib/util/strings/titleize';\nexport class TitleValueConverter {\n    toView(value) {\n        return titleize(value);\n    }\n}\n","import { DateValueConverter } from './date-format';\nimport { NumberValueConverter } from './number';\nimport { isValid } from '../../util/dates/isValid';\n\n/**\n * Converts a value into a user friendly display.\n *\n * Tries with numbers, dates, and strings\n */\nexport class UnknownValueConverter {\n    toView(value, format?: string) {\n        if (!isNaN(value)) {\n            return NumberValueConverter.prototype.toView(value, format);\n        }\n\n        if (isValid(value)) {\n            return DateValueConverter.prototype.toView(value, format || 'MM-DD-YYYY');\n        }\n\n        return value;\n    }\n\n}\n","import { Service } from '@feathersjs/feathers';\nimport { Job } from '@wsb_dev/datafi-shared/lib/types/Job';\nimport { LogManager } from 'aurelia-framework';\nconst log = LogManager.getLogger('dfp:api');\n\nconst MAX_POLL_COUNT = 50;\n\nexport function getJobResult<T>(service: Service<Job<T>>, job: Job<T>, maxPollCount = MAX_POLL_COUNT): Promise<Job<T>> {\n\n    return new Promise((resolve, reject) => {\n        let pollCount = 0;\n        const interval = setInterval(() => {\n            log.debug('Polling for job', job.id);\n            pollCount++;\n            if (pollCount > MAX_POLL_COUNT) {\n                clearInterval(interval);\n                return;\n            }\n\n            service.get(job.id, {\n                query: { $select: ['id', 'result', 'error', 'status'] },\n            }).then((jobResult) => {\n\n                const status = jobResult.status;\n\n                if (status === 'waiting' || status === 'active' || status === 'delayed' || status === 'waiting-children') {\n                    return;\n                }\n\n                log.debug('Job ', job.id, jobResult);\n                if (status === 'completed') {\n                    clearInterval(interval);\n                    resolve(jobResult);\n                    return;\n                }\n\n                if (status === 'failed') {\n                    clearInterval(interval);\n                    reject(new Error(jobResult.error));\n                }\n            });\n        }, 2000);\n    });\n}\n","import get from 'lodash.get';\nimport { HookContext } from '@feathersjs/feathers';\nimport { LogManager } from 'aurelia-framework';\n\nconst logger = LogManager.getLogger('dfp:api');\n\nexport function log(...props) {\n    if(!props){\n        props = [];\n    }\n    return function (context: HookContext) {\n        const name = context.service.name || context.service.path;\n        const level = context.type === 'error' ?\n            'error' :\n            'debug';\n        logger[level](`${name}<${context.method}>: `, ...props.map((p) => get(context, p)));\n    };\n}\n","import { SurveyItemField } from '@wsb_dev/datafi-shared/lib/types/SurveyItem';\n\nexport interface IXcelJsonConfig {\n    prop: keyof SurveyItemField;\n    type: any;\n}\n\nexport const xFormSchema: Record<keyof SurveyItemField, IXcelJsonConfig> = {\n    type: {prop: 'type', type: String},\n    label: {prop: 'label', type: String},\n    name: {prop: 'name', type: String},\n    hint: {prop: 'hint', type: String},\n    guidance_hint: {prop: 'guidance_hint', type: String},\n    appearance: {prop: 'appearance', type: String},\n    required: {prop: 'required', type: String},\n    required_message: {prop: 'required_message', type: String},\n    default: {prop: 'default', type: String},\n    relevant: {prop: 'relevant', type: String},\n    calculation: {prop: 'calculation', type: String},\n    constraint: {prop: 'constraint', type: String},\n    constraint_message: {prop: 'constraint_message', type: String},\n    readonly: {prop: 'readonly', type: String},\n    repeat_count: {prop: 'repeat_count', type: Number},\n    image: {prop: 'image', type: String},\n    audio: {prop: 'audio', type: String},\n    video: {prop: 'video', type: String},\n    parameters: {prop: 'parameters', type: String},\n\n};\n\nexport const xformChoicesSchema = {\n    list_name: {prop: 'list_name', type: String},\n    name: {prop: 'name', type: String},\n    label: {prop: 'label', type: String},\n};\n"],"sourceRoot":""}