retold-data-service 2.0.19 → 2.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/source/services/data-cloner/DataCloner-Command-Sync.js +15 -1
- package/source/services/data-cloner/pict-app/providers/Pict-Provider-DataCloner.js +16 -0
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Export.js +2 -0
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Sync.js +7 -0
- package/source/services/data-cloner/web/data-cloner.js +22 -0
- package/source/services/data-cloner/web/data-cloner.js.map +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
- package/test/integration-report.json +0 -230
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).dataCloner=t()}}(function(){return function t(e,i,n){function o(a,r){if(!i[a]){if(!e[a]){var l="function"==typeof require&&require;if(!r&&l)return l(a,!0);if(s)return s(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var d=i[a]={exports:{}};e[a][0].call(d.exports,function(t){return o(e[a][1][t]||t)},d,d.exports,t,e,i,n)}return i[a].exports}for(var s="function"==typeof require&&require,a=0;a<n.length;a++)o(n[a]);return o}({1:[function(t,e,i){e.exports={name:"fable-serviceproviderbase",version:"3.0.19",description:"Simple base classes for fable services.",main:"source/Fable-ServiceProviderBase.js",scripts:{start:"node source/Fable-ServiceProviderBase.js",test:"npx quack test",tests:"npx quack test -g",coverage:"npx quack coverage",build:"npx quack build",types:"tsc -p ./tsconfig.build.json",check:"tsc -p . --noEmit"},types:"types/source/Fable-ServiceProviderBase.d.ts",mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},repository:{type:"git",url:"https://github.com/stevenvelozo/fable-serviceproviderbase.git"},keywords:["entity","behavior"],author:"Steven Velozo <steven@velozo.com> (http://velozo.com/)",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/fable-serviceproviderbase/issues"},homepage:"https://github.com/stevenvelozo/fable-serviceproviderbase",devDependencies:{"@types/mocha":"^10.0.10",fable:"^3.1.62",quackage:"^1.0.58",typescript:"^5.9.3"}}},{}],2:[function(t,e,i){const n=t("../package.json");class o{constructor(t,e,i){this.fable,this.UUID,this.options,this.services,this.servicesMap,"object"==typeof t&&t.isFable?this.connectFable(t):this.fable=!1,this._PackageFableServiceProvider=n,this.fable?(this.UUID=t.getUUID(),this.options="object"==typeof e?e:{}):(this.options="object"!=typeof t||t.isFable?"object"==typeof e?e:{}:t,this.UUID=`CORE-SVC-${Math.floor(89999*Math.random()+1e4)}`),this.serviceType=`Unknown-${this.UUID}`,this.Hash="string"==typeof i?i:this.fable||"string"!=typeof e?`${this.UUID}`:e}connectFable(t){if("object"!=typeof t||!t.isFable){let e=`Fable Service Provider Base: Cannot connect to Fable, invalid Fable object passed in. The pFable parameter was a [${typeof t}].}`;return console.log(e),new Error(e)}return this.fable||(this.fable=t),this.log||(this.log=this.fable.Logging),this.services||(this.services=this.fable.services),this.servicesMap||(this.servicesMap=this.fable.servicesMap),!0}static isFableService=!0}e.exports=o,e.exports.CoreServiceProviderBase=o},{"../package.json":1}],3:[function(t,e,i){e.exports={name:"pict-application",version:"1.0.33",description:"Application base class for a pict view-based application",main:"source/Pict-Application.js",scripts:{test:"npx quack test",start:"node source/Pict-Application.js",coverage:"npx quack coverage",build:"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-application-image:local","docker-dev-run":'docker run -it -d --name pict-application-dev -p 30001:8080 -p 38086:8086 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/pict-application" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" pict-application-image:local',"docker-dev-shell":"docker exec -it pict-application-dev /bin/bash",tests:"npx quack test -g",lint:"eslint source/**",types:"tsc -p ."},types:"types/source/Pict-Application.d.ts",repository:{type:"git",url:"git+https://github.com/stevenvelozo/pict-application.git"},author:"steven velozo <steven@velozo.com>",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/pict-application/issues"},homepage:"https://github.com/stevenvelozo/pict-application#readme",devDependencies:{"@eslint/js":"^9.28.0","browser-env":"^3.3.0",eslint:"^9.28.0",pict:"^1.0.348","pict-provider":"^1.0.10","pict-view":"^1.0.66",quackage:"^1.0.58",typescript:"^5.9.3"},mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},dependencies:{"fable-serviceproviderbase":"^3.0.19"}}},{}],4:[function(t,e,i){const n=t("fable-serviceproviderbase"),o=t("../package.json"),s={Name:"DefaultPictApplication",MainViewportViewIdentifier:"Default-View",MainViewportRenderableHash:!1,MainViewportDestinationAddress:!1,MainViewportDefaultDataAddress:!1,AutoSolveAfterInitialize:!0,AutoRenderMainViewportViewAfterInitialize:!0,AutoRenderViewsAfterInitialize:!1,AutoLoginAfterInitialize:!1,AutoLoadDataAfterLogin:!1,ConfigurationOnlyViews:[],Manifests:{},IdentifierAddressPrefix:"PICT-"};e.exports=class extends n{constructor(t,e,i){let n="object"==typeof t.settings.PictApplicationConfiguration?t.settings.PictApplicationConfiguration:{};super(t,Object.assign({},JSON.parse(JSON.stringify(s)),n,e),i),this.options,this.log,this.fable,this.UUID,this.Hash,this.servicesMap,this.serviceType="PictApplication",this._Package=o,this.pict=this.fable,this.AppData=this.fable.AppData,this.Bundle=this.fable.Bundle,this.initializeTimestamp,this.lastSolvedTimestamp,this.lastLoginTimestamp,this.lastMarshalFromViewsTimestamp,this.lastMarshalToViewsTimestamp,this.lastAutoRenderTimestamp,this.lastLoadDataTimestamp;let a=Object.keys(this.options.Manifests);if(a.length>0)for(let t=0;t<a.length;t++){let e=a[t];this.fable.instantiateServiceProvider("Manifest",this.options.Manifests[e],e)}}onPreSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onPreSolve:`),!0}onPreSolveAsync(t){return this.onPreSolve(),t()}onBeforeSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeSolve:`),!0}onBeforeSolveAsync(t){return this.onBeforeSolve(),t()}onSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onSolve:`),!0}onSolveAsync(t){return this.onSolve(),t()}solve(){this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} executing solve() function...`);let t=Object.keys(this.pict.providers),e=[];for(let i=0;i<t.length;i++){let n=this.pict.providers[t[i]];n.options.AutoSolveWithApp&&e.push(n)}e.sort((t,e)=>t.options.AutoSolveOrdinal-e.options.AutoSolveOrdinal);for(let t=0;t<e.length;t++)e[t].solve(e[t]);this.onBeforeSolve();let i=Object.keys(this.pict.views),n=[];for(let t=0;t<i.length;t++){let e=this.pict.views[i[t]];e.options.AutoInitialize&&n.push(e)}n.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let t=0;t<n.length;t++)n[t].solve();return this.onSolve(),this.onAfterSolve(),this.lastSolvedTimestamp=this.fable.log.getTimeStamp(),!0}solveAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");e.anticipate(this.onBeforeSolveAsync.bind(this));let i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync Auto Callback Error: ${t}`,t)});let n=Object.keys(this.pict.providers),o=[];for(let t=0;t<n.length;t++){let e=this.pict.providers[n[t]];e.options.AutoSolveWithApp&&o.push(e)}o.sort((t,e)=>t.options.AutoSolveOrdinal-e.options.AutoSolveOrdinal);for(let t=0;t<o.length;t++)e.anticipate(o[t].solveAsync.bind(o[t]));let s=Object.keys(this.pict.views),a=[];for(let t=0;t<s.length;t++){let e=this.pict.views[s[t]];e.options.AutoSolveWithApp&&a.push(e)}a.sort((t,e)=>t.options.AutoSolveOrdinal-e.options.AutoSolveOrdinal);for(let t=0;t<a.length;t++)e.anticipate(a[t].solveAsync.bind(a[t]));e.anticipate(this.onSolveAsync.bind(this)),e.anticipate(this.onAfterSolveAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync() complete.`),this.lastSolvedTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterSolve:`),!0}onAfterSolveAsync(t){return this.onAfterSolve(),t()}onBeforeLoginAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeLoginAsync:`),t()}onLoginAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onLoginAsync:`),t()}loginAsync(t){const e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");let i=t;"function"!=typeof i&&(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loginAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loginAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeLoginAsync.bind(this)),e.anticipate(this.onLoginAsync.bind(this)),e.anticipate(this.onAfterLoginAsync.bind(this)),this.options.AutoLoadDataAfterLogin&&e.anticipate(t=>{if(!this.isLoggedIn())return t();this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto loading data after login...`),this.loadDataAsync(e=>{t(e)})}),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loginAsync() complete.`),this.lastLoginTimestamp=this.fable.log.getTimeStamp(),i(t)))}isLoggedIn(){return!0}onAfterLoginAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterLoginAsync:`),t()}onBeforeLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeLoadDataAsync:`),t()}onLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onLoadDataAsync:`),t()}loadDataAsync(t){const e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");let i=t;"function"!=typeof i&&(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loadDataAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loadDataAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeLoadDataAsync.bind(this));let n=Object.keys(this.pict.providers),o=[];for(let t=0;t<n.length;t++){let e=this.pict.providers[n[t]];e.options.AutoLoadDataWithApp&&o.push(e)}o.sort((t,e)=>t.options.AutoLoadDataOrdinal-e.options.AutoLoadDataOrdinal);for(const t of o)e.anticipate(t.onBeforeLoadDataAsync.bind(t));e.anticipate(this.onLoadDataAsync.bind(this));for(const t of o)e.anticipate(t.onLoadDataAsync.bind(t));e.anticipate(this.onAfterLoadDataAsync.bind(this));for(const t of o)e.anticipate(t.onAfterLoadDataAsync.bind(t));e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loadDataAsync() complete.`),this.lastLoadDataTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterLoadDataAsync:`),t()}onBeforeSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeSaveDataAsync:`),t()}onSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onSaveDataAsync:`),t()}saveDataAsync(t){const e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");let i=t;"function"!=typeof i&&(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} saveDataAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} saveDataAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeSaveDataAsync.bind(this));let n=Object.keys(this.pict.providers),o=[];for(let t=0;t<n.length;t++){let e=this.pict.providers[n[t]];e.options.AutoSaveDataWithApp&&o.push(e)}o.sort((t,e)=>t.options.AutoSaveDataOrdinal-e.options.AutoSaveDataOrdinal);for(const t of o)e.anticipate(t.onBeforeSaveDataAsync.bind(t));e.anticipate(this.onSaveDataAsync.bind(this));for(const t of o)e.anticipate(t.onSaveDataAsync.bind(t));e.anticipate(this.onAfterSaveDataAsync.bind(this));for(const t of o)e.anticipate(t.onAfterSaveDataAsync.bind(t));e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} saveDataAsync() complete.`),this.lastSaveDataTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterSaveDataAsync:`),t()}onBeforeInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeInitialize:`),!0}onBeforeInitializeAsync(t){return this.onBeforeInitialize(),t()}onInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onInitialize:`),!0}onInitializeAsync(t){return this.onInitialize(),t()}initialize(){if(this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} initialize:`),this.initializeTimestamp)return this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initialize called but initialization is already completed. Aborting.`),!1;{if(this.onBeforeInitialize(),"ConfigurationOnlyViews"in this.options)for(let t=0;t<this.options.ConfigurationOnlyViews.length;t++){let e=void 0===this.options.ConfigurationOnlyViews[t].ViewIdentifier?`AutoView-${this.fable.getUUID()}`:this.options.ConfigurationOnlyViews[t].ViewIdentifier;this.log.info(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} adding configuration only view: ${e}`),this.pict.addView(e,this.options.ConfigurationOnlyViews[t])}this.onInitialize();let t=Object.keys(this.pict.providers),e=[];for(let i=0;i<t.length;i++){let n=this.pict.providers[t[i]];n.options.AutoInitialize&&e.push(n)}e.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let t=0;t<e.length;t++)e[t].initialize();let i=Object.keys(this.pict.views),n=[];for(let t=0;t<i.length;t++){let e=this.pict.views[i[t]];e.options.AutoInitialize&&n.push(e)}n.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let t=0;t<n.length;t++)n[t].initialize();return this.onAfterInitialize(),this.options.AutoSolveAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto solving after initialization...`),this.solve()),this.options.AutoRenderMainViewportViewAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto rendering after initialization...`),this.render()),this.initializeTimestamp=this.fable.log.getTimeStamp(),this.onCompletionOfInitialize(),!0}}initializeAsync(t){this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync:`);let e="function"==typeof t&&t;if(e||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),e=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync Auto Callback Error: ${t}`,t)}),this.initializeTimestamp)return this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} async initialize called but initialization is already completed. Aborting.`),this.onCompletionOfInitializeAsync(e);{let t=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");if(this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} beginning initialization...`),"ConfigurationOnlyViews"in this.options)for(let t=0;t<this.options.ConfigurationOnlyViews.length;t++){let e=void 0===this.options.ConfigurationOnlyViews[t].ViewIdentifier?`AutoView-${this.fable.getUUID()}`:this.options.ConfigurationOnlyViews[t].ViewIdentifier;this.log.info(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} adding configuration only view: ${e}`),this.pict.addView(e,this.options.ConfigurationOnlyViews[t])}t.anticipate(this.onBeforeInitializeAsync.bind(this)),t.anticipate(this.onInitializeAsync.bind(this));let i=Object.keys(this.pict.providers),n=[];for(let t=0;t<i.length;t++){let e=this.pict.providers[i[t]];e.options.AutoInitialize&&n.push(e)}n.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let e=0;e<n.length;e++)t.anticipate(n[e].initializeAsync.bind(n[e]));let o=Object.keys(this.pict.views),s=[];for(let t=0;t<o.length;t++){let e=this.pict.views[o[t]];e.options.AutoInitialize&&s.push(e)}s.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let e=0;e<s.length;e++){let i=s[e];t.anticipate(i.initializeAsync.bind(i))}t.anticipate(this.onAfterInitializeAsync.bind(this)),this.options.AutoLoginAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto login (asynchronously) after initialization...`),t.anticipate(this.loginAsync.bind(this))),this.options.AutoSolveAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto solving (asynchronously) after initialization...`),t.anticipate(this.solveAsync.bind(this))),this.options.AutoRenderMainViewportViewAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto rendering (asynchronously) after initialization...`),t.anticipate(this.renderMainViewportAsync.bind(this))),t.wait(t=>(t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync Error: ${t.message||t}`,{stack:t.stack}),this.initializeTimestamp=this.fable.log.getTimeStamp(),this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initialization complete.`),e()))}}onAfterInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterInitialize:`),!0}onAfterInitializeAsync(t){return this.onAfterInitialize(),t()}onCompletionOfInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onCompletionOfInitialize:`),!0}onCompletionOfInitializeAsync(t){return this.onCompletionOfInitialize(),t()}onBeforeMarshalFromViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeMarshalFromViews:`),!0}onBeforeMarshalFromViewsAsync(t){return this.onBeforeMarshalFromViews(),t()}onMarshalFromViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onMarshalFromViews:`),!0}onMarshalFromViewsAsync(t){return this.onMarshalFromViews(),t()}marshalFromViews(){this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} executing marshalFromViews() function...`),this.onBeforeMarshalFromViews();let t=Object.keys(this.pict.views),e=[];for(let i=0;i<t.length;i++){let n=this.pict.views[t[i]];e.push(n)}for(let t=0;t<e.length;t++)e[t].marshalFromView();return this.onMarshalFromViews(),this.onAfterMarshalFromViews(),this.lastMarshalFromViewsTimestamp=this.fable.log.getTimeStamp(),!0}marshalFromViewsAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewsAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewsAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalFromViewsAsync.bind(this));let n=Object.keys(this.pict.views),o=[];for(let t=0;t<n.length;t++){let e=this.pict.views[n[t]];o.push(e)}for(let t=0;t<o.length;t++)e.anticipate(o[t].marshalFromViewAsync.bind(o[t]));e.anticipate(this.onMarshalFromViewsAsync.bind(this)),e.anticipate(this.onAfterMarshalFromViewsAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewsAsync() complete.`),this.lastMarshalFromViewsTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterMarshalFromViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterMarshalFromViews:`),!0}onAfterMarshalFromViewsAsync(t){return this.onAfterMarshalFromViews(),t()}onBeforeMarshalToViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeMarshalToViews:`),!0}onBeforeMarshalToViewsAsync(t){return this.onBeforeMarshalToViews(),t()}onMarshalToViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onMarshalToViews:`),!0}onMarshalToViewsAsync(t){return this.onMarshalToViews(),t()}marshalToViews(){this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} executing marshalToViews() function...`),this.onBeforeMarshalToViews();let t=Object.keys(this.pict.views),e=[];for(let i=0;i<t.length;i++){let n=this.pict.views[t[i]];e.push(n)}for(let t=0;t<e.length;t++)e[t].marshalToView();return this.onMarshalToViews(),this.onAfterMarshalToViews(),this.lastMarshalToViewsTimestamp=this.fable.log.getTimeStamp(),!0}marshalToViewsAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewsAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewsAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalToViewsAsync.bind(this));let n=Object.keys(this.pict.views),o=[];for(let t=0;t<n.length;t++){let e=this.pict.views[n[t]];o.push(e)}for(let t=0;t<o.length;t++)e.anticipate(o[t].marshalToViewAsync.bind(o[t]));e.anticipate(this.onMarshalToViewsAsync.bind(this)),e.anticipate(this.onAfterMarshalToViewsAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewsAsync() complete.`),this.lastMarshalToViewsTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterMarshalToViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterMarshalToViews:`),!0}onAfterMarshalToViewsAsync(t){return this.onAfterMarshalToViews(),t()}onBeforeRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeRender:`),!0}onBeforeRenderAsync(t){return this.onBeforeRender(),t()}render(t,e,i,n){let o="string"!=typeof t?this.options.MainViewportViewIdentifier:t,s="string"!=typeof e?this.options.MainViewportRenderableHash:e,a="string"!=typeof i?this.options.MainViewportDestinationAddress:i,r="string"!=typeof n?this.options.MainViewportDefaultDataAddress:n;this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} VIEW Renderable[${s}] Destination[${a}] TemplateDataAddress[${r}] render:`),this.onBeforeRender();let l="string"==typeof o&&this.servicesMap.PictView[o];return l?(this.onRender(),l.render(s,a,r),this.onAfterRender(),!0):(this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} could not render from View ${o} because it is not a valid view.`),!1)}onRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onRender:`),!0}onRenderAsync(t){return this.onRender(),t()}renderAsync(t,e,i,n,o){let s="string"!=typeof t?this.options.MainViewportViewIdentifier:t,a="string"!=typeof e?this.options.MainViewportRenderableHash:e,r="string"!=typeof i?this.options.MainViewportDestinationAddress:i,l="string"!=typeof n?this.options.MainViewportDefaultDataAddress:n,c="function"==typeof o?o:"function"==typeof n?n:"function"==typeof i?i:"function"==typeof e?e:"function"==typeof t&&t;c||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),c=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync Auto Callback Error: ${t}`,t)}),this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} VIEW Renderable[${a}] Destination[${r}] TemplateDataAddress[${l}] renderAsync:`);let d=this.fable.newAnticipate();d.anticipate(this.onBeforeRenderAsync.bind(this));let p="string"==typeof s&&this.servicesMap.PictView[s];if(!p){let t=`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} could not asynchronously render from View ${s} because it is not a valid view.`;return this.pict.LogNoisiness>3&&this.log.error(t),c(new Error(t))}return d.anticipate(this.onRenderAsync.bind(this)),d.anticipate(t=>{p.renderAsync.call(p,a,r,l,t)}),d.anticipate(this.onAfterRenderAsync.bind(this)),d.wait(c)}onAfterRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterRender:`),!0}onAfterRenderAsync(t){return this.onAfterRender(),t()}renderMainViewport(){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderMainViewport:`),this.render()}renderMainViewportAsync(t){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderMainViewportAsync:`),this.renderAsync(t)}renderAutoViews(){this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} beginning renderAutoViews...`);let t=Object.keys(this.pict.views);t.sort((t,e)=>this.pict.views[t].options.AutoRenderOrdinal-this.pict.views[e].options.AutoRenderOrdinal);for(let e=0;e<t.length;e++){let i=this.pict.views[t[e]];i.options.AutoRender&&i.render()}this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync complete.`)}renderAutoViewsAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync Auto Callback Error: ${t}`,t)}),this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} beginning renderAutoViewsAsync...`);let n=Object.keys(this.pict.views);n.sort((t,e)=>this.pict.views[t].options.AutoRenderOrdinal-this.pict.views[e].options.AutoRenderOrdinal);for(let t=0;t<n.length;t++){let i=this.pict.views[n[t]];i.options.AutoRender&&e.anticipate(i.renderAsync.bind(i))}e.wait(t=>(this.lastAutoRenderTimestamp=this.fable.log.getTimeStamp(),this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync complete.`),i(t)))}get isPictApplication(){return!0}}},{"../package.json":3,"fable-serviceproviderbase":2}],5:[function(t,e,i){e.exports={name:"pict-provider",version:"1.0.12",description:"Pict Provider Base Class",main:"source/Pict-Provider.js",scripts:{start:"node source/Pict-Provider.js",test:"npx quack test",tests:"npx quack test -g",coverage:"npx quack coverage",build:"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-provider-image:local","docker-dev-run":'docker run -it -d --name pict-provider-dev -p 24125:8080 -p 30027:8086 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/pict-provider" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" pict-provider-image:local',"docker-dev-shell":"docker exec -it pict-provider-dev /bin/bash",lint:"eslint source/**",types:"tsc -p ."},types:"types/source/Pict-Provider.d.ts",repository:{type:"git",url:"git+https://github.com/stevenvelozo/pict-provider.git"},author:"steven velozo <steven@velozo.com>",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/pict-provider/issues"},homepage:"https://github.com/stevenvelozo/pict-provider#readme",devDependencies:{"@eslint/js":"^9.39.1",eslint:"^9.39.1",pict:"^1.0.351",quackage:"^1.0.58",typescript:"^5.9.3"},dependencies:{"fable-serviceproviderbase":"^3.0.19"},mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]}}},{}],6:[function(t,e,i){const n=t("fable-serviceproviderbase"),o=t("../package.json"),s={ProviderIdentifier:!1,AutoInitialize:!0,AutoInitializeOrdinal:0,AutoLoadDataWithApp:!0,AutoLoadDataOrdinal:0,AutoSolveWithApp:!0,AutoSolveOrdinal:0,Manifests:{},Templates:[]};e.exports=class extends n{constructor(t,e,i){super(t,Object.assign({},JSON.parse(JSON.stringify(s)),e),i),this.fable,this.pict,this.log,this.options,this.UUID,this.Hash,this.options.ProviderIdentifier||(this.options.ProviderIdentifier=`AutoProviderID-${this.fable.getUUID()}`),this.serviceType="PictProvider",this._Package=o,this.pict=this.fable,this.AppData=this.pict.AppData,this.Bundle=this.pict.Bundle,this.initializeTimestamp=!1,this.lastSolvedTimestamp=!1;for(let t=0;t<this.options.Templates.length;t++){let e=this.options.Templates[t];e.hasOwnProperty("Postfix")&&e.hasOwnProperty("Template")?(e.Source||(e.Source=`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} options object.`),this.pict.TemplateProvider.addDefaultTemplate(e.Prefix,e.Postfix,e.Template,e.Source)):this.log.error(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} could not load Default Template ${t} in the options array.`,e)}}onBeforeInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onBeforeInitialize:`),!0}onBeforeInitializeAsync(t){return this.onBeforeInitialize(),t()}onInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onInitialize:`),!0}onInitializeAsync(t){return this.onInitialize(),t()}initialize(){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow PROVIDER [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialize:`),this.initializeTimestamp?(this.log.warn(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialize called but initialization is already completed. Aborting.`),!1):(this.onBeforeInitialize(),this.onInitialize(),this.onAfterInitialize(),this.initializeTimestamp=this.pict.log.getTimeStamp(),!0)}initializeAsync(t){if(this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow PROVIDER [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initializeAsync:`),this.initializeTimestamp)return this.log.warn(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} async initialize called but initialization is already completed. Aborting.`),t();{let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate");this.pict.LogNoisiness>0&&this.log.info(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} beginning initialization...`),e.anticipate(this.onBeforeInitializeAsync.bind(this)),e.anticipate(this.onInitializeAsync.bind(this)),e.anticipate(this.onAfterInitializeAsync.bind(this)),e.wait(e=>(this.initializeTimestamp=this.pict.log.getTimeStamp(),e?this.log.error(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialization failed: ${e.message||e}`,{Stack:e.stack}):this.pict.LogNoisiness>0&&this.log.info(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialization complete.`),t()))}}onAfterInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onAfterInitialize:`),!0}onAfterInitializeAsync(t){return this.onAfterInitialize(),t()}onPreRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onPreRender:`),!0}onPreRenderAsync(t){return this.onPreRender(),t()}render(){return this.onPreRender()}renderAsync(t){return this.onPreRender(),t()}onPreSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onPreSolve:`),!0}onPreSolveAsync(t){return this.onPreSolve(),t()}solve(){return this.onPreSolve()}solveAsync(t){return this.onPreSolve(),t()}onBeforeLoadDataAsync(t){return t()}onLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onLoadDataAsync:`),t()}onAfterLoadDataAsync(t){return t()}onBeforeSaveDataAsync(t){return t()}onSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onSaveDataAsync:`),t()}onAfterSaveDataAsync(t){return t()}}},{"../package.json":5,"fable-serviceproviderbase":2}],7:[function(t,e,i){e.exports={RenderOnLoad:!0,DefaultRenderable:"Histogram-Wrap",DefaultDestinationAddress:"#Histogram-Container-Div",Templates:[{Hash:"Histogram-Container",Template:"\x3c!-- Histogram Container Rendering Soon --\x3e"}],Renderables:[{RenderableHash:"Histogram-Wrap",TemplateHash:"Histogram-Container",DestinationAddress:"#Histogram-Container-Div"}],TargetElementAddress:"#Histogram-Container-Div",DataAddress:!1,Bins:[],LabelProperty:"Label",ValueProperty:"Value",Orientation:"vertical",RenderMode:"browser",MaxBarSize:200,BarThickness:30,BarGap:4,FillContainer:!1,ShowValues:!0,ShowLabels:!0,LabelInterval:0,BarColor:"#4A90D9",SelectedBarColor:"#2ECC71",SelectionRangeColor:"#85C1E9",Selectable:!1,SelectionMode:"range",SelectionDataAddress:!1,InitialSelection:null,BarCharacter:"█",BarPartialCharacters:[" ","▁","▂","▃","▄","▅","▆","▇","█"],EmptyCharacter:" ",SliderCharacter:"│",SliderHandleCharacter:"◆",TextWidth:60,TextHeight:15,CSS:".pict-histogram-container\n{\n\tdisplay: inline-block;\n\tposition: relative;\n\tfont-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n\tfont-size: 12px;\n\tuser-select: none;\n}\n.pict-histogram-chart\n{\n\tdisplay: flex;\n\talign-items: flex-end;\n\tposition: relative;\n}\n.pict-histogram-container.pict-histogram-horizontal\n{\n\tdisplay: inline-flex;\n\tflex-direction: row;\n\talign-items: stretch;\n}\n.pict-histogram-chart.pict-histogram-horizontal\n{\n\tflex-direction: column;\n\talign-items: flex-start;\n}\n.pict-histogram-bar-group\n{\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tcursor: default;\n\tflex-shrink: 0;\n}\n.pict-histogram-horizontal .pict-histogram-bar-group\n{\n\tflex-direction: row;\n\talign-items: center;\n}\n.pict-histogram-bar\n{\n\ttransition: background-color 0.15s ease, height 0.2s ease, width 0.2s ease;\n\tborder-radius: 2px 2px 0 0;\n\tmin-width: 1px;\n\tmin-height: 1px;\n}\n.pict-histogram-horizontal .pict-histogram-bar\n{\n\tborder-radius: 0 2px 2px 0;\n}\n.pict-histogram-bar.pict-histogram-selectable\n{\n\tcursor: pointer;\n}\n.pict-histogram-bar.pict-histogram-selectable:hover\n{\n\topacity: 0.8;\n}\n.pict-histogram-bar.pict-histogram-selected\n{\n\tbox-shadow: 0 0 0 2px rgba(46, 204, 113, 0.4);\n}\n.pict-histogram-bar.pict-histogram-in-range\n{\n\topacity: 0.9;\n}\n.pict-histogram-value-label\n{\n\ttext-align: center;\n\tcolor: #666;\n\tfont-size: 11px;\n\tpadding: 2px 0;\n\twhite-space: nowrap;\n}\n.pict-histogram-horizontal .pict-histogram-value-label\n{\n\tpadding: 0 4px;\n}\n.pict-histogram-bin-label\n{\n\ttext-align: center;\n\tcolor: #333;\n\tfont-size: 11px;\n\tpadding: 4px 2px 0 2px;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n.pict-histogram-horizontal .pict-histogram-bin-label\n{\n\tpadding: 0 4px 0 0;\n\ttext-align: right;\n\tmin-width: 40px;\n}\n.pict-histogram-range-slider-container\n{\n\tposition: relative;\n\twidth: 100%;\n\theight: 24px;\n\tmargin-top: 4px;\n}\n.pict-histogram-horizontal .pict-histogram-range-slider-container\n{\n\twidth: 24px;\n\theight: auto;\n\talign-self: stretch;\n\tmargin-top: 0;\n\tmargin-left: 4px;\n}\n.pict-histogram-range-track\n{\n\tposition: absolute;\n\ttop: 10px;\n\tleft: 0;\n\tright: 0;\n\theight: 4px;\n\tbackground: #E0E0E0;\n\tborder-radius: 2px;\n}\n.pict-histogram-horizontal .pict-histogram-range-track\n{\n\ttop: 0;\n\tleft: 10px;\n\tright: auto;\n\tbottom: 0;\n\twidth: 4px;\n\theight: auto;\n}\n.pict-histogram-range-fill\n{\n\tposition: absolute;\n\ttop: 10px;\n\theight: 4px;\n\tbackground: #4A90D9;\n\tborder-radius: 2px;\n}\n.pict-histogram-horizontal .pict-histogram-range-fill\n{\n\ttop: auto;\n\tleft: 10px;\n\twidth: 4px;\n\theight: auto;\n}\n.pict-histogram-range-handle\n{\n\tposition: absolute;\n\ttop: 4px;\n\twidth: 16px;\n\theight: 16px;\n\tbackground: #fff;\n\tborder: 2px solid #4A90D9;\n\tborder-radius: 50%;\n\tcursor: grab;\n\tz-index: 2;\n\ttransform: translateX(-50%);\n}\n.pict-histogram-horizontal .pict-histogram-range-handle\n{\n\ttop: auto;\n\tleft: 4px;\n\ttransform: translateY(-50%);\n}\n.pict-histogram-range-handle:active\n{\n\tcursor: grabbing;\n\tbackground: #4A90D9;\n}\n.pict-histogram-range-handle:active,\n.pict-histogram-range-handle:focus\n{\n\tbox-shadow: 0 0 0 3px rgba(74, 144, 217, 0.3);\n\toutline: none;\n}\n.pict-histogram-container.pict-histogram-fill\n{\n\tdisplay: block;\n\twidth: 100%;\n}\n.pict-histogram-fill .pict-histogram-chart\n{\n\twidth: 100%;\n}\n.pict-histogram-fill .pict-histogram-bar-group\n{\n\tflex: 1 1 0%;\n\tmin-width: 0;\n}\n.pict-histogram-fill .pict-histogram-bar\n{\n\twidth: 100%;\n}\n.pict-histogram-axis-line\n{\n\twidth: 100%;\n\theight: 1px;\n\tbackground: #ccc;\n}\n.pict-histogram-label-row\n{\n\tdisplay: flex;\n\twidth: 100%;\n}\n.pict-histogram-fill-label\n{\n\tfont-size: 10px;\n\tcolor: #666;\n\ttext-align: center;\n\twhite-space: nowrap;\n\toverflow: visible;\n\tline-height: 16px;\n}\n"}},{}],8:[function(t,e,i){const n=t("pict-view"),o=t("./Pict-Section-Histogram-DefaultConfiguration.js"),s=t("./renderers/Pict-Histogram-Renderer-Browser.js"),a=t("./renderers/Pict-Histogram-Renderer-ConsoleUI.js"),r=t("./renderers/Pict-Histogram-Renderer-CLI.js");e.exports=class extends n{constructor(t,e,i){super(t,Object.assign({},o,e),i),this.initialRenderComplete=!1,this._selectedIndices=new Set,this._selectionRangeStart=0,this._selectionRangeEnd=0,this._renderer=this._resolveRenderer(),this._applyInitialSelection()}_applyInitialSelection(){if(this.options.InitialSelection)this.setSelection(this.options.InitialSelection);else if(this.options.Selectable&&"range"===this.options.SelectionMode){let t=this.getBins();this._selectionRangeStart=0,this._selectionRangeEnd=Math.max(0,t.length-1),this._syncSelectionFromRange()}}_resolveRenderer(){switch(this.options.RenderMode){case"consoleui":return a;case"cli":return r;default:return s}}getBins(){if(this.options.DataAddress){const t={Fable:this.fable,Pict:this.fable,AppData:this.AppData,Bundle:this.Bundle,Options:this.options};let e=this.fable.manifest.getValueByHash(t,this.options.DataAddress);if(Array.isArray(e))return e;this.log.warn(`PICT-Histogram DataAddress [${this.options.DataAddress}] did not return an array.`)}return this.options.Bins||[]}setBins(t){if(Array.isArray(t)){if(this.options.Bins=t,this.options.DataAddress){const e={Fable:this.fable,Pict:this.fable,AppData:this.AppData,Bundle:this.Bundle,Options:this.options};this.fable.manifest.setValueByHash(e,this.options.DataAddress,t)}}else this.log.warn("PICT-Histogram setBins requires an array.")}isIndexSelected(t){return!!this.options.Selectable&&("range"===this.options.SelectionMode?t===this._selectionRangeStart||t===this._selectionRangeEnd:this._selectedIndices.has(t))}isIndexInRange(t){return!(!this.options.Selectable||"range"!==this.options.SelectionMode)&&(t>this._selectionRangeStart&&t<this._selectionRangeEnd)}getSelection(){if("range"===this.options.SelectionMode){let t=this.getBins(),e=[];for(let t=this._selectionRangeStart;t<=this._selectionRangeEnd;t++)e.push(t);return{Mode:"range",RangeStart:this._selectionRangeStart,RangeEnd:this._selectionRangeEnd,SelectedIndices:e,StartLabel:(t[this._selectionRangeStart]||{})[this.options.LabelProperty],EndLabel:(t[this._selectionRangeEnd]||{})[this.options.LabelProperty]}}return{Mode:this.options.SelectionMode,SelectedIndices:Array.from(this._selectedIndices).sort((t,e)=>t-e)}}setSelection(t){"range"===this.options.SelectionMode?t&&"number"==typeof t.Start&&"number"==typeof t.End&&(this._selectionRangeStart=t.Start,this._selectionRangeEnd=t.End,this._syncSelectionFromRange()):Array.isArray(t)&&(this._selectedIndices=new Set(t)),this._writeSelectionToAddress()}handleBarClick(t){"single"===this.options.SelectionMode?(this._selectedIndices.clear(),this._selectedIndices.add(t)):"multiple"===this.options.SelectionMode&&(this._selectedIndices.has(t)?this._selectedIndices.delete(t):this._selectedIndices.add(t)),this._writeSelectionToAddress(),this.onSelectionChange(this.getSelection()),this.renderHistogram()}handleRangeBarClick(t){Math.abs(t-this._selectionRangeStart)<=Math.abs(t-this._selectionRangeEnd)?this._selectionRangeStart=Math.min(t,this._selectionRangeEnd):this._selectionRangeEnd=Math.max(t,this._selectionRangeStart),this._syncSelectionFromRange(),this._writeSelectionToAddress(),this.onSelectionChange(this.getSelection()),this.renderHistogram()}_syncSelectionFromRange(){this._selectedIndices.clear();for(let t=this._selectionRangeStart;t<=this._selectionRangeEnd;t++)this._selectedIndices.add(t)}_writeSelectionToAddress(){if(!this.options.SelectionDataAddress)return;const t={Fable:this.fable,Pict:this.fable,AppData:this.AppData,Bundle:this.Bundle,Options:this.options};this.fable.manifest.setValueByHash(t,this.options.SelectionDataAddress,this.getSelection())}onSelectionChange(t){}onBeforeInitialize(){return super.onBeforeInitialize(),super.onBeforeInitialize()}onAfterRender(t){return this.pict.CSSMap.injectCSS(),this.initialRenderComplete||(this.onAfterInitialRender(),this.initialRenderComplete=!0),super.onAfterRender(t)}onAfterInitialRender(){this.renderHistogram()}renderHistogram(){this.pict.CSSMap&&this.pict.CSSMap.injectCSS(),this._renderer.render(this),this._renderer.wireEvents(this),this.initialRenderComplete=!0}marshalToView(){super.marshalToView(),this.initialRenderComplete&&this.renderHistogram()}marshalFromView(){super.marshalFromView(),this._writeSelectionToAddress()}setOrientation(t){"vertical"===t||"horizontal"===t?(this.options.Orientation=t,this.initialRenderComplete&&this.renderHistogram()):this.log.warn(`PICT-Histogram invalid orientation: ${t}`)}setRenderMode(t){this.options.RenderMode=t,this._renderer=this._resolveRenderer(),this.initialRenderComplete&&this.renderHistogram()}toText(){return"vertical"===this.options.Orientation?a.renderVertical(this):a.renderHorizontal(this)}},e.exports.default_configuration=o,e.exports.renderers={browser:s,consoleui:a,cli:r}},{"./Pict-Section-Histogram-DefaultConfiguration.js":7,"./renderers/Pict-Histogram-Renderer-Browser.js":9,"./renderers/Pict-Histogram-Renderer-CLI.js":10,"./renderers/Pict-Histogram-Renderer-ConsoleUI.js":11,"pict-view":13}],9:[function(t,e,i){function n(t,e,i,n,o,s,a){let r=t[n.LabelProperty]||"",l=t[n.ValueProperty]||0,c="vertical"===n.Orientation,d=o?n.SelectedBarColor:s?n.SelectionRangeColor:n.BarColor,p=n.Selectable?" pict-histogram-selectable":"",h=o?" pict-histogram-selected":"",u=s?" pict-histogram-in-range":"",g=n.FillContainer,m="";m=c?g?`height:${i}px;background-color:${d};`:`height:${i}px;width:${n.BarThickness}px;background-color:${d};`:g?`width:${i}px;background-color:${d};`:`width:${i}px;height:${n.BarThickness}px;background-color:${d};`;let f=n.BarThickness+n.BarGap,v="";v=g?"":c?`margin:0 ${n.BarGap/2}px;width:${f}px;`:`margin:${n.BarGap/2}px 0;`;let b=`<div class="pict-histogram-bar-group" style="${v}" data-histogram-index="${e}">`;if(c)n.ShowValues&&!g&&(b+=`<div class="pict-histogram-value-label" style="width:${f}px;">${l}</div>`),b+=`<div class="pict-histogram-bar${p}${h}${u}" style="${m}" data-histogram-index="${e}"></div>`,n.ShowLabels&&!g&&(b+=`<div class="pict-histogram-bin-label" style="width:${f}px;">${r}</div>`);else{if(n.ShowLabels){b+=`<div class="pict-histogram-bin-label" style="${a?`width:${a}px;min-width:${a}px;`:""}">${r}</div>`}b+=`<div class="pict-histogram-bar${p}${h}${u}" style="${m}" data-histogram-index="${e}"></div>`,n.ShowValues&&(b+=`<div class="pict-histogram-value-label">${l}</div>`)}return b+="</div>",b}function o(t,e,i){let n=e.getAttribute("data-handle"),o="vertical"===t.options.Orientation,s=!1;function a(e){if(!s)return;let a=t.getBins();if(!a||0===a.length)return;let r=function(){let t=i.querySelector(".pict-histogram-range-slider-container");if(!t)return{start:0,size:1};let e=t.getBoundingClientRect();return o?{start:e.left,size:e.width||1}:{start:e.top,size:e.height||1}}(),l=((o?e.clientX:e.clientY)-r.start)/r.size;l=Math.max(0,Math.min(1,l));let c=Math.round(l*(a.length-1));"start"===n?(c>t._selectionRangeEnd&&(c=t._selectionRangeEnd),t._selectionRangeStart=c):(c<t._selectionRangeStart&&(c=t._selectionRangeStart),t._selectionRangeEnd=c),t._syncSelectionFromRange(),t.renderHistogram()}function r(){s&&(s=!1,"undefined"!=typeof document&&(document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",r)))}e.addEventListener("mousedown",t=>{t.preventDefault(),s=!0,"undefined"!=typeof document&&(document.addEventListener("mousemove",a),document.addEventListener("mouseup",r))})}e.exports={render:function(t){let e=t.getBins();if(!e||0===e.length)return void t.services.ContentAssignment.assignContent(t.options.TargetElementAddress,'<div class="pict-histogram-container"><em>No histogram data</em></div>');let i=0;for(let n=0;n<e.length;n++){let o=e[n][t.options.ValueProperty]||0;o>i&&(i=o)}0===i&&(i=1);let o="vertical"===t.options.Orientation,s=o?"pict-histogram-vertical":"pict-histogram-horizontal",a=t.options.FillContainer?" pict-histogram-fill":"",r=0;if(!o&&t.options.ShowLabels&&!t.options.FillContainer){for(let i=0;i<e.length;i++){let n=6.5*String(e[i][t.options.LabelProperty]||"").length+8;n>r&&(r=n)}r=Math.max(r,40)}let l=`<div class="pict-histogram-container ${s}${a}">`;l+=`<div class="pict-histogram-chart ${s}${a}">`;for(let o=0;o<e.length;o++){let s=e[o][t.options.ValueProperty]||0,a=Math.round(s/i*t.options.MaxBarSize);s>0&&a<1&&(a=1);let c=t.isIndexSelected(o),d=!c&&t.isIndexInRange(o);l+=n(e[o],o,a,t.options,c,d,r)}l+="</div>",t.options.FillContainer&&o&&t.options.ShowLabels&&(l+='<div class="pict-histogram-axis-line"></div>',l+=function(t,e){if(!e||0===e.length)return"";let i=t.options.LabelInterval||0;if(i<=0){let n=t.services.ContentAssignment.getElement(t.options.TargetElementAddress),o=800;if(n&&n.length>0&&n[0]&&(o=n[0].clientWidth||800),e.length>0){let t=o/e.length;i=Math.max(1,Math.ceil(80/t))}else i=1}let n='<div class="pict-histogram-label-row">';for(let o=0;o<e.length;o++)if(o%i===0){let s=e[o][t.options.LabelProperty]||"",a=Math.min(i,e.length-o);n+=`<div class="pict-histogram-fill-label" style="flex:${a};">${s}</div>`,o+=a-1}return n+="</div>",n}(t,e)),t.options.Selectable&&"range"===t.options.SelectionMode&&(l+=function(t){let e=t.getBins();if(!e||0===e.length)return"";let i=t._selectionRangeStart,n=t._selectionRangeEnd,o=e.length-1,s=o>0?i/o*100:0,a=o>0?n/o*100:100,r='<div class="pict-histogram-range-slider-container">';return r+='<div class="pict-histogram-range-track"></div>',"vertical"===t.options.Orientation?(r+=`<div class="pict-histogram-range-fill" style="left:${s}%;right:${100-a}%;"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-start" tabindex="0" style="left:${s}%;" data-handle="start"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-end" tabindex="0" style="left:${a}%;" data-handle="end"></div>`):(r+=`<div class="pict-histogram-range-fill" style="top:${s}%;bottom:${100-a}%;"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-start" tabindex="0" style="top:${s}%;" data-handle="start"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-end" tabindex="0" style="top:${a}%;" data-handle="end"></div>`),r+="</div>",r}(t)),l+="</div>",t.services.ContentAssignment.assignContent(t.options.TargetElementAddress,l)},wireEvents:function(t){if(!t.options.Selectable)return;let e=t.services.ContentAssignment.getElement(t.options.TargetElementAddress);if(!e||e.length<1)return;let i=e[0];if(i){if("single"===t.options.SelectionMode||"multiple"===t.options.SelectionMode){let e=i.querySelectorAll(".pict-histogram-bar[data-histogram-index]");for(let i=0;i<e.length;i++)e[i].addEventListener("click",e=>{let i=parseInt(e.currentTarget.getAttribute("data-histogram-index"),10);isNaN(i)||t.handleBarClick(i)})}if("range"===t.options.SelectionMode){let e=i.querySelectorAll(".pict-histogram-bar[data-histogram-index]");for(let i=0;i<e.length;i++)e[i].addEventListener("click",e=>{let i=parseInt(e.currentTarget.getAttribute("data-histogram-index"),10);isNaN(i)||t.handleRangeBarClick(i)});let n=i.querySelectorAll(".pict-histogram-range-handle");for(let e=0;e<n.length;e++)o(t,n[e],i)}}}}},{}],10:[function(t,e,i){(function(t){(function(){const i={black:"[30m",red:"[31m",green:"[32m",yellow:"[33m",blue:"[34m",magenta:"[35m",cyan:"[36m",white:"[37m",reset:"[0m",bold:"[1m",dim:"[2m"};function n(t){if(!t)return i.blue;let e=t.toLowerCase();if(i[e])return i[e];if("#"===e.charAt(0)&&e.length>=7){let t=parseInt(e.substring(1,3),16),n=parseInt(e.substring(3,5),16),o=parseInt(e.substring(5,7),16);if(n>t&&n>o)return i.green;if(t>n&&t>o)return i.red;if(o>t&&o>n)return i.blue;if(t>200&&n>200)return i.yellow;if(t>200&&o>200)return i.magenta;if(n>200&&o>200)return i.cyan}return i.blue}function o(t){let e=t.getBins(),o=t.options,s=o.TextHeight||15,r=o.BarCharacter,c=o.BarPartialCharacters,d=n(o.BarColor),p=n(o.SelectedBarColor),h=n(o.SelectionRangeColor),u=i.reset;if(!e||0===e.length)return"(no data)\n";let g=0;for(let t=0;t<e.length;t++){let i=e[t][o.ValueProperty]||0;i>g&&(g=i)}0===g&&(g=1);let m=String(g).length+1,f=[];for(let n=s;n>=1;n--){let l="";n===s?l+=i.dim+a(String(g),m)+"|"+u:1===n?l+=i.dim+a("0",m)+"|"+u:n===Math.ceil(s/2)?l+=i.dim+a(String(Math.round(g/2)),m)+"|"+u:l+=i.dim+a("",m)+"|"+u;for(let i=0;i<e.length;i++){let a=(e[i][o.ValueProperty]||0)/g*s,m=Math.floor(a),f=a-m,v=t.isIndexSelected(i),b=!v&&t.isIndexInRange(i),y=v?p:b?h:d,S=" ";if(n<=m)S=r;else if(n===m+1&&f>0){S=c[Math.round(f*(c.length-1))]}l+=" "!==S?" "+y+S+S+S+u:" "}f.push(l)}let v=i.dim+a("",m)+"+";for(let t=0;t<e.length;t++)v+="----";if(v+=u,f.push(v),o.ShowLabels){let t=a("",m)+" ";for(let i=0;i<e.length;i++){t+=l(String(e[i][o.LabelProperty]||"").substring(0,4),4)}f.push(t)}if(o.Selectable&&"range"===o.SelectionMode){let n=t._selectionRangeStart,s=t._selectionRangeEnd,a=e[n]?e[n][o.LabelProperty]:n,r=e[s]?e[s][o.LabelProperty]:s;f.push(""),f.push(i.bold+" Selection: "+a+" - "+r+u)}return f.join("\n")+"\n"}function s(t){let e=t.getBins(),o=t.options,s=o.TextWidth||60,a=o.BarCharacter,l=n(o.BarColor),c=n(o.SelectedBarColor),d=n(o.SelectionRangeColor),p=i.reset;if(!e||0===e.length)return"(no data)\n";let h=0,u=0;for(let t=0;t<e.length;t++){let i=e[t][o.ValueProperty]||0;i>h&&(h=i);let n=String(e[t][o.LabelProperty]||"");n.length>u&&(u=n.length)}0===h&&(h=1);let g=Math.min(u,12),m=s-g-String(h).length-4;m<10&&(m=10);let f=[];for(let n=0;n<e.length;n++){let s=e[n][o.ValueProperty]||0,u=String(e[n][o.LabelProperty]||""),v=Math.round(s/h*m),b=t.isIndexSelected(n),y=!b&&t.isIndexInRange(n),S=b?c:y?d:l,w="";for(let t=0;t<v;t++)w+=a;let D=i.dim+r(u.substring(0,g),g)+" |"+p;D+=S+w+p,D+=" "+s,b?D+=i.bold+" *"+p:y&&(D+=i.dim+" ~"+p),f.push(D)}if(o.Selectable&&"range"===o.SelectionMode){let n=t._selectionRangeStart,s=t._selectionRangeEnd,a=e[n]?e[n][o.LabelProperty]:n,r=e[s]?e[s][o.LabelProperty]:s;f.push(""),f.push(i.bold+" Selection: "+a+" - "+r+p)}return f.join("\n")+"\n"}function a(t,e){let i=String(t);for(;i.length<e;)i=" "+i;return i}function r(t,e){let i=String(t);for(;i.length<e;)i+=" ";return i}function l(t,e){let i=String(t);for(;i.length<e;)i=i.length%2==0?i+" ":" "+i;return i}e.exports={render:function(e){let i;i="vertical"===e.options.Orientation?o(e):s(e),e.services&&e.services.ContentAssignment?e.services.ContentAssignment.assignContent(e.options.TargetElementAddress,i):void 0!==t&&t.stdout&&t.stdout.write(i)},wireEvents:function(){},renderVertical:o,renderHorizontal:s,colorToAnsi:n,ANSI_COLORS:i}}).call(this)}).call(this,t("_process"))},{_process:14}],11:[function(t,e,i){function n(t){let e=t.getBins(),i=t.options,n=i.TextHeight||15,o=i.BarCharacter,a=i.BarPartialCharacters,l=i.EmptyCharacter;if(!e||0===e.length)return"(no data)";let c=0;for(let t=0;t<e.length;t++){let n=e[t][i.ValueProperty]||0;n>c&&(c=n)}0===c&&(c=1);let d=String(c).length+1,p=[];for(let r=n;r>=1;r--){let h="";r===n?h+=s(String(c),d)+"|":1===r?h+=s("0",d)+"|":r===Math.ceil(n/2)?h+=s(String(Math.round(c/2)),d)+"|":h+=s("",d)+"|";for(let s=0;s<e.length;s++){let d=(e[s][i.ValueProperty]||0)/c*n,p=Math.floor(d),u=d-p,g=l;if(r<=p)g=o;else if(r===p+1&&u>0){g=a[Math.round(u*(a.length-1))]}let m=t.isIndexSelected(s),f=!m&&t.isIndexInRange(s);m&&g!==l?g="*":f&&g!==l&&(g="#"),h+=" "+g+g+g}p.push(h)}let h=s("",d)+"+";for(let t=0;t<e.length;t++)h+="----";if(p.push(h),i.ShowLabels){let t=s("",d)+" ";for(let n=0;n<e.length;n++){t+=r(String(e[n][i.LabelProperty]||"").substring(0,4),4)}p.push(t)}if(i.Selectable&&"range"===i.SelectionMode){let i=s("",d)+" ";for(let n=0;n<e.length;n++)n===t._selectionRangeStart?i+=" [ ":n===t._selectionRangeEnd?i+=" ] ":n>t._selectionRangeStart&&n<t._selectionRangeEnd?i+=" - ":i+=" ";p.push(i)}return p.join("\n")}function o(t){let e=t.getBins(),i=t.options,n=i.TextWidth||60,o=i.BarCharacter,s=i.BarPartialCharacters;if(!e||0===e.length)return"(no data)";let r=0,l=0;for(let t=0;t<e.length;t++){let n=e[t][i.ValueProperty]||0;n>r&&(r=n);let o=String(e[t][i.LabelProperty]||"");o.length>l&&(l=o.length)}0===r&&(r=1);let c=Math.min(l,12),d=n-c-2;d<10&&(d=10);let p=[];for(let n=0;n<e.length;n++){let l=e[n][i.ValueProperty]||0,h=String(e[n][i.LabelProperty]||""),u=l/r*d,g=Math.floor(u),m=u-g,f="";for(let t=0;t<g;t++)f+=o;if(m>0&&g<d){f+=s[Math.round(m*(s.length-1))]}let v=t.isIndexSelected(n),b=!v&&t.isIndexInRange(n),y=v?"*":b?"~":"",S=i.ShowValues?" "+l:"",w=a(h.substring(0,c),c)+" |"+f+S+y;p.push(w)}return i.Selectable&&"range"===i.SelectionMode&&(p.push(""),p.push(a("",c)+" Range: ["+t._selectionRangeStart+" - "+t._selectionRangeEnd+"]")),p.join("\n")}function s(t,e){let i=String(t);for(;i.length<e;)i=" "+i;return i}function a(t,e){let i=String(t);for(;i.length<e;)i+=" ";return i}function r(t,e){let i=String(t);for(;i.length<e;)i=i.length%2==0?i+" ":" "+i;return i}e.exports={render:function(t){let e;e="vertical"===t.options.Orientation?n(t):o(t),t.services.ContentAssignment.assignContent(t.options.TargetElementAddress,e)},wireEvents:function(){},renderVertical:n,renderHorizontal:o}},{}],12:[function(t,e,i){e.exports={name:"pict-view",version:"1.0.67",description:"Pict View Base Class",main:"source/Pict-View.js",scripts:{test:"npx quack test",tests:"npx quack test -g",start:"node source/Pict-View.js",coverage:"npx quack coverage",build:"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-view-image:local","docker-dev-run":'docker run -it -d --name pict-view-dev -p 30001:8080 -p 38086:8086 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/pict-view" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" pict-view-image:local',"docker-dev-shell":"docker exec -it pict-view-dev /bin/bash",types:"tsc -p .",lint:"eslint source/**"},types:"types/source/Pict-View.d.ts",repository:{type:"git",url:"git+https://github.com/stevenvelozo/pict-view.git"},author:"steven velozo <steven@velozo.com>",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/pict-view/issues"},homepage:"https://github.com/stevenvelozo/pict-view#readme",devDependencies:{"@eslint/js":"^9.39.1","browser-env":"^3.3.0",eslint:"^9.39.1",pict:"^1.0.348",quackage:"^1.0.58",typescript:"^5.9.3"},mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},dependencies:{fable:"^3.1.63","fable-serviceproviderbase":"^3.0.19"}}},{}],13:[function(t,e,i){const n=t("fable-serviceproviderbase"),o=t("../package.json"),s={DefaultRenderable:!1,DefaultDestinationAddress:!1,DefaultTemplateRecordAddress:!1,ViewIdentifier:!1,AutoInitialize:!0,AutoInitializeOrdinal:0,AutoRender:!0,AutoRenderOrdinal:0,AutoSolveWithApp:!0,AutoSolveOrdinal:0,CSSHash:!1,CSS:!1,CSSProvider:!1,CSSPriority:500,Templates:[],DefaultTemplates:[],Renderables:[],Manifests:{}};e.exports=class extends n{constructor(t,e,i){super(t,Object.assign({},JSON.parse(JSON.stringify(s)),e),i),this.fable,this.options,this.UUID,this.Hash,this.log;const n=this.Hash===this.UUID;this.UUID=`V-${this.UUID}`,n&&(this.Hash=this.UUID),this.options.ViewIdentifier||(this.options.ViewIdentifier=`AutoViewID-${this.fable.getUUID()}`),this.serviceType="PictView",this._Package=o,this.pict=this.fable,this.AppData=this.pict.AppData,this.Bundle=this.pict.Bundle,this.initializeTimestamp=!1,this.lastSolvedTimestamp=!1,this.lastRenderedTimestamp=!1,this.lastMarshalFromViewTimestamp=!1,this.lastMarshalToViewTimestamp=!1,this.pict.instantiateServiceProviderIfNotExists("TransactionTracking");for(let t=0;t<this.options.Templates.length;t++){let e=this.options.Templates[t];"Hash"in e&&"Template"in e?(e.Source||(e.Source=`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} options object.`),this.pict.TemplateProvider.addTemplate(e.Hash,e.Template,e.Source)):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not load Template ${t} in the options array.`,e)}for(let t=0;t<this.options.DefaultTemplates.length;t++){let e=this.options.DefaultTemplates[t];"Postfix"in e&&"Template"in e?(e.Source||(e.Source=`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} options object.`),this.pict.TemplateProvider.addDefaultTemplate(e.Prefix,e.Postfix,e.Template,e.Source)):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not load Default Template ${t} in the options array.`,e)}if(this.options.CSS){let t=this.options.CSSHash?this.options.CSSHash:`View-${this.options.ViewIdentifier}`,e=this.options.CSSProvider?this.options.CSSProvider:t;this.pict.CSSMap.addCSS(t,this.options.CSS,e,this.options.CSSPriority)}this.renderables={};for(let t=0;t<this.options.Renderables.length;t++){let e=this.options.Renderables[t];this.addRenderable(e)}}addRenderable(t,e,i,n,o){let s;if("object"==typeof t)s=t;else{s={RenderableHash:t,TemplateHash:e,DefaultTemplateRecordAddress:i,ContentDestinationAddress:n,RenderMethod:"string"!=typeof o?o:"replace"}}"string"!=typeof s.RenderableHash||"string"!=typeof s.TemplateHash?this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not load Renderable; RenderableHash or TemplateHash are invalid.`,s):(this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} adding renderable [${s.RenderableHash}] pointed to template ${s.TemplateHash}.`),this.renderables[s.RenderableHash]=s)}onBeforeInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeInitialize:`),!0}onBeforeInitializeAsync(t){return this.onBeforeInitialize(),t()}onInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onInitialize:`),!0}onInitializeAsync(t){return this.onInitialize(),t()}initialize(){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialize:`),this.initializeTimestamp?(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialize called but initialization is already completed. Aborting.`),!1):(this.onBeforeInitialize(),this.onInitialize(),this.onAfterInitialize(),this.initializeTimestamp=this.pict.log.getTimeStamp(),!0)}initializeAsync(t){if(this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initializeAsync:`),this.initializeTimestamp)return this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} async initialize called but initialization is already completed. Aborting.`),t();{let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate");this.pict.LogNoisiness>0&&this.log.info(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} beginning initialization...`),e.anticipate(this.onBeforeInitializeAsync.bind(this)),e.anticipate(this.onInitializeAsync.bind(this)),e.anticipate(this.onAfterInitializeAsync.bind(this)),e.wait(e=>(e&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialization failed: ${e.message||e}`,{stack:e.stack}),this.initializeTimestamp=this.pict.log.getTimeStamp(),this.pict.LogNoisiness>0&&this.log.info(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialization complete.`),t()))}}onAfterInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterInitialize:`),!0}onAfterInitializeAsync(t){return this.onAfterInitialize(),t()}onBeforeRender(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeRender:`),!0}onBeforeRenderAsync(t,e){return this.onBeforeRender(e),t()}onBeforeProject(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeProject:`),!0}onBeforeProjectAsync(t,e){return this.onBeforeProject(e),t()}buildRenderOptions(t,e,i){let n={Valid:!0};return n.RenderableHash="string"==typeof t?t:"string"==typeof this.options.DefaultRenderable&&this.options.DefaultRenderable,n.RenderableHash||(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not find a suitable RenderableHash ${n.RenderableHash} (param ${t}because it is not a valid renderable.`),n.Valid=!1),n.Renderable=this.renderables[n.RenderableHash],n.Renderable||(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${n.RenderableHash} (param ${t}) because it does not exist.`),n.Valid=!1),n.DestinationAddress="string"==typeof e?e:"string"==typeof n.Renderable.ContentDestinationAddress?n.Renderable.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress&&this.options.DefaultDestinationAddress,n.DestinationAddress||(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${n.RenderableHash} (param ${t}) because it does not have a valid destination address (param ${e}).`),n.Valid=!1),"object"==typeof i?(n.RecordAddress="Passed in as object",n.Record=i):(n.RecordAddress="string"==typeof i?i:"string"==typeof n.Renderable.DefaultTemplateRecordAddress?n.Renderable.DefaultTemplateRecordAddress:"string"==typeof this.options.DefaultTemplateRecordAddress&&this.options.DefaultTemplateRecordAddress,n.Record="string"==typeof n.RecordAddress?this.pict.DataProvider.getDataByAddress(n.RecordAddress):void 0),n}assignRenderContent(t,e,i){return this.pict.ContentAssignment.projectContent(t.RenderMethod,e,i,t.TestAddress)}render(t,e,i,n){return this.renderWithScope(this,t,e,i,n)}renderWithScope(t,e,i,n,o){let s,a,r,l="string"==typeof e?e:"string"==typeof this.options.DefaultRenderable&&this.options.DefaultRenderable;return l?("__Virtual"==l?s={RenderableHash:"__Virtual",TemplateHash:this.renderables[this.options.DefaultRenderable].TemplateHash,ContentDestinationAddress:"string"==typeof i?i:"string"==typeof s.ContentDestinationAddress?s.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null,RenderMethod:"virtual-assignment",TransactionHash:o&&o.TransactionHash,RootRenderableViewHash:o&&o.RootRenderableViewHash}:(s=Object.assign({},this.renderables[l]),s.ContentDestinationAddress="string"==typeof i?i:"string"==typeof s.ContentDestinationAddress?s.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null),s.TransactionHash||(s.TransactionHash=`ViewRender-V-${this.options.ViewIdentifier}-R-${l}-U-${this.pict.getUUID()}`,s.RootRenderableViewHash=this.Hash,this.pict.TransactionTracking.registerTransaction(s.TransactionHash)),s?s.ContentDestinationAddress?("object"==typeof n?(r=n,a="Passed in as object"):(a="string"==typeof n?n:"string"==typeof s.DefaultTemplateRecordAddress?s.DefaultTemplateRecordAddress:"string"==typeof this.options.DefaultTemplateRecordAddress&&this.options.DefaultTemplateRecordAddress,r="string"==typeof a?this.pict.DataProvider.getDataByAddress(a):void 0),this.onBeforeRender(s),this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] Renderable[${l}] Destination[${s.ContentDestinationAddress}] TemplateRecordAddress[${a}] render:`),this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Beginning Render of Renderable[${l}] to Destination [${s.ContentDestinationAddress}]...`),s.Content=this.pict.parseTemplateByHash(s.TemplateHash,r,null,[this],t,{RootRenderable:"object"==typeof o?o:s}),this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Assigning Renderable[${l}] content length ${s.Content.length} to Destination [${s.ContentDestinationAddress}] using render method [${s.RenderMethod}].`),this.onBeforeProject(s),this.onProject(s),"virtual-assignment"!==s.RenderMethod&&(this.onAfterProject(s),this.onAfterRender(s)),!0):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${l} (param ${e}) because it does not have a valid destination address.`),!1):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${l} (param ${e}) because it does not exist.`),!1)):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${l} (param ${e}) because it is not a valid renderable.`),!1)}renderAsync(t,e,i,n,o){return this.renderWithScopeAsync(this,t,e,i,n,o)}renderWithScopeAsync(t,e,i,n,o,s){let a,r,l,c="string"==typeof e?e:"string"==typeof this.options.DefaultRenderable&&this.options.DefaultRenderable,d="function"==typeof s?s:"function"==typeof n?n:"function"==typeof i?i:"function"==typeof e?e:"function"==typeof o?o:null;if(d||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),d=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync Auto Callback Error: ${t}`,t)}),!c)return this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not asynchronously render ${c} (param ${e}because it is not a valid renderable.`),d(new Error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not asynchronously render ${c} (param ${e}because it is not a valid renderable.`));if("__Virtual"==c?a={RenderableHash:"__Virtual",TemplateHash:this.renderables[this.options.DefaultRenderable].TemplateHash,ContentDestinationAddress:"string"==typeof i?i:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null,RenderMethod:"virtual-assignment",TransactionHash:o&&"function"!=typeof o&&o.TransactionHash,RootRenderableViewHash:o&&"function"!=typeof o&&o.RootRenderableViewHash}:(a=Object.assign({},this.renderables[c]),a.ContentDestinationAddress="string"==typeof i?i:"string"==typeof a.ContentDestinationAddress?a.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null),a.TransactionHash||(a.TransactionHash=`ViewRender-V-${this.options.ViewIdentifier}-R-${c}-U-${this.pict.getUUID()}`,a.RootRenderableViewHash=this.Hash,this.pict.TransactionTracking.registerTransaction(a.TransactionHash)),!a)return this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${c} (param ${e}) because it does not exist.`),d(new Error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${c} (param ${e}) because it does not exist.`));if(!a.ContentDestinationAddress)return this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${c} (param ${e}) because it does not have a valid destination address.`),d(new Error(`Could not render ${c}`));"object"==typeof n?(l=n,r="Passed in as object"):(r="string"==typeof n?n:"string"==typeof a.DefaultTemplateRecordAddress?a.DefaultTemplateRecordAddress:"string"==typeof this.options.DefaultTemplateRecordAddress&&this.options.DefaultTemplateRecordAddress,l="string"==typeof r?this.pict.DataProvider.getDataByAddress(r):void 0),this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] Renderable[${c}] Destination[${a.ContentDestinationAddress}] TemplateRecordAddress[${r}] renderAsync:`),this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Beginning Asynchronous Render (callback-style)...`);let p=this.fable.newAnticipate();p.anticipate(t=>{this.onBeforeRenderAsync(t,a)}),p.anticipate(i=>{this.pict.parseTemplateByHash(a.TemplateHash,l,(t,n)=>t?(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render (asynchronously) ${c} (param ${e}) because it did not parse the template.`,t),i(t)):(a.Content=n,i()),[this],t,{RootRenderable:"object"==typeof o?o:a})}),p.anticipate(t=>{this.onBeforeProjectAsync(t,a)}),p.anticipate(t=>{this.onProjectAsync(t,a)}),"virtual-assignment"!==a.RenderMethod&&(p.anticipate(t=>{this.onAfterProjectAsync(t,a)}),p.anticipate(t=>{this.onAfterRenderAsync(t,a)})),p.wait(d)}renderDefaultAsync(t){this.renderAsync(t)}basicRender(t,e,i){return this.basicRenderWithScope(this,t,e,i)}basicRenderWithScope(t,e,i,n){let o=this.buildRenderOptions(e,i,n);return o.Valid?(this.assignRenderContent(o.Renderable,o.DestinationAddress,this.pict.parseTemplateByHash(o.Renderable.TemplateHash,o.Record,null,[this],t,{RootRenderable:o.Renderable})),!0):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not perform a basic render of ${o.RenderableHash} because it is not valid.`),!1)}basicRenderAsync(t,e,i,n){return this.basicRenderWithScopeAsync(this,t,e,i,n)}basicRenderWithScopeAsync(t,e,i,n,o){let s="function"==typeof o?o:"function"==typeof n?n:"function"==typeof i?i:"function"==typeof e?e:null;s||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} basicRenderAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),s=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} basicRenderAsync Auto Callback Error: ${t}`,t)});const a=this.buildRenderOptions(e,i,n);if(!a.Valid){let t=`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not perform a basic render of ${a.RenderableHash} because it is not valid.`;return this.log.error(t),s(new Error(t))}this.pict.parseTemplateByHash(a.Renderable.TemplateHash,a.Record,(t,e)=>t?(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render (asynchronously) ${a.RenderableHash} because it did not parse the template.`,t),s(t)):(this.assignRenderContent(a.Renderable,a.DestinationAddress,e),s()),[this],t,{RootRenderable:a.Renderable})}onProject(t){this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onProject:`),"virtual-assignment"===t.RenderMethod&&this.pict.TransactionTracking.pushToTransactionQueue(t.TransactionHash,{ViewHash:this.Hash,Renderable:t},"Deferred-Post-Content-Assignment"),this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Assigning Renderable[${t.RenderableHash}] content length ${t.Content.length} to Destination [${t.ContentDestinationAddress}] using Async render method ${t.RenderMethod}.`),this.pict.ContentAssignment.projectContent(t.RenderMethod,t.ContentDestinationAddress,t.Content,t.TestAddress),this.lastRenderedTimestamp=this.pict.log.getTimeStamp()}onProjectAsync(t,e){return this.onProject(e),t()}onAfterRender(t){if(this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterRender:`),t&&t.RootRenderableViewHash===this.Hash){const e=this.pict.TransactionTracking.clearTransactionQueue(t.TransactionHash)||[];for(const i of e){const e=this.pict.views[i.Data.ViewHash];e?(e.onAfterProject(),e.onAfterRender(i.Data.Renderable)):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterRender: Could not find view for transaction hash ${t.TransactionHash} and ViewHash ${i.Data.ViewHash}.`)}}return!0}onAfterRenderAsync(t,e){this.onAfterRender(e);const i=this.fable.newAnticipate();if(e&&e.RootRenderableViewHash===this.Hash){const t=this.pict.TransactionTracking.clearTransactionQueue(e.TransactionHash)||[];for(const n of t){const t=this.pict.views[n.Data.ViewHash];t?(i.anticipate(t.onAfterProjectAsync.bind(t)),i.anticipate(e=>{t.onAfterRenderAsync(e,n.Data.Renderable)})):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterRenderAsync: Could not find view for transaction hash ${e.TransactionHash} and ViewHash ${n.Data.ViewHash}.`)}}return i.wait(t)}onAfterProject(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterProject:`),!0}onAfterProjectAsync(t,e){return t()}onBeforeSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeSolve:`),!0}onBeforeSolveAsync(t){return this.onBeforeSolve(),t()}onSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onSolve:`),!0}onSolveAsync(t){return this.onSolve(),t()}solve(){return this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} executing solve() function...`),this.onBeforeSolve(),this.onSolve(),this.onAfterSolve(),this.lastSolvedTimestamp=this.pict.log.getTimeStamp(),!0}solveAsync(t){let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t?t:null;i||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeSolveAsync.bind(this)),e.anticipate(this.onSolveAsync.bind(this)),e.anticipate(this.onAfterSolveAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} solveAsync() complete.`),this.lastSolvedTimestamp=this.pict.log.getTimeStamp(),i(t)))}onAfterSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterSolve:`),!0}onAfterSolveAsync(t){return this.onAfterSolve(),t()}onBeforeMarshalFromView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeMarshalFromView:`),!0}onBeforeMarshalFromViewAsync(t){return this.onBeforeMarshalFromView(),t()}onMarshalFromView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onMarshalFromView:`),!0}onMarshalFromViewAsync(t){return this.onMarshalFromView(),t()}marshalFromView(){return this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} executing solve() function...`),this.onBeforeMarshalFromView(),this.onMarshalFromView(),this.onAfterMarshalFromView(),this.lastMarshalFromViewTimestamp=this.pict.log.getTimeStamp(),!0}marshalFromViewAsync(t){let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t?t:null;i||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalFromViewAsync.bind(this)),e.anticipate(this.onMarshalFromViewAsync.bind(this)),e.anticipate(this.onAfterMarshalFromViewAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} marshalFromViewAsync() complete.`),this.lastMarshalFromViewTimestamp=this.pict.log.getTimeStamp(),i(t)))}onAfterMarshalFromView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterMarshalFromView:`),!0}onAfterMarshalFromViewAsync(t){return this.onAfterMarshalFromView(),t()}onBeforeMarshalToView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeMarshalToView:`),!0}onBeforeMarshalToViewAsync(t){return this.onBeforeMarshalToView(),t()}onMarshalToView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onMarshalToView:`),!0}onMarshalToViewAsync(t){return this.onMarshalToView(),t()}marshalToView(){return this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} executing solve() function...`),this.onBeforeMarshalToView(),this.onMarshalToView(),this.onAfterMarshalToView(),this.lastMarshalToViewTimestamp=this.pict.log.getTimeStamp(),!0}marshalToViewAsync(t){let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t?t:null;i||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalToViewAsync.bind(this)),e.anticipate(this.onMarshalToViewAsync.bind(this)),e.anticipate(this.onAfterMarshalToViewAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} marshalToViewAsync() complete.`),this.lastMarshalToViewTimestamp=this.pict.log.getTimeStamp(),i(t)))}onAfterMarshalToView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterMarshalToView:`),!0}onAfterMarshalToViewAsync(t){return this.onAfterMarshalToView(),t()}get isPictView(){return!0}}},{"../package.json":12,"fable-serviceproviderbase":2}],14:[function(t,e,i){var n,o,s=e.exports={};function a(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function l(t){if(n===setTimeout)return setTimeout(t,0);if((n===a||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:a}catch(t){n=a}try{o="function"==typeof clearTimeout?clearTimeout:r}catch(t){o=r}}();var c,d=[],p=!1,h=-1;function u(){p&&c&&(p=!1,c.length?d=c.concat(d):h=-1,d.length&&g())}function g(){if(!p){var t=l(u);p=!0;for(var e=d.length;e;){for(c=d,d=[];++h<e;)c&&c[h].run();h=-1,e=d.length}c=null,p=!1,function(t){if(o===clearTimeout)return clearTimeout(t);if((o===r||!o)&&clearTimeout)return o=clearTimeout,clearTimeout(t);try{return o(t)}catch(e){try{return o.call(null,t)}catch(e){return o.call(this,t)}}}(t)}}function m(t,e){this.fun=t,this.array=e}function f(){}s.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var i=1;i<arguments.length;i++)e[i-1]=arguments[i];d.push(new m(t,e)),1!==d.length||p||l(g)},m.prototype.run=function(){this.fun.apply(null,this.array)},s.title="browser",s.browser=!0,s.env={},s.argv=[],s.version="",s.versions={},s.on=f,s.addListener=f,s.once=f,s.off=f,s.removeListener=f,s.removeAllListeners=f,s.emit=f,s.prependListener=f,s.prependOnceListener=f,s.listeners=function(t){return[]},s.binding=function(t){throw new Error("process.binding is not supported")},s.cwd=function(){return"/"},s.chdir=function(t){throw new Error("process.chdir is not supported")},s.umask=function(){return 0}},{}],15:[function(t,e,i){e.exports={Name:"Retold Data Cloner",Hash:"DataCloner",MainViewportViewIdentifier:"DataCloner-Layout",MainViewportDestinationAddress:"#DataCloner-Application-Container",MainViewportDefaultDataAddress:"AppData.DataCloner",pict_configuration:{Product:"DataCloner"},AutoRenderMainViewportViewAfterInitialize:!1}},{}],16:[function(t,e,i){const n=t("pict-application"),o=t("./providers/Pict-Provider-DataCloner.js"),s=t("./views/PictView-DataCloner-Layout.js"),a=t("./views/PictView-DataCloner-Connection.js"),r=t("./views/PictView-DataCloner-Session.js"),l=t("./views/PictView-DataCloner-Schema.js"),c=t("./views/PictView-DataCloner-Deploy.js"),d=t("./views/PictView-DataCloner-Sync.js"),p=t("./views/PictView-DataCloner-Export.js"),h=t("./views/PictView-DataCloner-ViewData.js"),u=t("pict-section-histogram");e.exports=class extends n{constructor(t,e,i){super(t,e,i),this.pict.addProvider("DataCloner",o.default_configuration,o),this.pict.addView("DataCloner-Layout",s.default_configuration,s),this.pict.addView("DataCloner-Connection",a.default_configuration,a),this.pict.addView("DataCloner-Session",r.default_configuration,r),this.pict.addView("DataCloner-Schema",l.default_configuration,l),this.pict.addView("DataCloner-Deploy",c.default_configuration,c),this.pict.addView("DataCloner-Sync",d.default_configuration,d),this.pict.addView("DataCloner-Export",p.default_configuration,p),this.pict.addView("DataCloner-ViewData",h.default_configuration,h),this.pict.addView("DataCloner-StatusHistogram",{ViewIdentifier:"DataCloner-StatusHistogram",TargetElementAddress:"#DataCloner-Throughput-Histogram",DefaultDestinationAddress:"#DataCloner-Throughput-Histogram",RenderOnLoad:!1,Selectable:!1,Orientation:"vertical",FillContainer:!0,ShowValues:!1,ShowLabels:!0,MaxBarSize:80,BarColor:"#4a90d9",Bins:[]},u)}onAfterInitializeAsync(t){return this.pict.AppData.DataCloner={FetchedTables:[],DeployedTables:[],LastReport:null,ServerBusyAtLoad:!1,SyncPollTimer:null,LiveStatusTimer:null,StatusDetailExpanded:!1,StatusDetailTimer:null,StatusDetailData:null,LastLiveStatus:null,PersistFields:["serverURL","authMethod","authURI","checkURI","cookieName","cookieValueAddr","cookieValueTemplate","loginMarker","userName","password","schemaURL","pageSize","dateTimePrecisionMS","connProvider","sqliteFilePath","mysqlServer","mysqlPort","mysqlUser","mysqlPassword","mysqlDatabase","mysqlConnectionLimit","mssqlServer","mssqlPort","mssqlUser","mssqlPassword","mssqlDatabase","mssqlConnectionLimit","postgresqlHost","postgresqlPort","postgresqlUser","postgresqlPassword","postgresqlDatabase","postgresqlConnectionLimit","solrHost","solrPort","solrCore","solrPath","mongodbHost","mongodbPort","mongodbUser","mongodbPassword","mongodbDatabase","mongodbConnectionLimit","rocksdbFolder","bibliographFolder","syncMaxRecords"]},window.pict=this.pict,this.pict.views["DataCloner-Layout"].render(),this.pict.providers.DataCloner.initPersistence(),this.pict.views["DataCloner-Connection"].onProviderChange(),this.pict.providers.DataCloner.restoreDeployedTables(),this.pict.providers.DataCloner.startLiveStatusPolling(),this.pict.providers.DataCloner.initAccordionPreviews(),this.pict.providers.DataCloner.updateAllPreviews(),this.pict.views["DataCloner-Layout"].collapseAllSections(),this.pict.providers.DataCloner.initAutoProcess(),t()}},e.exports.default_configuration=t("./Pict-Application-DataCloner-Configuration.json")},{"./Pict-Application-DataCloner-Configuration.json":15,"./providers/Pict-Provider-DataCloner.js":18,"./views/PictView-DataCloner-Connection.js":19,"./views/PictView-DataCloner-Deploy.js":20,"./views/PictView-DataCloner-Export.js":21,"./views/PictView-DataCloner-Layout.js":22,"./views/PictView-DataCloner-Schema.js":23,"./views/PictView-DataCloner-Session.js":24,"./views/PictView-DataCloner-Sync.js":25,"./views/PictView-DataCloner-ViewData.js":26,"pict-application":4,"pict-section-histogram":8}],17:[function(t,e,i){e.exports={DataClonerApplication:t("./Pict-Application-DataCloner.js")},"undefined"!=typeof window&&(window.DataClonerApplication=e.exports.DataClonerApplication)},{"./Pict-Application-DataCloner.js":16}],18:[function(t,e,i){const n=t("pict-provider");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}api(t,e,i){let n={method:t,headers:{}};return i&&(n.headers["Content-Type"]="application/json",n.body=JSON.stringify(i)),fetch(e,n).then(function(t){return t.json()})}setStatus(t,e,i){let n=document.getElementById(t);n&&(n.className="status "+(i||"info"),n.textContent=e,n.style.display="block")}escapeHtml(t){let e=document.createElement("div");return e.appendChild(document.createTextNode(t)),e.innerHTML}setSectionPhase(t,e){let i=document.getElementById("phase"+t);i&&(i.className="accordion-phase","ok"===e?(i.innerHTML="✓",i.classList.add("visible","accordion-phase-ok")):"error"===e?(i.innerHTML="✗",i.classList.add("visible","accordion-phase-error")):"busy"===e?(i.innerHTML='<span class="phase-spinner"></span>',i.classList.add("visible","accordion-phase-busy")):i.innerHTML="")}updateAllPreviews(){let t=document.getElementById("connProvider");if(!t)return;t=t.value;let e=t;if("SQLite"===t){e="SQLite at "+(document.getElementById("sqliteFilePath").value||"data/cloned.sqlite")}else if("MySQL"===t){e="MySQL on "+(document.getElementById("mysqlServer").value||"127.0.0.1")+":"+(document.getElementById("mysqlPort").value||"3306")+" as "+(document.getElementById("mysqlUser").value||"root")}else if("MSSQL"===t){e="MSSQL on "+(document.getElementById("mssqlServer").value||"127.0.0.1")+":"+(document.getElementById("mssqlPort").value||"1433")+" as "+(document.getElementById("mssqlUser").value||"sa")}else if("PostgreSQL"===t){e="PostgreSQL on "+(document.getElementById("postgresqlHost").value||"127.0.0.1")+":"+(document.getElementById("postgresqlPort").value||"5432")+" as "+(document.getElementById("postgresqlUser").value||"postgres")}else if("MongoDB"===t){e="MongoDB on "+(document.getElementById("mongodbHost").value||"127.0.0.1")+":"+(document.getElementById("mongodbPort").value||"27017")}else if("Solr"===t){e="Solr on "+(document.getElementById("solrHost").value||"127.0.0.1")+":"+(document.getElementById("solrPort").value||"8983")}else if("RocksDB"===t){e="RocksDB at "+(document.getElementById("rocksdbFolder").value||"data/rocksdb")}else if("Bibliograph"===t){e="Bibliograph at "+(document.getElementById("bibliographFolder").value||"data/bibliograph")}document.getElementById("preview1").textContent=e;let i=document.getElementById("serverURL").value,n=document.getElementById("userName").value;if(i){let t=i;n&&(t+=" as "+n),document.getElementById("preview2").textContent=t}else document.getElementById("preview2").textContent="Configure remote server URL and credentials";let o=document.querySelectorAll('#tableList input[type="checkbox"]:checked');if(o.length>0)document.getElementById("preview3").textContent=o.length+" table"+(1===o.length?"":"s")+" selected";else{let t=document.getElementById("schemaURL").value;document.getElementById("preview3").textContent=t?"Schema from "+t:"Fetch and select tables from the remote server"}let s=document.getElementById("deployStatus"),a=s?s.textContent:"";a&&-1!==a.indexOf("deployed")?document.getElementById("preview4").textContent=a:document.getElementById("preview4").textContent="Create selected tables in the local database";let r=document.querySelector('input[name="syncMode"]:checked'),l=(r?r.value:"Initial")+" sync, page size "+(document.getElementById("pageSize").value||"100");document.getElementById("syncDeletedRecords").checked&&(l+=", including deleted"),document.getElementById("preview5").textContent=l;let c=document.getElementById("syncMaxRecords").value,d=document.getElementById("syncLogFile").checked,p=[];c&&parseInt(c,10)>0&&p.push("max "+c+" records"),d?p.push("log enabled"):p.push("log disabled"),document.getElementById("preview6").textContent=p.length>0?"Export: "+p.join(", "):"Generate JSON config for headless cloning";let h=document.getElementById("viewTable").value;document.getElementById("preview7").textContent=h?"Viewing "+h:"Browse synced table data"}initAccordionPreviews(){let t=this,e=["connProvider","sqliteFilePath","mysqlServer","mysqlPort","mysqlUser","mssqlServer","mssqlPort","mssqlUser","postgresqlHost","postgresqlPort","postgresqlUser","mongodbHost","mongodbPort","solrHost","solrPort","rocksdbFolder","bibliographFolder","serverURL","userName","schemaURL","pageSize","dateTimePrecisionMS","syncMaxRecords","viewTable","viewLimit"],i=function(){t.updateAllPreviews()};for(let t=0;t<e.length;t++){let n=document.getElementById(e[t]);n&&(n.addEventListener("input",i),n.addEventListener("change",i))}let n=["syncDeletedRecords","syncLogFile"];for(let t=0;t<n.length;t++){let e=document.getElementById(n[t]);e&&e.addEventListener("change",i)}document.querySelectorAll('input[name="syncMode"]').forEach(function(t){t.addEventListener("change",i)})}saveField(t){let e=document.getElementById(t);e&&localStorage.setItem("dataCloner_"+t,e.value)}restoreFields(){let t=this.pict.AppData.DataCloner.PersistFields;for(let e=0;e<t.length;e++){let i=t[e],n=localStorage.getItem("dataCloner_"+i);if(null!==n){let t=document.getElementById(i);t&&(t.value=n)}}let e=localStorage.getItem("dataCloner_syncDeletedRecords");null!==e&&(document.getElementById("syncDeletedRecords").checked="true"===e),"Ongoing"===localStorage.getItem("dataCloner_syncMode")&&(document.getElementById("syncModeOngoing").checked=!0);let i=localStorage.getItem("dataCloner_solrSecure");null!==i&&(document.getElementById("solrSecure").checked="true"===i)}initPersistence(){let t=this;this.restoreFields();let e=this.pict.AppData.DataCloner.PersistFields;for(let i=0;i<e.length;i++)(function(e){let i=document.getElementById(e);i&&(i.addEventListener("input",function(){t.saveField(e)}),i.addEventListener("change",function(){t.saveField(e)}))})(e[i]);let i=document.getElementById("syncDeletedRecords");i&&i.addEventListener("change",function(){localStorage.setItem("dataCloner_syncDeletedRecords",this.checked)}),document.querySelectorAll('input[name="syncMode"]').forEach(function(t){t.addEventListener("change",function(){localStorage.setItem("dataCloner_syncMode",this.value)})});let n=document.getElementById("solrSecure");n&&n.addEventListener("change",function(){localStorage.setItem("dataCloner_solrSecure",this.checked)});let o=["auto1","auto2","auto3","auto4","auto5"];for(let t=0;t<o.length;t++)(function(t){let e=document.getElementById(t);if(e){let i=localStorage.getItem("dataCloner_"+t);null!==i&&(e.checked="true"===i),e.addEventListener("change",function(){localStorage.setItem("dataCloner_"+t,this.checked)})}})(o[t])}startLiveStatusPolling(){let t=this.pict.AppData.DataCloner;t.LiveStatusTimer&&clearInterval(t.LiveStatusTimer),this.pollLiveStatus();let e=this;t.LiveStatusTimer=setInterval(function(){e.pollLiveStatus()},1500)}pollLiveStatus(){let t=this;this.api("GET","/clone/sync/live-status").then(function(e){t.renderLiveStatus(e)}).catch(function(){t.renderLiveStatus({Phase:"disconnected",Message:"Cannot reach server",TotalSynced:0,TotalRecords:0})})}renderLiveStatus(t){this.pict.AppData.DataCloner.LastLiveStatus=t;let e=document.getElementById("liveStatusBar"),i=document.getElementById("liveStatusMessage"),n=document.getElementById("liveStatusMeta"),o=document.getElementById("liveStatusProgressFill");if(!e)return;let s=e.classList.contains("expanded");e.className="live-status-bar phase-"+(t.Phase||"idle"),s&&e.classList.add("expanded"),i.textContent=t.Message||"Idle";let a=[];if("syncing"===t.Phase||"stopping"===t.Phase){if(t.Elapsed&&a.push('<span class="live-status-meta-item">⏱ '+t.Elapsed+"</span>"),t.ETA&&a.push('<span class="live-status-meta-item">~'+t.ETA+" remaining</span>"),t.TotalTables>0&&a.push('<span class="live-status-meta-item"><strong>'+t.Completed+"</strong> / "+t.TotalTables+" tables</span>"),t.TotalSynced>0){let e=t.TotalSynced.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");if(t.PreCountGrandTotal>0){let i=t.PreCountGrandTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");a.push('<span class="live-status-meta-item"><strong>'+e+"</strong> / "+i+" records</span>")}else a.push('<span class="live-status-meta-item"><strong>'+e+"</strong> records</span>")}else if(t.PreCountGrandTotal>0){let e=t.PreCountGrandTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");a.push('<span class="live-status-meta-item">'+e+" records to sync</span>")}if(t.PreCountProgress&&t.PreCountProgress.Counted<t.PreCountProgress.TotalTables){let e=t.PreCountGrandTotal>0?" ("+t.PreCountGrandTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")+" records found)":"";a.push('<span class="live-status-meta-item">counting: '+t.PreCountProgress.Counted+" / "+t.PreCountProgress.TotalTables+" tables"+e+"</span>")}t.Errors>0&&a.push('<span class="live-status-meta-item" style="color:#dc3545"><strong>'+t.Errors+"</strong> error"+(1===t.Errors?"":"s")+"</span>")}else if("complete"===t.Phase&&t.TotalSynced>0){let e=t.TotalSynced.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");a.push('<span class="live-status-meta-item"><strong>'+e+"</strong> records synced</span>")}n.innerHTML=a.join("");let r=0;if("syncing"===t.Phase&&t.PreCountProgress&&t.PreCountProgress.Counted<t.PreCountProgress.TotalTables)r=Math.min(t.PreCountProgress.Counted/t.PreCountProgress.TotalTables*100,99);else if("syncing"===t.Phase&&t.PreCountGrandTotal>0&&t.TotalSynced>0)r=Math.min(t.TotalSynced/t.PreCountGrandTotal*100,99.9);else if("syncing"===t.Phase&&t.TotalTables>0){let e=t.Completed/t.TotalTables*100;if(t.ActiveProgress&&t.ActiveProgress.Total>0){r=e+t.ActiveProgress.Synced/t.ActiveProgress.Total*(100/t.TotalTables)}else r=e}else"complete"===t.Phase&&(r=100);if(o.style.width=Math.min(100,Math.round(r))+"%",("syncing"===t.Phase||"stopping"===t.Phase)&&!this.pict.AppData.DataCloner.StatusDetailExpanded){let t=this.pict.views["DataCloner-Layout"];t&&"function"==typeof t.toggleStatusDetail&&t.toggleStatusDetail()}if(this.pict.AppData.DataCloner.StatusDetailExpanded&&this.renderStatusDetail(),"complete"===t.Phase&&!this.pict.AppData.DataCloner.LastReport){let t=this;this.api("GET","/clone/sync/report").then(function(e){e&&e.ReportVersion&&(t.pict.AppData.DataCloner.LastReport=e,t.pict.AppData.DataCloner.StatusDetailExpanded&&t.renderStatusDetail())}).catch(function(){})}}onStatusDetailExpanded(){let t=this.pict.AppData.DataCloner;t.StatusDetailExpanded=!0,this.renderStatusDetail(),t.StatusDetailTimer&&clearInterval(t.StatusDetailTimer);let e=this;t.StatusDetailTimer=setInterval(function(){e.pollStatusDetail()},2e3),this.pollStatusDetail()}onStatusDetailCollapsed(){let t=this.pict.AppData.DataCloner;t.StatusDetailExpanded=!1,t.StatusDetailTimer&&(clearInterval(t.StatusDetailTimer),t.StatusDetailTimer=null)}pollStatusDetail(){let t=this;this.api("GET","/clone/sync/status").then(function(e){t.pict.AppData.DataCloner.StatusDetailData=e,t.renderStatusDetail()}).catch(function(){})}renderCountingPhaseDetail(t,e){let i=e.Tables||[],n=e.Counted||0,o=e.TotalTables||0,s=0,a='<div class="status-detail-section">';if(a+='<div class="status-detail-section-title">Counting Records ('+n+" / "+o+" tables)</div>",i.length>0){a+='<table class="precount-table">',a+='<thead><tr><th>Table</th><th style="text-align:right">Records</th><th style="text-align:right">Time</th></tr></thead>',a+="<tbody>";for(let t=0;t<i.length;t++){let e=i[t];s+=e.Count;let n=this.formatNumber(e.Count),o=e.ElapsedMs<1e3?e.ElapsedMs+"ms":(e.ElapsedMs/1e3).toFixed(1)+"s";a+="<tr"+(e.Error?' class="precount-error"':"")+">",a+="<td>"+this.escapeHtml(e.Name)+"</td>",a+='<td style="text-align:right; font-variant-numeric:tabular-nums">'+n+"</td>",a+='<td style="text-align:right; font-variant-numeric:tabular-nums; color:#888">'+o+"</td>",a+="</tr>"}a+="</tbody>",a+="<tfoot><tr>",a+="<td><strong>Total</strong></td>",a+='<td style="text-align:right; font-variant-numeric:tabular-nums"><strong>'+this.formatNumber(s)+"</strong></td>",a+="<td></td>",a+="</tr></tfoot>",a+="</table>"}let r=o-n;r>0&&(a+='<div class="precount-pending">',a+='<span class="precount-spinner"></span> ',a+=r+" table"+(1===r?"":"s")+" remaining…",a+="</div>"),a+="</div>",t.innerHTML=a}renderStatusDetail(){let t=document.getElementById("DataCloner-StatusDetail-Container");if(!t)return;let e=this.pict.AppData.DataCloner,i=e.LastLiveStatus,n=e.StatusDetailData,o=e.LastReport;if(i&&i.PreCountProgress&&i.PreCountProgress.Tables&&"syncing"===i.Phase&&i.PreCountProgress.Counted<i.PreCountProgress.TotalTables){this.renderCountingPhaseDetail(t,i.PreCountProgress);let e=document.getElementById("DataCloner-Throughput-Histogram");return void(e&&(e.style.display="none"))}let s={},a=[],r=[],l=!1;if(!i||"syncing"!==i.Phase&&"stopping"!==i.Phase)if(o&&o.ReportVersion){for(let t=0;t<o.Tables.length;t++){let e=o.Tables[t];s[e.Name]=e}a=o.ThroughputSamples||[],r=o.EventLog||[]}else n&&n.Tables&&(s=n.Tables,i&&i.ThroughputSamples&&(a=i.ThroughputSamples));else l=!0,n&&n.Tables&&(s=n.Tables),i.ThroughputSamples&&(a=i.ThroughputSamples);let c=[],d=[],p=[],h=[],u=Object.keys(s);for(let t=0;t<u.length;t++){let e=u[t],i=s[e];"Syncing"===i.Status?c.push({Name:e,Data:i}):"Pending"===i.Status?d.push(e):"Complete"===i.Status?p.push({Name:e,Data:i}):"Error"!==i.Status&&"Partial"!==i.Status||h.push({Name:e,Data:i})}let g="";if(c.length>0||d.length>0){g+='<div class="status-detail-section">',g+='<div class="status-detail-section-title">Running</div>';for(let t=0;t<c.length;t++){let e=c[t],i=e.Data.Total>0?Math.round(e.Data.Synced/e.Data.Total*100):0,n=this.formatNumber(e.Data.Synced||0),o=this.formatNumber(e.Data.Total||0);g+='<div class="running-op-row">',g+=' <div class="running-op-name">'+this.escapeHtml(e.Name)+"</div>",g+=' <div class="running-op-bar"><div class="running-op-bar-fill" style="width:'+i+'%"></div></div>',g+=' <div class="running-op-count">'+n+" / "+o+" ("+i+"%)</div>",g+="</div>"}d.length>0&&(g+='<div class="running-op-pending">'+d.length+" table"+(1===d.length?"":"s")+" waiting</div>"),g+="</div>"}if(p.length>0){g+='<div class="status-detail-section">',g+='<div class="status-detail-section-title">Completed ('+p.length+")</div>";for(let t=0;t<p.length;t++)g+=this.renderCompletedRow(p[t]);g+="</div>"}if(h.length>0){g+='<div class="status-detail-section">',g+='<div class="status-detail-section-title">Errors ('+h.length+")</div>";for(let t=0;t<h.length;t++)g+=this.renderErrorRow(h[t],r);g+="</div>"}""===g&&(g=l?'<div style="font-size:0.9em; color:#888; padding:8px 0">Sync in progress, waiting for table data…</div>':'<div style="font-size:0.9em; color:#888; padding:8px 0">No sync data available. Run a sync to see operation details here.</div>'),t.innerHTML=g,this.updateThroughputHistogram(a)}updateThroughputHistogram(t){let e=document.getElementById("DataCloner-Throughput-Histogram");if(!e)return;if(!t||t.length<2)return void(e.style.display="none");let i=[];for(let e=1;e<t.length;e++){let n=t[e].synced-t[e-1].synced;n<0&&(n=0),i.push({delta:n,t:t[e].t})}let n=e.clientWidth||800,o=Math.max(20,Math.floor(n/6)),s=i;if(i.length>o){let t=Math.ceil(i.length/o);s=[];for(let e=0;e<i.length;e+=t){let n=0,o=0;for(let s=e;s<Math.min(e+t,i.length);s++)n+=i[s].delta,o=i[s].t;s.push({delta:n,t:o})}}let a=!1;for(let t=0;t<s.length;t++)if(s[t].delta>0){a=!0;break}if(!a)return void(e.style.display="none");let r=t[0].t,l=[];for(let t=0;t<s.length;t++){let e=Math.round((s[t].t-r)/1e3);l.push({Label:this.formatElapsed(e),Value:s[t].delta})}e.style.display="";let c=this.pict.views["DataCloner-StatusHistogram"];c&&(c.setBins(l),c.renderHistogram())}formatElapsed(t){if(t<60)return t+"s";if(t<3600){let e=t%60;return Math.floor(t/60)+":"+(e<10?"0":"")+e}let e=Math.floor(t/3600),i=Math.floor(t%3600/60);return e+"h"+(i<10?"0":"")+i}formatCompact(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e4?(t/1e3).toFixed(0)+"K":t>=1e3?(t/1e3).toFixed(1)+"K":t.toString()}formatNumber(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}renderCompletedRow(t){let e=t.Data.New||0,i=t.Data.Updated||0,n=t.Data.Unchanged||0,o=t.Data.Deleted||0,s=t.Data.ServerTotal||0,a=n+e+i+o;0===a&&s>0&&(a=s,n=s);let r='<div class="completed-op-row">';if(r+='<div class="completed-op-header">',r+=' <span class="completed-op-checkmark">✓</span>',r+=' <span class="completed-op-name">'+this.escapeHtml(t.Name)+"</span>",r+="</div>",a>0){let t=Math.round(n/a*100),s=Math.round(e/a*100),l=Math.round(i/a*100),c=Math.round(o/a*100),d=t+s+l+c;100!==d&&d>0&&(t+=100-d,t<0&&(t=0)),r+='<div class="ratio-bar-container">',t>0&&(r+='<div class="ratio-bar-segment unchanged" style="width:'+t+'%" title="Unchanged: '+this.formatNumber(n)+'"></div>'),s>0&&(r+='<div class="ratio-bar-segment new-records" style="width:'+s+'%" title="New: '+this.formatNumber(e)+'"></div>'),l>0&&(r+='<div class="ratio-bar-segment updated" style="width:'+l+'%" title="Updated: '+this.formatNumber(i)+'"></div>'),c>0&&(r+='<div class="ratio-bar-segment deleted" style="width:'+c+'%" title="Deleted: '+this.formatNumber(o)+'"></div>'),r+="</div>",r+='<div class="ratio-bar-legend">',n>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot unchanged-dot"></span> Unchanged ('+this.formatNumber(n)+")</span>"),e>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot new-dot"></span> New ('+this.formatNumber(e)+")</span>"),i>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot updated-dot"></span> Updated ('+this.formatNumber(i)+")</span>"),o>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot deleted-dot"></span> Deleted ('+this.formatNumber(o)+")</span>"),r+="</div>"}return r+="</div>",r}renderErrorRow(t,e){let i=t.Data.Synced||0,n=t.Data.Total||0,o=this.formatNumber(i),s=this.formatNumber(n),a='<div class="error-op-row">';if(a+='<div class="error-op-header">',a+=' <span style="color:#dc3545">✗</span>',a+=' <span class="error-op-name">'+this.escapeHtml(t.Name)+"</span>",a+=' <span class="error-op-status">'+t.Data.Status+" — "+o+" / "+s+"</span>",a+="</div>",t.Data.ErrorMessage&&(a+='<div class="error-op-message">'+this.escapeHtml(t.Data.ErrorMessage)+"</div>"),e&&e.length>0){let i=[];for(let n=0;n<e.length;n++){let o=e[n];!o.Data||o.Data.Table!==t.Name||"TableError"!==o.Type&&"TablePartial"!==o.Type||i.push(o)}if(i.length>0){a+='<div class="error-op-log-entries">';for(let t=0;t<i.length;t++){let e=i[t].Timestamp.replace("T"," ").replace(/\.\d+Z$/,"");a+="<div>"+this.escapeHtml(e+" "+i[t].Message)+"</div>"}a+="</div>"}}return a+="</div>",a}saveDeployedTables(){localStorage.setItem("dataCloner_deployedTables",JSON.stringify(this.pict.AppData.DataCloner.DeployedTables))}restoreDeployedTables(){try{let t=localStorage.getItem("dataCloner_deployedTables");t&&(this.pict.AppData.DataCloner.DeployedTables=JSON.parse(t),this.pict.views["DataCloner-ViewData"].populateViewTableDropdown())}catch(t){}}initAutoProcess(){let t=this;this.api("GET","/clone/sync/live-status").then(function(e){if("syncing"===e.Phase||"stopping"===e.Phase)return t.pict.AppData.DataCloner.ServerBusyAtLoad=!0,t.setSectionPhase(5,"busy"),void t.pict.views["DataCloner-Sync"].startPolling();t.runAutoProcessChain()}).catch(function(){})}runAutoProcessChain(){let t=this,e=0,i=2e3;document.getElementById("auto1")&&document.getElementById("auto1").checked&&(setTimeout(function(){t.pict.views["DataCloner-Connection"].connectProvider()},e),e+=i),document.getElementById("auto2")&&document.getElementById("auto2").checked&&(setTimeout(function(){t.pict.views["DataCloner-Session"].goAction()},e),e+=3500),document.getElementById("auto3")&&document.getElementById("auto3").checked&&(setTimeout(function(){t.pict.views["DataCloner-Schema"].fetchSchema()},e),e+=i),document.getElementById("auto4")&&document.getElementById("auto4").checked&&(setTimeout(function(){t.pict.views["DataCloner-Deploy"].deploySchema()},e),e+=i),document.getElementById("auto5")&&document.getElementById("auto5").checked&&setTimeout(function(){t.pict.views["DataCloner-Sync"].startSync()},e)}},e.exports.default_configuration={ProviderIdentifier:"DataCloner",AutoInitialize:!0,AutoInitializeOrdinal:0}},{"pict-provider":6}],19:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}onProviderChange(){let t=document.getElementById("connProvider").value,e=["SQLite","MySQL","MSSQL","PostgreSQL","Solr","MongoDB","RocksDB","Bibliograph"];for(let i=0;i<e.length;i++){let n=document.getElementById("config"+e[i]);n&&(n.style.display=t===e[i]?"":"none")}this.pict.providers.DataCloner.saveField("connProvider")}getProviderConfig(){let t=document.getElementById("connProvider").value,e={};return"SQLite"===t?e.SQLiteFilePath=document.getElementById("sqliteFilePath").value.trim()||"data/cloned.sqlite":"MySQL"===t?(e.host=document.getElementById("mysqlServer").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("mysqlPort").value,10)||3306,e.user=document.getElementById("mysqlUser").value.trim()||"root",e.password=document.getElementById("mysqlPassword").value,e.database=document.getElementById("mysqlDatabase").value.trim(),e.connectionLimit=parseInt(document.getElementById("mysqlConnectionLimit").value,10)||20):"MSSQL"===t?(e.server=document.getElementById("mssqlServer").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("mssqlPort").value,10)||1433,e.user=document.getElementById("mssqlUser").value.trim()||"sa",e.password=document.getElementById("mssqlPassword").value,e.database=document.getElementById("mssqlDatabase").value.trim(),e.connectionLimit=parseInt(document.getElementById("mssqlConnectionLimit").value,10)||20):"PostgreSQL"===t?(e.host=document.getElementById("postgresqlHost").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("postgresqlPort").value,10)||5432,e.user=document.getElementById("postgresqlUser").value.trim()||"postgres",e.password=document.getElementById("postgresqlPassword").value,e.database=document.getElementById("postgresqlDatabase").value.trim(),e.max=parseInt(document.getElementById("postgresqlConnectionLimit").value,10)||10):"Solr"===t?(e.host=document.getElementById("solrHost").value.trim()||"localhost",e.port=parseInt(document.getElementById("solrPort").value,10)||8983,e.core=document.getElementById("solrCore").value.trim()||"default",e.path=document.getElementById("solrPath").value.trim()||"/solr",e.secure=document.getElementById("solrSecure").checked):"MongoDB"===t?(e.host=document.getElementById("mongodbHost").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("mongodbPort").value,10)||27017,e.user=document.getElementById("mongodbUser").value.trim(),e.password=document.getElementById("mongodbPassword").value,e.database=document.getElementById("mongodbDatabase").value.trim()||"test",e.maxPoolSize=parseInt(document.getElementById("mongodbConnectionLimit").value,10)||10):"RocksDB"===t?e.RocksDBFolder=document.getElementById("rocksdbFolder").value.trim()||"data/rocksdb":"Bibliograph"===t&&(e.StorageFolder=document.getElementById("bibliographFolder").value.trim()||"data/bibliograph"),{Provider:t,Config:e}}connectProvider(){let t=this.getProviderConfig();this.pict.providers.DataCloner.setSectionPhase(1,"busy"),this.pict.providers.DataCloner.setStatus("connectionStatus","Connecting to "+t.Provider+"...","info"),this.pict.providers.DataCloner.api("POST","/clone/connection/configure",t).then(t=>{t.Success?(this.pict.providers.DataCloner.setStatus("connectionStatus",t.Message,"ok"),this.pict.providers.DataCloner.setSectionPhase(1,"ok")):(this.pict.providers.DataCloner.setStatus("connectionStatus","Connection failed: "+(t.Error||"Unknown error"),"error"),this.pict.providers.DataCloner.setSectionPhase(1,"error"))}).catch(t=>{this.pict.providers.DataCloner.setStatus("connectionStatus","Request failed: "+t.message,"error"),this.pict.providers.DataCloner.setSectionPhase(1,"error")})}testConnection(){let t=this.getProviderConfig();this.pict.providers.DataCloner.setStatus("connectionStatus","Testing "+t.Provider+" connection...","info"),this.pict.providers.DataCloner.api("POST","/clone/connection/test",t).then(t=>{t.Success?this.pict.providers.DataCloner.setStatus("connectionStatus",t.Message,"ok"):this.pict.providers.DataCloner.setStatus("connectionStatus","Test failed: "+(t.Error||"Unknown error"),"error")}).catch(t=>{this.pict.providers.DataCloner.setStatus("connectionStatus","Request failed: "+t.message,"error")})}checkConnectionStatus(){this.pict.providers.DataCloner.api("GET","/clone/connection/status").then(t=>{t.Connected&&(this.pict.providers.DataCloner.setStatus("connectionStatus","Connected: "+t.Provider,"ok"),this.pict.providers.DataCloner.setSectionPhase(1,"ok"))}).catch(()=>{})}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Connection",DefaultRenderable:"DataCloner-Connection",DefaultDestinationAddress:"#DataCloner-Section-Connection",Templates:[{Hash:"DataCloner-Connection",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">1</div>\n\t<div class="accordion-card" id="section1" data-section="1">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section1\')">\n\t\t\t<div class="accordion-title">Database Connection</div>\n\t\t\t<span class="accordion-phase" id="phase1"></span>\n\t\t\t<div class="accordion-preview" id="preview1">SQLite at data/cloned.sqlite</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Connection\'].connectProvider()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto1"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<p style="font-size:0.9em; color:#666; margin-bottom:10px">Configure the local database where cloned data will be stored. SQLite is connected by default.</p>\n\n\t\t\t<div class="inline-group">\n\t\t\t\t<div style="flex:0 0 200px">\n\t\t\t\t\t<label for="connProvider">Provider</label>\n\t\t\t\t\t<select id="connProvider" onchange="pict.views[\'DataCloner-Connection\'].onProviderChange()">\n\t\t\t\t\t\t<option value="SQLite" selected>SQLite</option>\n\t\t\t\t\t\t<option value="MySQL">MySQL</option>\n\t\t\t\t\t\t<option value="MSSQL">MSSQL</option>\n\t\t\t\t\t\t<option value="PostgreSQL">PostgreSQL</option>\n\t\t\t\t\t\t<option value="Solr">Solr</option>\n\t\t\t\t\t\t<option value="MongoDB">MongoDB</option>\n\t\t\t\t\t\t<option value="RocksDB">RocksDB</option>\n\t\t\t\t\t\t<option value="Bibliograph">Bibliograph</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:1; display:flex; align-items:flex-end; gap:8px">\n\t\t\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Connection\'].connectProvider()">Connect</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Connection\'].testConnection()">Test Connection</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- SQLite Config --\x3e\n\t\t\t<div id="configSQLite">\n\t\t\t\t<label for="sqliteFilePath">SQLite File Path</label>\n\t\t\t\t<input type="text" id="sqliteFilePath" placeholder="data/cloned.sqlite" value="data/cloned.sqlite">\n\t\t\t</div>\n\n\t\t\t\x3c!-- MySQL Config --\x3e\n\t\t\t<div id="configMySQL" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="mysqlServer">Server</label>\n\t\t\t\t\t\t<input type="text" id="mysqlServer" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="mysqlPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="mysqlPort" placeholder="3306" value="3306">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mysqlUser">User</label>\n\t\t\t\t\t\t<input type="text" id="mysqlUser" placeholder="root" value="root">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mysqlPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="mysqlPassword" placeholder="password">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="mysqlDatabase">Database</label>\n\t\t\t\t<input type="text" id="mysqlDatabase" placeholder="meadow_clone">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mysqlConnectionLimit">Connection Limit</label>\n\t\t\t\t\t\t<input type="number" id="mysqlConnectionLimit" placeholder="20" value="20">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- MSSQL Config --\x3e\n\t\t\t<div id="configMSSQL" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="mssqlServer">Server</label>\n\t\t\t\t\t\t<input type="text" id="mssqlServer" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="mssqlPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="mssqlPort" placeholder="1433" value="1433">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mssqlUser">User</label>\n\t\t\t\t\t\t<input type="text" id="mssqlUser" placeholder="sa" value="sa">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mssqlPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="mssqlPassword" placeholder="password">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="mssqlDatabase">Database</label>\n\t\t\t\t<input type="text" id="mssqlDatabase" placeholder="meadow_clone">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mssqlConnectionLimit">Connection Limit</label>\n\t\t\t\t\t\t<input type="number" id="mssqlConnectionLimit" placeholder="20" value="20">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- PostgreSQL Config --\x3e\n\t\t\t<div id="configPostgreSQL" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="postgresqlHost">Host</label>\n\t\t\t\t\t\t<input type="text" id="postgresqlHost" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="postgresqlPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="postgresqlPort" placeholder="5432" value="5432">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="postgresqlUser">User</label>\n\t\t\t\t\t\t<input type="text" id="postgresqlUser" placeholder="postgres" value="postgres">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="postgresqlPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="postgresqlPassword" placeholder="password">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="postgresqlDatabase">Database</label>\n\t\t\t\t<input type="text" id="postgresqlDatabase" placeholder="meadow_clone">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="postgresqlConnectionLimit">Connection Pool Limit</label>\n\t\t\t\t\t\t<input type="number" id="postgresqlConnectionLimit" placeholder="10" value="10">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- Solr Config --\x3e\n\t\t\t<div id="configSolr" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="solrHost">Host</label>\n\t\t\t\t\t\t<input type="text" id="solrHost" placeholder="localhost" value="localhost">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="solrPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="solrPort" placeholder="8983" value="8983">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="solrCore">Core</label>\n\t\t\t\t\t\t<input type="text" id="solrCore" placeholder="default" value="default">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="solrPath">Path</label>\n\t\t\t\t\t\t<input type="text" id="solrPath" placeholder="/solr" value="/solr">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="checkbox-row">\n\t\t\t\t\t<input type="checkbox" id="solrSecure">\n\t\t\t\t\t<label for="solrSecure">Use HTTPS</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- MongoDB Config --\x3e\n\t\t\t<div id="configMongoDB" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="mongodbHost">Host</label>\n\t\t\t\t\t\t<input type="text" id="mongodbHost" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="mongodbPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="mongodbPort" placeholder="27017" value="27017">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mongodbUser">User</label>\n\t\t\t\t\t\t<input type="text" id="mongodbUser" placeholder="(optional)">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mongodbPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="mongodbPassword" placeholder="(optional)">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="mongodbDatabase">Database</label>\n\t\t\t\t<input type="text" id="mongodbDatabase" placeholder="test" value="test">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mongodbConnectionLimit">Max Pool Size</label>\n\t\t\t\t\t\t<input type="number" id="mongodbConnectionLimit" placeholder="10" value="10">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- RocksDB Config --\x3e\n\t\t\t<div id="configRocksDB" style="display:none">\n\t\t\t\t<label for="rocksdbFolder">RocksDB Folder Path</label>\n\t\t\t\t<input type="text" id="rocksdbFolder" placeholder="data/rocksdb" value="data/rocksdb">\n\t\t\t</div>\n\n\t\t\t\x3c!-- Bibliograph Config --\x3e\n\t\t\t<div id="configBibliograph" style="display:none">\n\t\t\t\t<label for="bibliographFolder">Storage Folder Path</label>\n\t\t\t\t<input type="text" id="bibliographFolder" placeholder="data/bibliograph" value="data/bibliograph">\n\t\t\t</div>\n\n\t\t\t<div id="connectionStatus"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Connection",TemplateHash:"DataCloner-Connection",DestinationAddress:"#DataCloner-Section-Connection"}]}},{"pict-view":13}],20:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}deploySchema(){let t=this.pict.views["DataCloner-Schema"].getSelectedTables();if(0===t.length)return this.pict.providers.DataCloner.setStatus("deployStatus","No tables selected. Fetch a schema and select tables first.","error"),void this.pict.providers.DataCloner.setSectionPhase(4,"error");this.pict.providers.DataCloner.setSectionPhase(4,"busy"),this.pict.providers.DataCloner.setStatus("deployStatus","Deploying "+t.length+" tables...","info");let e=this;this.pict.providers.DataCloner.api("POST","/clone/schema/deploy",{Tables:t}).then(function(i){i.Success?(e.pict.providers.DataCloner.setStatus("deployStatus",i.Message,"ok"),e.pict.providers.DataCloner.setSectionPhase(4,"ok"),e.pict.AppData.DataCloner.DeployedTables=i.TablesDeployed||t,e.pict.providers.DataCloner.saveDeployedTables(),e.pict.views["DataCloner-ViewData"].populateViewTableDropdown(),e.pict.providers.DataCloner.updateAllPreviews()):(e.pict.providers.DataCloner.setStatus("deployStatus","Deploy failed: "+(i.Error||"Unknown error"),"error"),e.pict.providers.DataCloner.setSectionPhase(4,"error"))}).catch(function(t){e.pict.providers.DataCloner.setStatus("deployStatus","Request failed: "+t.message,"error"),e.pict.providers.DataCloner.setSectionPhase(4,"error")})}resetDatabase(){if(!confirm("This will delete ALL data in the local SQLite database. Continue?"))return;this.pict.providers.DataCloner.setStatus("deployStatus","Resetting database...","info");let t=this;this.pict.providers.DataCloner.api("POST","/clone/reset").then(function(e){if(e.Success){t.pict.providers.DataCloner.setStatus("deployStatus",e.Message,"ok");let i=document.getElementById("syncProgress");i&&(i.innerHTML="")}else t.pict.providers.DataCloner.setStatus("deployStatus","Reset failed: "+(e.Error||"Unknown error"),"error")}).catch(function(e){t.pict.providers.DataCloner.setStatus("deployStatus","Request failed: "+e.message,"error")})}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Deploy",DefaultRenderable:"DataCloner-Deploy",DefaultDestinationAddress:"#DataCloner-Section-Deploy",Templates:[{Hash:"DataCloner-Deploy",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">4</div>\n\t<div class="accordion-card" id="section4" data-section="4">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section4\')">\n\t\t\t<div class="accordion-title">Deploy Schema</div>\n\t\t\t<span class="accordion-phase" id="phase4"></span>\n\t\t\t<div class="accordion-preview" id="preview4">Create selected tables in the local database</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Deploy\'].deploySchema()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto4"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<p style="font-size:0.9em; color:#666; margin-bottom:10px">Creates the selected tables in the local database and sets up CRUD endpoints (e.g. GET /1.0/Documents).</p>\n\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Deploy\'].deploySchema()">Deploy Selected Tables</button>\n\t\t\t<button class="danger" onclick="pict.views[\'DataCloner-Deploy\'].resetDatabase()">Reset Database</button>\n\t\t\t<div id="deployStatus"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Deploy",TemplateHash:"DataCloner-Deploy",DestinationAddress:"#DataCloner-Section-Deploy"}]}},{"pict-view":13}],21:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}buildConfigObject(){let t=document.getElementById("connProvider").value,e={};e.LocalDatabase={Provider:t,Config:{}};let i=e.LocalDatabase.Config;"SQLite"===t?i.SQLiteFilePath=document.getElementById("sqliteFilePath").value.trim()||"data/cloned.sqlite":"MySQL"===t?(i.host=document.getElementById("mysqlServer").value.trim()||"127.0.0.1",i.port=parseInt(document.getElementById("mysqlPort").value,10)||3306,i.user=document.getElementById("mysqlUser").value.trim()||"root",i.password=document.getElementById("mysqlPassword").value,i.database=document.getElementById("mysqlDatabase").value.trim(),i.connectionLimit=parseInt(document.getElementById("mysqlConnectionLimit").value,10)||20):"MSSQL"===t?(i.server=document.getElementById("mssqlServer").value.trim()||"127.0.0.1",i.port=parseInt(document.getElementById("mssqlPort").value,10)||1433,i.user=document.getElementById("mssqlUser").value.trim()||"sa",i.password=document.getElementById("mssqlPassword").value,i.database=document.getElementById("mssqlDatabase").value.trim(),i.connectionLimit=parseInt(document.getElementById("mssqlConnectionLimit").value,10)||20):"PostgreSQL"===t&&(i.host=document.getElementById("postgresqlHost").value.trim()||"127.0.0.1",i.port=parseInt(document.getElementById("postgresqlPort").value,10)||5432,i.user=document.getElementById("postgresqlUser").value.trim()||"postgres",i.password=document.getElementById("postgresqlPassword").value,i.database=document.getElementById("postgresqlDatabase").value.trim(),i.max=parseInt(document.getElementById("postgresqlConnectionLimit").value,10)||10),e.RemoteSession={};let n=document.getElementById("serverURL").value.trim();n&&(e.RemoteSession.ServerURL=n+"/1.0/");let o=document.getElementById("authMethod").value.trim();o&&(e.RemoteSession.AuthenticationMethod=o);let s=document.getElementById("authURI").value.trim();s&&(e.RemoteSession.AuthenticationURITemplate=s);let a=document.getElementById("checkURI").value.trim();a&&(e.RemoteSession.CheckSessionURITemplate=a);let r=document.getElementById("cookieName").value.trim();r&&(e.RemoteSession.CookieName=r);let l=document.getElementById("cookieValueAddr").value.trim();l&&(e.RemoteSession.CookieValueAddress=l);let c=document.getElementById("cookieValueTemplate").value.trim();c&&(e.RemoteSession.CookieValueTemplate=c);let d=document.getElementById("loginMarker").value.trim();d&&(e.RemoteSession.CheckSessionLoginMarker=d);let p=document.getElementById("userName").value.trim(),h=document.getElementById("password").value;(p||h)&&(e.Credentials={},p&&(e.Credentials.UserName=p),h&&(e.Credentials.Password=h));let u=document.getElementById("schemaURL").value.trim();u&&(e.SchemaURL=u);let g=this.pict.views["DataCloner-Schema"].getSelectedTables();g.length>0&&(e.Tables=g),e.Sync={},e.Sync.Mode=document.querySelector('input[name="syncMode"]:checked').value,e.Sync.PageSize=parseInt(document.getElementById("pageSize").value,10)||100,e.Sync.SyncDeletedRecords=document.getElementById("syncDeletedRecords").checked;let m=parseInt(document.getElementById("dateTimePrecisionMS").value,10);isNaN(m)||1e3===m||(e.Sync.DateTimePrecisionMS=m);let f=parseInt(document.getElementById("syncMaxRecords").value,10);return f>0&&(e.Sync.MaxRecords=f),e}buildMeadowIntegrationConfig(){let t=document.getElementById("connProvider").value,e={},i=document.getElementById("serverURL").value.trim();e.Source={ServerURL:i?i+"/1.0/":"https://localhost:8080/1.0/"},e.Source.UserID=!1,e.Source.Password=!1,e.Destination={},"MySQL"===t?(e.Destination.Provider="MySQL",e.Destination.MySQL={},e.Destination.MySQL.server=document.getElementById("mysqlServer").value.trim()||"127.0.0.1",e.Destination.MySQL.port=parseInt(document.getElementById("mysqlPort").value,10)||3306,e.Destination.MySQL.user=document.getElementById("mysqlUser").value.trim()||"root",e.Destination.MySQL.password=document.getElementById("mysqlPassword").value||"",e.Destination.MySQL.database=document.getElementById("mysqlDatabase").value.trim()||"meadow",e.Destination.MySQL.connectionLimit=parseInt(document.getElementById("mysqlConnectionLimit").value,10)||20):"MSSQL"===t?(e.Destination.Provider="MSSQL",e.Destination.MSSQL={},e.Destination.MSSQL.server=document.getElementById("mssqlServer").value.trim()||"127.0.0.1",e.Destination.MSSQL.port=parseInt(document.getElementById("mssqlPort").value,10)||1433,e.Destination.MSSQL.user=document.getElementById("mssqlUser").value.trim()||"sa",e.Destination.MSSQL.password=document.getElementById("mssqlPassword").value||"",e.Destination.MSSQL.database=document.getElementById("mssqlDatabase").value.trim()||"meadow",e.Destination.MSSQL.ConnectionPoolLimit=parseInt(document.getElementById("mssqlConnectionLimit").value,10)||20):(e.Destination.Provider="MySQL",e.Destination.MySQL={server:"127.0.0.1",port:3306,user:"root",password:"",database:"meadow",connectionLimit:20});let n=document.getElementById("schemaURL").value.trim();n?e.SchemaURL=n:e.SchemaPath="./schema/Model-Extended.json",e.Sync={},e.Sync.DefaultSyncMode=document.querySelector('input[name="syncMode"]:checked').value,e.Sync.PageSize=parseInt(document.getElementById("pageSize").value,10)||100;let o=parseInt(document.getElementById("dateTimePrecisionMS").value,10);isNaN(o)||(e.Sync.DateTimePrecisionMS=o);let s=this.pict.views["DataCloner-Schema"].getSelectedTables();e.Sync.SyncEntityList=s.length>0?s:[],e.Sync.SyncEntityOptions={},e.SessionManager={Sessions:{}};let a={Type:"Cookie"},r=document.getElementById("authMethod").value.trim()||"get";a.AuthenticationMethod=r;let l=document.getElementById("authURI").value.trim();l?"/"===l.charAt(0)?a.AuthenticationURITemplate=(i||"")+l:a.AuthenticationURITemplate=l:i&&("post"===r?(a.AuthenticationURITemplate=i+"/1.0/Authenticate",a.AuthenticationRequestBody={UserName:"{~D:Record.UserName~}",Password:"{~D:Record.Password~}"}):a.AuthenticationURITemplate=i+"/1.0/Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}");let c=document.getElementById("checkURI").value.trim();c?a.CheckSessionURITemplate="/"===c.charAt(0)?(i||"")+c:c:i&&(a.CheckSessionURITemplate=i+"/1.0/CheckSession");let d=document.getElementById("loginMarker").value.trim();if(a.CheckSessionLoginMarkerType="boolean",a.CheckSessionLoginMarker=d||"LoggedIn",i)try{let t=new URL(i);a.DomainMatch=t.host}catch(t){a.DomainMatch=i}let p=document.getElementById("cookieName").value.trim();a.CookieName=p||"SessionID";let h=document.getElementById("cookieValueAddr").value.trim();h&&(a.CookieValueAddress=h);let u=document.getElementById("cookieValueTemplate").value.trim();u&&(a.CookieValueTemplate=u);let g=document.getElementById("userName").value.trim(),m=document.getElementById("password").value;return a.Credentials={},g&&(a.Credentials.UserName=g),m&&(a.Credentials.Password=m),e.SessionManager.Sessions.SourceAPI=a,e}generateConfig(){let t=this.buildConfigObject(),e=JSON.stringify(t,null,"\t"),i=document.getElementById("configOutput");i.value=e,i.style.display="";let n=document.getElementById("syncLogFile").checked?" --log":"",o="",s=parseInt(document.getElementById("syncMaxRecords").value,10);s>0&&(o=" --max "+s);let a=document.getElementById("cliCommand");a.style.display="",a.querySelector("div").textContent="npx retold-data-service-clone --config clone-config.json --run"+n+o;let r=document.getElementById("cliOneShot");r.style.display="";let l="npx retold-data-service-clone --config-json '"+JSON.stringify(t).replace(/'/g,"'\\''")+"' --run"+n+o;r.querySelector("div").textContent=l;let c=this.buildMeadowIntegrationConfig(),d=JSON.stringify(c,null,"\t");document.getElementById("mdwintExport").style.display="",document.getElementById("mdwintConfigOutput").value=d;document.getElementById("mdwintCLICommand").querySelector("div").textContent="mdwint clone --schema_path ./schema/Model-Extended.json";let p=document.getElementById("connProvider").value;"MySQL"!==p&&"MSSQL"!==p?this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","Note: mdwint clone only supports MySQL and MSSQL destinations. The config defaults to MySQL; update the Destination section for your target database.","warn"):this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","",""),this.pict.providers.DataCloner.setStatus("configExportStatus","Config generated. Save as clone-config.json or copy the one-liner below.","ok")}copyConfig(){let t=document.getElementById("configOutput");if(!t.value)return void this.pict.providers.DataCloner.setStatus("configExportStatus","Generate a config first.","warn");let e=this;navigator.clipboard.writeText(t.value).then(function(){e.pict.providers.DataCloner.setStatus("configExportStatus","Config copied to clipboard.","ok")})}copyCLI(){let t=document.getElementById("cliCommand").querySelector("div").textContent,e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("configExportStatus","CLI command copied to clipboard.","ok")})}copyOneShot(){let t=document.getElementById("cliOneShot").querySelector("div").textContent,e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("configExportStatus","One-liner copied to clipboard.","ok")})}downloadConfig(){let t=document.getElementById("configOutput");t.value||this.generateConfig();let e=new Blob([t.value],{type:"application/json"}),i=document.createElement("a");i.href=URL.createObjectURL(e),i.download="clone-config.json",i.click(),URL.revokeObjectURL(i.href),this.pict.providers.DataCloner.setStatus("configExportStatus","Config downloaded as clone-config.json.","ok")}copyMdwintConfig(){let t=document.getElementById("mdwintConfigOutput");if(!t.value)return void this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","Generate a config first.","warn");let e=this;navigator.clipboard.writeText(t.value).then(function(){e.pict.providers.DataCloner.setStatus("mdwintConfigStatus",".meadow.config.json copied to clipboard.","ok")})}copyMdwintCLI(){let t=document.getElementById("mdwintCLICommand").querySelector("div").textContent,e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("mdwintConfigStatus","mdwint CLI command copied to clipboard.","ok")})}downloadMdwintConfig(){let t=document.getElementById("mdwintConfigOutput");t.value||this.generateConfig();let e=new Blob([t.value],{type:"application/json"}),i=document.createElement("a");i.href=URL.createObjectURL(e),i.download=".meadow.config.json",i.click(),URL.revokeObjectURL(i.href),this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","Config downloaded as .meadow.config.json.","ok")}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Export",DefaultRenderable:"DataCloner-Export",DefaultDestinationAddress:"#DataCloner-Section-Export",Templates:[{Hash:"DataCloner-Export",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">6</div>\n\t<div class="accordion-card" id="section6" data-section="6">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section6\')">\n\t\t\t<div class="accordion-title">Export Configuration</div>\n\t\t\t<div class="accordion-preview" id="preview6">Generate JSON config for headless cloning</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<p style="font-size:0.9em; color:#666; margin-bottom:10px">Generate a JSON config file from your current settings. Use it to run headless clones from the command line.</p>\n\t\t\t<div style="display:flex; gap:8px; margin-bottom:10px">\n\t\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Export\'].generateConfig()">Generate Config</button>\n\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].copyConfig()">Copy to Clipboard</button>\n\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].downloadConfig()">Download JSON</button>\n\t\t\t</div>\n\t\t\t<div id="configExportStatus"></div>\n\t\t\t<div id="cliCommand" style="display:none; margin-bottom:10px">\n\t\t\t\t<label style="margin-bottom:4px">CLI Command <span style="color:#888; font-weight:normal">(with config file)</span></label>\n\t\t\t\t<div style="background:#1a1a1a; color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer" onclick="pict.views[\'DataCloner-Export\'].copyCLI()" title="Click to copy"></div>\n\t\t\t</div>\n\t\t\t<div id="cliOneShot" style="display:none; margin-bottom:10px">\n\t\t\t\t<label style="margin-bottom:4px">One-liner <span style="color:#888; font-weight:normal">(no config file needed)</span></label>\n\t\t\t\t<div style="background:#1a1a1a; color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer; white-space:pre-wrap" onclick="pict.views[\'DataCloner-Export\'].copyOneShot()" title="Click to copy"></div>\n\t\t\t</div>\n\t\t\t<textarea id="configOutput" style="display:none; width:100%; min-height:300px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid #ccc; border-radius:4px; background:#fafafa; tab-size:4; resize:vertical" readonly></textarea>\n\n\t\t\t<div id="mdwintExport" style="display:none; margin-top:16px; padding-top:16px; border-top:1px solid #eee">\n\t\t\t\t<h3 style="margin:0 0 8px; font-size:1em">meadow-integration CLI <span style="color:#888; font-weight:normal; font-size:0.85em">(mdwint clone)</span></h3>\n\t\t\t\t<p style="font-size:0.85em; color:#666; margin-bottom:8px">Save as <code>.meadow.config.json</code> in your project root, then run the command below. Requires a local Meadow extended schema JSON file.</p>\n\t\t\t\t<div style="display:flex; gap:8px; margin-bottom:10px">\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].copyMdwintConfig()">Copy Config</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].downloadMdwintConfig()">Download .meadow.config.json</button>\n\t\t\t\t</div>\n\t\t\t\t<div id="mdwintCLICommand" style="margin-bottom:10px">\n\t\t\t\t\t<label style="margin-bottom:4px">CLI Command</label>\n\t\t\t\t\t<div style="background:#1a1a1a; color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer" onclick="pict.views[\'DataCloner-Export\'].copyMdwintCLI()" title="Click to copy"></div>\n\t\t\t\t</div>\n\t\t\t\t<div id="mdwintConfigStatus"></div>\n\t\t\t\t<textarea id="mdwintConfigOutput" style="width:100%; min-height:250px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid #ccc; border-radius:4px; background:#fafafa; tab-size:4; resize:vertical" readonly></textarea>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Export",TemplateHash:"DataCloner-Export",DestinationAddress:"#DataCloner-Section-Export"}]}},{"pict-view":13}],22:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}onAfterRender(){this.pict.views["DataCloner-Connection"].render(),this.pict.views["DataCloner-Session"].render(),this.pict.views["DataCloner-Schema"].render(),this.pict.views["DataCloner-Deploy"].render(),this.pict.views["DataCloner-Sync"].render(),this.pict.views["DataCloner-Export"].render(),this.pict.views["DataCloner-ViewData"].render(),this.pict.CSSMap.injectCSS()}toggleSection(t){let e=document.getElementById(t);e&&e.classList.toggle("open")}expandAllSections(){let t=document.querySelectorAll(".accordion-card");for(let e=0;e<t.length;e++)t[e].classList.add("open")}collapseAllSections(){let t=document.querySelectorAll(".accordion-card");for(let e=0;e<t.length;e++)t[e].classList.remove("open")}toggleStatusDetail(){let t=document.getElementById("liveStatusDetail"),e=document.getElementById("liveStatusMeta"),i=document.getElementById("liveStatusMessage"),n=document.getElementById("liveStatusToggle"),o=document.getElementById("liveStatusBar");t&&("none"!==t.style.display?(t.style.display="none",e.style.display="",i.style.display="",n.innerHTML="▼",o.classList.remove("expanded"),this.pict.providers.DataCloner.onStatusDetailCollapsed()):(t.style.display="",e.style.display="none",i.style.display="none",n.innerHTML="▲",o.classList.add("expanded"),this.pict.providers.DataCloner.onStatusDetailExpanded()))}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Layout",DefaultRenderable:"DataCloner-Layout",DefaultDestinationAddress:"#DataCloner-Application-Container",CSS:'\n* { box-sizing: border-box; margin: 0; padding: 0; }\nbody { font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif; background: #f5f5f5; color: #333; padding: 20px; }\nh1 { margin-bottom: 20px; color: #1a1a1a; }\nh2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px solid #ddd; padding-bottom: 6px; }\n\n.section { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }\n\n/* Accordion layout */\n.accordion-row { display: flex; gap: 0; margin-bottom: 16px; align-items: stretch; }\n.accordion-number {\n\tflex: 0 0 48px; display: flex; align-items: flex-start; justify-content: center;\n\tpadding-top: 16px; font-size: 1.6em; font-weight: 700; color: #4a90d9;\n\tuser-select: none;\n}\n.accordion-card {\n\tflex: 1; background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n\toverflow: hidden; min-width: 0;\n}\n.accordion-header {\n\tdisplay: flex; align-items: center; padding: 14px 20px; cursor: pointer;\n\tuser-select: none; gap: 12px; transition: background 0.15s; line-height: 1.4;\n}\n.accordion-header:hover { background: #fafafa; }\n.accordion-title { font-weight: 600; color: #333; font-size: 1.05em; white-space: nowrap; }\n.accordion-preview { flex: 1; font-style: italic; color: #888; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.accordion-toggle {\n\tflex: 0 0 20px; display: flex; align-items: center; justify-content: center;\n\tborder-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: #888;\n}\n.accordion-header:hover .accordion-toggle { background: #eee; color: #555; }\n.accordion-card.open .accordion-toggle { transform: rotate(180deg); }\n.accordion-body { padding: 0 20px 20px; display: none; }\n.accordion-card.open .accordion-body { display: block; }\n.accordion-card.open .accordion-header { border-bottom: 1px solid #eee; }\n.accordion-card.open .accordion-preview { display: none; }\n\n/* Action controls (go link + auto checkbox) */\n.accordion-actions { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }\n.accordion-card.open .accordion-actions { display: none; }\n.accordion-go {\n\tfont-size: 0.82em; color: #4a90d9; cursor: pointer; text-decoration: none;\n\tfont-weight: 500; white-space: nowrap; padding: 2px 6px; border-radius: 3px;\n\ttransition: background 0.15s;\n}\n.accordion-go:hover { background: #e8f0fe; text-decoration: underline; }\n.accordion-auto {\n\tfont-size: 0.82em; color: #999; white-space: nowrap; cursor: pointer;\n}\n.accordion-auto .auto-label { display: none; }\n.accordion-auto:hover .auto-label { display: inline; }\n.accordion-auto input[type="checkbox"] { width: auto; margin: 0; cursor: pointer; vertical-align: middle; position: relative; top: 0px; opacity: 0.75; transition: opacity 0.15s; }\n.accordion-auto:hover input[type="checkbox"] { opacity: 1; }\n.accordion-auto:hover { color: #666; }\n\n/* Phase status indicator */\n.accordion-phase {\n\tflex: 0 0 auto; display: none; align-items: center; justify-content: center;\n\tfont-size: 0.85em; line-height: 1;\n}\n.accordion-phase.visible { display: flex; }\n.accordion-phase-ok { color: #28a745; }\n.accordion-phase-error { color: #dc3545; }\n.accordion-phase-busy { color: #28a745; }\n.accordion-phase-busy .phase-spinner {\n\tdisplay: inline-block; width: 14px; height: 14px;\n\tborder: 2px solid #28a745; border-top-color: transparent; border-radius: 50%;\n\tanimation: phase-spin 0.8s linear infinite; vertical-align: middle;\n}\n@keyframes phase-spin {\n\tto { transform: rotate(360deg); }\n}\n\n.accordion-controls {\n\tdisplay: flex; gap: 8px; margin-bottom: 12px; justify-content: flex-end;\n}\n.accordion-controls button {\n\tpadding: 4px 10px; font-size: 0.82em; font-weight: 500; background: none;\n\tborder: 1px solid #ccc; border-radius: 4px; color: #666; cursor: pointer; margin: 0;\n}\n.accordion-controls button:hover { background: #f0f0f0; border-color: #aaa; color: #333; }\n\nlabel { display: block; font-weight: 600; margin-bottom: 4px; font-size: 0.9em; }\ninput[type="text"], input[type="password"], input[type="number"] {\n\twidth: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;\n\tfont-size: 0.95em; margin-bottom: 10px;\n}\ninput[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {\n\toutline: none; border-color: #4a90d9;\n}\n\nbutton {\n\tpadding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;\n\tfont-size: 0.9em; font-weight: 600; margin-right: 8px; margin-bottom: 8px;\n}\nbutton.primary { background: #4a90d9; color: #fff; }\nbutton.primary:hover { background: #357abd; }\nbutton.secondary { background: #6c757d; color: #fff; }\nbutton.secondary:hover { background: #5a6268; }\nbutton.danger { background: #dc3545; color: #fff; }\nbutton.danger:hover { background: #c82333; }\nbutton.success { background: #28a745; color: #fff; }\nbutton.success:hover { background: #218838; }\nbutton:disabled { opacity: 0.5; cursor: not-allowed; }\n\n.status { padding: 8px 12px; border-radius: 4px; margin-top: 10px; font-size: 0.9em; }\n.status.ok { background: #d4edda; color: #155724; }\n.status.error { background: #f8d7da; color: #721c24; }\n.status.info { background: #d1ecf1; color: #0c5460; }\n.status.warn { background: #fff3cd; color: #856404; }\n\n.inline-group { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 10px; }\n.inline-group > div { flex: 1; }\n\na { color: #4a90d9; }\n\nselect { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }\n\n.checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }\n.checkbox-row input[type="checkbox"] { width: auto; margin: 0; }\n.checkbox-row label { display: inline; margin: 0; font-weight: normal; cursor: pointer; }\n\n/* Live Status Bar */\n.live-status-bar {\n\tbackground: #fff; border-radius: 8px; margin-bottom: 16px;\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.1);\n\tposition: sticky; top: 0; z-index: 100; border-left: 4px solid #6c757d;\n}\n.live-status-bar.phase-idle { border-left-color: #6c757d; }\n.live-status-bar.phase-disconnected { border-left-color: #dc3545; }\n.live-status-bar.phase-ready { border-left-color: #4a90d9; }\n.live-status-bar.phase-syncing { border-left-color: #28a745; }\n.live-status-bar.phase-stopping { border-left-color: #ffc107; }\n.live-status-bar.phase-complete { border-left-color: #28a745; }\n\n.live-status-dot {\n\twidth: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;\n\tbackground: #6c757d;\n}\n.live-status-bar.phase-idle .live-status-dot { background: #6c757d; }\n.live-status-bar.phase-disconnected .live-status-dot { background: #dc3545; }\n.live-status-bar.phase-ready .live-status-dot { background: #4a90d9; }\n.live-status-bar.phase-syncing .live-status-dot {\n\tbackground: #28a745;\n\tanimation: live-pulse 1.5s ease-in-out infinite;\n}\n.live-status-bar.phase-stopping .live-status-dot {\n\tbackground: #ffc107;\n\tanimation: live-pulse 0.8s ease-in-out infinite;\n}\n.live-status-bar.phase-complete .live-status-dot { background: #28a745; }\n\n@keyframes live-pulse {\n\t0%, 100% { opacity: 1; transform: scale(1); }\n\t50% { opacity: 0.4; transform: scale(0.8); }\n}\n\n.live-status-message { flex: 1; font-size: 0.92em; color: #333; line-height: 1.4; }\n\n.live-status-meta {\n\tdisplay: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: #666;\n}\n.live-status-meta-item { white-space: nowrap; }\n.live-status-meta-item strong { color: #333; }\n\n.live-status-progress-bar {\n\theight: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden;\n\tposition: absolute; bottom: 0; left: 0; right: 0;\n}\n.live-status-progress-fill {\n\theight: 100%; background: #28a745; transition: width 1s ease;\n}\n/* Expandable status bar */\n.live-status-header {\n\tdisplay: flex; align-items: center; gap: 14px; cursor: pointer;\n\tpadding: 14px 20px; user-select: none;\n}\n.live-status-bar.expanded .live-status-header {\n\tborder-bottom: 1px solid #e9ecef; padding-bottom: 10px;\n}\n.live-status-expand-toggle {\n\tflex: 0 0 20px; display: flex; align-items: center; justify-content: center;\n\tfont-size: 0.7em; color: #888; transition: transform 0.25s;\n}\n.live-status-bar.expanded .live-status-expand-toggle { transform: rotate(180deg); }\n\n.live-status-detail {\n\tpadding: 12px 20px 16px; max-height: 60vh; overflow-y: auto;\n}\n\n/* Status Detail Sections */\n.status-detail-section { margin-bottom: 14px; }\n.status-detail-section:last-child { margin-bottom: 0; }\n.status-detail-section-title {\n\tfont-size: 0.85em; font-weight: 600; color: #555; text-transform: uppercase;\n\tletter-spacing: 0.5px; margin-bottom: 8px; padding-bottom: 4px;\n\tborder-bottom: 1px solid #eee;\n}\n\n/* Running Operations */\n.running-op-row {\n\tdisplay: flex; align-items: center; gap: 12px; padding: 6px 0;\n\tfont-size: 0.9em;\n}\n.running-op-name { font-weight: 600; min-width: 180px; }\n.running-op-bar {\n\tflex: 1; height: 8px; background: #e9ecef; border-radius: 4px; overflow: hidden;\n\tmin-width: 120px;\n}\n.running-op-bar-fill { height: 100%; background: #4a90d9; transition: width 0.5s ease; }\n.running-op-count { font-size: 0.85em; color: #666; white-space: nowrap; }\n.running-op-pending { color: #888; font-size: 0.85em; font-style: italic; padding: 4px 0; }\n\n/* Completed Operations */\n.completed-op-row { padding: 8px 0; border-bottom: 1px solid #f0f0f0; }\n.completed-op-row:last-child { border-bottom: none; }\n.completed-op-header {\n\tdisplay: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px;\n}\n.completed-op-name { font-weight: 600; }\n.completed-op-stats { color: #666; font-size: 0.85em; }\n.completed-op-checkmark { color: #28a745; }\n\n/* Ratio Bar */\n.ratio-bar-container {\n\tdisplay: flex; height: 10px; border-radius: 5px; overflow: hidden;\n\tbackground: #e9ecef; margin: 4px 0;\n}\n.ratio-bar-segment { height: 100%; transition: width 0.5s ease; }\n.ratio-bar-segment.unchanged { background: #6c757d; }\n.ratio-bar-segment.new-records { background: #28a745; }\n.ratio-bar-segment.updated { background: #4a90d9; }\n.ratio-bar-segment.deleted { background: #dc3545; }\n.ratio-bar-legend {\n\tdisplay: flex; gap: 12px; font-size: 0.75em; color: #666; margin-top: 2px; flex-wrap: wrap;\n}\n.ratio-bar-legend-item { display: flex; align-items: center; gap: 4px; }\n.ratio-bar-legend-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }\n.ratio-bar-legend-dot.unchanged-dot { background: #6c757d; }\n.ratio-bar-legend-dot.new-dot { background: #28a745; }\n.ratio-bar-legend-dot.updated-dot { background: #4a90d9; }\n.ratio-bar-legend-dot.deleted-dot { background: #dc3545; }\n\n/* Error Operations */\n.error-op-row { padding: 6px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.9em; }\n.error-op-row:last-child { border-bottom: none; }\n.error-op-header { display: flex; align-items: center; gap: 8px; }\n.error-op-name { font-weight: 600; color: #dc3545; }\n.error-op-status { font-size: 0.82em; color: #dc3545; }\n.error-op-message { font-size: 0.82em; color: #888; margin-top: 2px; padding-left: 18px; }\n.error-op-log-entries {\n\tfont-size: 0.78em; color: #888; margin-top: 4px; padding-left: 18px;\n\tfont-family: monospace; max-height: 80px; overflow-y: auto;\n}\n\n/* Pre-count Table */\n.precount-table {\n\twidth: 100%; border-collapse: collapse; font-size: 0.88em;\n}\n.precount-table thead th {\n\ttext-align: left; font-weight: 600; color: #555; font-size: 0.85em;\n\ttext-transform: uppercase; letter-spacing: 0.3px;\n\tpadding: 4px 8px 6px; border-bottom: 2px solid #e9ecef;\n}\n.precount-table tbody td {\n\tpadding: 4px 8px; border-bottom: 1px solid #f0f0f0;\n}\n.precount-table tbody tr:last-child td { border-bottom: 1px solid #e9ecef; }\n.precount-table tfoot td {\n\tpadding: 6px 8px 2px; font-size: 0.95em;\n}\n.precount-error td { color: #dc3545; }\n.precount-pending {\n\tcolor: #888; font-size: 0.85em; font-style: italic; padding: 8px 0 2px;\n\tdisplay: flex; align-items: center; gap: 6px;\n}\n.precount-spinner {\n\tdisplay: inline-block; width: 12px; height: 12px;\n\tborder: 2px solid #ddd; border-top-color: #4a90d9;\n\tborder-radius: 50%; animation: precount-spin 0.8s linear infinite;\n}\n@keyframes precount-spin { to { transform: rotate(360deg); } }\n',Templates:[{Hash:"DataCloner-Layout",Template:'\n<h1>Retold Data Cloner</h1>\n\n\x3c!-- Live Status Bar (Expandable) --\x3e\n<div id="liveStatusBar" class="live-status-bar phase-idle" style="position:relative">\n\t<div class="live-status-header" onclick="pict.views[\'DataCloner-Layout\'].toggleStatusDetail()">\n\t\t<div class="live-status-dot"></div>\n\t\t<div class="live-status-message" id="liveStatusMessage">Idle</div>\n\t\t<div class="live-status-meta" id="liveStatusMeta"></div>\n\t\t<div class="live-status-expand-toggle" id="liveStatusToggle">▼</div>\n\t</div>\n\t<div class="live-status-detail" id="liveStatusDetail" style="display:none">\n\t\t<div id="DataCloner-Throughput-Histogram"></div>\n\t\t<div id="DataCloner-StatusDetail-Container"></div>\n\t</div>\n\t<div class="live-status-progress-bar"><div class="live-status-progress-fill" id="liveStatusProgressFill" style="width:0%"></div></div>\n</div>\n\n\x3c!-- Expand / Collapse All --\x3e\n<div class="accordion-controls">\n\t<button onclick="pict.views[\'DataCloner-Layout\'].expandAllSections()">Expand All</button>\n\t<button onclick="pict.views[\'DataCloner-Layout\'].collapseAllSections()">Collapse All</button>\n</div>\n\n\x3c!-- Section containers --\x3e\n<div id="DataCloner-Section-Connection"></div>\n<div id="DataCloner-Section-Session"></div>\n<div id="DataCloner-Section-Schema"></div>\n<div id="DataCloner-Section-Deploy"></div>\n<div id="DataCloner-Section-Sync"></div>\n<div id="DataCloner-Section-Export"></div>\n<div id="DataCloner-Section-ViewData"></div>\n'}],Renderables:[{RenderableHash:"DataCloner-Layout",TemplateHash:"DataCloner-Layout",DestinationAddress:"#DataCloner-Application-Container"}]}},{"pict-view":13}],23:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}fetchSchema(){let t=document.getElementById("schemaURL").value.trim(),e={};t&&(e.SchemaURL=t),this.pict.providers.DataCloner.setSectionPhase(3,"busy"),this.pict.providers.DataCloner.setStatus("schemaStatus","Fetching schema...","info"),this.pict.providers.DataCloner.api("POST","/clone/schema/fetch",e).then(t=>{t.Success?(this.pict.AppData.DataCloner.FetchedTables=t.Tables||[],this.pict.providers.DataCloner.setStatus("schemaStatus","Fetched "+t.TableCount+" tables from "+t.SchemaURL,"ok"),this.pict.providers.DataCloner.setSectionPhase(3,"ok"),this.renderTableList()):(this.pict.providers.DataCloner.setStatus("schemaStatus","Fetch failed: "+(t.Error||"Unknown error"),"error"),this.pict.providers.DataCloner.setSectionPhase(3,"error"))}).catch(t=>{this.pict.providers.DataCloner.setStatus("schemaStatus","Request failed: "+t.message,"error"),this.pict.providers.DataCloner.setSectionPhase(3,"error")})}loadSavedSelections(){try{let t=localStorage.getItem("dataCloner_selectedTables");if(t)return JSON.parse(t)}catch(t){}return null}saveSelections(){let t=this.getSelectedTables();localStorage.setItem("dataCloner_selectedTables",JSON.stringify(t)),this.updateSelectionCount(),this.pict.providers.DataCloner.updateAllPreviews()}updateSelectionCount(){let t=this.pict.AppData.DataCloner.FetchedTables||[],e=this.getSelectedTables().length,i=document.getElementById("tableSelectionCount");i&&(i.textContent=e+" / "+t.length+" selected")}renderTableList(){let t=this.pict.AppData.DataCloner.FetchedTables||[],e=document.getElementById("tableList");e.innerHTML="";let i=this.loadSavedSelections(),n=null;if(i){n={};for(let t=0;t<i.length;t++)n[i[t]]=!0}for(let i=0;i<t.length;i++){let o=t[i],s=document.createElement("div");s.className="table-item",s.setAttribute("data-table",o.toLowerCase());let a=document.createElement("input");a.type="checkbox",a.id="tbl_"+o,a.value=o,a.checked=!!n&&!0===n[o],a.addEventListener("change",()=>{this.saveSelections()});let r=document.createElement("label");r.htmlFor="tbl_"+o,r.textContent=o,s.appendChild(a),s.appendChild(r),e.appendChild(s)}document.getElementById("tableSelection").style.display=t.length>0?"block":"none",document.getElementById("tableFilter").value="",this.updateSelectionCount()}filterTableList(){let t=document.getElementById("tableFilter").value.toLowerCase().trim(),e=document.getElementById("tableList").children;for(let i=0;i<e.length;i++){let n=e[i].getAttribute("data-table")||"";e[i].style.display=!t||n.indexOf(t)>=0?"":"none"}}selectAllTables(t){let e=this.pict.AppData.DataCloner.FetchedTables||[],i=document.getElementById("tableFilter").value.toLowerCase().trim();for(let n=0;n<e.length;n++){let o=e[n];if(i&&o.toLowerCase().indexOf(i)<0)continue;let s=document.getElementById("tbl_"+o);s&&(s.checked=t)}this.saveSelections()}getSelectedTables(){let t=this.pict.AppData.DataCloner.FetchedTables||[],e=[];for(let i=0;i<t.length;i++){let n=document.getElementById("tbl_"+t[i]);n&&n.checked&&e.push(t[i])}return e}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Schema",DefaultRenderable:"DataCloner-Schema",DefaultDestinationAddress:"#DataCloner-Section-Schema",CSS:'\n.table-list { max-height: 300px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px; padding: 8px; margin: 10px 0; }\n.table-item { padding: 4px 8px; display: flex; align-items: center; }\n.table-item:hover { background: #f0f0f0; }\n.table-item input[type="checkbox"] { margin-right: 8px; width: auto; }\n.table-item label { display: inline; font-weight: normal; margin-bottom: 0; cursor: pointer; }\n',Templates:[{Hash:"DataCloner-Schema",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">3</div>\n\t<div class="accordion-card" id="section3" data-section="3">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section3\')">\n\t\t\t<div class="accordion-title">Remote Schema</div>\n\t\t\t<span class="accordion-phase" id="phase3"></span>\n\t\t\t<div class="accordion-preview" id="preview3">Fetch and select tables from the remote server</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Schema\'].fetchSchema()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto3"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<label for="schemaURL">Schema URL (leave blank for default: /1.0/Retold/Models)</label>\n\t\t\t<input type="text" id="schemaURL" placeholder="http://remote-server:8086/1.0/Retold/Models">\n\n\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Schema\'].fetchSchema()">Fetch Schema</button>\n\t\t\t<div id="schemaStatus"></div>\n\n\t\t\t<div id="tableSelection" style="display:none">\n\t\t\t\t<h3 style="margin:12px 0 8px; font-size:1em;">Select Tables</h3>\n\t\t\t\t<div style="display:flex; gap:8px; align-items:center; margin-bottom:8px">\n\t\t\t\t\t<input type="text" id="tableFilter" placeholder="Filter tables..." style="flex:1; margin-bottom:0" oninput="pict.views[\'DataCloner-Schema\'].filterTableList()">\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Schema\'].selectAllTables(true)" style="font-size:0.8em">Select All</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Schema\'].selectAllTables(false)" style="font-size:0.8em">Deselect All</button>\n\t\t\t\t\t<span id="tableSelectionCount" style="font-size:0.85em; color:#666; white-space:nowrap"></span>\n\t\t\t\t</div>\n\t\t\t\t<div id="tableList" class="table-list"></div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Schema",TemplateHash:"DataCloner-Schema",DestinationAddress:"#DataCloner-Section-Schema"}]}},{"pict-view":13}],24:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}configureSession(){let t=document.getElementById("serverURL").value.trim();if(!t)return void this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Server URL is required.","error");let e={ServerURL:t.replace(/\/+$/,"")+"/1.0/"},i=document.getElementById("authMethod").value.trim();i&&(e.AuthenticationMethod=i);let n=document.getElementById("authURI").value.trim();n&&(e.AuthenticationURITemplate=n);let o=document.getElementById("checkURI").value.trim();o&&(e.CheckSessionURITemplate=o);let s=document.getElementById("cookieName").value.trim();s&&(e.CookieName=s);let a=document.getElementById("cookieValueAddr").value.trim();a&&(e.CookieValueAddress=a);let r=document.getElementById("cookieValueTemplate").value.trim();r&&(e.CookieValueTemplate=r);let l=document.getElementById("loginMarker").value.trim();l&&(e.CheckSessionLoginMarker=l),this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Configuring session...","info"),this.pict.providers.DataCloner.api("POST","/clone/session/configure",e).then(t=>{t.Success?this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Session configured for "+t.ServerURL+" (domain: "+t.DomainMatch+")","ok"):this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Configuration failed: "+(t.Error||"Unknown error"),"error")}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Request failed: "+t.message,"error")})}authenticate(){let t=document.getElementById("userName").value.trim(),e=document.getElementById("password").value.trim();if(!t||!e)return this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Username and password are required.","error"),void this.pict.providers.DataCloner.setSectionPhase(2,"error");this.pict.providers.DataCloner.setSectionPhase(2,"busy"),this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Authenticating...","info"),this.pict.providers.DataCloner.api("POST","/clone/session/authenticate",{UserName:t,Password:e}).then(t=>{t.Success&&t.Authenticated?(this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Authenticated successfully.","ok"),this.pict.providers.DataCloner.setSectionPhase(2,"ok")):(this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Authentication failed: "+(t.Error||"Not authenticated"),"error"),this.pict.providers.DataCloner.setSectionPhase(2,"error"))}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Request failed: "+t.message,"error"),this.pict.providers.DataCloner.setSectionPhase(2,"error")})}checkSession(){this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Checking session...","info"),this.pict.providers.DataCloner.api("GET","/clone/session/check").then(t=>{t.Authenticated?this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Session is active. Server: "+(t.ServerURL||"N/A"),"ok"):t.Configured?this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Session configured but not authenticated.","warn"):this.pict.providers.DataCloner.setStatus("sessionAuthStatus","No session configured.","warn")}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Request failed: "+t.message,"error")})}deauthenticate(){this.pict.providers.DataCloner.api("POST","/clone/session/deauthenticate").then(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Session deauthenticated.","info")}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Request failed: "+t.message,"error")})}goAction(){this.pict.providers.DataCloner.setSectionPhase(2,"busy"),this.configureSession(),setTimeout(()=>{this.authenticate()},1500)}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Session",DefaultRenderable:"DataCloner-Session",DefaultDestinationAddress:"#DataCloner-Section-Session",Templates:[{Hash:"DataCloner-Session",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">2</div>\n\t<div class="accordion-card" id="section2" data-section="2">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section2\')">\n\t\t\t<div class="accordion-title">Remote Session</div>\n\t\t\t<span class="accordion-phase" id="phase2"></span>\n\t\t\t<div class="accordion-preview" id="preview2">Configure remote server URL and credentials</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Session\'].goAction()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto2"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<div class="inline-group">\n\t\t\t\t<div style="flex:2">\n\t\t\t\t\t<label for="serverURL">Remote Server URL</label>\n\t\t\t\t\t<input type="text" id="serverURL" placeholder="http://remote-server:8086" value="">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:1">\n\t\t\t\t\t<label for="authMethod">Auth Method</label>\n\t\t\t\t\t<input type="text" id="authMethod" placeholder="get" value="get">\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<details style="margin-bottom:10px">\n\t\t\t\t<summary style="cursor:pointer; font-size:0.9em; color:#666">Advanced Session Options</summary>\n\t\t\t\t<div style="padding:10px 0">\n\t\t\t\t\t<label for="authURI">Authentication URI Template (leave blank for default)</label>\n\t\t\t\t\t<input type="text" id="authURI" placeholder="Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}">\n\t\t\t\t\t<label for="checkURI">Check Session URI Template</label>\n\t\t\t\t\t<input type="text" id="checkURI" placeholder="CheckSession">\n\t\t\t\t\t<label for="cookieName">Cookie Name</label>\n\t\t\t\t\t<input type="text" id="cookieName" placeholder="SessionID" value="SessionID">\n\t\t\t\t\t<label for="cookieValueAddr">Cookie Value Address</label>\n\t\t\t\t\t<input type="text" id="cookieValueAddr" placeholder="SessionID" value="SessionID">\n\t\t\t\t\t<label for="cookieValueTemplate">Cookie Value Template (overrides Address if set)</label>\n\t\t\t\t\t<input type="text" id="cookieValueTemplate" placeholder="{~D:Record.SessionID~}">\n\t\t\t\t\t<label for="loginMarker">Login Marker</label>\n\t\t\t\t\t<input type="text" id="loginMarker" placeholder="LoggedIn" value="LoggedIn">\n\t\t\t\t</div>\n\t\t\t</details>\n\n\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Session\'].configureSession()">Configure Session</button>\n\t\t\t<div id="sessionConfigStatus"></div>\n\n\t\t\t<hr style="margin:16px 0; border:none; border-top:1px solid #eee">\n\n\t\t\t<div class="inline-group">\n\t\t\t\t<div>\n\t\t\t\t\t<label for="userName">Username</label>\n\t\t\t\t\t<input type="text" id="userName" placeholder="username">\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<label for="password">Password</label>\n\t\t\t\t\t<input type="password" id="password" placeholder="password">\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<button class="success" onclick="pict.views[\'DataCloner-Session\'].authenticate()">Authenticate</button>\n\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Session\'].checkSession()">Check Session</button>\n\t\t\t<button class="danger" onclick="pict.views[\'DataCloner-Session\'].deauthenticate()">Deauthenticate</button>\n\t\t\t<div id="sessionAuthStatus"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Session",TemplateHash:"DataCloner-Session",DestinationAddress:"#DataCloner-Section-Session"}]}},{"pict-view":13}],25:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}startSync(){let t=this.pict.views["DataCloner-Schema"].getSelectedTables(),e=parseInt(document.getElementById("pageSize").value,10)||100,i=parseInt(document.getElementById("dateTimePrecisionMS").value,10);isNaN(i)&&(i=1e3);let n=document.getElementById("syncDeletedRecords").checked,o=document.querySelector('input[name="syncMode"]:checked').value,s=parseInt(document.getElementById("syncMaxRecords").value,10)||0,a=document.getElementById("syncLogFile").checked;if(0===t.length)return this.pict.providers.DataCloner.setStatus("syncStatus","No tables selected for sync.","error"),void this.pict.providers.DataCloner.setSectionPhase(5,"error");this.pict.providers.DataCloner.setSectionPhase(5,"busy"),this.pict.providers.DataCloner.setStatus("syncStatus","Starting "+o.toLowerCase()+" sync...","info");let r=this,l={Tables:t,PageSize:e,DateTimePrecisionMS:i,SyncDeletedRecords:n,SyncMode:o};s>0&&(l.MaxRecordsPerEntity=s),a&&(l.LogToFile=!0),this.pict.providers.DataCloner.api("POST","/clone/sync/start",l).then(function(t){if(t.Success){let e=t.SyncMode+" sync started for "+t.Tables.length+" tables.";t.SyncDeletedRecords&&(e+=" (including deleted records)"),r.pict.providers.DataCloner.setStatus("syncStatus",e,"ok"),r.startPolling()}else r.pict.providers.DataCloner.setStatus("syncStatus","Sync start failed: "+(t.Error||"Unknown error"),"error"),r.pict.providers.DataCloner.setSectionPhase(5,"error")}).catch(function(t){r.pict.providers.DataCloner.setStatus("syncStatus","Request failed: "+t.message,"error"),r.pict.providers.DataCloner.setSectionPhase(5,"error")})}stopSync(){let t=this;this.pict.providers.DataCloner.api("POST","/clone/sync/stop").then(function(e){t.pict.providers.DataCloner.setStatus("syncStatus","Sync stop requested.","warn")}).catch(function(e){t.pict.providers.DataCloner.setStatus("syncStatus","Request failed: "+e.message,"error")})}startPolling(){this.pict.AppData.DataCloner.SyncPollTimer&&clearInterval(this.pict.AppData.DataCloner.SyncPollTimer);let t=this;this.pict.AppData.DataCloner.SyncPollTimer=setInterval(function(){t.pollSyncStatus()},2e3),this.pollSyncStatus()}stopPolling(){this.pict.AppData.DataCloner.SyncPollTimer&&(clearInterval(this.pict.AppData.DataCloner.SyncPollTimer),this.pict.AppData.DataCloner.SyncPollTimer=null)}pollSyncStatus(){let t=this;this.pict.providers.DataCloner.api("GET","/clone/sync/status").then(function(e){if(t.renderSyncProgress(e),!e.Running&&!e.Stopping&&(t.stopPolling(),Object.keys(e.Tables||{}).length>0)){let i=e.Tables||{},n=!1,o=!1,s=Object.keys(i);for(let t=0;t<s.length;t++)"Error"===i[s[t]].Status&&(n=!0),"Partial"===i[s[t]].Status&&(o=!0);n?(t.pict.providers.DataCloner.setStatus("syncStatus","Sync finished with errors. Check the table below for details.","error"),t.pict.providers.DataCloner.setSectionPhase(5,"error")):o?(t.pict.providers.DataCloner.setStatus("syncStatus","Sync finished. Some records were skipped (GUID conflicts or permission issues).","warn"),t.pict.providers.DataCloner.setSectionPhase(5,"ok")):(t.pict.providers.DataCloner.setStatus("syncStatus","Sync complete.","ok"),t.pict.providers.DataCloner.setSectionPhase(5,"ok")),t.fetchSyncReport()}}).catch(function(t){})}fetchSyncReport(){let t=this;this.pict.providers.DataCloner.api("GET","/clone/sync/report").then(function(e){e&&e.ReportVersion&&(t.pict.AppData.DataCloner.LastReport=e,t.renderSyncReport(e))}).catch(function(t){})}renderSyncReport(t){document.getElementById("syncReportSection").style.display="";let e=document.getElementById("reportSummaryCards"),i="outcome-"+t.Outcome.toLowerCase(),n={Success:"#28a745",Partial:"#ffc107",Error:"#dc3545",Stopped:"#6c757d"}[t.Outcome]||"#666",o=t.RunTimestamps.DurationSeconds||0,s=o<60?o+"s":Math.floor(o/60)+"m "+o%60+"s",a=t.Summary.TotalSynced.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","),r=t.Summary.TotalRecords.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");e.innerHTML='<div class="report-card '+i+'"> <div class="card-label">Outcome</div> <div class="card-value" style="color:'+n+'">'+t.Outcome+'</div></div><div class="report-card"> <div class="card-label">Mode</div> <div class="card-value">'+t.Config.SyncMode+'</div></div><div class="report-card"> <div class="card-label">Duration</div> <div class="card-value">'+s+'</div></div><div class="report-card"> <div class="card-label">Tables</div> <div class="card-value">'+t.Summary.Complete+" / "+t.Summary.TotalTables+'</div></div><div class="report-card"> <div class="card-label">Records</div> <div class="card-value">'+a+'</div> <div style="font-size:0.75em; color:#888">of '+r+"</div></div>";let l=document.getElementById("reportAnomalies");if(0===t.Anomalies.length)l.innerHTML='<div style="color:#28a745; font-weight:600; font-size:0.9em">No anomalies detected.</div>';else{let e='<h4 style="margin:0 0 8px; color:#dc3545; font-size:0.95em">Anomalies ('+t.Anomalies.length+")</h4>";e+='<table class="progress-table">',e+="<tr><th>Table</th><th>Type</th><th>Message</th></tr>";for(let i=0;i<t.Anomalies.length;i++){let n=t.Anomalies[i],o="Error"===n.Type?"#dc3545":"Partial"===n.Type?"#ffc107":"#6c757d";e+="<tr>",e+="<td><strong>"+this.pict.providers.DataCloner.escapeHtml(n.Table)+"</strong></td>",e+='<td style="color:'+o+'">'+n.Type+"</td>",e+="<td>"+this.pict.providers.DataCloner.escapeHtml(n.Message)+"</td>",e+="</tr>"}e+="</table>",l.innerHTML=e}let c=document.getElementById("reportTopTables"),d=Math.min(10,t.Tables.length);if(d>0){let e='<h4 style="margin:0 0 8px; font-size:0.95em; color:#444">Top Tables by Duration</h4>';e+='<table class="progress-table">',e+="<tr><th>Table</th><th>Duration</th><th>Records</th><th>Status</th></tr>";for(let i=0;i<d;i++){let n=t.Tables[i],o=n.DurationSeconds<60?n.DurationSeconds+"s":Math.floor(n.DurationSeconds/60)+"m "+n.DurationSeconds%60+"s",s=n.Total.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","),a={Complete:"#28a745",Error:"#dc3545",Partial:"#ffc107"}[n.Status]||"#666";e+="<tr>",e+="<td><strong>"+this.pict.providers.DataCloner.escapeHtml(n.Name)+"</strong></td>",e+="<td>"+o+"</td>",e+="<td>"+s+"</td>",e+='<td style="color:'+a+'">'+n.Status+"</td>",e+="</tr>"}e+="</table>",c.innerHTML=e}}downloadReport(){if(!this.pict.AppData.DataCloner.LastReport)return void this.pict.providers.DataCloner.setStatus("reportStatus","No report available.","warn");let t=JSON.stringify(this.pict.AppData.DataCloner.LastReport,null,"\t"),e=new Blob([t],{type:"application/json"}),i=document.createElement("a");i.href=URL.createObjectURL(e);let n=(new Date).toISOString().replace(/[:.]/g,"-").slice(0,19);i.download="DataCloner-Report-"+n+".json",i.click(),URL.revokeObjectURL(i.href),this.pict.providers.DataCloner.setStatus("reportStatus","Report downloaded.","ok")}copyReport(){if(!this.pict.AppData.DataCloner.LastReport)return void this.pict.providers.DataCloner.setStatus("reportStatus","No report available.","warn");let t=JSON.stringify(this.pict.AppData.DataCloner.LastReport,null,"\t"),e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("reportStatus","Report copied to clipboard.","ok")})}renderSyncProgress(t){let e=document.getElementById("syncProgress"),i=t.Tables||{},n=Object.keys(i);if(0===n.length)return void(e.innerHTML="");let o=[],s=[],a=[],r=[];for(let t=0;t<n.length;t++){let e=n[t],l=i[e];"Syncing"===l.Status?o.push({Name:e,Data:l}):"Pending"===l.Status?s.push({Name:e,Data:l}):"Complete"===l.Status?a.push({Name:e,Data:l}):r.push({Name:e,Data:l})}let l="",c=(t,e)=>{let i=0;0!==e.Total||"Complete"!==e.Status&&"Error"!==e.Status?e.Total>0&&(i=Math.round(e.Synced/e.Total*100)):i=100;let n="#28a745";"Error"===e.Status?n="#dc3545":"Partial"===e.Status?n="#ffc107":"Syncing"===e.Status?n="#4a90d9":"Pending"===e.Status&&(n="#adb5bd");let o=e.Status;"Complete"===e.Status&&0===e.Total&&(o="Complete (empty)"),"Partial"===e.Status&&(o="Partial ⚠"),"Error"===e.Status&&(o="Error ✖");let s="";e.ErrorMessage?s=e.ErrorMessage:e.Skipped>0?s=e.Skipped+" record(s) skipped":(e.Errors||0)>0?s=e.Errors+" error(s)":"Complete"===e.Status&&0===e.Total?s="No records on server":"Complete"===e.Status&&(s="✔ OK");let a="<tr>";return a+="<td><strong>"+t+"</strong></td>",a+="<td>"+o+"</td>",a+="<td>",a+='<div class="progress-bar-container"><div class="progress-bar-fill" style="width:'+i+"%; background:"+n+'"></div></div>',a+=" "+i+"%",a+="</td>",a+="<td>"+e.Synced+" / "+e.Total+"</td>",a+="<td>"+s+"</td>",a+="</tr>",a};if(o.length>0){l+='<div class="sync-section-header">Syncing</div>',l+='<table class="progress-table">',l+="<tr><th>Table</th><th>Status</th><th>Progress</th><th>Synced</th><th>Details</th></tr>";for(let t=0;t<o.length;t++)l+=c(o[t].Name,o[t].Data);l+="</table>"}if(s.length>0){l+='<div class="sync-section-header">Next Up <span class="sync-section-count">'+s.length+"</span></div>";let t=Math.min(8,s.length);l+='<table class="progress-table progress-table-muted">';for(let e=0;e<t;e++)l+="<tr><td>"+s[e].Name+"</td>",s[e].Data.Total>0?l+='<td class="sync-pending-count">'+s[e].Data.Total.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")+" records</td>":l+='<td class="sync-pending-count">—</td>',l+="</tr>";l+="</table>",s.length>t&&(l+='<div class="sync-section-overflow">+ '+(s.length-t)+" more table"+(s.length-t===1?"":"s")+"</div>")}if(r.length>0){l+='<div class="sync-section-header sync-section-header-error">Errors <span class="sync-section-count">'+r.length+"</span></div>",l+='<table class="progress-table">',l+="<tr><th>Table</th><th>Status</th><th>Progress</th><th>Synced</th><th>Details</th></tr>";for(let t=0;t<r.length;t++)l+=c(r[t].Name,r[t].Data);l+="</table>"}if(a.length>0){l+='<div class="sync-section-header sync-section-header-ok">Completed <span class="sync-section-count">'+a.length+"</span></div>",l+='<table class="progress-table">',l+="<tr><th>Table</th><th>Status</th><th>Progress</th><th>Synced</th><th>Details</th></tr>";for(let t=0;t<a.length;t++)l+=c(a[t].Name,a[t].Data);l+="</table>"}e.innerHTML=l}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Sync",DefaultRenderable:"DataCloner-Sync",DefaultDestinationAddress:"#DataCloner-Section-Sync",CSS:"\n.progress-table { width: 100%; border-collapse: collapse; margin-top: 4px; margin-bottom: 4px; }\n.progress-table th, .progress-table td { text-align: left; padding: 6px 12px; border-bottom: 1px solid #eee; font-size: 0.9em; }\n.progress-table th { background: #f8f9fa; font-weight: 600; }\n.progress-table-muted td { color: #888; padding: 3px 12px; font-size: 0.85em; border-bottom: 1px solid #f4f5f6; }\n.progress-bar-container { width: 120px; height: 16px; background: #e9ecef; border-radius: 8px; overflow: hidden; display: inline-block; vertical-align: middle; }\n.progress-bar-fill { height: 100%; background: #28a745; transition: width 0.3s; }\n.sync-section-header { font-size: 0.8em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: #4a90d9; padding: 10px 0 2px 0; margin-top: 6px; border-top: 1px solid #e0e0e0; }\n.sync-section-header:first-child { border-top: none; margin-top: 10px; }\n.sync-section-header-error { color: #dc3545; }\n.sync-section-header-ok { color: #28a745; }\n.sync-section-count { font-weight: 400; color: #999; font-size: 0.95em; }\n.sync-section-overflow { font-size: 0.8em; color: #aaa; padding: 2px 12px 6px; }\n.sync-pending-count { text-align: right; color: #aaa; font-size: 0.85em; }\n.report-card { background: #f8f9fa; border-radius: 8px; padding: 12px 16px; min-width: 140px; text-align: center; border: 1px solid #e9ecef; }\n.report-card .card-label { font-size: 0.8em; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }\n.report-card .card-value { font-size: 1.4em; font-weight: 700; }\n.report-card.outcome-success { border-left: 4px solid #28a745; }\n.report-card.outcome-partial { border-left: 4px solid #ffc107; }\n.report-card.outcome-error { border-left: 4px solid #dc3545; }\n.report-card.outcome-stopped { border-left: 4px solid #6c757d; }\n",Templates:[{Hash:"DataCloner-Sync",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">5</div>\n\t<div class="accordion-card" id="section5" data-section="5">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section5\')">\n\t\t\t<div class="accordion-title">Synchronize Data</div>\n\t\t\t<span class="accordion-phase" id="phase5"></span>\n\t\t\t<div class="accordion-preview" id="preview5">Initial sync, page size 100</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Sync\'].startSync()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto5"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<div style="display:flex; gap:8px; align-items:flex-end; margin-bottom:4px">\n\t\t\t\t<div style="flex:0 0 150px">\n\t\t\t\t\t<label for="pageSize">Page Size</label>\n\t\t\t\t\t<input type="number" id="pageSize" value="100" min="1" max="10000" style="margin-bottom:0">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 220px">\n\t\t\t\t\t<label for="dateTimePrecisionMS">Timestamp Precision (ms)</label>\n\t\t\t\t\t<input type="number" id="dateTimePrecisionMS" value="1000" min="0" max="60000" style="margin-bottom:0">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 auto; display:flex; gap:8px">\n\t\t\t\t\t<button class="success" style="margin:0" onclick="pict.views[\'DataCloner-Sync\'].startSync()">Start Sync</button>\n\t\t\t\t\t<button class="danger" style="margin:0" onclick="pict.views[\'DataCloner-Sync\'].stopSync()">Stop Sync</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div style="font-size:0.8em; color:#888; margin-bottom:10px; padding-left:158px">Cross-DB tolerance for date comparison (default: 1000ms)</div>\n\n\t\t\t<div style="margin-bottom:10px">\n\t\t\t\t<label style="margin-bottom:6px">Sync Mode</label>\n\t\t\t\t<div style="display:flex; gap:16px; align-items:center">\n\t\t\t\t\t<label style="font-weight:normal; margin:0; cursor:pointer">\n\t\t\t\t\t\t<input type="radio" name="syncMode" id="syncModeInitial" value="Initial" checked> Initial\n\t\t\t\t\t\t<span style="color:#888; font-size:0.85em">(full clone — download all records)</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<label style="font-weight:normal; margin:0; cursor:pointer">\n\t\t\t\t\t\t<input type="radio" name="syncMode" id="syncModeOngoing" value="Ongoing"> Ongoing\n\t\t\t\t\t\t<span style="color:#888; font-size:0.85em">(delta — only new/updated records since last sync)</span>\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class="checkbox-row">\n\t\t\t\t<input type="checkbox" id="syncDeletedRecords">\n\t\t\t\t<label for="syncDeletedRecords">Sync deleted records (fetch records marked Deleted=1 on source and mirror locally)</label>\n\t\t\t</div>\n\n\t\t\t<div class="inline-group" style="margin-top:8px; margin-bottom:4px">\n\t\t\t\t<div style="flex:0 0 200px">\n\t\t\t\t\t<label for="syncMaxRecords">Max Records per Entity</label>\n\t\t\t\t\t<input type="number" id="syncMaxRecords" value="" min="0" placeholder="0 = unlimited" style="margin-bottom:0">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 auto; display:flex; align-items:flex-end; padding-bottom:2px">\n\t\t\t\t\t<div class="checkbox-row" style="margin-bottom:0">\n\t\t\t\t\t\t<input type="checkbox" id="syncLogFile" checked>\n\t\t\t\t\t\t<label for="syncLogFile">Write log file</label>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div id="syncStatus"></div>\n\t\t\t<div id="syncProgress"></div>\n\n\t\t\t\x3c!-- Sync Report (appears after sync completes) --\x3e\n\t\t\t<div id="syncReportSection" style="display:none; margin-top:16px; padding-top:16px; border-top:2px solid #ddd">\n\t\t\t\t<h3 style="margin:0 0 12px; font-size:1.1em">Sync Report</h3>\n\n\t\t\t\t\x3c!-- Summary cards --\x3e\n\t\t\t\t<div id="reportSummaryCards" style="display:flex; gap:12px; flex-wrap:wrap; margin-bottom:16px"></div>\n\n\t\t\t\t\x3c!-- Anomalies --\x3e\n\t\t\t\t<div id="reportAnomalies" style="margin-bottom:16px"></div>\n\n\t\t\t\t\x3c!-- Top tables by duration --\x3e\n\t\t\t\t<div id="reportTopTables" style="margin-bottom:16px"></div>\n\n\t\t\t\t\x3c!-- Buttons --\x3e\n\t\t\t\t<div style="display:flex; gap:8px">\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Sync\'].downloadReport()">Download Report JSON</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Sync\'].copyReport()">Copy Report</button>\n\t\t\t\t</div>\n\t\t\t\t<div id="reportStatus"></div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Sync",TemplateHash:"DataCloner-Sync",DestinationAddress:"#DataCloner-Section-Sync"}]}},{"pict-view":13}],26:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}populateViewTableDropdown(){let t=document.getElementById("viewTable");if(!t)return;let e=t.value;t.innerHTML="";let i=this.pict.AppData.DataCloner.DeployedTables;if(!i||0===i.length){let e=document.createElement("option");return e.value="",e.textContent="— deploy tables first —",void t.appendChild(e)}for(let e=0;e<i.length;e++){let n=document.createElement("option");n.value=i[e],n.textContent=i[e],t.appendChild(n)}e&&(t.value=e)}loadTableData(){let t=document.getElementById("viewTable").value,e=parseInt(document.getElementById("viewLimit").value,10)||100;if(!t)return void this.pict.providers.DataCloner.setStatus("viewStatus","Select a table first.","error");this.pict.providers.DataCloner.setStatus("viewStatus","Loading "+t+"...","info"),document.getElementById("viewDataContainer").innerHTML="";let i=this;this.pict.providers.DataCloner.api("GET","/1.0/"+t+"s/0/"+e).then(function(t){Array.isArray(t)?(i.pict.providers.DataCloner.setStatus("viewStatus",t.length+" row(s) returned"+(t.length>=e?" (limit reached — increase Max Rows to see more)":"")+".","ok"),i.renderDataTable(t)):i.pict.providers.DataCloner.setStatus("viewStatus","Unexpected response (not an array). The table may not be deployed yet.","error")}).catch(function(t){i.pict.providers.DataCloner.setStatus("viewStatus","Request failed: "+t.message,"error")})}renderDataTable(t){let e=document.getElementById("viewDataContainer");if(!t||0===t.length)return void(e.innerHTML='<p style="color:#666; font-size:0.9em; padding:8px">No rows.</p>');let i=Object.keys(t[0]),n='<table class="data-table">';n+="<thead><tr>";for(let t=0;t<i.length;t++)n+="<th>"+this.pict.providers.DataCloner.escapeHtml(i[t])+"</th>";n+="</tr></thead>",n+="<tbody>";for(let e=0;e<t.length;e++){n+="<tr>";for(let o=0;o<i.length;o++){let s=t[e][i[o]],a=null==s?"":String(s);n+='<td title="'+this.pict.providers.DataCloner.escapeHtml(a)+'">'+this.pict.providers.DataCloner.escapeHtml(a)+"</td>"}n+="</tr>"}n+="</tbody></table>",e.innerHTML=n}},e.exports.default_configuration={ViewIdentifier:"DataCloner-ViewData",DefaultRenderable:"DataCloner-ViewData",DefaultDestinationAddress:"#DataCloner-Section-ViewData",CSS:"\n.data-table { width: 100%; border-collapse: collapse; font-size: 0.8em; font-family: monospace; }\n.data-table th { background: #f8f9fa; font-weight: 600; text-align: left; padding: 4px 8px; border: 1px solid #ddd; white-space: nowrap; position: sticky; top: 0; }\n.data-table td { padding: 4px 8px; border: 1px solid #eee; white-space: nowrap; max-width: 300px; overflow: hidden; text-overflow: ellipsis; }\n.data-table tr:nth-child(even) { background: #fafafa; }\n.data-table tr:hover { background: #f0f7ff; }\n",Templates:[{Hash:"DataCloner-ViewData",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">7</div>\n\t<div class="accordion-card" id="section7" data-section="7">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section7\')">\n\t\t\t<div class="accordion-title">View Data</div>\n\t\t\t<div class="accordion-preview" id="preview7">Browse synced table data</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<div class="inline-group">\n\t\t\t\t<div style="flex:1">\n\t\t\t\t\t<label for="viewTable">Table</label>\n\t\t\t\t\t<select id="viewTable">\n\t\t\t\t\t\t<option value="">— deploy tables first —</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 120px">\n\t\t\t\t\t<label for="viewLimit">Max Rows</label>\n\t\t\t\t\t<input type="number" id="viewLimit" value="100" min="1" max="10000">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 auto; display:flex; align-items:flex-end">\n\t\t\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-ViewData\'].loadTableData()">Load</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div id="viewStatus"></div>\n\t\t\t<div id="viewDataContainer" style="overflow-x:auto; margin-top:10px"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-ViewData",TemplateHash:"DataCloner-ViewData",DestinationAddress:"#DataCloner-Section-ViewData"}]}},{"pict-view":13}]},{},[17])(17)});
|
|
1
|
+
"use strict";!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).dataCloner=t()}}(function(){return function t(e,i,n){function o(a,r){if(!i[a]){if(!e[a]){var l="function"==typeof require&&require;if(!r&&l)return l(a,!0);if(s)return s(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var d=i[a]={exports:{}};e[a][0].call(d.exports,function(t){return o(e[a][1][t]||t)},d,d.exports,t,e,i,n)}return i[a].exports}for(var s="function"==typeof require&&require,a=0;a<n.length;a++)o(n[a]);return o}({1:[function(t,e,i){e.exports={name:"fable-serviceproviderbase",version:"3.0.19",description:"Simple base classes for fable services.",main:"source/Fable-ServiceProviderBase.js",scripts:{start:"node source/Fable-ServiceProviderBase.js",test:"npx quack test",tests:"npx quack test -g",coverage:"npx quack coverage",build:"npx quack build",types:"tsc -p ./tsconfig.build.json",check:"tsc -p . --noEmit"},types:"types/source/Fable-ServiceProviderBase.d.ts",mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},repository:{type:"git",url:"https://github.com/stevenvelozo/fable-serviceproviderbase.git"},keywords:["entity","behavior"],author:"Steven Velozo <steven@velozo.com> (http://velozo.com/)",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/fable-serviceproviderbase/issues"},homepage:"https://github.com/stevenvelozo/fable-serviceproviderbase",devDependencies:{"@types/mocha":"^10.0.10",fable:"^3.1.62",quackage:"^1.0.58",typescript:"^5.9.3"}}},{}],2:[function(t,e,i){const n=t("../package.json");class o{constructor(t,e,i){this.fable,this.UUID,this.options,this.services,this.servicesMap,"object"==typeof t&&t.isFable?this.connectFable(t):this.fable=!1,this._PackageFableServiceProvider=n,this.fable?(this.UUID=t.getUUID(),this.options="object"==typeof e?e:{}):(this.options="object"!=typeof t||t.isFable?"object"==typeof e?e:{}:t,this.UUID=`CORE-SVC-${Math.floor(89999*Math.random()+1e4)}`),this.serviceType=`Unknown-${this.UUID}`,this.Hash="string"==typeof i?i:this.fable||"string"!=typeof e?`${this.UUID}`:e}connectFable(t){if("object"!=typeof t||!t.isFable){let e=`Fable Service Provider Base: Cannot connect to Fable, invalid Fable object passed in. The pFable parameter was a [${typeof t}].}`;return console.log(e),new Error(e)}return this.fable||(this.fable=t),this.log||(this.log=this.fable.Logging),this.services||(this.services=this.fable.services),this.servicesMap||(this.servicesMap=this.fable.servicesMap),!0}static isFableService=!0}e.exports=o,e.exports.CoreServiceProviderBase=o},{"../package.json":1}],3:[function(t,e,i){e.exports={name:"pict-application",version:"1.0.33",description:"Application base class for a pict view-based application",main:"source/Pict-Application.js",scripts:{test:"npx quack test",start:"node source/Pict-Application.js",coverage:"npx quack coverage",build:"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-application-image:local","docker-dev-run":'docker run -it -d --name pict-application-dev -p 30001:8080 -p 38086:8086 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/pict-application" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" pict-application-image:local',"docker-dev-shell":"docker exec -it pict-application-dev /bin/bash",tests:"npx quack test -g",lint:"eslint source/**",types:"tsc -p ."},types:"types/source/Pict-Application.d.ts",repository:{type:"git",url:"git+https://github.com/stevenvelozo/pict-application.git"},author:"steven velozo <steven@velozo.com>",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/pict-application/issues"},homepage:"https://github.com/stevenvelozo/pict-application#readme",devDependencies:{"@eslint/js":"^9.28.0","browser-env":"^3.3.0",eslint:"^9.28.0",pict:"^1.0.348","pict-provider":"^1.0.10","pict-view":"^1.0.66",quackage:"^1.0.58",typescript:"^5.9.3"},mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},dependencies:{"fable-serviceproviderbase":"^3.0.19"}}},{}],4:[function(t,e,i){const n=t("fable-serviceproviderbase"),o=t("../package.json"),s={Name:"DefaultPictApplication",MainViewportViewIdentifier:"Default-View",MainViewportRenderableHash:!1,MainViewportDestinationAddress:!1,MainViewportDefaultDataAddress:!1,AutoSolveAfterInitialize:!0,AutoRenderMainViewportViewAfterInitialize:!0,AutoRenderViewsAfterInitialize:!1,AutoLoginAfterInitialize:!1,AutoLoadDataAfterLogin:!1,ConfigurationOnlyViews:[],Manifests:{},IdentifierAddressPrefix:"PICT-"};e.exports=class extends n{constructor(t,e,i){let n="object"==typeof t.settings.PictApplicationConfiguration?t.settings.PictApplicationConfiguration:{};super(t,Object.assign({},JSON.parse(JSON.stringify(s)),n,e),i),this.options,this.log,this.fable,this.UUID,this.Hash,this.servicesMap,this.serviceType="PictApplication",this._Package=o,this.pict=this.fable,this.AppData=this.fable.AppData,this.Bundle=this.fable.Bundle,this.initializeTimestamp,this.lastSolvedTimestamp,this.lastLoginTimestamp,this.lastMarshalFromViewsTimestamp,this.lastMarshalToViewsTimestamp,this.lastAutoRenderTimestamp,this.lastLoadDataTimestamp;let a=Object.keys(this.options.Manifests);if(a.length>0)for(let t=0;t<a.length;t++){let e=a[t];this.fable.instantiateServiceProvider("Manifest",this.options.Manifests[e],e)}}onPreSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onPreSolve:`),!0}onPreSolveAsync(t){return this.onPreSolve(),t()}onBeforeSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeSolve:`),!0}onBeforeSolveAsync(t){return this.onBeforeSolve(),t()}onSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onSolve:`),!0}onSolveAsync(t){return this.onSolve(),t()}solve(){this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} executing solve() function...`);let t=Object.keys(this.pict.providers),e=[];for(let i=0;i<t.length;i++){let n=this.pict.providers[t[i]];n.options.AutoSolveWithApp&&e.push(n)}e.sort((t,e)=>t.options.AutoSolveOrdinal-e.options.AutoSolveOrdinal);for(let t=0;t<e.length;t++)e[t].solve(e[t]);this.onBeforeSolve();let i=Object.keys(this.pict.views),n=[];for(let t=0;t<i.length;t++){let e=this.pict.views[i[t]];e.options.AutoInitialize&&n.push(e)}n.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let t=0;t<n.length;t++)n[t].solve();return this.onSolve(),this.onAfterSolve(),this.lastSolvedTimestamp=this.fable.log.getTimeStamp(),!0}solveAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");e.anticipate(this.onBeforeSolveAsync.bind(this));let i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync Auto Callback Error: ${t}`,t)});let n=Object.keys(this.pict.providers),o=[];for(let t=0;t<n.length;t++){let e=this.pict.providers[n[t]];e.options.AutoSolveWithApp&&o.push(e)}o.sort((t,e)=>t.options.AutoSolveOrdinal-e.options.AutoSolveOrdinal);for(let t=0;t<o.length;t++)e.anticipate(o[t].solveAsync.bind(o[t]));let s=Object.keys(this.pict.views),a=[];for(let t=0;t<s.length;t++){let e=this.pict.views[s[t]];e.options.AutoSolveWithApp&&a.push(e)}a.sort((t,e)=>t.options.AutoSolveOrdinal-e.options.AutoSolveOrdinal);for(let t=0;t<a.length;t++)e.anticipate(a[t].solveAsync.bind(a[t]));e.anticipate(this.onSolveAsync.bind(this)),e.anticipate(this.onAfterSolveAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync() complete.`),this.lastSolvedTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterSolve:`),!0}onAfterSolveAsync(t){return this.onAfterSolve(),t()}onBeforeLoginAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeLoginAsync:`),t()}onLoginAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onLoginAsync:`),t()}loginAsync(t){const e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");let i=t;"function"!=typeof i&&(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loginAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loginAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeLoginAsync.bind(this)),e.anticipate(this.onLoginAsync.bind(this)),e.anticipate(this.onAfterLoginAsync.bind(this)),this.options.AutoLoadDataAfterLogin&&e.anticipate(t=>{if(!this.isLoggedIn())return t();this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto loading data after login...`),this.loadDataAsync(e=>{t(e)})}),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loginAsync() complete.`),this.lastLoginTimestamp=this.fable.log.getTimeStamp(),i(t)))}isLoggedIn(){return!0}onAfterLoginAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterLoginAsync:`),t()}onBeforeLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeLoadDataAsync:`),t()}onLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onLoadDataAsync:`),t()}loadDataAsync(t){const e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");let i=t;"function"!=typeof i&&(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loadDataAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loadDataAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeLoadDataAsync.bind(this));let n=Object.keys(this.pict.providers),o=[];for(let t=0;t<n.length;t++){let e=this.pict.providers[n[t]];e.options.AutoLoadDataWithApp&&o.push(e)}o.sort((t,e)=>t.options.AutoLoadDataOrdinal-e.options.AutoLoadDataOrdinal);for(const t of o)e.anticipate(t.onBeforeLoadDataAsync.bind(t));e.anticipate(this.onLoadDataAsync.bind(this));for(const t of o)e.anticipate(t.onLoadDataAsync.bind(t));e.anticipate(this.onAfterLoadDataAsync.bind(this));for(const t of o)e.anticipate(t.onAfterLoadDataAsync.bind(t));e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} loadDataAsync() complete.`),this.lastLoadDataTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterLoadDataAsync:`),t()}onBeforeSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeSaveDataAsync:`),t()}onSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onSaveDataAsync:`),t()}saveDataAsync(t){const e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");let i=t;"function"!=typeof i&&(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} saveDataAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} saveDataAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeSaveDataAsync.bind(this));let n=Object.keys(this.pict.providers),o=[];for(let t=0;t<n.length;t++){let e=this.pict.providers[n[t]];e.options.AutoSaveDataWithApp&&o.push(e)}o.sort((t,e)=>t.options.AutoSaveDataOrdinal-e.options.AutoSaveDataOrdinal);for(const t of o)e.anticipate(t.onBeforeSaveDataAsync.bind(t));e.anticipate(this.onSaveDataAsync.bind(this));for(const t of o)e.anticipate(t.onSaveDataAsync.bind(t));e.anticipate(this.onAfterSaveDataAsync.bind(this));for(const t of o)e.anticipate(t.onAfterSaveDataAsync.bind(t));e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} saveDataAsync() complete.`),this.lastSaveDataTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterSaveDataAsync:`),t()}onBeforeInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeInitialize:`),!0}onBeforeInitializeAsync(t){return this.onBeforeInitialize(),t()}onInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onInitialize:`),!0}onInitializeAsync(t){return this.onInitialize(),t()}initialize(){if(this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} initialize:`),this.initializeTimestamp)return this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initialize called but initialization is already completed. Aborting.`),!1;{if(this.onBeforeInitialize(),"ConfigurationOnlyViews"in this.options)for(let t=0;t<this.options.ConfigurationOnlyViews.length;t++){let e=void 0===this.options.ConfigurationOnlyViews[t].ViewIdentifier?`AutoView-${this.fable.getUUID()}`:this.options.ConfigurationOnlyViews[t].ViewIdentifier;this.log.info(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} adding configuration only view: ${e}`),this.pict.addView(e,this.options.ConfigurationOnlyViews[t])}this.onInitialize();let t=Object.keys(this.pict.providers),e=[];for(let i=0;i<t.length;i++){let n=this.pict.providers[t[i]];n.options.AutoInitialize&&e.push(n)}e.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let t=0;t<e.length;t++)e[t].initialize();let i=Object.keys(this.pict.views),n=[];for(let t=0;t<i.length;t++){let e=this.pict.views[i[t]];e.options.AutoInitialize&&n.push(e)}n.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let t=0;t<n.length;t++)n[t].initialize();return this.onAfterInitialize(),this.options.AutoSolveAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto solving after initialization...`),this.solve()),this.options.AutoRenderMainViewportViewAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto rendering after initialization...`),this.render()),this.initializeTimestamp=this.fable.log.getTimeStamp(),this.onCompletionOfInitialize(),!0}}initializeAsync(t){this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync:`);let e="function"==typeof t&&t;if(e||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),e=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync Auto Callback Error: ${t}`,t)}),this.initializeTimestamp)return this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} async initialize called but initialization is already completed. Aborting.`),this.onCompletionOfInitializeAsync(e);{let t=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate");if(this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} beginning initialization...`),"ConfigurationOnlyViews"in this.options)for(let t=0;t<this.options.ConfigurationOnlyViews.length;t++){let e=void 0===this.options.ConfigurationOnlyViews[t].ViewIdentifier?`AutoView-${this.fable.getUUID()}`:this.options.ConfigurationOnlyViews[t].ViewIdentifier;this.log.info(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} adding configuration only view: ${e}`),this.pict.addView(e,this.options.ConfigurationOnlyViews[t])}t.anticipate(this.onBeforeInitializeAsync.bind(this)),t.anticipate(this.onInitializeAsync.bind(this));let i=Object.keys(this.pict.providers),n=[];for(let t=0;t<i.length;t++){let e=this.pict.providers[i[t]];e.options.AutoInitialize&&n.push(e)}n.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let e=0;e<n.length;e++)t.anticipate(n[e].initializeAsync.bind(n[e]));let o=Object.keys(this.pict.views),s=[];for(let t=0;t<o.length;t++){let e=this.pict.views[o[t]];e.options.AutoInitialize&&s.push(e)}s.sort((t,e)=>t.options.AutoInitializeOrdinal-e.options.AutoInitializeOrdinal);for(let e=0;e<s.length;e++){let i=s[e];t.anticipate(i.initializeAsync.bind(i))}t.anticipate(this.onAfterInitializeAsync.bind(this)),this.options.AutoLoginAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto login (asynchronously) after initialization...`),t.anticipate(this.loginAsync.bind(this))),this.options.AutoSolveAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto solving (asynchronously) after initialization...`),t.anticipate(this.solveAsync.bind(this))),this.options.AutoRenderMainViewportViewAfterInitialize&&(this.pict.LogNoisiness>1&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} auto rendering (asynchronously) after initialization...`),t.anticipate(this.renderMainViewportAsync.bind(this))),t.wait(t=>(t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initializeAsync Error: ${t.message||t}`,{stack:t.stack}),this.initializeTimestamp=this.fable.log.getTimeStamp(),this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} initialization complete.`),e()))}}onAfterInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterInitialize:`),!0}onAfterInitializeAsync(t){return this.onAfterInitialize(),t()}onCompletionOfInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onCompletionOfInitialize:`),!0}onCompletionOfInitializeAsync(t){return this.onCompletionOfInitialize(),t()}onBeforeMarshalFromViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeMarshalFromViews:`),!0}onBeforeMarshalFromViewsAsync(t){return this.onBeforeMarshalFromViews(),t()}onMarshalFromViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onMarshalFromViews:`),!0}onMarshalFromViewsAsync(t){return this.onMarshalFromViews(),t()}marshalFromViews(){this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} executing marshalFromViews() function...`),this.onBeforeMarshalFromViews();let t=Object.keys(this.pict.views),e=[];for(let i=0;i<t.length;i++){let n=this.pict.views[t[i]];e.push(n)}for(let t=0;t<e.length;t++)e[t].marshalFromView();return this.onMarshalFromViews(),this.onAfterMarshalFromViews(),this.lastMarshalFromViewsTimestamp=this.fable.log.getTimeStamp(),!0}marshalFromViewsAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewsAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewsAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalFromViewsAsync.bind(this));let n=Object.keys(this.pict.views),o=[];for(let t=0;t<n.length;t++){let e=this.pict.views[n[t]];o.push(e)}for(let t=0;t<o.length;t++)e.anticipate(o[t].marshalFromViewAsync.bind(o[t]));e.anticipate(this.onMarshalFromViewsAsync.bind(this)),e.anticipate(this.onAfterMarshalFromViewsAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewsAsync() complete.`),this.lastMarshalFromViewsTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterMarshalFromViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterMarshalFromViews:`),!0}onAfterMarshalFromViewsAsync(t){return this.onAfterMarshalFromViews(),t()}onBeforeMarshalToViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeMarshalToViews:`),!0}onBeforeMarshalToViewsAsync(t){return this.onBeforeMarshalToViews(),t()}onMarshalToViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onMarshalToViews:`),!0}onMarshalToViewsAsync(t){return this.onMarshalToViews(),t()}marshalToViews(){this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} executing marshalToViews() function...`),this.onBeforeMarshalToViews();let t=Object.keys(this.pict.views),e=[];for(let i=0;i<t.length;i++){let n=this.pict.views[t[i]];e.push(n)}for(let t=0;t<e.length;t++)e[t].marshalToView();return this.onMarshalToViews(),this.onAfterMarshalToViews(),this.lastMarshalToViewsTimestamp=this.fable.log.getTimeStamp(),!0}marshalToViewsAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewsAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewsAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalToViewsAsync.bind(this));let n=Object.keys(this.pict.views),o=[];for(let t=0;t<n.length;t++){let e=this.pict.views[n[t]];o.push(e)}for(let t=0;t<o.length;t++)e.anticipate(o[t].marshalToViewAsync.bind(o[t]));e.anticipate(this.onMarshalToViewsAsync.bind(this)),e.anticipate(this.onAfterMarshalToViewsAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewsAsync() complete.`),this.lastMarshalToViewsTimestamp=this.fable.log.getTimeStamp(),i(t)))}onAfterMarshalToViews(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterMarshalToViews:`),!0}onAfterMarshalToViewsAsync(t){return this.onAfterMarshalToViews(),t()}onBeforeRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onBeforeRender:`),!0}onBeforeRenderAsync(t){return this.onBeforeRender(),t()}render(t,e,i,n){let o="string"!=typeof t?this.options.MainViewportViewIdentifier:t,s="string"!=typeof e?this.options.MainViewportRenderableHash:e,a="string"!=typeof i?this.options.MainViewportDestinationAddress:i,r="string"!=typeof n?this.options.MainViewportDefaultDataAddress:n;this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} VIEW Renderable[${s}] Destination[${a}] TemplateDataAddress[${r}] render:`),this.onBeforeRender();let l="string"==typeof o&&this.servicesMap.PictView[o];return l?(this.onRender(),l.render(s,a,r),this.onAfterRender(),!0):(this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} could not render from View ${o} because it is not a valid view.`),!1)}onRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onRender:`),!0}onRenderAsync(t){return this.onRender(),t()}renderAsync(t,e,i,n,o){let s="string"!=typeof t?this.options.MainViewportViewIdentifier:t,a="string"!=typeof e?this.options.MainViewportRenderableHash:e,r="string"!=typeof i?this.options.MainViewportDestinationAddress:i,l="string"!=typeof n?this.options.MainViewportDefaultDataAddress:n,c="function"==typeof o?o:"function"==typeof n?n:"function"==typeof i?i:"function"==typeof e?e:"function"==typeof t&&t;c||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),c=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync Auto Callback Error: ${t}`,t)}),this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} VIEW Renderable[${a}] Destination[${r}] TemplateDataAddress[${l}] renderAsync:`);let d=this.fable.newAnticipate();d.anticipate(this.onBeforeRenderAsync.bind(this));let p="string"==typeof s&&this.servicesMap.PictView[s];if(!p){let t=`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} could not asynchronously render from View ${s} because it is not a valid view.`;return this.pict.LogNoisiness>3&&this.log.error(t),c(new Error(t))}return d.anticipate(this.onRenderAsync.bind(this)),d.anticipate(t=>{p.renderAsync.call(p,a,r,l,t)}),d.anticipate(this.onAfterRenderAsync.bind(this)),d.wait(c)}onAfterRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} onAfterRender:`),!0}onAfterRenderAsync(t){return this.onAfterRender(),t()}renderMainViewport(){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderMainViewport:`),this.render()}renderMainViewportAsync(t){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow APPLICATION [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderMainViewportAsync:`),this.renderAsync(t)}renderAutoViews(){this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} beginning renderAutoViews...`);let t=Object.keys(this.pict.views);t.sort((t,e)=>this.pict.views[t].options.AutoRenderOrdinal-this.pict.views[e].options.AutoRenderOrdinal);for(let e=0;e<t.length;e++){let i=this.pict.views[t[e]];i.options.AutoRender&&i.render()}this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync complete.`)}renderAutoViewsAsync(t){let e=this.fable.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t&&t;i||(this.log.warn(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync Auto Callback Error: ${t}`,t)}),this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} beginning renderAutoViewsAsync...`);let n=Object.keys(this.pict.views);n.sort((t,e)=>this.pict.views[t].options.AutoRenderOrdinal-this.pict.views[e].options.AutoRenderOrdinal);for(let t=0;t<n.length;t++){let i=this.pict.views[n[t]];i.options.AutoRender&&e.anticipate(i.renderAsync.bind(i))}e.wait(t=>(this.lastAutoRenderTimestamp=this.fable.log.getTimeStamp(),this.pict.LogNoisiness>0&&this.log.trace(`PictApp [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAutoViewsAsync complete.`),i(t)))}get isPictApplication(){return!0}}},{"../package.json":3,"fable-serviceproviderbase":2}],5:[function(t,e,i){e.exports={name:"pict-provider",version:"1.0.12",description:"Pict Provider Base Class",main:"source/Pict-Provider.js",scripts:{start:"node source/Pict-Provider.js",test:"npx quack test",tests:"npx quack test -g",coverage:"npx quack coverage",build:"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-provider-image:local","docker-dev-run":'docker run -it -d --name pict-provider-dev -p 24125:8080 -p 30027:8086 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/pict-provider" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" pict-provider-image:local',"docker-dev-shell":"docker exec -it pict-provider-dev /bin/bash",lint:"eslint source/**",types:"tsc -p ."},types:"types/source/Pict-Provider.d.ts",repository:{type:"git",url:"git+https://github.com/stevenvelozo/pict-provider.git"},author:"steven velozo <steven@velozo.com>",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/pict-provider/issues"},homepage:"https://github.com/stevenvelozo/pict-provider#readme",devDependencies:{"@eslint/js":"^9.39.1",eslint:"^9.39.1",pict:"^1.0.351",quackage:"^1.0.58",typescript:"^5.9.3"},dependencies:{"fable-serviceproviderbase":"^3.0.19"},mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]}}},{}],6:[function(t,e,i){const n=t("fable-serviceproviderbase"),o=t("../package.json"),s={ProviderIdentifier:!1,AutoInitialize:!0,AutoInitializeOrdinal:0,AutoLoadDataWithApp:!0,AutoLoadDataOrdinal:0,AutoSolveWithApp:!0,AutoSolveOrdinal:0,Manifests:{},Templates:[]};e.exports=class extends n{constructor(t,e,i){super(t,Object.assign({},JSON.parse(JSON.stringify(s)),e),i),this.fable,this.pict,this.log,this.options,this.UUID,this.Hash,this.options.ProviderIdentifier||(this.options.ProviderIdentifier=`AutoProviderID-${this.fable.getUUID()}`),this.serviceType="PictProvider",this._Package=o,this.pict=this.fable,this.AppData=this.pict.AppData,this.Bundle=this.pict.Bundle,this.initializeTimestamp=!1,this.lastSolvedTimestamp=!1;for(let t=0;t<this.options.Templates.length;t++){let e=this.options.Templates[t];e.hasOwnProperty("Postfix")&&e.hasOwnProperty("Template")?(e.Source||(e.Source=`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} options object.`),this.pict.TemplateProvider.addDefaultTemplate(e.Prefix,e.Postfix,e.Template,e.Source)):this.log.error(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} could not load Default Template ${t} in the options array.`,e)}}onBeforeInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onBeforeInitialize:`),!0}onBeforeInitializeAsync(t){return this.onBeforeInitialize(),t()}onInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onInitialize:`),!0}onInitializeAsync(t){return this.onInitialize(),t()}initialize(){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow PROVIDER [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialize:`),this.initializeTimestamp?(this.log.warn(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialize called but initialization is already completed. Aborting.`),!1):(this.onBeforeInitialize(),this.onInitialize(),this.onAfterInitialize(),this.initializeTimestamp=this.pict.log.getTimeStamp(),!0)}initializeAsync(t){if(this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow PROVIDER [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initializeAsync:`),this.initializeTimestamp)return this.log.warn(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} async initialize called but initialization is already completed. Aborting.`),t();{let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate");this.pict.LogNoisiness>0&&this.log.info(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} beginning initialization...`),e.anticipate(this.onBeforeInitializeAsync.bind(this)),e.anticipate(this.onInitializeAsync.bind(this)),e.anticipate(this.onAfterInitializeAsync.bind(this)),e.wait(e=>(this.initializeTimestamp=this.pict.log.getTimeStamp(),e?this.log.error(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialization failed: ${e.message||e}`,{Stack:e.stack}):this.pict.LogNoisiness>0&&this.log.info(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} initialization complete.`),t()))}}onAfterInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onAfterInitialize:`),!0}onAfterInitializeAsync(t){return this.onAfterInitialize(),t()}onPreRender(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onPreRender:`),!0}onPreRenderAsync(t){return this.onPreRender(),t()}render(){return this.onPreRender()}renderAsync(t){return this.onPreRender(),t()}onPreSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onPreSolve:`),!0}onPreSolveAsync(t){return this.onPreSolve(),t()}solve(){return this.onPreSolve()}solveAsync(t){return this.onPreSolve(),t()}onBeforeLoadDataAsync(t){return t()}onLoadDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onLoadDataAsync:`),t()}onAfterLoadDataAsync(t){return t()}onBeforeSaveDataAsync(t){return t()}onSaveDataAsync(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictProvider [${this.UUID}]::[${this.Hash}] ${this.options.ProviderIdentifier} onSaveDataAsync:`),t()}onAfterSaveDataAsync(t){return t()}}},{"../package.json":5,"fable-serviceproviderbase":2}],7:[function(t,e,i){e.exports={RenderOnLoad:!0,DefaultRenderable:"Histogram-Wrap",DefaultDestinationAddress:"#Histogram-Container-Div",Templates:[{Hash:"Histogram-Container",Template:"\x3c!-- Histogram Container Rendering Soon --\x3e"}],Renderables:[{RenderableHash:"Histogram-Wrap",TemplateHash:"Histogram-Container",DestinationAddress:"#Histogram-Container-Div"}],TargetElementAddress:"#Histogram-Container-Div",DataAddress:!1,Bins:[],LabelProperty:"Label",ValueProperty:"Value",Orientation:"vertical",RenderMode:"browser",MaxBarSize:200,BarThickness:30,BarGap:4,FillContainer:!1,ShowValues:!0,ShowLabels:!0,LabelInterval:0,BarColor:"#4A90D9",SelectedBarColor:"#2ECC71",SelectionRangeColor:"#85C1E9",Selectable:!1,SelectionMode:"range",SelectionDataAddress:!1,InitialSelection:null,BarCharacter:"█",BarPartialCharacters:[" ","▁","▂","▃","▄","▅","▆","▇","█"],EmptyCharacter:" ",SliderCharacter:"│",SliderHandleCharacter:"◆",TextWidth:60,TextHeight:15,CSS:".pict-histogram-container\n{\n\tdisplay: inline-block;\n\tposition: relative;\n\tfont-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n\tfont-size: 12px;\n\tuser-select: none;\n}\n.pict-histogram-chart\n{\n\tdisplay: flex;\n\talign-items: flex-end;\n\tposition: relative;\n}\n.pict-histogram-container.pict-histogram-horizontal\n{\n\tdisplay: inline-flex;\n\tflex-direction: row;\n\talign-items: stretch;\n}\n.pict-histogram-chart.pict-histogram-horizontal\n{\n\tflex-direction: column;\n\talign-items: flex-start;\n}\n.pict-histogram-bar-group\n{\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tcursor: default;\n\tflex-shrink: 0;\n}\n.pict-histogram-horizontal .pict-histogram-bar-group\n{\n\tflex-direction: row;\n\talign-items: center;\n}\n.pict-histogram-bar\n{\n\ttransition: background-color 0.15s ease, height 0.2s ease, width 0.2s ease;\n\tborder-radius: 2px 2px 0 0;\n\tmin-width: 1px;\n\tmin-height: 1px;\n}\n.pict-histogram-horizontal .pict-histogram-bar\n{\n\tborder-radius: 0 2px 2px 0;\n}\n.pict-histogram-bar.pict-histogram-selectable\n{\n\tcursor: pointer;\n}\n.pict-histogram-bar.pict-histogram-selectable:hover\n{\n\topacity: 0.8;\n}\n.pict-histogram-bar.pict-histogram-selected\n{\n\tbox-shadow: 0 0 0 2px rgba(46, 204, 113, 0.4);\n}\n.pict-histogram-bar.pict-histogram-in-range\n{\n\topacity: 0.9;\n}\n.pict-histogram-value-label\n{\n\ttext-align: center;\n\tcolor: #666;\n\tfont-size: 11px;\n\tpadding: 2px 0;\n\twhite-space: nowrap;\n}\n.pict-histogram-horizontal .pict-histogram-value-label\n{\n\tpadding: 0 4px;\n}\n.pict-histogram-bin-label\n{\n\ttext-align: center;\n\tcolor: #333;\n\tfont-size: 11px;\n\tpadding: 4px 2px 0 2px;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n.pict-histogram-horizontal .pict-histogram-bin-label\n{\n\tpadding: 0 4px 0 0;\n\ttext-align: right;\n\tmin-width: 40px;\n}\n.pict-histogram-range-slider-container\n{\n\tposition: relative;\n\twidth: 100%;\n\theight: 24px;\n\tmargin-top: 4px;\n}\n.pict-histogram-horizontal .pict-histogram-range-slider-container\n{\n\twidth: 24px;\n\theight: auto;\n\talign-self: stretch;\n\tmargin-top: 0;\n\tmargin-left: 4px;\n}\n.pict-histogram-range-track\n{\n\tposition: absolute;\n\ttop: 10px;\n\tleft: 0;\n\tright: 0;\n\theight: 4px;\n\tbackground: #E0E0E0;\n\tborder-radius: 2px;\n}\n.pict-histogram-horizontal .pict-histogram-range-track\n{\n\ttop: 0;\n\tleft: 10px;\n\tright: auto;\n\tbottom: 0;\n\twidth: 4px;\n\theight: auto;\n}\n.pict-histogram-range-fill\n{\n\tposition: absolute;\n\ttop: 10px;\n\theight: 4px;\n\tbackground: #4A90D9;\n\tborder-radius: 2px;\n}\n.pict-histogram-horizontal .pict-histogram-range-fill\n{\n\ttop: auto;\n\tleft: 10px;\n\twidth: 4px;\n\theight: auto;\n}\n.pict-histogram-range-handle\n{\n\tposition: absolute;\n\ttop: 4px;\n\twidth: 16px;\n\theight: 16px;\n\tbackground: #fff;\n\tborder: 2px solid #4A90D9;\n\tborder-radius: 50%;\n\tcursor: grab;\n\tz-index: 2;\n\ttransform: translateX(-50%);\n}\n.pict-histogram-horizontal .pict-histogram-range-handle\n{\n\ttop: auto;\n\tleft: 4px;\n\ttransform: translateY(-50%);\n}\n.pict-histogram-range-handle:active\n{\n\tcursor: grabbing;\n\tbackground: #4A90D9;\n}\n.pict-histogram-range-handle:active,\n.pict-histogram-range-handle:focus\n{\n\tbox-shadow: 0 0 0 3px rgba(74, 144, 217, 0.3);\n\toutline: none;\n}\n.pict-histogram-container.pict-histogram-fill\n{\n\tdisplay: block;\n\twidth: 100%;\n}\n.pict-histogram-fill .pict-histogram-chart\n{\n\twidth: 100%;\n}\n.pict-histogram-fill .pict-histogram-bar-group\n{\n\tflex: 1 1 0%;\n\tmin-width: 0;\n}\n.pict-histogram-fill .pict-histogram-bar\n{\n\twidth: 100%;\n}\n.pict-histogram-axis-line\n{\n\twidth: 100%;\n\theight: 1px;\n\tbackground: #ccc;\n}\n.pict-histogram-label-row\n{\n\tdisplay: flex;\n\twidth: 100%;\n}\n.pict-histogram-fill-label\n{\n\tfont-size: 10px;\n\tcolor: #666;\n\ttext-align: center;\n\twhite-space: nowrap;\n\toverflow: visible;\n\tline-height: 16px;\n}\n"}},{}],8:[function(t,e,i){const n=t("pict-view"),o=t("./Pict-Section-Histogram-DefaultConfiguration.js"),s=t("./renderers/Pict-Histogram-Renderer-Browser.js"),a=t("./renderers/Pict-Histogram-Renderer-ConsoleUI.js"),r=t("./renderers/Pict-Histogram-Renderer-CLI.js");e.exports=class extends n{constructor(t,e,i){super(t,Object.assign({},o,e),i),this.initialRenderComplete=!1,this._selectedIndices=new Set,this._selectionRangeStart=0,this._selectionRangeEnd=0,this._renderer=this._resolveRenderer(),this._applyInitialSelection()}_applyInitialSelection(){if(this.options.InitialSelection)this.setSelection(this.options.InitialSelection);else if(this.options.Selectable&&"range"===this.options.SelectionMode){let t=this.getBins();this._selectionRangeStart=0,this._selectionRangeEnd=Math.max(0,t.length-1),this._syncSelectionFromRange()}}_resolveRenderer(){switch(this.options.RenderMode){case"consoleui":return a;case"cli":return r;default:return s}}getBins(){if(this.options.DataAddress){const t={Fable:this.fable,Pict:this.fable,AppData:this.AppData,Bundle:this.Bundle,Options:this.options};let e=this.fable.manifest.getValueByHash(t,this.options.DataAddress);if(Array.isArray(e))return e;this.log.warn(`PICT-Histogram DataAddress [${this.options.DataAddress}] did not return an array.`)}return this.options.Bins||[]}setBins(t){if(Array.isArray(t)){if(this.options.Bins=t,this.options.DataAddress){const e={Fable:this.fable,Pict:this.fable,AppData:this.AppData,Bundle:this.Bundle,Options:this.options};this.fable.manifest.setValueByHash(e,this.options.DataAddress,t)}}else this.log.warn("PICT-Histogram setBins requires an array.")}isIndexSelected(t){return!!this.options.Selectable&&("range"===this.options.SelectionMode?t===this._selectionRangeStart||t===this._selectionRangeEnd:this._selectedIndices.has(t))}isIndexInRange(t){return!(!this.options.Selectable||"range"!==this.options.SelectionMode)&&(t>this._selectionRangeStart&&t<this._selectionRangeEnd)}getSelection(){if("range"===this.options.SelectionMode){let t=this.getBins(),e=[];for(let t=this._selectionRangeStart;t<=this._selectionRangeEnd;t++)e.push(t);return{Mode:"range",RangeStart:this._selectionRangeStart,RangeEnd:this._selectionRangeEnd,SelectedIndices:e,StartLabel:(t[this._selectionRangeStart]||{})[this.options.LabelProperty],EndLabel:(t[this._selectionRangeEnd]||{})[this.options.LabelProperty]}}return{Mode:this.options.SelectionMode,SelectedIndices:Array.from(this._selectedIndices).sort((t,e)=>t-e)}}setSelection(t){"range"===this.options.SelectionMode?t&&"number"==typeof t.Start&&"number"==typeof t.End&&(this._selectionRangeStart=t.Start,this._selectionRangeEnd=t.End,this._syncSelectionFromRange()):Array.isArray(t)&&(this._selectedIndices=new Set(t)),this._writeSelectionToAddress()}handleBarClick(t){"single"===this.options.SelectionMode?(this._selectedIndices.clear(),this._selectedIndices.add(t)):"multiple"===this.options.SelectionMode&&(this._selectedIndices.has(t)?this._selectedIndices.delete(t):this._selectedIndices.add(t)),this._writeSelectionToAddress(),this.onSelectionChange(this.getSelection()),this.renderHistogram()}handleRangeBarClick(t){Math.abs(t-this._selectionRangeStart)<=Math.abs(t-this._selectionRangeEnd)?this._selectionRangeStart=Math.min(t,this._selectionRangeEnd):this._selectionRangeEnd=Math.max(t,this._selectionRangeStart),this._syncSelectionFromRange(),this._writeSelectionToAddress(),this.onSelectionChange(this.getSelection()),this.renderHistogram()}_syncSelectionFromRange(){this._selectedIndices.clear();for(let t=this._selectionRangeStart;t<=this._selectionRangeEnd;t++)this._selectedIndices.add(t)}_writeSelectionToAddress(){if(!this.options.SelectionDataAddress)return;const t={Fable:this.fable,Pict:this.fable,AppData:this.AppData,Bundle:this.Bundle,Options:this.options};this.fable.manifest.setValueByHash(t,this.options.SelectionDataAddress,this.getSelection())}onSelectionChange(t){}onBeforeInitialize(){return super.onBeforeInitialize(),super.onBeforeInitialize()}onAfterRender(t){return this.pict.CSSMap.injectCSS(),this.initialRenderComplete||(this.onAfterInitialRender(),this.initialRenderComplete=!0),super.onAfterRender(t)}onAfterInitialRender(){this.renderHistogram()}renderHistogram(){this.pict.CSSMap&&this.pict.CSSMap.injectCSS(),this._renderer.render(this),this._renderer.wireEvents(this),this.initialRenderComplete=!0}marshalToView(){super.marshalToView(),this.initialRenderComplete&&this.renderHistogram()}marshalFromView(){super.marshalFromView(),this._writeSelectionToAddress()}setOrientation(t){"vertical"===t||"horizontal"===t?(this.options.Orientation=t,this.initialRenderComplete&&this.renderHistogram()):this.log.warn(`PICT-Histogram invalid orientation: ${t}`)}setRenderMode(t){this.options.RenderMode=t,this._renderer=this._resolveRenderer(),this.initialRenderComplete&&this.renderHistogram()}toText(){return"vertical"===this.options.Orientation?a.renderVertical(this):a.renderHorizontal(this)}},e.exports.default_configuration=o,e.exports.renderers={browser:s,consoleui:a,cli:r}},{"./Pict-Section-Histogram-DefaultConfiguration.js":7,"./renderers/Pict-Histogram-Renderer-Browser.js":9,"./renderers/Pict-Histogram-Renderer-CLI.js":10,"./renderers/Pict-Histogram-Renderer-ConsoleUI.js":11,"pict-view":13}],9:[function(t,e,i){function n(t,e,i,n,o,s,a){let r=t[n.LabelProperty]||"",l=t[n.ValueProperty]||0,c="vertical"===n.Orientation,d=o?n.SelectedBarColor:s?n.SelectionRangeColor:n.BarColor,p=n.Selectable?" pict-histogram-selectable":"",h=o?" pict-histogram-selected":"",u=s?" pict-histogram-in-range":"",g=n.FillContainer,m="";m=c?g?`height:${i}px;background-color:${d};`:`height:${i}px;width:${n.BarThickness}px;background-color:${d};`:g?`width:${i}px;background-color:${d};`:`width:${i}px;height:${n.BarThickness}px;background-color:${d};`;let f=n.BarThickness+n.BarGap,v="";v=g?"":c?`margin:0 ${n.BarGap/2}px;width:${f}px;`:`margin:${n.BarGap/2}px 0;`;let b=`<div class="pict-histogram-bar-group" style="${v}" data-histogram-index="${e}">`;if(c)n.ShowValues&&!g&&(b+=`<div class="pict-histogram-value-label" style="width:${f}px;">${l}</div>`),b+=`<div class="pict-histogram-bar${p}${h}${u}" style="${m}" data-histogram-index="${e}"></div>`,n.ShowLabels&&!g&&(b+=`<div class="pict-histogram-bin-label" style="width:${f}px;">${r}</div>`);else{if(n.ShowLabels){b+=`<div class="pict-histogram-bin-label" style="${a?`width:${a}px;min-width:${a}px;`:""}">${r}</div>`}b+=`<div class="pict-histogram-bar${p}${h}${u}" style="${m}" data-histogram-index="${e}"></div>`,n.ShowValues&&(b+=`<div class="pict-histogram-value-label">${l}</div>`)}return b+="</div>",b}function o(t,e,i){let n=e.getAttribute("data-handle"),o="vertical"===t.options.Orientation,s=!1;function a(e){if(!s)return;let a=t.getBins();if(!a||0===a.length)return;let r=function(){let t=i.querySelector(".pict-histogram-range-slider-container");if(!t)return{start:0,size:1};let e=t.getBoundingClientRect();return o?{start:e.left,size:e.width||1}:{start:e.top,size:e.height||1}}(),l=((o?e.clientX:e.clientY)-r.start)/r.size;l=Math.max(0,Math.min(1,l));let c=Math.round(l*(a.length-1));"start"===n?(c>t._selectionRangeEnd&&(c=t._selectionRangeEnd),t._selectionRangeStart=c):(c<t._selectionRangeStart&&(c=t._selectionRangeStart),t._selectionRangeEnd=c),t._syncSelectionFromRange(),t.renderHistogram()}function r(){s&&(s=!1,"undefined"!=typeof document&&(document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",r)))}e.addEventListener("mousedown",t=>{t.preventDefault(),s=!0,"undefined"!=typeof document&&(document.addEventListener("mousemove",a),document.addEventListener("mouseup",r))})}e.exports={render:function(t){let e=t.getBins();if(!e||0===e.length)return void t.services.ContentAssignment.assignContent(t.options.TargetElementAddress,'<div class="pict-histogram-container"><em>No histogram data</em></div>');let i=0;for(let n=0;n<e.length;n++){let o=e[n][t.options.ValueProperty]||0;o>i&&(i=o)}0===i&&(i=1);let o="vertical"===t.options.Orientation,s=o?"pict-histogram-vertical":"pict-histogram-horizontal",a=t.options.FillContainer?" pict-histogram-fill":"",r=0;if(!o&&t.options.ShowLabels&&!t.options.FillContainer){for(let i=0;i<e.length;i++){let n=6.5*String(e[i][t.options.LabelProperty]||"").length+8;n>r&&(r=n)}r=Math.max(r,40)}let l=`<div class="pict-histogram-container ${s}${a}">`;l+=`<div class="pict-histogram-chart ${s}${a}">`;for(let o=0;o<e.length;o++){let s=e[o][t.options.ValueProperty]||0,a=Math.round(s/i*t.options.MaxBarSize);s>0&&a<1&&(a=1);let c=t.isIndexSelected(o),d=!c&&t.isIndexInRange(o);l+=n(e[o],o,a,t.options,c,d,r)}l+="</div>",t.options.FillContainer&&o&&t.options.ShowLabels&&(l+='<div class="pict-histogram-axis-line"></div>',l+=function(t,e){if(!e||0===e.length)return"";let i=t.options.LabelInterval||0;if(i<=0){let n=t.services.ContentAssignment.getElement(t.options.TargetElementAddress),o=800;if(n&&n.length>0&&n[0]&&(o=n[0].clientWidth||800),e.length>0){let t=o/e.length;i=Math.max(1,Math.ceil(80/t))}else i=1}let n='<div class="pict-histogram-label-row">';for(let o=0;o<e.length;o++)if(o%i===0){let s=e[o][t.options.LabelProperty]||"",a=Math.min(i,e.length-o);n+=`<div class="pict-histogram-fill-label" style="flex:${a};">${s}</div>`,o+=a-1}return n+="</div>",n}(t,e)),t.options.Selectable&&"range"===t.options.SelectionMode&&(l+=function(t){let e=t.getBins();if(!e||0===e.length)return"";let i=t._selectionRangeStart,n=t._selectionRangeEnd,o=e.length-1,s=o>0?i/o*100:0,a=o>0?n/o*100:100,r='<div class="pict-histogram-range-slider-container">';return r+='<div class="pict-histogram-range-track"></div>',"vertical"===t.options.Orientation?(r+=`<div class="pict-histogram-range-fill" style="left:${s}%;right:${100-a}%;"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-start" tabindex="0" style="left:${s}%;" data-handle="start"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-end" tabindex="0" style="left:${a}%;" data-handle="end"></div>`):(r+=`<div class="pict-histogram-range-fill" style="top:${s}%;bottom:${100-a}%;"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-start" tabindex="0" style="top:${s}%;" data-handle="start"></div>`,r+=`<div class="pict-histogram-range-handle pict-histogram-range-handle-end" tabindex="0" style="top:${a}%;" data-handle="end"></div>`),r+="</div>",r}(t)),l+="</div>",t.services.ContentAssignment.assignContent(t.options.TargetElementAddress,l)},wireEvents:function(t){if(!t.options.Selectable)return;let e=t.services.ContentAssignment.getElement(t.options.TargetElementAddress);if(!e||e.length<1)return;let i=e[0];if(i){if("single"===t.options.SelectionMode||"multiple"===t.options.SelectionMode){let e=i.querySelectorAll(".pict-histogram-bar[data-histogram-index]");for(let i=0;i<e.length;i++)e[i].addEventListener("click",e=>{let i=parseInt(e.currentTarget.getAttribute("data-histogram-index"),10);isNaN(i)||t.handleBarClick(i)})}if("range"===t.options.SelectionMode){let e=i.querySelectorAll(".pict-histogram-bar[data-histogram-index]");for(let i=0;i<e.length;i++)e[i].addEventListener("click",e=>{let i=parseInt(e.currentTarget.getAttribute("data-histogram-index"),10);isNaN(i)||t.handleRangeBarClick(i)});let n=i.querySelectorAll(".pict-histogram-range-handle");for(let e=0;e<n.length;e++)o(t,n[e],i)}}}}},{}],10:[function(t,e,i){(function(t){(function(){const i={black:"[30m",red:"[31m",green:"[32m",yellow:"[33m",blue:"[34m",magenta:"[35m",cyan:"[36m",white:"[37m",reset:"[0m",bold:"[1m",dim:"[2m"};function n(t){if(!t)return i.blue;let e=t.toLowerCase();if(i[e])return i[e];if("#"===e.charAt(0)&&e.length>=7){let t=parseInt(e.substring(1,3),16),n=parseInt(e.substring(3,5),16),o=parseInt(e.substring(5,7),16);if(n>t&&n>o)return i.green;if(t>n&&t>o)return i.red;if(o>t&&o>n)return i.blue;if(t>200&&n>200)return i.yellow;if(t>200&&o>200)return i.magenta;if(n>200&&o>200)return i.cyan}return i.blue}function o(t){let e=t.getBins(),o=t.options,s=o.TextHeight||15,r=o.BarCharacter,c=o.BarPartialCharacters,d=n(o.BarColor),p=n(o.SelectedBarColor),h=n(o.SelectionRangeColor),u=i.reset;if(!e||0===e.length)return"(no data)\n";let g=0;for(let t=0;t<e.length;t++){let i=e[t][o.ValueProperty]||0;i>g&&(g=i)}0===g&&(g=1);let m=String(g).length+1,f=[];for(let n=s;n>=1;n--){let l="";n===s?l+=i.dim+a(String(g),m)+"|"+u:1===n?l+=i.dim+a("0",m)+"|"+u:n===Math.ceil(s/2)?l+=i.dim+a(String(Math.round(g/2)),m)+"|"+u:l+=i.dim+a("",m)+"|"+u;for(let i=0;i<e.length;i++){let a=(e[i][o.ValueProperty]||0)/g*s,m=Math.floor(a),f=a-m,v=t.isIndexSelected(i),b=!v&&t.isIndexInRange(i),y=v?p:b?h:d,S=" ";if(n<=m)S=r;else if(n===m+1&&f>0){S=c[Math.round(f*(c.length-1))]}l+=" "!==S?" "+y+S+S+S+u:" "}f.push(l)}let v=i.dim+a("",m)+"+";for(let t=0;t<e.length;t++)v+="----";if(v+=u,f.push(v),o.ShowLabels){let t=a("",m)+" ";for(let i=0;i<e.length;i++){t+=l(String(e[i][o.LabelProperty]||"").substring(0,4),4)}f.push(t)}if(o.Selectable&&"range"===o.SelectionMode){let n=t._selectionRangeStart,s=t._selectionRangeEnd,a=e[n]?e[n][o.LabelProperty]:n,r=e[s]?e[s][o.LabelProperty]:s;f.push(""),f.push(i.bold+" Selection: "+a+" - "+r+u)}return f.join("\n")+"\n"}function s(t){let e=t.getBins(),o=t.options,s=o.TextWidth||60,a=o.BarCharacter,l=n(o.BarColor),c=n(o.SelectedBarColor),d=n(o.SelectionRangeColor),p=i.reset;if(!e||0===e.length)return"(no data)\n";let h=0,u=0;for(let t=0;t<e.length;t++){let i=e[t][o.ValueProperty]||0;i>h&&(h=i);let n=String(e[t][o.LabelProperty]||"");n.length>u&&(u=n.length)}0===h&&(h=1);let g=Math.min(u,12),m=s-g-String(h).length-4;m<10&&(m=10);let f=[];for(let n=0;n<e.length;n++){let s=e[n][o.ValueProperty]||0,u=String(e[n][o.LabelProperty]||""),v=Math.round(s/h*m),b=t.isIndexSelected(n),y=!b&&t.isIndexInRange(n),S=b?c:y?d:l,w="";for(let t=0;t<v;t++)w+=a;let D=i.dim+r(u.substring(0,g),g)+" |"+p;D+=S+w+p,D+=" "+s,b?D+=i.bold+" *"+p:y&&(D+=i.dim+" ~"+p),f.push(D)}if(o.Selectable&&"range"===o.SelectionMode){let n=t._selectionRangeStart,s=t._selectionRangeEnd,a=e[n]?e[n][o.LabelProperty]:n,r=e[s]?e[s][o.LabelProperty]:s;f.push(""),f.push(i.bold+" Selection: "+a+" - "+r+p)}return f.join("\n")+"\n"}function a(t,e){let i=String(t);for(;i.length<e;)i=" "+i;return i}function r(t,e){let i=String(t);for(;i.length<e;)i+=" ";return i}function l(t,e){let i=String(t);for(;i.length<e;)i=i.length%2==0?i+" ":" "+i;return i}e.exports={render:function(e){let i;i="vertical"===e.options.Orientation?o(e):s(e),e.services&&e.services.ContentAssignment?e.services.ContentAssignment.assignContent(e.options.TargetElementAddress,i):void 0!==t&&t.stdout&&t.stdout.write(i)},wireEvents:function(){},renderVertical:o,renderHorizontal:s,colorToAnsi:n,ANSI_COLORS:i}}).call(this)}).call(this,t("_process"))},{_process:14}],11:[function(t,e,i){function n(t){let e=t.getBins(),i=t.options,n=i.TextHeight||15,o=i.BarCharacter,a=i.BarPartialCharacters,l=i.EmptyCharacter;if(!e||0===e.length)return"(no data)";let c=0;for(let t=0;t<e.length;t++){let n=e[t][i.ValueProperty]||0;n>c&&(c=n)}0===c&&(c=1);let d=String(c).length+1,p=[];for(let r=n;r>=1;r--){let h="";r===n?h+=s(String(c),d)+"|":1===r?h+=s("0",d)+"|":r===Math.ceil(n/2)?h+=s(String(Math.round(c/2)),d)+"|":h+=s("",d)+"|";for(let s=0;s<e.length;s++){let d=(e[s][i.ValueProperty]||0)/c*n,p=Math.floor(d),u=d-p,g=l;if(r<=p)g=o;else if(r===p+1&&u>0){g=a[Math.round(u*(a.length-1))]}let m=t.isIndexSelected(s),f=!m&&t.isIndexInRange(s);m&&g!==l?g="*":f&&g!==l&&(g="#"),h+=" "+g+g+g}p.push(h)}let h=s("",d)+"+";for(let t=0;t<e.length;t++)h+="----";if(p.push(h),i.ShowLabels){let t=s("",d)+" ";for(let n=0;n<e.length;n++){t+=r(String(e[n][i.LabelProperty]||"").substring(0,4),4)}p.push(t)}if(i.Selectable&&"range"===i.SelectionMode){let i=s("",d)+" ";for(let n=0;n<e.length;n++)n===t._selectionRangeStart?i+=" [ ":n===t._selectionRangeEnd?i+=" ] ":n>t._selectionRangeStart&&n<t._selectionRangeEnd?i+=" - ":i+=" ";p.push(i)}return p.join("\n")}function o(t){let e=t.getBins(),i=t.options,n=i.TextWidth||60,o=i.BarCharacter,s=i.BarPartialCharacters;if(!e||0===e.length)return"(no data)";let r=0,l=0;for(let t=0;t<e.length;t++){let n=e[t][i.ValueProperty]||0;n>r&&(r=n);let o=String(e[t][i.LabelProperty]||"");o.length>l&&(l=o.length)}0===r&&(r=1);let c=Math.min(l,12),d=n-c-2;d<10&&(d=10);let p=[];for(let n=0;n<e.length;n++){let l=e[n][i.ValueProperty]||0,h=String(e[n][i.LabelProperty]||""),u=l/r*d,g=Math.floor(u),m=u-g,f="";for(let t=0;t<g;t++)f+=o;if(m>0&&g<d){f+=s[Math.round(m*(s.length-1))]}let v=t.isIndexSelected(n),b=!v&&t.isIndexInRange(n),y=v?"*":b?"~":"",S=i.ShowValues?" "+l:"",w=a(h.substring(0,c),c)+" |"+f+S+y;p.push(w)}return i.Selectable&&"range"===i.SelectionMode&&(p.push(""),p.push(a("",c)+" Range: ["+t._selectionRangeStart+" - "+t._selectionRangeEnd+"]")),p.join("\n")}function s(t,e){let i=String(t);for(;i.length<e;)i=" "+i;return i}function a(t,e){let i=String(t);for(;i.length<e;)i+=" ";return i}function r(t,e){let i=String(t);for(;i.length<e;)i=i.length%2==0?i+" ":" "+i;return i}e.exports={render:function(t){let e;e="vertical"===t.options.Orientation?n(t):o(t),t.services.ContentAssignment.assignContent(t.options.TargetElementAddress,e)},wireEvents:function(){},renderVertical:n,renderHorizontal:o}},{}],12:[function(t,e,i){e.exports={name:"pict-view",version:"1.0.67",description:"Pict View Base Class",main:"source/Pict-View.js",scripts:{test:"npx quack test",tests:"npx quack test -g",start:"node source/Pict-View.js",coverage:"npx quack coverage",build:"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-view-image:local","docker-dev-run":'docker run -it -d --name pict-view-dev -p 30001:8080 -p 38086:8086 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/pict-view" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" pict-view-image:local',"docker-dev-shell":"docker exec -it pict-view-dev /bin/bash",types:"tsc -p .",lint:"eslint source/**"},types:"types/source/Pict-View.d.ts",repository:{type:"git",url:"git+https://github.com/stevenvelozo/pict-view.git"},author:"steven velozo <steven@velozo.com>",license:"MIT",bugs:{url:"https://github.com/stevenvelozo/pict-view/issues"},homepage:"https://github.com/stevenvelozo/pict-view#readme",devDependencies:{"@eslint/js":"^9.39.1","browser-env":"^3.3.0",eslint:"^9.39.1",pict:"^1.0.348",quackage:"^1.0.58",typescript:"^5.9.3"},mocha:{diff:!0,extension:["js"],package:"./package.json",reporter:"spec",slow:"75",timeout:"5000",ui:"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},dependencies:{fable:"^3.1.63","fable-serviceproviderbase":"^3.0.19"}}},{}],13:[function(t,e,i){const n=t("fable-serviceproviderbase"),o=t("../package.json"),s={DefaultRenderable:!1,DefaultDestinationAddress:!1,DefaultTemplateRecordAddress:!1,ViewIdentifier:!1,AutoInitialize:!0,AutoInitializeOrdinal:0,AutoRender:!0,AutoRenderOrdinal:0,AutoSolveWithApp:!0,AutoSolveOrdinal:0,CSSHash:!1,CSS:!1,CSSProvider:!1,CSSPriority:500,Templates:[],DefaultTemplates:[],Renderables:[],Manifests:{}};e.exports=class extends n{constructor(t,e,i){super(t,Object.assign({},JSON.parse(JSON.stringify(s)),e),i),this.fable,this.options,this.UUID,this.Hash,this.log;const n=this.Hash===this.UUID;this.UUID=`V-${this.UUID}`,n&&(this.Hash=this.UUID),this.options.ViewIdentifier||(this.options.ViewIdentifier=`AutoViewID-${this.fable.getUUID()}`),this.serviceType="PictView",this._Package=o,this.pict=this.fable,this.AppData=this.pict.AppData,this.Bundle=this.pict.Bundle,this.initializeTimestamp=!1,this.lastSolvedTimestamp=!1,this.lastRenderedTimestamp=!1,this.lastMarshalFromViewTimestamp=!1,this.lastMarshalToViewTimestamp=!1,this.pict.instantiateServiceProviderIfNotExists("TransactionTracking");for(let t=0;t<this.options.Templates.length;t++){let e=this.options.Templates[t];"Hash"in e&&"Template"in e?(e.Source||(e.Source=`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} options object.`),this.pict.TemplateProvider.addTemplate(e.Hash,e.Template,e.Source)):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not load Template ${t} in the options array.`,e)}for(let t=0;t<this.options.DefaultTemplates.length;t++){let e=this.options.DefaultTemplates[t];"Postfix"in e&&"Template"in e?(e.Source||(e.Source=`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} options object.`),this.pict.TemplateProvider.addDefaultTemplate(e.Prefix,e.Postfix,e.Template,e.Source)):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not load Default Template ${t} in the options array.`,e)}if(this.options.CSS){let t=this.options.CSSHash?this.options.CSSHash:`View-${this.options.ViewIdentifier}`,e=this.options.CSSProvider?this.options.CSSProvider:t;this.pict.CSSMap.addCSS(t,this.options.CSS,e,this.options.CSSPriority)}this.renderables={};for(let t=0;t<this.options.Renderables.length;t++){let e=this.options.Renderables[t];this.addRenderable(e)}}addRenderable(t,e,i,n,o){let s;if("object"==typeof t)s=t;else{s={RenderableHash:t,TemplateHash:e,DefaultTemplateRecordAddress:i,ContentDestinationAddress:n,RenderMethod:"string"!=typeof o?o:"replace"}}"string"!=typeof s.RenderableHash||"string"!=typeof s.TemplateHash?this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not load Renderable; RenderableHash or TemplateHash are invalid.`,s):(this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} adding renderable [${s.RenderableHash}] pointed to template ${s.TemplateHash}.`),this.renderables[s.RenderableHash]=s)}onBeforeInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeInitialize:`),!0}onBeforeInitializeAsync(t){return this.onBeforeInitialize(),t()}onInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onInitialize:`),!0}onInitializeAsync(t){return this.onInitialize(),t()}initialize(){return this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialize:`),this.initializeTimestamp?(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialize called but initialization is already completed. Aborting.`),!1):(this.onBeforeInitialize(),this.onInitialize(),this.onAfterInitialize(),this.initializeTimestamp=this.pict.log.getTimeStamp(),!0)}initializeAsync(t){if(this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initializeAsync:`),this.initializeTimestamp)return this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} async initialize called but initialization is already completed. Aborting.`),t();{let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate");this.pict.LogNoisiness>0&&this.log.info(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} beginning initialization...`),e.anticipate(this.onBeforeInitializeAsync.bind(this)),e.anticipate(this.onInitializeAsync.bind(this)),e.anticipate(this.onAfterInitializeAsync.bind(this)),e.wait(e=>(e&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialization failed: ${e.message||e}`,{stack:e.stack}),this.initializeTimestamp=this.pict.log.getTimeStamp(),this.pict.LogNoisiness>0&&this.log.info(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} initialization complete.`),t()))}}onAfterInitialize(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterInitialize:`),!0}onAfterInitializeAsync(t){return this.onAfterInitialize(),t()}onBeforeRender(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeRender:`),!0}onBeforeRenderAsync(t,e){return this.onBeforeRender(e),t()}onBeforeProject(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeProject:`),!0}onBeforeProjectAsync(t,e){return this.onBeforeProject(e),t()}buildRenderOptions(t,e,i){let n={Valid:!0};return n.RenderableHash="string"==typeof t?t:"string"==typeof this.options.DefaultRenderable&&this.options.DefaultRenderable,n.RenderableHash||(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not find a suitable RenderableHash ${n.RenderableHash} (param ${t}because it is not a valid renderable.`),n.Valid=!1),n.Renderable=this.renderables[n.RenderableHash],n.Renderable||(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${n.RenderableHash} (param ${t}) because it does not exist.`),n.Valid=!1),n.DestinationAddress="string"==typeof e?e:"string"==typeof n.Renderable.ContentDestinationAddress?n.Renderable.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress&&this.options.DefaultDestinationAddress,n.DestinationAddress||(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${n.RenderableHash} (param ${t}) because it does not have a valid destination address (param ${e}).`),n.Valid=!1),"object"==typeof i?(n.RecordAddress="Passed in as object",n.Record=i):(n.RecordAddress="string"==typeof i?i:"string"==typeof n.Renderable.DefaultTemplateRecordAddress?n.Renderable.DefaultTemplateRecordAddress:"string"==typeof this.options.DefaultTemplateRecordAddress&&this.options.DefaultTemplateRecordAddress,n.Record="string"==typeof n.RecordAddress?this.pict.DataProvider.getDataByAddress(n.RecordAddress):void 0),n}assignRenderContent(t,e,i){return this.pict.ContentAssignment.projectContent(t.RenderMethod,e,i,t.TestAddress)}render(t,e,i,n){return this.renderWithScope(this,t,e,i,n)}renderWithScope(t,e,i,n,o){let s,a,r,l="string"==typeof e?e:"string"==typeof this.options.DefaultRenderable&&this.options.DefaultRenderable;return l?("__Virtual"==l?s={RenderableHash:"__Virtual",TemplateHash:this.renderables[this.options.DefaultRenderable].TemplateHash,ContentDestinationAddress:"string"==typeof i?i:"string"==typeof s.ContentDestinationAddress?s.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null,RenderMethod:"virtual-assignment",TransactionHash:o&&o.TransactionHash,RootRenderableViewHash:o&&o.RootRenderableViewHash}:(s=Object.assign({},this.renderables[l]),s.ContentDestinationAddress="string"==typeof i?i:"string"==typeof s.ContentDestinationAddress?s.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null),s.TransactionHash||(s.TransactionHash=`ViewRender-V-${this.options.ViewIdentifier}-R-${l}-U-${this.pict.getUUID()}`,s.RootRenderableViewHash=this.Hash,this.pict.TransactionTracking.registerTransaction(s.TransactionHash)),s?s.ContentDestinationAddress?("object"==typeof n?(r=n,a="Passed in as object"):(a="string"==typeof n?n:"string"==typeof s.DefaultTemplateRecordAddress?s.DefaultTemplateRecordAddress:"string"==typeof this.options.DefaultTemplateRecordAddress&&this.options.DefaultTemplateRecordAddress,r="string"==typeof a?this.pict.DataProvider.getDataByAddress(a):void 0),this.onBeforeRender(s),this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] Renderable[${l}] Destination[${s.ContentDestinationAddress}] TemplateRecordAddress[${a}] render:`),this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Beginning Render of Renderable[${l}] to Destination [${s.ContentDestinationAddress}]...`),s.Content=this.pict.parseTemplateByHash(s.TemplateHash,r,null,[this],t,{RootRenderable:"object"==typeof o?o:s}),this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Assigning Renderable[${l}] content length ${s.Content.length} to Destination [${s.ContentDestinationAddress}] using render method [${s.RenderMethod}].`),this.onBeforeProject(s),this.onProject(s),"virtual-assignment"!==s.RenderMethod&&(this.onAfterProject(s),this.onAfterRender(s)),!0):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${l} (param ${e}) because it does not have a valid destination address.`),!1):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${l} (param ${e}) because it does not exist.`),!1)):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${l} (param ${e}) because it is not a valid renderable.`),!1)}renderAsync(t,e,i,n,o){return this.renderWithScopeAsync(this,t,e,i,n,o)}renderWithScopeAsync(t,e,i,n,o,s){let a,r,l,c="string"==typeof e?e:"string"==typeof this.options.DefaultRenderable&&this.options.DefaultRenderable,d="function"==typeof s?s:"function"==typeof n?n:"function"==typeof i?i:"function"==typeof e?e:"function"==typeof o?o:null;if(d||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),d=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} renderAsync Auto Callback Error: ${t}`,t)}),!c)return this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not asynchronously render ${c} (param ${e}because it is not a valid renderable.`),d(new Error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not asynchronously render ${c} (param ${e}because it is not a valid renderable.`));if("__Virtual"==c?a={RenderableHash:"__Virtual",TemplateHash:this.renderables[this.options.DefaultRenderable].TemplateHash,ContentDestinationAddress:"string"==typeof i?i:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null,RenderMethod:"virtual-assignment",TransactionHash:o&&"function"!=typeof o&&o.TransactionHash,RootRenderableViewHash:o&&"function"!=typeof o&&o.RootRenderableViewHash}:(a=Object.assign({},this.renderables[c]),a.ContentDestinationAddress="string"==typeof i?i:"string"==typeof a.ContentDestinationAddress?a.ContentDestinationAddress:"string"==typeof this.options.DefaultDestinationAddress?this.options.DefaultDestinationAddress:null),a.TransactionHash||(a.TransactionHash=`ViewRender-V-${this.options.ViewIdentifier}-R-${c}-U-${this.pict.getUUID()}`,a.RootRenderableViewHash=this.Hash,this.pict.TransactionTracking.registerTransaction(a.TransactionHash)),!a)return this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${c} (param ${e}) because it does not exist.`),d(new Error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${c} (param ${e}) because it does not exist.`));if(!a.ContentDestinationAddress)return this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render ${c} (param ${e}) because it does not have a valid destination address.`),d(new Error(`Could not render ${c}`));"object"==typeof n?(l=n,r="Passed in as object"):(r="string"==typeof n?n:"string"==typeof a.DefaultTemplateRecordAddress?a.DefaultTemplateRecordAddress:"string"==typeof this.options.DefaultTemplateRecordAddress&&this.options.DefaultTemplateRecordAddress,l="string"==typeof r?this.pict.DataProvider.getDataByAddress(r):void 0),this.pict.LogControlFlow&&this.log.trace(`PICT-ControlFlow VIEW [${this.UUID}]::[${this.Hash}] Renderable[${c}] Destination[${a.ContentDestinationAddress}] TemplateRecordAddress[${r}] renderAsync:`),this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Beginning Asynchronous Render (callback-style)...`);let p=this.fable.newAnticipate();p.anticipate(t=>{this.onBeforeRenderAsync(t,a)}),p.anticipate(i=>{this.pict.parseTemplateByHash(a.TemplateHash,l,(t,n)=>t?(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render (asynchronously) ${c} (param ${e}) because it did not parse the template.`,t),i(t)):(a.Content=n,i()),[this],t,{RootRenderable:"object"==typeof o?o:a})}),p.anticipate(t=>{this.onBeforeProjectAsync(t,a)}),p.anticipate(t=>{this.onProjectAsync(t,a)}),"virtual-assignment"!==a.RenderMethod&&(p.anticipate(t=>{this.onAfterProjectAsync(t,a)}),p.anticipate(t=>{this.onAfterRenderAsync(t,a)})),p.wait(d)}renderDefaultAsync(t){this.renderAsync(t)}basicRender(t,e,i){return this.basicRenderWithScope(this,t,e,i)}basicRenderWithScope(t,e,i,n){let o=this.buildRenderOptions(e,i,n);return o.Valid?(this.assignRenderContent(o.Renderable,o.DestinationAddress,this.pict.parseTemplateByHash(o.Renderable.TemplateHash,o.Record,null,[this],t,{RootRenderable:o.Renderable})),!0):(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not perform a basic render of ${o.RenderableHash} because it is not valid.`),!1)}basicRenderAsync(t,e,i,n){return this.basicRenderWithScopeAsync(this,t,e,i,n)}basicRenderWithScopeAsync(t,e,i,n,o){let s="function"==typeof o?o:"function"==typeof n?n:"function"==typeof i?i:"function"==typeof e?e:null;s||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} basicRenderAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),s=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} basicRenderAsync Auto Callback Error: ${t}`,t)});const a=this.buildRenderOptions(e,i,n);if(!a.Valid){let t=`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not perform a basic render of ${a.RenderableHash} because it is not valid.`;return this.log.error(t),s(new Error(t))}this.pict.parseTemplateByHash(a.Renderable.TemplateHash,a.Record,(t,e)=>t?(this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} could not render (asynchronously) ${a.RenderableHash} because it did not parse the template.`,t),s(t)):(this.assignRenderContent(a.Renderable,a.DestinationAddress,e),s()),[this],t,{RootRenderable:a.Renderable})}onProject(t){this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onProject:`),"virtual-assignment"===t.RenderMethod&&this.pict.TransactionTracking.pushToTransactionQueue(t.TransactionHash,{ViewHash:this.Hash,Renderable:t},"Deferred-Post-Content-Assignment"),this.pict.LogNoisiness>0&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} Assigning Renderable[${t.RenderableHash}] content length ${t.Content.length} to Destination [${t.ContentDestinationAddress}] using Async render method ${t.RenderMethod}.`),this.pict.ContentAssignment.projectContent(t.RenderMethod,t.ContentDestinationAddress,t.Content,t.TestAddress),this.lastRenderedTimestamp=this.pict.log.getTimeStamp()}onProjectAsync(t,e){return this.onProject(e),t()}onAfterRender(t){if(this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterRender:`),t&&t.RootRenderableViewHash===this.Hash){const e=this.pict.TransactionTracking.clearTransactionQueue(t.TransactionHash)||[];for(const i of e){const e=this.pict.views[i.Data.ViewHash];e?(e.onAfterProject(),e.onAfterRender(i.Data.Renderable)):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterRender: Could not find view for transaction hash ${t.TransactionHash} and ViewHash ${i.Data.ViewHash}.`)}}return!0}onAfterRenderAsync(t,e){this.onAfterRender(e);const i=this.fable.newAnticipate();if(e&&e.RootRenderableViewHash===this.Hash){const t=this.pict.TransactionTracking.clearTransactionQueue(e.TransactionHash)||[];for(const n of t){const t=this.pict.views[n.Data.ViewHash];t?(i.anticipate(t.onAfterProjectAsync.bind(t)),i.anticipate(e=>{t.onAfterRenderAsync(e,n.Data.Renderable)})):this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterRenderAsync: Could not find view for transaction hash ${e.TransactionHash} and ViewHash ${n.Data.ViewHash}.`)}}return i.wait(t)}onAfterProject(t){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterProject:`),!0}onAfterProjectAsync(t,e){return t()}onBeforeSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeSolve:`),!0}onBeforeSolveAsync(t){return this.onBeforeSolve(),t()}onSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onSolve:`),!0}onSolveAsync(t){return this.onSolve(),t()}solve(){return this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} executing solve() function...`),this.onBeforeSolve(),this.onSolve(),this.onAfterSolve(),this.lastSolvedTimestamp=this.pict.log.getTimeStamp(),!0}solveAsync(t){let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t?t:null;i||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} solveAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeSolveAsync.bind(this)),e.anticipate(this.onSolveAsync.bind(this)),e.anticipate(this.onAfterSolveAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} solveAsync() complete.`),this.lastSolvedTimestamp=this.pict.log.getTimeStamp(),i(t)))}onAfterSolve(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterSolve:`),!0}onAfterSolveAsync(t){return this.onAfterSolve(),t()}onBeforeMarshalFromView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeMarshalFromView:`),!0}onBeforeMarshalFromViewAsync(t){return this.onBeforeMarshalFromView(),t()}onMarshalFromView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onMarshalFromView:`),!0}onMarshalFromViewAsync(t){return this.onMarshalFromView(),t()}marshalFromView(){return this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} executing solve() function...`),this.onBeforeMarshalFromView(),this.onMarshalFromView(),this.onAfterMarshalFromView(),this.lastMarshalFromViewTimestamp=this.pict.log.getTimeStamp(),!0}marshalFromViewAsync(t){let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t?t:null;i||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalFromViewAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalFromViewAsync.bind(this)),e.anticipate(this.onMarshalFromViewAsync.bind(this)),e.anticipate(this.onAfterMarshalFromViewAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} marshalFromViewAsync() complete.`),this.lastMarshalFromViewTimestamp=this.pict.log.getTimeStamp(),i(t)))}onAfterMarshalFromView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterMarshalFromView:`),!0}onAfterMarshalFromViewAsync(t){return this.onAfterMarshalFromView(),t()}onBeforeMarshalToView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onBeforeMarshalToView:`),!0}onBeforeMarshalToViewAsync(t){return this.onBeforeMarshalToView(),t()}onMarshalToView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onMarshalToView:`),!0}onMarshalToViewAsync(t){return this.onMarshalToView(),t()}marshalToView(){return this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} executing solve() function...`),this.onBeforeMarshalToView(),this.onMarshalToView(),this.onAfterMarshalToView(),this.lastMarshalToViewTimestamp=this.pict.log.getTimeStamp(),!0}marshalToViewAsync(t){let e=this.pict.instantiateServiceProviderWithoutRegistration("Anticipate"),i="function"==typeof t?t:null;i||(this.log.warn(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewAsync was called without a valid callback. A callback will be generated but this could lead to race conditions.`),i=t=>{t&&this.log.error(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.Name} marshalToViewAsync Auto Callback Error: ${t}`,t)}),e.anticipate(this.onBeforeMarshalToViewAsync.bind(this)),e.anticipate(this.onMarshalToViewAsync.bind(this)),e.anticipate(this.onAfterMarshalToViewAsync.bind(this)),e.wait(t=>(this.pict.LogNoisiness>2&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} marshalToViewAsync() complete.`),this.lastMarshalToViewTimestamp=this.pict.log.getTimeStamp(),i(t)))}onAfterMarshalToView(){return this.pict.LogNoisiness>3&&this.log.trace(`PictView [${this.UUID}]::[${this.Hash}] ${this.options.ViewIdentifier} onAfterMarshalToView:`),!0}onAfterMarshalToViewAsync(t){return this.onAfterMarshalToView(),t()}get isPictView(){return!0}}},{"../package.json":12,"fable-serviceproviderbase":2}],14:[function(t,e,i){var n,o,s=e.exports={};function a(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function l(t){if(n===setTimeout)return setTimeout(t,0);if((n===a||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:a}catch(t){n=a}try{o="function"==typeof clearTimeout?clearTimeout:r}catch(t){o=r}}();var c,d=[],p=!1,h=-1;function u(){p&&c&&(p=!1,c.length?d=c.concat(d):h=-1,d.length&&g())}function g(){if(!p){var t=l(u);p=!0;for(var e=d.length;e;){for(c=d,d=[];++h<e;)c&&c[h].run();h=-1,e=d.length}c=null,p=!1,function(t){if(o===clearTimeout)return clearTimeout(t);if((o===r||!o)&&clearTimeout)return o=clearTimeout,clearTimeout(t);try{return o(t)}catch(e){try{return o.call(null,t)}catch(e){return o.call(this,t)}}}(t)}}function m(t,e){this.fun=t,this.array=e}function f(){}s.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var i=1;i<arguments.length;i++)e[i-1]=arguments[i];d.push(new m(t,e)),1!==d.length||p||l(g)},m.prototype.run=function(){this.fun.apply(null,this.array)},s.title="browser",s.browser=!0,s.env={},s.argv=[],s.version="",s.versions={},s.on=f,s.addListener=f,s.once=f,s.off=f,s.removeListener=f,s.removeAllListeners=f,s.emit=f,s.prependListener=f,s.prependOnceListener=f,s.listeners=function(t){return[]},s.binding=function(t){throw new Error("process.binding is not supported")},s.cwd=function(){return"/"},s.chdir=function(t){throw new Error("process.chdir is not supported")},s.umask=function(){return 0}},{}],15:[function(t,e,i){e.exports={Name:"Retold Data Cloner",Hash:"DataCloner",MainViewportViewIdentifier:"DataCloner-Layout",MainViewportDestinationAddress:"#DataCloner-Application-Container",MainViewportDefaultDataAddress:"AppData.DataCloner",pict_configuration:{Product:"DataCloner"},AutoRenderMainViewportViewAfterInitialize:!1}},{}],16:[function(t,e,i){const n=t("pict-application"),o=t("./providers/Pict-Provider-DataCloner.js"),s=t("./views/PictView-DataCloner-Layout.js"),a=t("./views/PictView-DataCloner-Connection.js"),r=t("./views/PictView-DataCloner-Session.js"),l=t("./views/PictView-DataCloner-Schema.js"),c=t("./views/PictView-DataCloner-Deploy.js"),d=t("./views/PictView-DataCloner-Sync.js"),p=t("./views/PictView-DataCloner-Export.js"),h=t("./views/PictView-DataCloner-ViewData.js"),u=t("pict-section-histogram");e.exports=class extends n{constructor(t,e,i){super(t,e,i),this.pict.addProvider("DataCloner",o.default_configuration,o),this.pict.addView("DataCloner-Layout",s.default_configuration,s),this.pict.addView("DataCloner-Connection",a.default_configuration,a),this.pict.addView("DataCloner-Session",r.default_configuration,r),this.pict.addView("DataCloner-Schema",l.default_configuration,l),this.pict.addView("DataCloner-Deploy",c.default_configuration,c),this.pict.addView("DataCloner-Sync",d.default_configuration,d),this.pict.addView("DataCloner-Export",p.default_configuration,p),this.pict.addView("DataCloner-ViewData",h.default_configuration,h),this.pict.addView("DataCloner-StatusHistogram",{ViewIdentifier:"DataCloner-StatusHistogram",TargetElementAddress:"#DataCloner-Throughput-Histogram",DefaultDestinationAddress:"#DataCloner-Throughput-Histogram",RenderOnLoad:!1,Selectable:!1,Orientation:"vertical",FillContainer:!0,ShowValues:!1,ShowLabels:!0,MaxBarSize:80,BarColor:"#4a90d9",Bins:[]},u)}onAfterInitializeAsync(t){return this.pict.AppData.DataCloner={FetchedTables:[],DeployedTables:[],LastReport:null,ServerBusyAtLoad:!1,SyncPollTimer:null,LiveStatusTimer:null,StatusDetailExpanded:!1,StatusDetailTimer:null,StatusDetailData:null,LastLiveStatus:null,PersistFields:["serverURL","authMethod","authURI","checkURI","cookieName","cookieValueAddr","cookieValueTemplate","loginMarker","userName","password","schemaURL","pageSize","dateTimePrecisionMS","connProvider","sqliteFilePath","mysqlServer","mysqlPort","mysqlUser","mysqlPassword","mysqlDatabase","mysqlConnectionLimit","mssqlServer","mssqlPort","mssqlUser","mssqlPassword","mssqlDatabase","mssqlConnectionLimit","postgresqlHost","postgresqlPort","postgresqlUser","postgresqlPassword","postgresqlDatabase","postgresqlConnectionLimit","solrHost","solrPort","solrCore","solrPath","mongodbHost","mongodbPort","mongodbUser","mongodbPassword","mongodbDatabase","mongodbConnectionLimit","rocksdbFolder","bibliographFolder","syncMaxRecords"]},window.pict=this.pict,this.pict.views["DataCloner-Layout"].render(),this.pict.providers.DataCloner.initPersistence(),this.pict.views["DataCloner-Connection"].onProviderChange(),this.pict.providers.DataCloner.restoreDeployedTables(),this.pict.providers.DataCloner.startLiveStatusPolling(),this.pict.providers.DataCloner.initAccordionPreviews(),this.pict.providers.DataCloner.updateAllPreviews(),this.pict.views["DataCloner-Layout"].collapseAllSections(),this.pict.providers.DataCloner.initAutoProcess(),t()}},e.exports.default_configuration=t("./Pict-Application-DataCloner-Configuration.json")},{"./Pict-Application-DataCloner-Configuration.json":15,"./providers/Pict-Provider-DataCloner.js":18,"./views/PictView-DataCloner-Connection.js":19,"./views/PictView-DataCloner-Deploy.js":20,"./views/PictView-DataCloner-Export.js":21,"./views/PictView-DataCloner-Layout.js":22,"./views/PictView-DataCloner-Schema.js":23,"./views/PictView-DataCloner-Session.js":24,"./views/PictView-DataCloner-Sync.js":25,"./views/PictView-DataCloner-ViewData.js":26,"pict-application":4,"pict-section-histogram":8}],17:[function(t,e,i){e.exports={DataClonerApplication:t("./Pict-Application-DataCloner.js")},"undefined"!=typeof window&&(window.DataClonerApplication=e.exports.DataClonerApplication)},{"./Pict-Application-DataCloner.js":16}],18:[function(t,e,i){const n=t("pict-provider");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}api(t,e,i){let n={method:t,headers:{}};return i&&(n.headers["Content-Type"]="application/json",n.body=JSON.stringify(i)),fetch(e,n).then(function(t){return t.json()})}setStatus(t,e,i){let n=document.getElementById(t);n&&(n.className="status "+(i||"info"),n.textContent=e,n.style.display="block")}escapeHtml(t){let e=document.createElement("div");return e.appendChild(document.createTextNode(t)),e.innerHTML}setSectionPhase(t,e){let i=document.getElementById("phase"+t);i&&(i.className="accordion-phase","ok"===e?(i.innerHTML="✓",i.classList.add("visible","accordion-phase-ok")):"error"===e?(i.innerHTML="✗",i.classList.add("visible","accordion-phase-error")):"busy"===e?(i.innerHTML='<span class="phase-spinner"></span>',i.classList.add("visible","accordion-phase-busy")):i.innerHTML="")}updateAllPreviews(){let t=document.getElementById("connProvider");if(!t)return;t=t.value;let e=t;if("SQLite"===t){e="SQLite at "+(document.getElementById("sqliteFilePath").value||"data/cloned.sqlite")}else if("MySQL"===t){e="MySQL on "+(document.getElementById("mysqlServer").value||"127.0.0.1")+":"+(document.getElementById("mysqlPort").value||"3306")+" as "+(document.getElementById("mysqlUser").value||"root")}else if("MSSQL"===t){e="MSSQL on "+(document.getElementById("mssqlServer").value||"127.0.0.1")+":"+(document.getElementById("mssqlPort").value||"1433")+" as "+(document.getElementById("mssqlUser").value||"sa")}else if("PostgreSQL"===t){e="PostgreSQL on "+(document.getElementById("postgresqlHost").value||"127.0.0.1")+":"+(document.getElementById("postgresqlPort").value||"5432")+" as "+(document.getElementById("postgresqlUser").value||"postgres")}else if("MongoDB"===t){e="MongoDB on "+(document.getElementById("mongodbHost").value||"127.0.0.1")+":"+(document.getElementById("mongodbPort").value||"27017")}else if("Solr"===t){e="Solr on "+(document.getElementById("solrHost").value||"127.0.0.1")+":"+(document.getElementById("solrPort").value||"8983")}else if("RocksDB"===t){e="RocksDB at "+(document.getElementById("rocksdbFolder").value||"data/rocksdb")}else if("Bibliograph"===t){e="Bibliograph at "+(document.getElementById("bibliographFolder").value||"data/bibliograph")}document.getElementById("preview1").textContent=e;let i=document.getElementById("serverURL").value,n=document.getElementById("userName").value;if(i){let t=i;n&&(t+=" as "+n),document.getElementById("preview2").textContent=t}else document.getElementById("preview2").textContent="Configure remote server URL and credentials";let o=document.querySelectorAll('#tableList input[type="checkbox"]:checked');if(o.length>0)document.getElementById("preview3").textContent=o.length+" table"+(1===o.length?"":"s")+" selected";else{let t=document.getElementById("schemaURL").value;document.getElementById("preview3").textContent=t?"Schema from "+t:"Fetch and select tables from the remote server"}let s=document.getElementById("deployStatus"),a=s?s.textContent:"";a&&-1!==a.indexOf("deployed")?document.getElementById("preview4").textContent=a:document.getElementById("preview4").textContent="Create selected tables in the local database";let r=document.querySelector('input[name="syncMode"]:checked'),l=(r?r.value:"Initial")+" sync, page size "+(document.getElementById("pageSize").value||"100");document.getElementById("syncDeletedRecords").checked&&(l+=", including deleted"),document.getElementById("preview5").textContent=l;let c=document.getElementById("syncMaxRecords").value,d=document.getElementById("syncLogFile").checked,p=[];c&&parseInt(c,10)>0&&p.push("max "+c+" records"),d?p.push("log enabled"):p.push("log disabled"),document.getElementById("preview6").textContent=p.length>0?"Export: "+p.join(", "):"Generate JSON config for headless cloning";let h=document.getElementById("viewTable").value;document.getElementById("preview7").textContent=h?"Viewing "+h:"Browse synced table data"}initAccordionPreviews(){let t=this,e=["connProvider","sqliteFilePath","mysqlServer","mysqlPort","mysqlUser","mssqlServer","mssqlPort","mssqlUser","postgresqlHost","postgresqlPort","postgresqlUser","mongodbHost","mongodbPort","solrHost","solrPort","rocksdbFolder","bibliographFolder","serverURL","userName","schemaURL","pageSize","dateTimePrecisionMS","syncMaxRecords","viewTable","viewLimit"],i=function(){t.updateAllPreviews()};for(let t=0;t<e.length;t++){let n=document.getElementById(e[t]);n&&(n.addEventListener("input",i),n.addEventListener("change",i))}let n=["syncDeletedRecords","syncLogFile"];for(let t=0;t<n.length;t++){let e=document.getElementById(n[t]);e&&e.addEventListener("change",i)}document.querySelectorAll('input[name="syncMode"]').forEach(function(t){t.addEventListener("change",i)})}saveField(t){let e=document.getElementById(t);e&&localStorage.setItem("dataCloner_"+t,e.value)}restoreFields(){let t=this.pict.AppData.DataCloner.PersistFields;for(let e=0;e<t.length;e++){let i=t[e],n=localStorage.getItem("dataCloner_"+i);if(null!==n){let t=document.getElementById(i);t&&(t.value=n)}}let e=localStorage.getItem("dataCloner_syncDeletedRecords");null!==e&&(document.getElementById("syncDeletedRecords").checked="true"===e),"Ongoing"===localStorage.getItem("dataCloner_syncMode")&&(document.getElementById("syncModeOngoing").checked=!0);let i=localStorage.getItem("dataCloner_solrSecure");null!==i&&(document.getElementById("solrSecure").checked="true"===i);let n=localStorage.getItem("dataCloner_syncAdvancedIDPagination");null!==n&&(document.getElementById("syncAdvancedIDPagination").checked="true"===n)}initPersistence(){let t=this;this.restoreFields();let e=this.pict.AppData.DataCloner.PersistFields;for(let i=0;i<e.length;i++)(function(e){let i=document.getElementById(e);i&&(i.addEventListener("input",function(){t.saveField(e)}),i.addEventListener("change",function(){t.saveField(e)}))})(e[i]);let i=document.getElementById("syncDeletedRecords");i&&i.addEventListener("change",function(){localStorage.setItem("dataCloner_syncDeletedRecords",this.checked)}),document.querySelectorAll('input[name="syncMode"]').forEach(function(t){t.addEventListener("change",function(){localStorage.setItem("dataCloner_syncMode",this.value)})});let n=document.getElementById("solrSecure");n&&n.addEventListener("change",function(){localStorage.setItem("dataCloner_solrSecure",this.checked)});let o=document.getElementById("syncAdvancedIDPagination");o&&o.addEventListener("change",function(){localStorage.setItem("dataCloner_syncAdvancedIDPagination",this.checked)});let s=["auto1","auto2","auto3","auto4","auto5"];for(let t=0;t<s.length;t++)(function(t){let e=document.getElementById(t);if(e){let i=localStorage.getItem("dataCloner_"+t);null!==i&&(e.checked="true"===i),e.addEventListener("change",function(){localStorage.setItem("dataCloner_"+t,this.checked)})}})(s[t])}startLiveStatusPolling(){let t=this.pict.AppData.DataCloner;t.LiveStatusTimer&&clearInterval(t.LiveStatusTimer),this.pollLiveStatus();let e=this;t.LiveStatusTimer=setInterval(function(){e.pollLiveStatus()},1500)}pollLiveStatus(){let t=this;this.api("GET","/clone/sync/live-status").then(function(e){t.renderLiveStatus(e)}).catch(function(){t.renderLiveStatus({Phase:"disconnected",Message:"Cannot reach server",TotalSynced:0,TotalRecords:0})})}renderLiveStatus(t){this.pict.AppData.DataCloner.LastLiveStatus=t;let e=document.getElementById("liveStatusBar"),i=document.getElementById("liveStatusMessage"),n=document.getElementById("liveStatusMeta"),o=document.getElementById("liveStatusProgressFill");if(!e)return;let s=e.classList.contains("expanded");e.className="live-status-bar phase-"+(t.Phase||"idle"),s&&e.classList.add("expanded"),i.textContent=t.Message||"Idle";let a=[];if("syncing"===t.Phase||"stopping"===t.Phase){if(t.Elapsed&&a.push('<span class="live-status-meta-item">⏱ '+t.Elapsed+"</span>"),t.ETA&&a.push('<span class="live-status-meta-item">~'+t.ETA+" remaining</span>"),t.TotalTables>0&&a.push('<span class="live-status-meta-item"><strong>'+t.Completed+"</strong> / "+t.TotalTables+" tables</span>"),t.TotalSynced>0){let e=t.TotalSynced.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");if(t.PreCountGrandTotal>0){let i=t.PreCountGrandTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");a.push('<span class="live-status-meta-item"><strong>'+e+"</strong> / "+i+" records</span>")}else a.push('<span class="live-status-meta-item"><strong>'+e+"</strong> records</span>")}else if(t.PreCountGrandTotal>0){let e=t.PreCountGrandTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");a.push('<span class="live-status-meta-item">'+e+" records to sync</span>")}if(t.PreCountProgress&&t.PreCountProgress.Counted<t.PreCountProgress.TotalTables){let e=t.PreCountGrandTotal>0?" ("+t.PreCountGrandTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")+" records found)":"";a.push('<span class="live-status-meta-item">counting: '+t.PreCountProgress.Counted+" / "+t.PreCountProgress.TotalTables+" tables"+e+"</span>")}t.Errors>0&&a.push('<span class="live-status-meta-item" style="color:#dc3545"><strong>'+t.Errors+"</strong> error"+(1===t.Errors?"":"s")+"</span>")}else if("complete"===t.Phase&&t.TotalSynced>0){let e=t.TotalSynced.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");a.push('<span class="live-status-meta-item"><strong>'+e+"</strong> records synced</span>")}n.innerHTML=a.join("");let r=0;if("syncing"===t.Phase&&t.PreCountProgress&&t.PreCountProgress.Counted<t.PreCountProgress.TotalTables)r=Math.min(t.PreCountProgress.Counted/t.PreCountProgress.TotalTables*100,99);else if("syncing"===t.Phase&&t.PreCountGrandTotal>0&&t.TotalSynced>0)r=Math.min(t.TotalSynced/t.PreCountGrandTotal*100,99.9);else if("syncing"===t.Phase&&t.TotalTables>0){let e=t.Completed/t.TotalTables*100;if(t.ActiveProgress&&t.ActiveProgress.Total>0){r=e+t.ActiveProgress.Synced/t.ActiveProgress.Total*(100/t.TotalTables)}else r=e}else"complete"===t.Phase&&(r=100);if(o.style.width=Math.min(100,Math.round(r))+"%",("syncing"===t.Phase||"stopping"===t.Phase)&&!this.pict.AppData.DataCloner.StatusDetailExpanded){let t=this.pict.views["DataCloner-Layout"];t&&"function"==typeof t.toggleStatusDetail&&t.toggleStatusDetail()}if(this.pict.AppData.DataCloner.StatusDetailExpanded&&this.renderStatusDetail(),"complete"===t.Phase&&!this.pict.AppData.DataCloner.LastReport){let t=this;this.api("GET","/clone/sync/report").then(function(e){e&&e.ReportVersion&&(t.pict.AppData.DataCloner.LastReport=e,t.pict.AppData.DataCloner.StatusDetailExpanded&&t.renderStatusDetail())}).catch(function(){})}}onStatusDetailExpanded(){let t=this.pict.AppData.DataCloner;t.StatusDetailExpanded=!0,this.renderStatusDetail(),t.StatusDetailTimer&&clearInterval(t.StatusDetailTimer);let e=this;t.StatusDetailTimer=setInterval(function(){e.pollStatusDetail()},2e3),this.pollStatusDetail()}onStatusDetailCollapsed(){let t=this.pict.AppData.DataCloner;t.StatusDetailExpanded=!1,t.StatusDetailTimer&&(clearInterval(t.StatusDetailTimer),t.StatusDetailTimer=null)}pollStatusDetail(){let t=this;this.api("GET","/clone/sync/status").then(function(e){t.pict.AppData.DataCloner.StatusDetailData=e,t.renderStatusDetail()}).catch(function(){})}renderCountingPhaseDetail(t,e){let i=e.Tables||[],n=e.Counted||0,o=e.TotalTables||0,s=0,a='<div class="status-detail-section">';if(a+='<div class="status-detail-section-title">Counting Records ('+n+" / "+o+" tables)</div>",i.length>0){a+='<table class="precount-table">',a+='<thead><tr><th>Table</th><th style="text-align:right">Records</th><th style="text-align:right">Time</th></tr></thead>',a+="<tbody>";for(let t=0;t<i.length;t++){let e=i[t];s+=e.Count;let n=this.formatNumber(e.Count),o=e.ElapsedMs<1e3?e.ElapsedMs+"ms":(e.ElapsedMs/1e3).toFixed(1)+"s";a+="<tr"+(e.Error?' class="precount-error"':"")+">",a+="<td>"+this.escapeHtml(e.Name)+"</td>",a+='<td style="text-align:right; font-variant-numeric:tabular-nums">'+n+"</td>",a+='<td style="text-align:right; font-variant-numeric:tabular-nums; color:#888">'+o+"</td>",a+="</tr>"}a+="</tbody>",a+="<tfoot><tr>",a+="<td><strong>Total</strong></td>",a+='<td style="text-align:right; font-variant-numeric:tabular-nums"><strong>'+this.formatNumber(s)+"</strong></td>",a+="<td></td>",a+="</tr></tfoot>",a+="</table>"}let r=o-n;r>0&&(a+='<div class="precount-pending">',a+='<span class="precount-spinner"></span> ',a+=r+" table"+(1===r?"":"s")+" remaining…",a+="</div>"),a+="</div>",t.innerHTML=a}renderStatusDetail(){let t=document.getElementById("DataCloner-StatusDetail-Container");if(!t)return;let e=this.pict.AppData.DataCloner,i=e.LastLiveStatus,n=e.StatusDetailData,o=e.LastReport;if(i&&i.PreCountProgress&&i.PreCountProgress.Tables&&"syncing"===i.Phase&&i.PreCountProgress.Counted<i.PreCountProgress.TotalTables){this.renderCountingPhaseDetail(t,i.PreCountProgress);let e=document.getElementById("DataCloner-Throughput-Histogram");return void(e&&(e.style.display="none"))}let s={},a=[],r=[],l=!1;if(!i||"syncing"!==i.Phase&&"stopping"!==i.Phase)if(o&&o.ReportVersion){for(let t=0;t<o.Tables.length;t++){let e=o.Tables[t];s[e.Name]=e}a=o.ThroughputSamples||[],r=o.EventLog||[]}else n&&n.Tables&&(s=n.Tables,i&&i.ThroughputSamples&&(a=i.ThroughputSamples));else l=!0,n&&n.Tables&&(s=n.Tables),i.ThroughputSamples&&(a=i.ThroughputSamples);let c=[],d=[],p=[],h=[],u=Object.keys(s);for(let t=0;t<u.length;t++){let e=u[t],i=s[e];"Syncing"===i.Status?c.push({Name:e,Data:i}):"Pending"===i.Status?d.push(e):"Complete"===i.Status?p.push({Name:e,Data:i}):"Error"!==i.Status&&"Partial"!==i.Status||h.push({Name:e,Data:i})}let g="";if(c.length>0||d.length>0){g+='<div class="status-detail-section">',g+='<div class="status-detail-section-title">Running</div>';for(let t=0;t<c.length;t++){let e=c[t],i=e.Data.Total>0?Math.round(e.Data.Synced/e.Data.Total*100):0,n=this.formatNumber(e.Data.Synced||0),o=this.formatNumber(e.Data.Total||0);g+='<div class="running-op-row">',g+=' <div class="running-op-name">'+this.escapeHtml(e.Name)+"</div>",g+=' <div class="running-op-bar"><div class="running-op-bar-fill" style="width:'+i+'%"></div></div>',g+=' <div class="running-op-count">'+n+" / "+o+" ("+i+"%)</div>",g+="</div>"}d.length>0&&(g+='<div class="running-op-pending">'+d.length+" table"+(1===d.length?"":"s")+" waiting</div>"),g+="</div>"}if(p.length>0){g+='<div class="status-detail-section">',g+='<div class="status-detail-section-title">Completed ('+p.length+")</div>";for(let t=0;t<p.length;t++)g+=this.renderCompletedRow(p[t]);g+="</div>"}if(h.length>0){g+='<div class="status-detail-section">',g+='<div class="status-detail-section-title">Errors ('+h.length+")</div>";for(let t=0;t<h.length;t++)g+=this.renderErrorRow(h[t],r);g+="</div>"}""===g&&(g=l?'<div style="font-size:0.9em; color:#888; padding:8px 0">Sync in progress, waiting for table data…</div>':'<div style="font-size:0.9em; color:#888; padding:8px 0">No sync data available. Run a sync to see operation details here.</div>'),t.innerHTML=g,this.updateThroughputHistogram(a)}updateThroughputHistogram(t){let e=document.getElementById("DataCloner-Throughput-Histogram");if(!e)return;if(!t||t.length<2)return void(e.style.display="none");let i=[];for(let e=1;e<t.length;e++){let n=t[e].synced-t[e-1].synced;n<0&&(n=0),i.push({delta:n,t:t[e].t})}let n=e.clientWidth||800,o=Math.max(20,Math.floor(n/6)),s=i;if(i.length>o){let t=Math.ceil(i.length/o);s=[];for(let e=0;e<i.length;e+=t){let n=0,o=0;for(let s=e;s<Math.min(e+t,i.length);s++)n+=i[s].delta,o=i[s].t;s.push({delta:n,t:o})}}let a=!1;for(let t=0;t<s.length;t++)if(s[t].delta>0){a=!0;break}if(!a)return void(e.style.display="none");let r=t[0].t,l=[];for(let t=0;t<s.length;t++){let e=Math.round((s[t].t-r)/1e3);l.push({Label:this.formatElapsed(e),Value:s[t].delta})}e.style.display="";let c=this.pict.views["DataCloner-StatusHistogram"];c&&(c.setBins(l),c.renderHistogram())}formatElapsed(t){if(t<60)return t+"s";if(t<3600){let e=t%60;return Math.floor(t/60)+":"+(e<10?"0":"")+e}let e=Math.floor(t/3600),i=Math.floor(t%3600/60);return e+"h"+(i<10?"0":"")+i}formatCompact(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e4?(t/1e3).toFixed(0)+"K":t>=1e3?(t/1e3).toFixed(1)+"K":t.toString()}formatNumber(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}renderCompletedRow(t){let e=t.Data.New||0,i=t.Data.Updated||0,n=t.Data.Unchanged||0,o=t.Data.Deleted||0,s=t.Data.ServerTotal||0,a=n+e+i+o;0===a&&s>0&&(a=s,n=s);let r='<div class="completed-op-row">';if(r+='<div class="completed-op-header">',r+=' <span class="completed-op-checkmark">✓</span>',r+=' <span class="completed-op-name">'+this.escapeHtml(t.Name)+"</span>",r+="</div>",a>0){let t=Math.round(n/a*100),s=Math.round(e/a*100),l=Math.round(i/a*100),c=Math.round(o/a*100),d=t+s+l+c;100!==d&&d>0&&(t+=100-d,t<0&&(t=0)),r+='<div class="ratio-bar-container">',t>0&&(r+='<div class="ratio-bar-segment unchanged" style="width:'+t+'%" title="Unchanged: '+this.formatNumber(n)+'"></div>'),s>0&&(r+='<div class="ratio-bar-segment new-records" style="width:'+s+'%" title="New: '+this.formatNumber(e)+'"></div>'),l>0&&(r+='<div class="ratio-bar-segment updated" style="width:'+l+'%" title="Updated: '+this.formatNumber(i)+'"></div>'),c>0&&(r+='<div class="ratio-bar-segment deleted" style="width:'+c+'%" title="Deleted: '+this.formatNumber(o)+'"></div>'),r+="</div>",r+='<div class="ratio-bar-legend">',n>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot unchanged-dot"></span> Unchanged ('+this.formatNumber(n)+")</span>"),e>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot new-dot"></span> New ('+this.formatNumber(e)+")</span>"),i>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot updated-dot"></span> Updated ('+this.formatNumber(i)+")</span>"),o>0&&(r+='<span class="ratio-bar-legend-item"><span class="ratio-bar-legend-dot deleted-dot"></span> Deleted ('+this.formatNumber(o)+")</span>"),r+="</div>"}return r+="</div>",r}renderErrorRow(t,e){let i=t.Data.Synced||0,n=t.Data.Total||0,o=this.formatNumber(i),s=this.formatNumber(n),a='<div class="error-op-row">';if(a+='<div class="error-op-header">',a+=' <span style="color:#dc3545">✗</span>',a+=' <span class="error-op-name">'+this.escapeHtml(t.Name)+"</span>",a+=' <span class="error-op-status">'+t.Data.Status+" — "+o+" / "+s+"</span>",a+="</div>",t.Data.ErrorMessage&&(a+='<div class="error-op-message">'+this.escapeHtml(t.Data.ErrorMessage)+"</div>"),e&&e.length>0){let i=[];for(let n=0;n<e.length;n++){let o=e[n];!o.Data||o.Data.Table!==t.Name||"TableError"!==o.Type&&"TablePartial"!==o.Type||i.push(o)}if(i.length>0){a+='<div class="error-op-log-entries">';for(let t=0;t<i.length;t++){let e=i[t].Timestamp.replace("T"," ").replace(/\.\d+Z$/,"");a+="<div>"+this.escapeHtml(e+" "+i[t].Message)+"</div>"}a+="</div>"}}return a+="</div>",a}saveDeployedTables(){localStorage.setItem("dataCloner_deployedTables",JSON.stringify(this.pict.AppData.DataCloner.DeployedTables))}restoreDeployedTables(){try{let t=localStorage.getItem("dataCloner_deployedTables");t&&(this.pict.AppData.DataCloner.DeployedTables=JSON.parse(t),this.pict.views["DataCloner-ViewData"].populateViewTableDropdown())}catch(t){}}initAutoProcess(){let t=this;this.api("GET","/clone/sync/live-status").then(function(e){if("syncing"===e.Phase||"stopping"===e.Phase)return t.pict.AppData.DataCloner.ServerBusyAtLoad=!0,t.setSectionPhase(5,"busy"),void t.pict.views["DataCloner-Sync"].startPolling();t.runAutoProcessChain()}).catch(function(){})}runAutoProcessChain(){let t=this,e=0,i=2e3;document.getElementById("auto1")&&document.getElementById("auto1").checked&&(setTimeout(function(){t.pict.views["DataCloner-Connection"].connectProvider()},e),e+=i),document.getElementById("auto2")&&document.getElementById("auto2").checked&&(setTimeout(function(){t.pict.views["DataCloner-Session"].goAction()},e),e+=3500),document.getElementById("auto3")&&document.getElementById("auto3").checked&&(setTimeout(function(){t.pict.views["DataCloner-Schema"].fetchSchema()},e),e+=i),document.getElementById("auto4")&&document.getElementById("auto4").checked&&(setTimeout(function(){t.pict.views["DataCloner-Deploy"].deploySchema()},e),e+=i),document.getElementById("auto5")&&document.getElementById("auto5").checked&&setTimeout(function(){t.pict.views["DataCloner-Sync"].startSync()},e)}},e.exports.default_configuration={ProviderIdentifier:"DataCloner",AutoInitialize:!0,AutoInitializeOrdinal:0}},{"pict-provider":6}],19:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}onProviderChange(){let t=document.getElementById("connProvider").value,e=["SQLite","MySQL","MSSQL","PostgreSQL","Solr","MongoDB","RocksDB","Bibliograph"];for(let i=0;i<e.length;i++){let n=document.getElementById("config"+e[i]);n&&(n.style.display=t===e[i]?"":"none")}this.pict.providers.DataCloner.saveField("connProvider")}getProviderConfig(){let t=document.getElementById("connProvider").value,e={};return"SQLite"===t?e.SQLiteFilePath=document.getElementById("sqliteFilePath").value.trim()||"data/cloned.sqlite":"MySQL"===t?(e.host=document.getElementById("mysqlServer").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("mysqlPort").value,10)||3306,e.user=document.getElementById("mysqlUser").value.trim()||"root",e.password=document.getElementById("mysqlPassword").value,e.database=document.getElementById("mysqlDatabase").value.trim(),e.connectionLimit=parseInt(document.getElementById("mysqlConnectionLimit").value,10)||20):"MSSQL"===t?(e.server=document.getElementById("mssqlServer").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("mssqlPort").value,10)||1433,e.user=document.getElementById("mssqlUser").value.trim()||"sa",e.password=document.getElementById("mssqlPassword").value,e.database=document.getElementById("mssqlDatabase").value.trim(),e.connectionLimit=parseInt(document.getElementById("mssqlConnectionLimit").value,10)||20):"PostgreSQL"===t?(e.host=document.getElementById("postgresqlHost").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("postgresqlPort").value,10)||5432,e.user=document.getElementById("postgresqlUser").value.trim()||"postgres",e.password=document.getElementById("postgresqlPassword").value,e.database=document.getElementById("postgresqlDatabase").value.trim(),e.max=parseInt(document.getElementById("postgresqlConnectionLimit").value,10)||10):"Solr"===t?(e.host=document.getElementById("solrHost").value.trim()||"localhost",e.port=parseInt(document.getElementById("solrPort").value,10)||8983,e.core=document.getElementById("solrCore").value.trim()||"default",e.path=document.getElementById("solrPath").value.trim()||"/solr",e.secure=document.getElementById("solrSecure").checked):"MongoDB"===t?(e.host=document.getElementById("mongodbHost").value.trim()||"127.0.0.1",e.port=parseInt(document.getElementById("mongodbPort").value,10)||27017,e.user=document.getElementById("mongodbUser").value.trim(),e.password=document.getElementById("mongodbPassword").value,e.database=document.getElementById("mongodbDatabase").value.trim()||"test",e.maxPoolSize=parseInt(document.getElementById("mongodbConnectionLimit").value,10)||10):"RocksDB"===t?e.RocksDBFolder=document.getElementById("rocksdbFolder").value.trim()||"data/rocksdb":"Bibliograph"===t&&(e.StorageFolder=document.getElementById("bibliographFolder").value.trim()||"data/bibliograph"),{Provider:t,Config:e}}connectProvider(){let t=this.getProviderConfig();this.pict.providers.DataCloner.setSectionPhase(1,"busy"),this.pict.providers.DataCloner.setStatus("connectionStatus","Connecting to "+t.Provider+"...","info"),this.pict.providers.DataCloner.api("POST","/clone/connection/configure",t).then(t=>{t.Success?(this.pict.providers.DataCloner.setStatus("connectionStatus",t.Message,"ok"),this.pict.providers.DataCloner.setSectionPhase(1,"ok")):(this.pict.providers.DataCloner.setStatus("connectionStatus","Connection failed: "+(t.Error||"Unknown error"),"error"),this.pict.providers.DataCloner.setSectionPhase(1,"error"))}).catch(t=>{this.pict.providers.DataCloner.setStatus("connectionStatus","Request failed: "+t.message,"error"),this.pict.providers.DataCloner.setSectionPhase(1,"error")})}testConnection(){let t=this.getProviderConfig();this.pict.providers.DataCloner.setStatus("connectionStatus","Testing "+t.Provider+" connection...","info"),this.pict.providers.DataCloner.api("POST","/clone/connection/test",t).then(t=>{t.Success?this.pict.providers.DataCloner.setStatus("connectionStatus",t.Message,"ok"):this.pict.providers.DataCloner.setStatus("connectionStatus","Test failed: "+(t.Error||"Unknown error"),"error")}).catch(t=>{this.pict.providers.DataCloner.setStatus("connectionStatus","Request failed: "+t.message,"error")})}checkConnectionStatus(){this.pict.providers.DataCloner.api("GET","/clone/connection/status").then(t=>{t.Connected&&(this.pict.providers.DataCloner.setStatus("connectionStatus","Connected: "+t.Provider,"ok"),this.pict.providers.DataCloner.setSectionPhase(1,"ok"))}).catch(()=>{})}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Connection",DefaultRenderable:"DataCloner-Connection",DefaultDestinationAddress:"#DataCloner-Section-Connection",Templates:[{Hash:"DataCloner-Connection",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">1</div>\n\t<div class="accordion-card" id="section1" data-section="1">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section1\')">\n\t\t\t<div class="accordion-title">Database Connection</div>\n\t\t\t<span class="accordion-phase" id="phase1"></span>\n\t\t\t<div class="accordion-preview" id="preview1">SQLite at data/cloned.sqlite</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Connection\'].connectProvider()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto1"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<p style="font-size:0.9em; color:#666; margin-bottom:10px">Configure the local database where cloned data will be stored. SQLite is connected by default.</p>\n\n\t\t\t<div class="inline-group">\n\t\t\t\t<div style="flex:0 0 200px">\n\t\t\t\t\t<label for="connProvider">Provider</label>\n\t\t\t\t\t<select id="connProvider" onchange="pict.views[\'DataCloner-Connection\'].onProviderChange()">\n\t\t\t\t\t\t<option value="SQLite" selected>SQLite</option>\n\t\t\t\t\t\t<option value="MySQL">MySQL</option>\n\t\t\t\t\t\t<option value="MSSQL">MSSQL</option>\n\t\t\t\t\t\t<option value="PostgreSQL">PostgreSQL</option>\n\t\t\t\t\t\t<option value="Solr">Solr</option>\n\t\t\t\t\t\t<option value="MongoDB">MongoDB</option>\n\t\t\t\t\t\t<option value="RocksDB">RocksDB</option>\n\t\t\t\t\t\t<option value="Bibliograph">Bibliograph</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:1; display:flex; align-items:flex-end; gap:8px">\n\t\t\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Connection\'].connectProvider()">Connect</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Connection\'].testConnection()">Test Connection</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- SQLite Config --\x3e\n\t\t\t<div id="configSQLite">\n\t\t\t\t<label for="sqliteFilePath">SQLite File Path</label>\n\t\t\t\t<input type="text" id="sqliteFilePath" placeholder="data/cloned.sqlite" value="data/cloned.sqlite">\n\t\t\t</div>\n\n\t\t\t\x3c!-- MySQL Config --\x3e\n\t\t\t<div id="configMySQL" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="mysqlServer">Server</label>\n\t\t\t\t\t\t<input type="text" id="mysqlServer" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="mysqlPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="mysqlPort" placeholder="3306" value="3306">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mysqlUser">User</label>\n\t\t\t\t\t\t<input type="text" id="mysqlUser" placeholder="root" value="root">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mysqlPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="mysqlPassword" placeholder="password">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="mysqlDatabase">Database</label>\n\t\t\t\t<input type="text" id="mysqlDatabase" placeholder="meadow_clone">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mysqlConnectionLimit">Connection Limit</label>\n\t\t\t\t\t\t<input type="number" id="mysqlConnectionLimit" placeholder="20" value="20">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- MSSQL Config --\x3e\n\t\t\t<div id="configMSSQL" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="mssqlServer">Server</label>\n\t\t\t\t\t\t<input type="text" id="mssqlServer" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="mssqlPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="mssqlPort" placeholder="1433" value="1433">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mssqlUser">User</label>\n\t\t\t\t\t\t<input type="text" id="mssqlUser" placeholder="sa" value="sa">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mssqlPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="mssqlPassword" placeholder="password">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="mssqlDatabase">Database</label>\n\t\t\t\t<input type="text" id="mssqlDatabase" placeholder="meadow_clone">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mssqlConnectionLimit">Connection Limit</label>\n\t\t\t\t\t\t<input type="number" id="mssqlConnectionLimit" placeholder="20" value="20">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- PostgreSQL Config --\x3e\n\t\t\t<div id="configPostgreSQL" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="postgresqlHost">Host</label>\n\t\t\t\t\t\t<input type="text" id="postgresqlHost" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="postgresqlPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="postgresqlPort" placeholder="5432" value="5432">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="postgresqlUser">User</label>\n\t\t\t\t\t\t<input type="text" id="postgresqlUser" placeholder="postgres" value="postgres">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="postgresqlPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="postgresqlPassword" placeholder="password">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="postgresqlDatabase">Database</label>\n\t\t\t\t<input type="text" id="postgresqlDatabase" placeholder="meadow_clone">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="postgresqlConnectionLimit">Connection Pool Limit</label>\n\t\t\t\t\t\t<input type="number" id="postgresqlConnectionLimit" placeholder="10" value="10">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- Solr Config --\x3e\n\t\t\t<div id="configSolr" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="solrHost">Host</label>\n\t\t\t\t\t\t<input type="text" id="solrHost" placeholder="localhost" value="localhost">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="solrPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="solrPort" placeholder="8983" value="8983">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="solrCore">Core</label>\n\t\t\t\t\t\t<input type="text" id="solrCore" placeholder="default" value="default">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="solrPath">Path</label>\n\t\t\t\t\t\t<input type="text" id="solrPath" placeholder="/solr" value="/solr">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="checkbox-row">\n\t\t\t\t\t<input type="checkbox" id="solrSecure">\n\t\t\t\t\t<label for="solrSecure">Use HTTPS</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- MongoDB Config --\x3e\n\t\t\t<div id="configMongoDB" style="display:none">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div style="flex:2">\n\t\t\t\t\t\t<label for="mongodbHost">Host</label>\n\t\t\t\t\t\t<input type="text" id="mongodbHost" placeholder="127.0.0.1" value="127.0.0.1">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style="flex:1">\n\t\t\t\t\t\t<label for="mongodbPort">Port</label>\n\t\t\t\t\t\t<input type="number" id="mongodbPort" placeholder="27017" value="27017">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mongodbUser">User</label>\n\t\t\t\t\t\t<input type="text" id="mongodbUser" placeholder="(optional)">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mongodbPassword">Password</label>\n\t\t\t\t\t\t<input type="password" id="mongodbPassword" placeholder="(optional)">\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<label for="mongodbDatabase">Database</label>\n\t\t\t\t<input type="text" id="mongodbDatabase" placeholder="test" value="test">\n\t\t\t\t<div class="inline-group">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<label for="mongodbConnectionLimit">Max Pool Size</label>\n\t\t\t\t\t\t<input type="number" id="mongodbConnectionLimit" placeholder="10" value="10">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t\x3c!-- RocksDB Config --\x3e\n\t\t\t<div id="configRocksDB" style="display:none">\n\t\t\t\t<label for="rocksdbFolder">RocksDB Folder Path</label>\n\t\t\t\t<input type="text" id="rocksdbFolder" placeholder="data/rocksdb" value="data/rocksdb">\n\t\t\t</div>\n\n\t\t\t\x3c!-- Bibliograph Config --\x3e\n\t\t\t<div id="configBibliograph" style="display:none">\n\t\t\t\t<label for="bibliographFolder">Storage Folder Path</label>\n\t\t\t\t<input type="text" id="bibliographFolder" placeholder="data/bibliograph" value="data/bibliograph">\n\t\t\t</div>\n\n\t\t\t<div id="connectionStatus"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Connection",TemplateHash:"DataCloner-Connection",DestinationAddress:"#DataCloner-Section-Connection"}]}},{"pict-view":13}],20:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}deploySchema(){let t=this.pict.views["DataCloner-Schema"].getSelectedTables();if(0===t.length)return this.pict.providers.DataCloner.setStatus("deployStatus","No tables selected. Fetch a schema and select tables first.","error"),void this.pict.providers.DataCloner.setSectionPhase(4,"error");this.pict.providers.DataCloner.setSectionPhase(4,"busy"),this.pict.providers.DataCloner.setStatus("deployStatus","Deploying "+t.length+" tables...","info");let e=this;this.pict.providers.DataCloner.api("POST","/clone/schema/deploy",{Tables:t}).then(function(i){i.Success?(e.pict.providers.DataCloner.setStatus("deployStatus",i.Message,"ok"),e.pict.providers.DataCloner.setSectionPhase(4,"ok"),e.pict.AppData.DataCloner.DeployedTables=i.TablesDeployed||t,e.pict.providers.DataCloner.saveDeployedTables(),e.pict.views["DataCloner-ViewData"].populateViewTableDropdown(),e.pict.providers.DataCloner.updateAllPreviews()):(e.pict.providers.DataCloner.setStatus("deployStatus","Deploy failed: "+(i.Error||"Unknown error"),"error"),e.pict.providers.DataCloner.setSectionPhase(4,"error"))}).catch(function(t){e.pict.providers.DataCloner.setStatus("deployStatus","Request failed: "+t.message,"error"),e.pict.providers.DataCloner.setSectionPhase(4,"error")})}resetDatabase(){if(!confirm("This will delete ALL data in the local SQLite database. Continue?"))return;this.pict.providers.DataCloner.setStatus("deployStatus","Resetting database...","info");let t=this;this.pict.providers.DataCloner.api("POST","/clone/reset").then(function(e){if(e.Success){t.pict.providers.DataCloner.setStatus("deployStatus",e.Message,"ok");let i=document.getElementById("syncProgress");i&&(i.innerHTML="")}else t.pict.providers.DataCloner.setStatus("deployStatus","Reset failed: "+(e.Error||"Unknown error"),"error")}).catch(function(e){t.pict.providers.DataCloner.setStatus("deployStatus","Request failed: "+e.message,"error")})}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Deploy",DefaultRenderable:"DataCloner-Deploy",DefaultDestinationAddress:"#DataCloner-Section-Deploy",Templates:[{Hash:"DataCloner-Deploy",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">4</div>\n\t<div class="accordion-card" id="section4" data-section="4">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section4\')">\n\t\t\t<div class="accordion-title">Deploy Schema</div>\n\t\t\t<span class="accordion-phase" id="phase4"></span>\n\t\t\t<div class="accordion-preview" id="preview4">Create selected tables in the local database</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Deploy\'].deploySchema()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto4"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<p style="font-size:0.9em; color:#666; margin-bottom:10px">Creates the selected tables in the local database and sets up CRUD endpoints (e.g. GET /1.0/Documents).</p>\n\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Deploy\'].deploySchema()">Deploy Selected Tables</button>\n\t\t\t<button class="danger" onclick="pict.views[\'DataCloner-Deploy\'].resetDatabase()">Reset Database</button>\n\t\t\t<div id="deployStatus"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Deploy",TemplateHash:"DataCloner-Deploy",DestinationAddress:"#DataCloner-Section-Deploy"}]}},{"pict-view":13}],21:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}buildConfigObject(){let t=document.getElementById("connProvider").value,e={};e.LocalDatabase={Provider:t,Config:{}};let i=e.LocalDatabase.Config;"SQLite"===t?i.SQLiteFilePath=document.getElementById("sqliteFilePath").value.trim()||"data/cloned.sqlite":"MySQL"===t?(i.host=document.getElementById("mysqlServer").value.trim()||"127.0.0.1",i.port=parseInt(document.getElementById("mysqlPort").value,10)||3306,i.user=document.getElementById("mysqlUser").value.trim()||"root",i.password=document.getElementById("mysqlPassword").value,i.database=document.getElementById("mysqlDatabase").value.trim(),i.connectionLimit=parseInt(document.getElementById("mysqlConnectionLimit").value,10)||20):"MSSQL"===t?(i.server=document.getElementById("mssqlServer").value.trim()||"127.0.0.1",i.port=parseInt(document.getElementById("mssqlPort").value,10)||1433,i.user=document.getElementById("mssqlUser").value.trim()||"sa",i.password=document.getElementById("mssqlPassword").value,i.database=document.getElementById("mssqlDatabase").value.trim(),i.connectionLimit=parseInt(document.getElementById("mssqlConnectionLimit").value,10)||20):"PostgreSQL"===t&&(i.host=document.getElementById("postgresqlHost").value.trim()||"127.0.0.1",i.port=parseInt(document.getElementById("postgresqlPort").value,10)||5432,i.user=document.getElementById("postgresqlUser").value.trim()||"postgres",i.password=document.getElementById("postgresqlPassword").value,i.database=document.getElementById("postgresqlDatabase").value.trim(),i.max=parseInt(document.getElementById("postgresqlConnectionLimit").value,10)||10),e.RemoteSession={};let n=document.getElementById("serverURL").value.trim();n&&(e.RemoteSession.ServerURL=n+"/1.0/");let o=document.getElementById("authMethod").value.trim();o&&(e.RemoteSession.AuthenticationMethod=o);let s=document.getElementById("authURI").value.trim();s&&(e.RemoteSession.AuthenticationURITemplate=s);let a=document.getElementById("checkURI").value.trim();a&&(e.RemoteSession.CheckSessionURITemplate=a);let r=document.getElementById("cookieName").value.trim();r&&(e.RemoteSession.CookieName=r);let l=document.getElementById("cookieValueAddr").value.trim();l&&(e.RemoteSession.CookieValueAddress=l);let c=document.getElementById("cookieValueTemplate").value.trim();c&&(e.RemoteSession.CookieValueTemplate=c);let d=document.getElementById("loginMarker").value.trim();d&&(e.RemoteSession.CheckSessionLoginMarker=d);let p=document.getElementById("userName").value.trim(),h=document.getElementById("password").value;(p||h)&&(e.Credentials={},p&&(e.Credentials.UserName=p),h&&(e.Credentials.Password=h));let u=document.getElementById("schemaURL").value.trim();u&&(e.SchemaURL=u);let g=this.pict.views["DataCloner-Schema"].getSelectedTables();g.length>0&&(e.Tables=g),e.Sync={},e.Sync.Mode=document.querySelector('input[name="syncMode"]:checked').value,e.Sync.PageSize=parseInt(document.getElementById("pageSize").value,10)||100,e.Sync.SyncDeletedRecords=document.getElementById("syncDeletedRecords").checked;let m=parseInt(document.getElementById("dateTimePrecisionMS").value,10);isNaN(m)||1e3===m||(e.Sync.DateTimePrecisionMS=m);let f=parseInt(document.getElementById("syncMaxRecords").value,10);return f>0&&(e.Sync.MaxRecords=f),document.getElementById("syncAdvancedIDPagination").checked&&(e.Sync.UseAdvancedIDPagination=!0),e}buildMeadowIntegrationConfig(){let t=document.getElementById("connProvider").value,e={},i=document.getElementById("serverURL").value.trim();e.Source={ServerURL:i?i+"/1.0/":"https://localhost:8080/1.0/"},e.Source.UserID=!1,e.Source.Password=!1,e.Destination={},"MySQL"===t?(e.Destination.Provider="MySQL",e.Destination.MySQL={},e.Destination.MySQL.server=document.getElementById("mysqlServer").value.trim()||"127.0.0.1",e.Destination.MySQL.port=parseInt(document.getElementById("mysqlPort").value,10)||3306,e.Destination.MySQL.user=document.getElementById("mysqlUser").value.trim()||"root",e.Destination.MySQL.password=document.getElementById("mysqlPassword").value||"",e.Destination.MySQL.database=document.getElementById("mysqlDatabase").value.trim()||"meadow",e.Destination.MySQL.connectionLimit=parseInt(document.getElementById("mysqlConnectionLimit").value,10)||20):"MSSQL"===t?(e.Destination.Provider="MSSQL",e.Destination.MSSQL={},e.Destination.MSSQL.server=document.getElementById("mssqlServer").value.trim()||"127.0.0.1",e.Destination.MSSQL.port=parseInt(document.getElementById("mssqlPort").value,10)||1433,e.Destination.MSSQL.user=document.getElementById("mssqlUser").value.trim()||"sa",e.Destination.MSSQL.password=document.getElementById("mssqlPassword").value||"",e.Destination.MSSQL.database=document.getElementById("mssqlDatabase").value.trim()||"meadow",e.Destination.MSSQL.ConnectionPoolLimit=parseInt(document.getElementById("mssqlConnectionLimit").value,10)||20):(e.Destination.Provider="MySQL",e.Destination.MySQL={server:"127.0.0.1",port:3306,user:"root",password:"",database:"meadow",connectionLimit:20});let n=document.getElementById("schemaURL").value.trim();n?e.SchemaURL=n:e.SchemaPath="./schema/Model-Extended.json",e.Sync={},e.Sync.DefaultSyncMode=document.querySelector('input[name="syncMode"]:checked').value,e.Sync.PageSize=parseInt(document.getElementById("pageSize").value,10)||100;let o=parseInt(document.getElementById("dateTimePrecisionMS").value,10);isNaN(o)||(e.Sync.DateTimePrecisionMS=o);let s=this.pict.views["DataCloner-Schema"].getSelectedTables();e.Sync.SyncEntityList=s.length>0?s:[],e.Sync.SyncEntityOptions={},document.getElementById("syncAdvancedIDPagination").checked&&(e.Sync.UseAdvancedIDPagination=!0),e.SessionManager={Sessions:{}};let a={Type:"Cookie"},r=document.getElementById("authMethod").value.trim()||"get";a.AuthenticationMethod=r;let l=document.getElementById("authURI").value.trim();l?"/"===l.charAt(0)?a.AuthenticationURITemplate=(i||"")+l:a.AuthenticationURITemplate=l:i&&("post"===r?(a.AuthenticationURITemplate=i+"/1.0/Authenticate",a.AuthenticationRequestBody={UserName:"{~D:Record.UserName~}",Password:"{~D:Record.Password~}"}):a.AuthenticationURITemplate=i+"/1.0/Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}");let c=document.getElementById("checkURI").value.trim();c?a.CheckSessionURITemplate="/"===c.charAt(0)?(i||"")+c:c:i&&(a.CheckSessionURITemplate=i+"/1.0/CheckSession");let d=document.getElementById("loginMarker").value.trim();if(a.CheckSessionLoginMarkerType="boolean",a.CheckSessionLoginMarker=d||"LoggedIn",i)try{let t=new URL(i);a.DomainMatch=t.host}catch(t){a.DomainMatch=i}let p=document.getElementById("cookieName").value.trim();a.CookieName=p||"SessionID";let h=document.getElementById("cookieValueAddr").value.trim();h&&(a.CookieValueAddress=h);let u=document.getElementById("cookieValueTemplate").value.trim();u&&(a.CookieValueTemplate=u);let g=document.getElementById("userName").value.trim(),m=document.getElementById("password").value;return a.Credentials={},g&&(a.Credentials.UserName=g),m&&(a.Credentials.Password=m),e.SessionManager.Sessions.SourceAPI=a,e}generateConfig(){let t=this.buildConfigObject(),e=JSON.stringify(t,null,"\t"),i=document.getElementById("configOutput");i.value=e,i.style.display="";let n=document.getElementById("syncLogFile").checked?" --log":"",o="",s=parseInt(document.getElementById("syncMaxRecords").value,10);s>0&&(o=" --max "+s);let a=document.getElementById("cliCommand");a.style.display="",a.querySelector("div").textContent="npx retold-data-service-clone --config clone-config.json --run"+n+o;let r=document.getElementById("cliOneShot");r.style.display="";let l="npx retold-data-service-clone --config-json '"+JSON.stringify(t).replace(/'/g,"'\\''")+"' --run"+n+o;r.querySelector("div").textContent=l;let c=this.buildMeadowIntegrationConfig(),d=JSON.stringify(c,null,"\t");document.getElementById("mdwintExport").style.display="",document.getElementById("mdwintConfigOutput").value=d;document.getElementById("mdwintCLICommand").querySelector("div").textContent="mdwint clone --schema_path ./schema/Model-Extended.json";let p=document.getElementById("connProvider").value;"MySQL"!==p&&"MSSQL"!==p?this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","Note: mdwint clone only supports MySQL and MSSQL destinations. The config defaults to MySQL; update the Destination section for your target database.","warn"):this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","",""),this.pict.providers.DataCloner.setStatus("configExportStatus","Config generated. Save as clone-config.json or copy the one-liner below.","ok")}copyConfig(){let t=document.getElementById("configOutput");if(!t.value)return void this.pict.providers.DataCloner.setStatus("configExportStatus","Generate a config first.","warn");let e=this;navigator.clipboard.writeText(t.value).then(function(){e.pict.providers.DataCloner.setStatus("configExportStatus","Config copied to clipboard.","ok")})}copyCLI(){let t=document.getElementById("cliCommand").querySelector("div").textContent,e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("configExportStatus","CLI command copied to clipboard.","ok")})}copyOneShot(){let t=document.getElementById("cliOneShot").querySelector("div").textContent,e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("configExportStatus","One-liner copied to clipboard.","ok")})}downloadConfig(){let t=document.getElementById("configOutput");t.value||this.generateConfig();let e=new Blob([t.value],{type:"application/json"}),i=document.createElement("a");i.href=URL.createObjectURL(e),i.download="clone-config.json",i.click(),URL.revokeObjectURL(i.href),this.pict.providers.DataCloner.setStatus("configExportStatus","Config downloaded as clone-config.json.","ok")}copyMdwintConfig(){let t=document.getElementById("mdwintConfigOutput");if(!t.value)return void this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","Generate a config first.","warn");let e=this;navigator.clipboard.writeText(t.value).then(function(){e.pict.providers.DataCloner.setStatus("mdwintConfigStatus",".meadow.config.json copied to clipboard.","ok")})}copyMdwintCLI(){let t=document.getElementById("mdwintCLICommand").querySelector("div").textContent,e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("mdwintConfigStatus","mdwint CLI command copied to clipboard.","ok")})}downloadMdwintConfig(){let t=document.getElementById("mdwintConfigOutput");t.value||this.generateConfig();let e=new Blob([t.value],{type:"application/json"}),i=document.createElement("a");i.href=URL.createObjectURL(e),i.download=".meadow.config.json",i.click(),URL.revokeObjectURL(i.href),this.pict.providers.DataCloner.setStatus("mdwintConfigStatus","Config downloaded as .meadow.config.json.","ok")}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Export",DefaultRenderable:"DataCloner-Export",DefaultDestinationAddress:"#DataCloner-Section-Export",Templates:[{Hash:"DataCloner-Export",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">6</div>\n\t<div class="accordion-card" id="section6" data-section="6">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section6\')">\n\t\t\t<div class="accordion-title">Export Configuration</div>\n\t\t\t<div class="accordion-preview" id="preview6">Generate JSON config for headless cloning</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<p style="font-size:0.9em; color:#666; margin-bottom:10px">Generate a JSON config file from your current settings. Use it to run headless clones from the command line.</p>\n\t\t\t<div style="display:flex; gap:8px; margin-bottom:10px">\n\t\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Export\'].generateConfig()">Generate Config</button>\n\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].copyConfig()">Copy to Clipboard</button>\n\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].downloadConfig()">Download JSON</button>\n\t\t\t</div>\n\t\t\t<div id="configExportStatus"></div>\n\t\t\t<div id="cliCommand" style="display:none; margin-bottom:10px">\n\t\t\t\t<label style="margin-bottom:4px">CLI Command <span style="color:#888; font-weight:normal">(with config file)</span></label>\n\t\t\t\t<div style="background:#1a1a1a; color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer" onclick="pict.views[\'DataCloner-Export\'].copyCLI()" title="Click to copy"></div>\n\t\t\t</div>\n\t\t\t<div id="cliOneShot" style="display:none; margin-bottom:10px">\n\t\t\t\t<label style="margin-bottom:4px">One-liner <span style="color:#888; font-weight:normal">(no config file needed)</span></label>\n\t\t\t\t<div style="background:#1a1a1a; color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer; white-space:pre-wrap" onclick="pict.views[\'DataCloner-Export\'].copyOneShot()" title="Click to copy"></div>\n\t\t\t</div>\n\t\t\t<textarea id="configOutput" style="display:none; width:100%; min-height:300px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid #ccc; border-radius:4px; background:#fafafa; tab-size:4; resize:vertical" readonly></textarea>\n\n\t\t\t<div id="mdwintExport" style="display:none; margin-top:16px; padding-top:16px; border-top:1px solid #eee">\n\t\t\t\t<h3 style="margin:0 0 8px; font-size:1em">meadow-integration CLI <span style="color:#888; font-weight:normal; font-size:0.85em">(mdwint clone)</span></h3>\n\t\t\t\t<p style="font-size:0.85em; color:#666; margin-bottom:8px">Save as <code>.meadow.config.json</code> in your project root, then run the command below. Requires a local Meadow extended schema JSON file.</p>\n\t\t\t\t<div style="display:flex; gap:8px; margin-bottom:10px">\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].copyMdwintConfig()">Copy Config</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Export\'].downloadMdwintConfig()">Download .meadow.config.json</button>\n\t\t\t\t</div>\n\t\t\t\t<div id="mdwintCLICommand" style="margin-bottom:10px">\n\t\t\t\t\t<label style="margin-bottom:4px">CLI Command</label>\n\t\t\t\t\t<div style="background:#1a1a1a; color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer" onclick="pict.views[\'DataCloner-Export\'].copyMdwintCLI()" title="Click to copy"></div>\n\t\t\t\t</div>\n\t\t\t\t<div id="mdwintConfigStatus"></div>\n\t\t\t\t<textarea id="mdwintConfigOutput" style="width:100%; min-height:250px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid #ccc; border-radius:4px; background:#fafafa; tab-size:4; resize:vertical" readonly></textarea>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Export",TemplateHash:"DataCloner-Export",DestinationAddress:"#DataCloner-Section-Export"}]}},{"pict-view":13}],22:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}onAfterRender(){this.pict.views["DataCloner-Connection"].render(),this.pict.views["DataCloner-Session"].render(),this.pict.views["DataCloner-Schema"].render(),this.pict.views["DataCloner-Deploy"].render(),this.pict.views["DataCloner-Sync"].render(),this.pict.views["DataCloner-Export"].render(),this.pict.views["DataCloner-ViewData"].render(),this.pict.CSSMap.injectCSS()}toggleSection(t){let e=document.getElementById(t);e&&e.classList.toggle("open")}expandAllSections(){let t=document.querySelectorAll(".accordion-card");for(let e=0;e<t.length;e++)t[e].classList.add("open")}collapseAllSections(){let t=document.querySelectorAll(".accordion-card");for(let e=0;e<t.length;e++)t[e].classList.remove("open")}toggleStatusDetail(){let t=document.getElementById("liveStatusDetail"),e=document.getElementById("liveStatusMeta"),i=document.getElementById("liveStatusMessage"),n=document.getElementById("liveStatusToggle"),o=document.getElementById("liveStatusBar");t&&("none"!==t.style.display?(t.style.display="none",e.style.display="",i.style.display="",n.innerHTML="▼",o.classList.remove("expanded"),this.pict.providers.DataCloner.onStatusDetailCollapsed()):(t.style.display="",e.style.display="none",i.style.display="none",n.innerHTML="▲",o.classList.add("expanded"),this.pict.providers.DataCloner.onStatusDetailExpanded()))}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Layout",DefaultRenderable:"DataCloner-Layout",DefaultDestinationAddress:"#DataCloner-Application-Container",CSS:'\n* { box-sizing: border-box; margin: 0; padding: 0; }\nbody { font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif; background: #f5f5f5; color: #333; padding: 20px; }\nh1 { margin-bottom: 20px; color: #1a1a1a; }\nh2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px solid #ddd; padding-bottom: 6px; }\n\n.section { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }\n\n/* Accordion layout */\n.accordion-row { display: flex; gap: 0; margin-bottom: 16px; align-items: stretch; }\n.accordion-number {\n\tflex: 0 0 48px; display: flex; align-items: flex-start; justify-content: center;\n\tpadding-top: 16px; font-size: 1.6em; font-weight: 700; color: #4a90d9;\n\tuser-select: none;\n}\n.accordion-card {\n\tflex: 1; background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n\toverflow: hidden; min-width: 0;\n}\n.accordion-header {\n\tdisplay: flex; align-items: center; padding: 14px 20px; cursor: pointer;\n\tuser-select: none; gap: 12px; transition: background 0.15s; line-height: 1.4;\n}\n.accordion-header:hover { background: #fafafa; }\n.accordion-title { font-weight: 600; color: #333; font-size: 1.05em; white-space: nowrap; }\n.accordion-preview { flex: 1; font-style: italic; color: #888; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.accordion-toggle {\n\tflex: 0 0 20px; display: flex; align-items: center; justify-content: center;\n\tborder-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: #888;\n}\n.accordion-header:hover .accordion-toggle { background: #eee; color: #555; }\n.accordion-card.open .accordion-toggle { transform: rotate(180deg); }\n.accordion-body { padding: 0 20px 20px; display: none; }\n.accordion-card.open .accordion-body { display: block; }\n.accordion-card.open .accordion-header { border-bottom: 1px solid #eee; }\n.accordion-card.open .accordion-preview { display: none; }\n\n/* Action controls (go link + auto checkbox) */\n.accordion-actions { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }\n.accordion-card.open .accordion-actions { display: none; }\n.accordion-go {\n\tfont-size: 0.82em; color: #4a90d9; cursor: pointer; text-decoration: none;\n\tfont-weight: 500; white-space: nowrap; padding: 2px 6px; border-radius: 3px;\n\ttransition: background 0.15s;\n}\n.accordion-go:hover { background: #e8f0fe; text-decoration: underline; }\n.accordion-auto {\n\tfont-size: 0.82em; color: #999; white-space: nowrap; cursor: pointer;\n}\n.accordion-auto .auto-label { display: none; }\n.accordion-auto:hover .auto-label { display: inline; }\n.accordion-auto input[type="checkbox"] { width: auto; margin: 0; cursor: pointer; vertical-align: middle; position: relative; top: 0px; opacity: 0.75; transition: opacity 0.15s; }\n.accordion-auto:hover input[type="checkbox"] { opacity: 1; }\n.accordion-auto:hover { color: #666; }\n\n/* Phase status indicator */\n.accordion-phase {\n\tflex: 0 0 auto; display: none; align-items: center; justify-content: center;\n\tfont-size: 0.85em; line-height: 1;\n}\n.accordion-phase.visible { display: flex; }\n.accordion-phase-ok { color: #28a745; }\n.accordion-phase-error { color: #dc3545; }\n.accordion-phase-busy { color: #28a745; }\n.accordion-phase-busy .phase-spinner {\n\tdisplay: inline-block; width: 14px; height: 14px;\n\tborder: 2px solid #28a745; border-top-color: transparent; border-radius: 50%;\n\tanimation: phase-spin 0.8s linear infinite; vertical-align: middle;\n}\n@keyframes phase-spin {\n\tto { transform: rotate(360deg); }\n}\n\n.accordion-controls {\n\tdisplay: flex; gap: 8px; margin-bottom: 12px; justify-content: flex-end;\n}\n.accordion-controls button {\n\tpadding: 4px 10px; font-size: 0.82em; font-weight: 500; background: none;\n\tborder: 1px solid #ccc; border-radius: 4px; color: #666; cursor: pointer; margin: 0;\n}\n.accordion-controls button:hover { background: #f0f0f0; border-color: #aaa; color: #333; }\n\nlabel { display: block; font-weight: 600; margin-bottom: 4px; font-size: 0.9em; }\ninput[type="text"], input[type="password"], input[type="number"] {\n\twidth: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;\n\tfont-size: 0.95em; margin-bottom: 10px;\n}\ninput[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {\n\toutline: none; border-color: #4a90d9;\n}\n\nbutton {\n\tpadding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;\n\tfont-size: 0.9em; font-weight: 600; margin-right: 8px; margin-bottom: 8px;\n}\nbutton.primary { background: #4a90d9; color: #fff; }\nbutton.primary:hover { background: #357abd; }\nbutton.secondary { background: #6c757d; color: #fff; }\nbutton.secondary:hover { background: #5a6268; }\nbutton.danger { background: #dc3545; color: #fff; }\nbutton.danger:hover { background: #c82333; }\nbutton.success { background: #28a745; color: #fff; }\nbutton.success:hover { background: #218838; }\nbutton:disabled { opacity: 0.5; cursor: not-allowed; }\n\n.status { padding: 8px 12px; border-radius: 4px; margin-top: 10px; font-size: 0.9em; }\n.status.ok { background: #d4edda; color: #155724; }\n.status.error { background: #f8d7da; color: #721c24; }\n.status.info { background: #d1ecf1; color: #0c5460; }\n.status.warn { background: #fff3cd; color: #856404; }\n\n.inline-group { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 10px; }\n.inline-group > div { flex: 1; }\n\na { color: #4a90d9; }\n\nselect { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }\n\n.checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }\n.checkbox-row input[type="checkbox"] { width: auto; margin: 0; }\n.checkbox-row label { display: inline; margin: 0; font-weight: normal; cursor: pointer; }\n\n/* Live Status Bar */\n.live-status-bar {\n\tbackground: #fff; border-radius: 8px; margin-bottom: 16px;\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.1);\n\tposition: sticky; top: 0; z-index: 100; border-left: 4px solid #6c757d;\n}\n.live-status-bar.phase-idle { border-left-color: #6c757d; }\n.live-status-bar.phase-disconnected { border-left-color: #dc3545; }\n.live-status-bar.phase-ready { border-left-color: #4a90d9; }\n.live-status-bar.phase-syncing { border-left-color: #28a745; }\n.live-status-bar.phase-stopping { border-left-color: #ffc107; }\n.live-status-bar.phase-complete { border-left-color: #28a745; }\n\n.live-status-dot {\n\twidth: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;\n\tbackground: #6c757d;\n}\n.live-status-bar.phase-idle .live-status-dot { background: #6c757d; }\n.live-status-bar.phase-disconnected .live-status-dot { background: #dc3545; }\n.live-status-bar.phase-ready .live-status-dot { background: #4a90d9; }\n.live-status-bar.phase-syncing .live-status-dot {\n\tbackground: #28a745;\n\tanimation: live-pulse 1.5s ease-in-out infinite;\n}\n.live-status-bar.phase-stopping .live-status-dot {\n\tbackground: #ffc107;\n\tanimation: live-pulse 0.8s ease-in-out infinite;\n}\n.live-status-bar.phase-complete .live-status-dot { background: #28a745; }\n\n@keyframes live-pulse {\n\t0%, 100% { opacity: 1; transform: scale(1); }\n\t50% { opacity: 0.4; transform: scale(0.8); }\n}\n\n.live-status-message { flex: 1; font-size: 0.92em; color: #333; line-height: 1.4; }\n\n.live-status-meta {\n\tdisplay: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: #666;\n}\n.live-status-meta-item { white-space: nowrap; }\n.live-status-meta-item strong { color: #333; }\n\n.live-status-progress-bar {\n\theight: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden;\n\tposition: absolute; bottom: 0; left: 0; right: 0;\n}\n.live-status-progress-fill {\n\theight: 100%; background: #28a745; transition: width 1s ease;\n}\n/* Expandable status bar */\n.live-status-header {\n\tdisplay: flex; align-items: center; gap: 14px; cursor: pointer;\n\tpadding: 14px 20px; user-select: none;\n}\n.live-status-bar.expanded .live-status-header {\n\tborder-bottom: 1px solid #e9ecef; padding-bottom: 10px;\n}\n.live-status-expand-toggle {\n\tflex: 0 0 20px; display: flex; align-items: center; justify-content: center;\n\tfont-size: 0.7em; color: #888; transition: transform 0.25s;\n}\n.live-status-bar.expanded .live-status-expand-toggle { transform: rotate(180deg); }\n\n.live-status-detail {\n\tpadding: 12px 20px 16px; max-height: 60vh; overflow-y: auto;\n}\n\n/* Status Detail Sections */\n.status-detail-section { margin-bottom: 14px; }\n.status-detail-section:last-child { margin-bottom: 0; }\n.status-detail-section-title {\n\tfont-size: 0.85em; font-weight: 600; color: #555; text-transform: uppercase;\n\tletter-spacing: 0.5px; margin-bottom: 8px; padding-bottom: 4px;\n\tborder-bottom: 1px solid #eee;\n}\n\n/* Running Operations */\n.running-op-row {\n\tdisplay: flex; align-items: center; gap: 12px; padding: 6px 0;\n\tfont-size: 0.9em;\n}\n.running-op-name { font-weight: 600; min-width: 180px; }\n.running-op-bar {\n\tflex: 1; height: 8px; background: #e9ecef; border-radius: 4px; overflow: hidden;\n\tmin-width: 120px;\n}\n.running-op-bar-fill { height: 100%; background: #4a90d9; transition: width 0.5s ease; }\n.running-op-count { font-size: 0.85em; color: #666; white-space: nowrap; }\n.running-op-pending { color: #888; font-size: 0.85em; font-style: italic; padding: 4px 0; }\n\n/* Completed Operations */\n.completed-op-row { padding: 8px 0; border-bottom: 1px solid #f0f0f0; }\n.completed-op-row:last-child { border-bottom: none; }\n.completed-op-header {\n\tdisplay: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px;\n}\n.completed-op-name { font-weight: 600; }\n.completed-op-stats { color: #666; font-size: 0.85em; }\n.completed-op-checkmark { color: #28a745; }\n\n/* Ratio Bar */\n.ratio-bar-container {\n\tdisplay: flex; height: 10px; border-radius: 5px; overflow: hidden;\n\tbackground: #e9ecef; margin: 4px 0;\n}\n.ratio-bar-segment { height: 100%; transition: width 0.5s ease; }\n.ratio-bar-segment.unchanged { background: #6c757d; }\n.ratio-bar-segment.new-records { background: #28a745; }\n.ratio-bar-segment.updated { background: #4a90d9; }\n.ratio-bar-segment.deleted { background: #dc3545; }\n.ratio-bar-legend {\n\tdisplay: flex; gap: 12px; font-size: 0.75em; color: #666; margin-top: 2px; flex-wrap: wrap;\n}\n.ratio-bar-legend-item { display: flex; align-items: center; gap: 4px; }\n.ratio-bar-legend-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }\n.ratio-bar-legend-dot.unchanged-dot { background: #6c757d; }\n.ratio-bar-legend-dot.new-dot { background: #28a745; }\n.ratio-bar-legend-dot.updated-dot { background: #4a90d9; }\n.ratio-bar-legend-dot.deleted-dot { background: #dc3545; }\n\n/* Error Operations */\n.error-op-row { padding: 6px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.9em; }\n.error-op-row:last-child { border-bottom: none; }\n.error-op-header { display: flex; align-items: center; gap: 8px; }\n.error-op-name { font-weight: 600; color: #dc3545; }\n.error-op-status { font-size: 0.82em; color: #dc3545; }\n.error-op-message { font-size: 0.82em; color: #888; margin-top: 2px; padding-left: 18px; }\n.error-op-log-entries {\n\tfont-size: 0.78em; color: #888; margin-top: 4px; padding-left: 18px;\n\tfont-family: monospace; max-height: 80px; overflow-y: auto;\n}\n\n/* Pre-count Table */\n.precount-table {\n\twidth: 100%; border-collapse: collapse; font-size: 0.88em;\n}\n.precount-table thead th {\n\ttext-align: left; font-weight: 600; color: #555; font-size: 0.85em;\n\ttext-transform: uppercase; letter-spacing: 0.3px;\n\tpadding: 4px 8px 6px; border-bottom: 2px solid #e9ecef;\n}\n.precount-table tbody td {\n\tpadding: 4px 8px; border-bottom: 1px solid #f0f0f0;\n}\n.precount-table tbody tr:last-child td { border-bottom: 1px solid #e9ecef; }\n.precount-table tfoot td {\n\tpadding: 6px 8px 2px; font-size: 0.95em;\n}\n.precount-error td { color: #dc3545; }\n.precount-pending {\n\tcolor: #888; font-size: 0.85em; font-style: italic; padding: 8px 0 2px;\n\tdisplay: flex; align-items: center; gap: 6px;\n}\n.precount-spinner {\n\tdisplay: inline-block; width: 12px; height: 12px;\n\tborder: 2px solid #ddd; border-top-color: #4a90d9;\n\tborder-radius: 50%; animation: precount-spin 0.8s linear infinite;\n}\n@keyframes precount-spin { to { transform: rotate(360deg); } }\n',Templates:[{Hash:"DataCloner-Layout",Template:'\n<h1>Retold Data Cloner</h1>\n\n\x3c!-- Live Status Bar (Expandable) --\x3e\n<div id="liveStatusBar" class="live-status-bar phase-idle" style="position:relative">\n\t<div class="live-status-header" onclick="pict.views[\'DataCloner-Layout\'].toggleStatusDetail()">\n\t\t<div class="live-status-dot"></div>\n\t\t<div class="live-status-message" id="liveStatusMessage">Idle</div>\n\t\t<div class="live-status-meta" id="liveStatusMeta"></div>\n\t\t<div class="live-status-expand-toggle" id="liveStatusToggle">▼</div>\n\t</div>\n\t<div class="live-status-detail" id="liveStatusDetail" style="display:none">\n\t\t<div id="DataCloner-Throughput-Histogram"></div>\n\t\t<div id="DataCloner-StatusDetail-Container"></div>\n\t</div>\n\t<div class="live-status-progress-bar"><div class="live-status-progress-fill" id="liveStatusProgressFill" style="width:0%"></div></div>\n</div>\n\n\x3c!-- Expand / Collapse All --\x3e\n<div class="accordion-controls">\n\t<button onclick="pict.views[\'DataCloner-Layout\'].expandAllSections()">Expand All</button>\n\t<button onclick="pict.views[\'DataCloner-Layout\'].collapseAllSections()">Collapse All</button>\n</div>\n\n\x3c!-- Section containers --\x3e\n<div id="DataCloner-Section-Connection"></div>\n<div id="DataCloner-Section-Session"></div>\n<div id="DataCloner-Section-Schema"></div>\n<div id="DataCloner-Section-Deploy"></div>\n<div id="DataCloner-Section-Sync"></div>\n<div id="DataCloner-Section-Export"></div>\n<div id="DataCloner-Section-ViewData"></div>\n'}],Renderables:[{RenderableHash:"DataCloner-Layout",TemplateHash:"DataCloner-Layout",DestinationAddress:"#DataCloner-Application-Container"}]}},{"pict-view":13}],23:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}fetchSchema(){let t=document.getElementById("schemaURL").value.trim(),e={};t&&(e.SchemaURL=t),this.pict.providers.DataCloner.setSectionPhase(3,"busy"),this.pict.providers.DataCloner.setStatus("schemaStatus","Fetching schema...","info"),this.pict.providers.DataCloner.api("POST","/clone/schema/fetch",e).then(t=>{t.Success?(this.pict.AppData.DataCloner.FetchedTables=t.Tables||[],this.pict.providers.DataCloner.setStatus("schemaStatus","Fetched "+t.TableCount+" tables from "+t.SchemaURL,"ok"),this.pict.providers.DataCloner.setSectionPhase(3,"ok"),this.renderTableList()):(this.pict.providers.DataCloner.setStatus("schemaStatus","Fetch failed: "+(t.Error||"Unknown error"),"error"),this.pict.providers.DataCloner.setSectionPhase(3,"error"))}).catch(t=>{this.pict.providers.DataCloner.setStatus("schemaStatus","Request failed: "+t.message,"error"),this.pict.providers.DataCloner.setSectionPhase(3,"error")})}loadSavedSelections(){try{let t=localStorage.getItem("dataCloner_selectedTables");if(t)return JSON.parse(t)}catch(t){}return null}saveSelections(){let t=this.getSelectedTables();localStorage.setItem("dataCloner_selectedTables",JSON.stringify(t)),this.updateSelectionCount(),this.pict.providers.DataCloner.updateAllPreviews()}updateSelectionCount(){let t=this.pict.AppData.DataCloner.FetchedTables||[],e=this.getSelectedTables().length,i=document.getElementById("tableSelectionCount");i&&(i.textContent=e+" / "+t.length+" selected")}renderTableList(){let t=this.pict.AppData.DataCloner.FetchedTables||[],e=document.getElementById("tableList");e.innerHTML="";let i=this.loadSavedSelections(),n=null;if(i){n={};for(let t=0;t<i.length;t++)n[i[t]]=!0}for(let i=0;i<t.length;i++){let o=t[i],s=document.createElement("div");s.className="table-item",s.setAttribute("data-table",o.toLowerCase());let a=document.createElement("input");a.type="checkbox",a.id="tbl_"+o,a.value=o,a.checked=!!n&&!0===n[o],a.addEventListener("change",()=>{this.saveSelections()});let r=document.createElement("label");r.htmlFor="tbl_"+o,r.textContent=o,s.appendChild(a),s.appendChild(r),e.appendChild(s)}document.getElementById("tableSelection").style.display=t.length>0?"block":"none",document.getElementById("tableFilter").value="",this.updateSelectionCount()}filterTableList(){let t=document.getElementById("tableFilter").value.toLowerCase().trim(),e=document.getElementById("tableList").children;for(let i=0;i<e.length;i++){let n=e[i].getAttribute("data-table")||"";e[i].style.display=!t||n.indexOf(t)>=0?"":"none"}}selectAllTables(t){let e=this.pict.AppData.DataCloner.FetchedTables||[],i=document.getElementById("tableFilter").value.toLowerCase().trim();for(let n=0;n<e.length;n++){let o=e[n];if(i&&o.toLowerCase().indexOf(i)<0)continue;let s=document.getElementById("tbl_"+o);s&&(s.checked=t)}this.saveSelections()}getSelectedTables(){let t=this.pict.AppData.DataCloner.FetchedTables||[],e=[];for(let i=0;i<t.length;i++){let n=document.getElementById("tbl_"+t[i]);n&&n.checked&&e.push(t[i])}return e}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Schema",DefaultRenderable:"DataCloner-Schema",DefaultDestinationAddress:"#DataCloner-Section-Schema",CSS:'\n.table-list { max-height: 300px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px; padding: 8px; margin: 10px 0; }\n.table-item { padding: 4px 8px; display: flex; align-items: center; }\n.table-item:hover { background: #f0f0f0; }\n.table-item input[type="checkbox"] { margin-right: 8px; width: auto; }\n.table-item label { display: inline; font-weight: normal; margin-bottom: 0; cursor: pointer; }\n',Templates:[{Hash:"DataCloner-Schema",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">3</div>\n\t<div class="accordion-card" id="section3" data-section="3">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section3\')">\n\t\t\t<div class="accordion-title">Remote Schema</div>\n\t\t\t<span class="accordion-phase" id="phase3"></span>\n\t\t\t<div class="accordion-preview" id="preview3">Fetch and select tables from the remote server</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Schema\'].fetchSchema()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto3"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<label for="schemaURL">Schema URL (leave blank for default: /1.0/Retold/Models)</label>\n\t\t\t<input type="text" id="schemaURL" placeholder="http://remote-server:8086/1.0/Retold/Models">\n\n\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Schema\'].fetchSchema()">Fetch Schema</button>\n\t\t\t<div id="schemaStatus"></div>\n\n\t\t\t<div id="tableSelection" style="display:none">\n\t\t\t\t<h3 style="margin:12px 0 8px; font-size:1em;">Select Tables</h3>\n\t\t\t\t<div style="display:flex; gap:8px; align-items:center; margin-bottom:8px">\n\t\t\t\t\t<input type="text" id="tableFilter" placeholder="Filter tables..." style="flex:1; margin-bottom:0" oninput="pict.views[\'DataCloner-Schema\'].filterTableList()">\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Schema\'].selectAllTables(true)" style="font-size:0.8em">Select All</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Schema\'].selectAllTables(false)" style="font-size:0.8em">Deselect All</button>\n\t\t\t\t\t<span id="tableSelectionCount" style="font-size:0.85em; color:#666; white-space:nowrap"></span>\n\t\t\t\t</div>\n\t\t\t\t<div id="tableList" class="table-list"></div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Schema",TemplateHash:"DataCloner-Schema",DestinationAddress:"#DataCloner-Section-Schema"}]}},{"pict-view":13}],24:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}configureSession(){let t=document.getElementById("serverURL").value.trim();if(!t)return void this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Server URL is required.","error");let e={ServerURL:t.replace(/\/+$/,"")+"/1.0/"},i=document.getElementById("authMethod").value.trim();i&&(e.AuthenticationMethod=i);let n=document.getElementById("authURI").value.trim();n&&(e.AuthenticationURITemplate=n);let o=document.getElementById("checkURI").value.trim();o&&(e.CheckSessionURITemplate=o);let s=document.getElementById("cookieName").value.trim();s&&(e.CookieName=s);let a=document.getElementById("cookieValueAddr").value.trim();a&&(e.CookieValueAddress=a);let r=document.getElementById("cookieValueTemplate").value.trim();r&&(e.CookieValueTemplate=r);let l=document.getElementById("loginMarker").value.trim();l&&(e.CheckSessionLoginMarker=l),this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Configuring session...","info"),this.pict.providers.DataCloner.api("POST","/clone/session/configure",e).then(t=>{t.Success?this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Session configured for "+t.ServerURL+" (domain: "+t.DomainMatch+")","ok"):this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Configuration failed: "+(t.Error||"Unknown error"),"error")}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionConfigStatus","Request failed: "+t.message,"error")})}authenticate(){let t=document.getElementById("userName").value.trim(),e=document.getElementById("password").value.trim();if(!t||!e)return this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Username and password are required.","error"),void this.pict.providers.DataCloner.setSectionPhase(2,"error");this.pict.providers.DataCloner.setSectionPhase(2,"busy"),this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Authenticating...","info"),this.pict.providers.DataCloner.api("POST","/clone/session/authenticate",{UserName:t,Password:e}).then(t=>{t.Success&&t.Authenticated?(this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Authenticated successfully.","ok"),this.pict.providers.DataCloner.setSectionPhase(2,"ok")):(this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Authentication failed: "+(t.Error||"Not authenticated"),"error"),this.pict.providers.DataCloner.setSectionPhase(2,"error"))}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Request failed: "+t.message,"error"),this.pict.providers.DataCloner.setSectionPhase(2,"error")})}checkSession(){this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Checking session...","info"),this.pict.providers.DataCloner.api("GET","/clone/session/check").then(t=>{t.Authenticated?this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Session is active. Server: "+(t.ServerURL||"N/A"),"ok"):t.Configured?this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Session configured but not authenticated.","warn"):this.pict.providers.DataCloner.setStatus("sessionAuthStatus","No session configured.","warn")}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Request failed: "+t.message,"error")})}deauthenticate(){this.pict.providers.DataCloner.api("POST","/clone/session/deauthenticate").then(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Session deauthenticated.","info")}).catch(t=>{this.pict.providers.DataCloner.setStatus("sessionAuthStatus","Request failed: "+t.message,"error")})}goAction(){this.pict.providers.DataCloner.setSectionPhase(2,"busy"),this.configureSession(),setTimeout(()=>{this.authenticate()},1500)}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Session",DefaultRenderable:"DataCloner-Session",DefaultDestinationAddress:"#DataCloner-Section-Session",Templates:[{Hash:"DataCloner-Session",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">2</div>\n\t<div class="accordion-card" id="section2" data-section="2">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section2\')">\n\t\t\t<div class="accordion-title">Remote Session</div>\n\t\t\t<span class="accordion-phase" id="phase2"></span>\n\t\t\t<div class="accordion-preview" id="preview2">Configure remote server URL and credentials</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Session\'].goAction()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto2"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<div class="inline-group">\n\t\t\t\t<div style="flex:2">\n\t\t\t\t\t<label for="serverURL">Remote Server URL</label>\n\t\t\t\t\t<input type="text" id="serverURL" placeholder="http://remote-server:8086" value="">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:1">\n\t\t\t\t\t<label for="authMethod">Auth Method</label>\n\t\t\t\t\t<input type="text" id="authMethod" placeholder="get" value="get">\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<details style="margin-bottom:10px">\n\t\t\t\t<summary style="cursor:pointer; font-size:0.9em; color:#666">Advanced Session Options</summary>\n\t\t\t\t<div style="padding:10px 0">\n\t\t\t\t\t<label for="authURI">Authentication URI Template (leave blank for default)</label>\n\t\t\t\t\t<input type="text" id="authURI" placeholder="Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}">\n\t\t\t\t\t<label for="checkURI">Check Session URI Template</label>\n\t\t\t\t\t<input type="text" id="checkURI" placeholder="CheckSession">\n\t\t\t\t\t<label for="cookieName">Cookie Name</label>\n\t\t\t\t\t<input type="text" id="cookieName" placeholder="SessionID" value="SessionID">\n\t\t\t\t\t<label for="cookieValueAddr">Cookie Value Address</label>\n\t\t\t\t\t<input type="text" id="cookieValueAddr" placeholder="SessionID" value="SessionID">\n\t\t\t\t\t<label for="cookieValueTemplate">Cookie Value Template (overrides Address if set)</label>\n\t\t\t\t\t<input type="text" id="cookieValueTemplate" placeholder="{~D:Record.SessionID~}">\n\t\t\t\t\t<label for="loginMarker">Login Marker</label>\n\t\t\t\t\t<input type="text" id="loginMarker" placeholder="LoggedIn" value="LoggedIn">\n\t\t\t\t</div>\n\t\t\t</details>\n\n\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-Session\'].configureSession()">Configure Session</button>\n\t\t\t<div id="sessionConfigStatus"></div>\n\n\t\t\t<hr style="margin:16px 0; border:none; border-top:1px solid #eee">\n\n\t\t\t<div class="inline-group">\n\t\t\t\t<div>\n\t\t\t\t\t<label for="userName">Username</label>\n\t\t\t\t\t<input type="text" id="userName" placeholder="username">\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<label for="password">Password</label>\n\t\t\t\t\t<input type="password" id="password" placeholder="password">\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<button class="success" onclick="pict.views[\'DataCloner-Session\'].authenticate()">Authenticate</button>\n\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Session\'].checkSession()">Check Session</button>\n\t\t\t<button class="danger" onclick="pict.views[\'DataCloner-Session\'].deauthenticate()">Deauthenticate</button>\n\t\t\t<div id="sessionAuthStatus"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Session",TemplateHash:"DataCloner-Session",DestinationAddress:"#DataCloner-Section-Session"}]}},{"pict-view":13}],25:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}startSync(){let t=this.pict.views["DataCloner-Schema"].getSelectedTables(),e=parseInt(document.getElementById("pageSize").value,10)||100,i=parseInt(document.getElementById("dateTimePrecisionMS").value,10);isNaN(i)&&(i=1e3);let n=document.getElementById("syncDeletedRecords").checked,o=document.querySelector('input[name="syncMode"]:checked').value,s=parseInt(document.getElementById("syncMaxRecords").value,10)||0,a=document.getElementById("syncLogFile").checked,r=document.getElementById("syncAdvancedIDPagination").checked;if(0===t.length)return this.pict.providers.DataCloner.setStatus("syncStatus","No tables selected for sync.","error"),void this.pict.providers.DataCloner.setSectionPhase(5,"error");this.pict.providers.DataCloner.setSectionPhase(5,"busy"),this.pict.providers.DataCloner.setStatus("syncStatus","Starting "+o.toLowerCase()+" sync...","info");let l=this,c={Tables:t,PageSize:e,DateTimePrecisionMS:i,SyncDeletedRecords:n,SyncMode:o};s>0&&(c.MaxRecordsPerEntity=s),a&&(c.LogToFile=!0),r&&(c.UseAdvancedIDPagination=!0),this.pict.providers.DataCloner.api("POST","/clone/sync/start",c).then(function(t){if(t.Success){let e=t.SyncMode+" sync started for "+t.Tables.length+" tables.";t.SyncDeletedRecords&&(e+=" (including deleted records)"),l.pict.providers.DataCloner.setStatus("syncStatus",e,"ok"),l.startPolling()}else l.pict.providers.DataCloner.setStatus("syncStatus","Sync start failed: "+(t.Error||"Unknown error"),"error"),l.pict.providers.DataCloner.setSectionPhase(5,"error")}).catch(function(t){l.pict.providers.DataCloner.setStatus("syncStatus","Request failed: "+t.message,"error"),l.pict.providers.DataCloner.setSectionPhase(5,"error")})}stopSync(){let t=this;this.pict.providers.DataCloner.api("POST","/clone/sync/stop").then(function(e){t.pict.providers.DataCloner.setStatus("syncStatus","Sync stop requested.","warn")}).catch(function(e){t.pict.providers.DataCloner.setStatus("syncStatus","Request failed: "+e.message,"error")})}startPolling(){this.pict.AppData.DataCloner.SyncPollTimer&&clearInterval(this.pict.AppData.DataCloner.SyncPollTimer);let t=this;this.pict.AppData.DataCloner.SyncPollTimer=setInterval(function(){t.pollSyncStatus()},2e3),this.pollSyncStatus()}stopPolling(){this.pict.AppData.DataCloner.SyncPollTimer&&(clearInterval(this.pict.AppData.DataCloner.SyncPollTimer),this.pict.AppData.DataCloner.SyncPollTimer=null)}pollSyncStatus(){let t=this;this.pict.providers.DataCloner.api("GET","/clone/sync/status").then(function(e){if(t.renderSyncProgress(e),!e.Running&&!e.Stopping&&(t.stopPolling(),Object.keys(e.Tables||{}).length>0)){let i=e.Tables||{},n=!1,o=!1,s=Object.keys(i);for(let t=0;t<s.length;t++)"Error"===i[s[t]].Status&&(n=!0),"Partial"===i[s[t]].Status&&(o=!0);n?(t.pict.providers.DataCloner.setStatus("syncStatus","Sync finished with errors. Check the table below for details.","error"),t.pict.providers.DataCloner.setSectionPhase(5,"error")):o?(t.pict.providers.DataCloner.setStatus("syncStatus","Sync finished. Some records were skipped (GUID conflicts or permission issues).","warn"),t.pict.providers.DataCloner.setSectionPhase(5,"ok")):(t.pict.providers.DataCloner.setStatus("syncStatus","Sync complete.","ok"),t.pict.providers.DataCloner.setSectionPhase(5,"ok")),t.fetchSyncReport()}}).catch(function(t){})}fetchSyncReport(){let t=this;this.pict.providers.DataCloner.api("GET","/clone/sync/report").then(function(e){e&&e.ReportVersion&&(t.pict.AppData.DataCloner.LastReport=e,t.renderSyncReport(e))}).catch(function(t){})}renderSyncReport(t){document.getElementById("syncReportSection").style.display="";let e=document.getElementById("reportSummaryCards"),i="outcome-"+t.Outcome.toLowerCase(),n={Success:"#28a745",Partial:"#ffc107",Error:"#dc3545",Stopped:"#6c757d"}[t.Outcome]||"#666",o=t.RunTimestamps.DurationSeconds||0,s=o<60?o+"s":Math.floor(o/60)+"m "+o%60+"s",a=t.Summary.TotalSynced.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","),r=t.Summary.TotalRecords.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");e.innerHTML='<div class="report-card '+i+'"> <div class="card-label">Outcome</div> <div class="card-value" style="color:'+n+'">'+t.Outcome+'</div></div><div class="report-card"> <div class="card-label">Mode</div> <div class="card-value">'+t.Config.SyncMode+'</div></div><div class="report-card"> <div class="card-label">Duration</div> <div class="card-value">'+s+'</div></div><div class="report-card"> <div class="card-label">Tables</div> <div class="card-value">'+t.Summary.Complete+" / "+t.Summary.TotalTables+'</div></div><div class="report-card"> <div class="card-label">Records</div> <div class="card-value">'+a+'</div> <div style="font-size:0.75em; color:#888">of '+r+"</div></div>";let l=document.getElementById("reportAnomalies");if(0===t.Anomalies.length)l.innerHTML='<div style="color:#28a745; font-weight:600; font-size:0.9em">No anomalies detected.</div>';else{let e='<h4 style="margin:0 0 8px; color:#dc3545; font-size:0.95em">Anomalies ('+t.Anomalies.length+")</h4>";e+='<table class="progress-table">',e+="<tr><th>Table</th><th>Type</th><th>Message</th></tr>";for(let i=0;i<t.Anomalies.length;i++){let n=t.Anomalies[i],o="Error"===n.Type?"#dc3545":"Partial"===n.Type?"#ffc107":"#6c757d";e+="<tr>",e+="<td><strong>"+this.pict.providers.DataCloner.escapeHtml(n.Table)+"</strong></td>",e+='<td style="color:'+o+'">'+n.Type+"</td>",e+="<td>"+this.pict.providers.DataCloner.escapeHtml(n.Message)+"</td>",e+="</tr>"}e+="</table>",l.innerHTML=e}let c=document.getElementById("reportTopTables"),d=Math.min(10,t.Tables.length);if(d>0){let e='<h4 style="margin:0 0 8px; font-size:0.95em; color:#444">Top Tables by Duration</h4>';e+='<table class="progress-table">',e+="<tr><th>Table</th><th>Duration</th><th>Records</th><th>Status</th></tr>";for(let i=0;i<d;i++){let n=t.Tables[i],o=n.DurationSeconds<60?n.DurationSeconds+"s":Math.floor(n.DurationSeconds/60)+"m "+n.DurationSeconds%60+"s",s=n.Total.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","),a={Complete:"#28a745",Error:"#dc3545",Partial:"#ffc107"}[n.Status]||"#666";e+="<tr>",e+="<td><strong>"+this.pict.providers.DataCloner.escapeHtml(n.Name)+"</strong></td>",e+="<td>"+o+"</td>",e+="<td>"+s+"</td>",e+='<td style="color:'+a+'">'+n.Status+"</td>",e+="</tr>"}e+="</table>",c.innerHTML=e}}downloadReport(){if(!this.pict.AppData.DataCloner.LastReport)return void this.pict.providers.DataCloner.setStatus("reportStatus","No report available.","warn");let t=JSON.stringify(this.pict.AppData.DataCloner.LastReport,null,"\t"),e=new Blob([t],{type:"application/json"}),i=document.createElement("a");i.href=URL.createObjectURL(e);let n=(new Date).toISOString().replace(/[:.]/g,"-").slice(0,19);i.download="DataCloner-Report-"+n+".json",i.click(),URL.revokeObjectURL(i.href),this.pict.providers.DataCloner.setStatus("reportStatus","Report downloaded.","ok")}copyReport(){if(!this.pict.AppData.DataCloner.LastReport)return void this.pict.providers.DataCloner.setStatus("reportStatus","No report available.","warn");let t=JSON.stringify(this.pict.AppData.DataCloner.LastReport,null,"\t"),e=this;navigator.clipboard.writeText(t).then(function(){e.pict.providers.DataCloner.setStatus("reportStatus","Report copied to clipboard.","ok")})}renderSyncProgress(t){let e=document.getElementById("syncProgress"),i=t.Tables||{},n=Object.keys(i);if(0===n.length)return void(e.innerHTML="");let o=[],s=[],a=[],r=[];for(let t=0;t<n.length;t++){let e=n[t],l=i[e];"Syncing"===l.Status?o.push({Name:e,Data:l}):"Pending"===l.Status?s.push({Name:e,Data:l}):"Complete"===l.Status?a.push({Name:e,Data:l}):r.push({Name:e,Data:l})}let l="",c=(t,e)=>{let i=0;0!==e.Total||"Complete"!==e.Status&&"Error"!==e.Status?e.Total>0&&(i=Math.round(e.Synced/e.Total*100)):i=100;let n="#28a745";"Error"===e.Status?n="#dc3545":"Partial"===e.Status?n="#ffc107":"Syncing"===e.Status?n="#4a90d9":"Pending"===e.Status&&(n="#adb5bd");let o=e.Status;"Complete"===e.Status&&0===e.Total&&(o="Complete (empty)"),"Partial"===e.Status&&(o="Partial ⚠"),"Error"===e.Status&&(o="Error ✖");let s="";e.ErrorMessage?s=e.ErrorMessage:e.Skipped>0?s=e.Skipped+" record(s) skipped":(e.Errors||0)>0?s=e.Errors+" error(s)":"Complete"===e.Status&&0===e.Total?s="No records on server":"Complete"===e.Status&&(s="✔ OK");let a="<tr>";return a+="<td><strong>"+t+"</strong></td>",a+="<td>"+o+"</td>",a+="<td>",a+='<div class="progress-bar-container"><div class="progress-bar-fill" style="width:'+i+"%; background:"+n+'"></div></div>',a+=" "+i+"%",a+="</td>",a+="<td>"+e.Synced+" / "+e.Total+"</td>",a+="<td>"+s+"</td>",a+="</tr>",a};if(o.length>0){l+='<div class="sync-section-header">Syncing</div>',l+='<table class="progress-table">',l+="<tr><th>Table</th><th>Status</th><th>Progress</th><th>Synced</th><th>Details</th></tr>";for(let t=0;t<o.length;t++)l+=c(o[t].Name,o[t].Data);l+="</table>"}if(s.length>0){l+='<div class="sync-section-header">Next Up <span class="sync-section-count">'+s.length+"</span></div>";let t=Math.min(8,s.length);l+='<table class="progress-table progress-table-muted">';for(let e=0;e<t;e++)l+="<tr><td>"+s[e].Name+"</td>",s[e].Data.Total>0?l+='<td class="sync-pending-count">'+s[e].Data.Total.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")+" records</td>":l+='<td class="sync-pending-count">—</td>',l+="</tr>";l+="</table>",s.length>t&&(l+='<div class="sync-section-overflow">+ '+(s.length-t)+" more table"+(s.length-t===1?"":"s")+"</div>")}if(r.length>0){l+='<div class="sync-section-header sync-section-header-error">Errors <span class="sync-section-count">'+r.length+"</span></div>",l+='<table class="progress-table">',l+="<tr><th>Table</th><th>Status</th><th>Progress</th><th>Synced</th><th>Details</th></tr>";for(let t=0;t<r.length;t++)l+=c(r[t].Name,r[t].Data);l+="</table>"}if(a.length>0){l+='<div class="sync-section-header sync-section-header-ok">Completed <span class="sync-section-count">'+a.length+"</span></div>",l+='<table class="progress-table">',l+="<tr><th>Table</th><th>Status</th><th>Progress</th><th>Synced</th><th>Details</th></tr>";for(let t=0;t<a.length;t++)l+=c(a[t].Name,a[t].Data);l+="</table>"}e.innerHTML=l}},e.exports.default_configuration={ViewIdentifier:"DataCloner-Sync",DefaultRenderable:"DataCloner-Sync",DefaultDestinationAddress:"#DataCloner-Section-Sync",CSS:"\n.progress-table { width: 100%; border-collapse: collapse; margin-top: 4px; margin-bottom: 4px; }\n.progress-table th, .progress-table td { text-align: left; padding: 6px 12px; border-bottom: 1px solid #eee; font-size: 0.9em; }\n.progress-table th { background: #f8f9fa; font-weight: 600; }\n.progress-table-muted td { color: #888; padding: 3px 12px; font-size: 0.85em; border-bottom: 1px solid #f4f5f6; }\n.progress-bar-container { width: 120px; height: 16px; background: #e9ecef; border-radius: 8px; overflow: hidden; display: inline-block; vertical-align: middle; }\n.progress-bar-fill { height: 100%; background: #28a745; transition: width 0.3s; }\n.sync-section-header { font-size: 0.8em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: #4a90d9; padding: 10px 0 2px 0; margin-top: 6px; border-top: 1px solid #e0e0e0; }\n.sync-section-header:first-child { border-top: none; margin-top: 10px; }\n.sync-section-header-error { color: #dc3545; }\n.sync-section-header-ok { color: #28a745; }\n.sync-section-count { font-weight: 400; color: #999; font-size: 0.95em; }\n.sync-section-overflow { font-size: 0.8em; color: #aaa; padding: 2px 12px 6px; }\n.sync-pending-count { text-align: right; color: #aaa; font-size: 0.85em; }\n.report-card { background: #f8f9fa; border-radius: 8px; padding: 12px 16px; min-width: 140px; text-align: center; border: 1px solid #e9ecef; }\n.report-card .card-label { font-size: 0.8em; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }\n.report-card .card-value { font-size: 1.4em; font-weight: 700; }\n.report-card.outcome-success { border-left: 4px solid #28a745; }\n.report-card.outcome-partial { border-left: 4px solid #ffc107; }\n.report-card.outcome-error { border-left: 4px solid #dc3545; }\n.report-card.outcome-stopped { border-left: 4px solid #6c757d; }\n",Templates:[{Hash:"DataCloner-Sync",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">5</div>\n\t<div class="accordion-card" id="section5" data-section="5">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section5\')">\n\t\t\t<div class="accordion-title">Synchronize Data</div>\n\t\t\t<span class="accordion-phase" id="phase5"></span>\n\t\t\t<div class="accordion-preview" id="preview5">Initial sync, page size 100</div>\n\t\t\t<div class="accordion-actions">\n\t\t\t\t<span class="accordion-go" onclick="event.stopPropagation(); pict.views[\'DataCloner-Sync\'].startSync()">go</span>\n\t\t\t\t<label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto5"> <span class="auto-label">auto</span></label>\n\t\t\t</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<div style="display:flex; gap:8px; align-items:flex-end; margin-bottom:4px">\n\t\t\t\t<div style="flex:0 0 150px">\n\t\t\t\t\t<label for="pageSize">Page Size</label>\n\t\t\t\t\t<input type="number" id="pageSize" value="100" min="1" max="10000" style="margin-bottom:0">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 220px">\n\t\t\t\t\t<label for="dateTimePrecisionMS">Timestamp Precision (ms)</label>\n\t\t\t\t\t<input type="number" id="dateTimePrecisionMS" value="1000" min="0" max="60000" style="margin-bottom:0">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 auto; display:flex; gap:8px">\n\t\t\t\t\t<button class="success" style="margin:0" onclick="pict.views[\'DataCloner-Sync\'].startSync()">Start Sync</button>\n\t\t\t\t\t<button class="danger" style="margin:0" onclick="pict.views[\'DataCloner-Sync\'].stopSync()">Stop Sync</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div style="font-size:0.8em; color:#888; margin-bottom:10px; padding-left:158px">Cross-DB tolerance for date comparison (default: 1000ms)</div>\n\n\t\t\t<div style="margin-bottom:10px">\n\t\t\t\t<label style="margin-bottom:6px">Sync Mode</label>\n\t\t\t\t<div style="display:flex; gap:16px; align-items:center">\n\t\t\t\t\t<label style="font-weight:normal; margin:0; cursor:pointer">\n\t\t\t\t\t\t<input type="radio" name="syncMode" id="syncModeInitial" value="Initial" checked> Initial\n\t\t\t\t\t\t<span style="color:#888; font-size:0.85em">(full clone — download all records)</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<label style="font-weight:normal; margin:0; cursor:pointer">\n\t\t\t\t\t\t<input type="radio" name="syncMode" id="syncModeOngoing" value="Ongoing"> Ongoing\n\t\t\t\t\t\t<span style="color:#888; font-size:0.85em">(delta — only new/updated records since last sync)</span>\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class="checkbox-row">\n\t\t\t\t<input type="checkbox" id="syncDeletedRecords">\n\t\t\t\t<label for="syncDeletedRecords">Sync deleted records (fetch records marked Deleted=1 on source and mirror locally)</label>\n\t\t\t</div>\n\n\t\t\t<div class="checkbox-row">\n\t\t\t\t<input type="checkbox" id="syncAdvancedIDPagination">\n\t\t\t\t<label for="syncAdvancedIDPagination">Use advanced ID pagination (faster for large tables; uses keyset pagination instead of OFFSET)</label>\n\t\t\t</div>\n\n\t\t\t<div class="inline-group" style="margin-top:8px; margin-bottom:4px">\n\t\t\t\t<div style="flex:0 0 200px">\n\t\t\t\t\t<label for="syncMaxRecords">Max Records per Entity</label>\n\t\t\t\t\t<input type="number" id="syncMaxRecords" value="" min="0" placeholder="0 = unlimited" style="margin-bottom:0">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 auto; display:flex; align-items:flex-end; padding-bottom:2px">\n\t\t\t\t\t<div class="checkbox-row" style="margin-bottom:0">\n\t\t\t\t\t\t<input type="checkbox" id="syncLogFile" checked>\n\t\t\t\t\t\t<label for="syncLogFile">Write log file</label>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div id="syncStatus"></div>\n\t\t\t<div id="syncProgress"></div>\n\n\t\t\t\x3c!-- Sync Report (appears after sync completes) --\x3e\n\t\t\t<div id="syncReportSection" style="display:none; margin-top:16px; padding-top:16px; border-top:2px solid #ddd">\n\t\t\t\t<h3 style="margin:0 0 12px; font-size:1.1em">Sync Report</h3>\n\n\t\t\t\t\x3c!-- Summary cards --\x3e\n\t\t\t\t<div id="reportSummaryCards" style="display:flex; gap:12px; flex-wrap:wrap; margin-bottom:16px"></div>\n\n\t\t\t\t\x3c!-- Anomalies --\x3e\n\t\t\t\t<div id="reportAnomalies" style="margin-bottom:16px"></div>\n\n\t\t\t\t\x3c!-- Top tables by duration --\x3e\n\t\t\t\t<div id="reportTopTables" style="margin-bottom:16px"></div>\n\n\t\t\t\t\x3c!-- Buttons --\x3e\n\t\t\t\t<div style="display:flex; gap:8px">\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Sync\'].downloadReport()">Download Report JSON</button>\n\t\t\t\t\t<button class="secondary" onclick="pict.views[\'DataCloner-Sync\'].copyReport()">Copy Report</button>\n\t\t\t\t</div>\n\t\t\t\t<div id="reportStatus"></div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-Sync",TemplateHash:"DataCloner-Sync",DestinationAddress:"#DataCloner-Section-Sync"}]}},{"pict-view":13}],26:[function(t,e,i){const n=t("pict-view");e.exports=class extends n{constructor(t,e,i){super(t,e,i)}populateViewTableDropdown(){let t=document.getElementById("viewTable");if(!t)return;let e=t.value;t.innerHTML="";let i=this.pict.AppData.DataCloner.DeployedTables;if(!i||0===i.length){let e=document.createElement("option");return e.value="",e.textContent="— deploy tables first —",void t.appendChild(e)}for(let e=0;e<i.length;e++){let n=document.createElement("option");n.value=i[e],n.textContent=i[e],t.appendChild(n)}e&&(t.value=e)}loadTableData(){let t=document.getElementById("viewTable").value,e=parseInt(document.getElementById("viewLimit").value,10)||100;if(!t)return void this.pict.providers.DataCloner.setStatus("viewStatus","Select a table first.","error");this.pict.providers.DataCloner.setStatus("viewStatus","Loading "+t+"...","info"),document.getElementById("viewDataContainer").innerHTML="";let i=this;this.pict.providers.DataCloner.api("GET","/1.0/"+t+"s/0/"+e).then(function(t){Array.isArray(t)?(i.pict.providers.DataCloner.setStatus("viewStatus",t.length+" row(s) returned"+(t.length>=e?" (limit reached — increase Max Rows to see more)":"")+".","ok"),i.renderDataTable(t)):i.pict.providers.DataCloner.setStatus("viewStatus","Unexpected response (not an array). The table may not be deployed yet.","error")}).catch(function(t){i.pict.providers.DataCloner.setStatus("viewStatus","Request failed: "+t.message,"error")})}renderDataTable(t){let e=document.getElementById("viewDataContainer");if(!t||0===t.length)return void(e.innerHTML='<p style="color:#666; font-size:0.9em; padding:8px">No rows.</p>');let i=Object.keys(t[0]),n='<table class="data-table">';n+="<thead><tr>";for(let t=0;t<i.length;t++)n+="<th>"+this.pict.providers.DataCloner.escapeHtml(i[t])+"</th>";n+="</tr></thead>",n+="<tbody>";for(let e=0;e<t.length;e++){n+="<tr>";for(let o=0;o<i.length;o++){let s=t[e][i[o]],a=null==s?"":String(s);n+='<td title="'+this.pict.providers.DataCloner.escapeHtml(a)+'">'+this.pict.providers.DataCloner.escapeHtml(a)+"</td>"}n+="</tr>"}n+="</tbody></table>",e.innerHTML=n}},e.exports.default_configuration={ViewIdentifier:"DataCloner-ViewData",DefaultRenderable:"DataCloner-ViewData",DefaultDestinationAddress:"#DataCloner-Section-ViewData",CSS:"\n.data-table { width: 100%; border-collapse: collapse; font-size: 0.8em; font-family: monospace; }\n.data-table th { background: #f8f9fa; font-weight: 600; text-align: left; padding: 4px 8px; border: 1px solid #ddd; white-space: nowrap; position: sticky; top: 0; }\n.data-table td { padding: 4px 8px; border: 1px solid #eee; white-space: nowrap; max-width: 300px; overflow: hidden; text-overflow: ellipsis; }\n.data-table tr:nth-child(even) { background: #fafafa; }\n.data-table tr:hover { background: #f0f7ff; }\n",Templates:[{Hash:"DataCloner-ViewData",Template:'\n<div class="accordion-row">\n\t<div class="accordion-number">7</div>\n\t<div class="accordion-card" id="section7" data-section="7">\n\t\t<div class="accordion-header" onclick="pict.views[\'DataCloner-Layout\'].toggleSection(\'section7\')">\n\t\t\t<div class="accordion-title">View Data</div>\n\t\t\t<div class="accordion-preview" id="preview7">Browse synced table data</div>\n\t\t\t<div class="accordion-toggle">▼</div>\n\t\t</div>\n\t\t<div class="accordion-body">\n\t\t\t<div class="inline-group">\n\t\t\t\t<div style="flex:1">\n\t\t\t\t\t<label for="viewTable">Table</label>\n\t\t\t\t\t<select id="viewTable">\n\t\t\t\t\t\t<option value="">— deploy tables first —</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 120px">\n\t\t\t\t\t<label for="viewLimit">Max Rows</label>\n\t\t\t\t\t<input type="number" id="viewLimit" value="100" min="1" max="10000">\n\t\t\t\t</div>\n\t\t\t\t<div style="flex:0 0 auto; display:flex; align-items:flex-end">\n\t\t\t\t\t<button class="primary" onclick="pict.views[\'DataCloner-ViewData\'].loadTableData()">Load</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div id="viewStatus"></div>\n\t\t\t<div id="viewDataContainer" style="overflow-x:auto; margin-top:10px"></div>\n\t\t</div>\n\t</div>\n</div>\n'}],Renderables:[{RenderableHash:"DataCloner-ViewData",TemplateHash:"DataCloner-ViewData",DestinationAddress:"#DataCloner-Section-ViewData"}]}},{"pict-view":13}]},{},[17])(17)});
|
|
2
2
|
//# sourceMappingURL=data-cloner.min.js.map
|