docula 1.2.0 → 1.6.0
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/README.md +33 -716
- package/dist/docula.d.ts +106 -13
- package/dist/docula.js +863 -160
- package/package.json +6 -2
- package/templates/classic/changelog.hbs +23 -2
- package/templates/classic/css/base.css +75 -0
- package/templates/classic/css/variables.css +30 -0
- package/templates/classic/home.hbs +7 -0
- package/templates/modern/api.hbs +39 -2
- package/templates/modern/changelog-entry.hbs +1 -1
- package/templates/modern/changelog.hbs +24 -3
- package/templates/modern/css/styles.css +124 -36
- package/templates/modern/css/variables.css +32 -0
- package/templates/modern/home.hbs +10 -3
- package/templates/modern/includes/api-reference.hbs +1 -1
- package/templates/modern/includes/documentation.hbs +1 -1
- package/templates/modern/includes/footer.hbs +5 -2
- package/templates/modern/includes/header-bar.hbs +40 -22
- package/templates/modern/includes/header.hbs +18 -3
- package/templates/modern/includes/home.hbs +1 -1
- package/templates/modern/includes/scripts.hbs +43 -34
- package/templates/modern/js/api.js +17 -6
package/dist/docula.js
CHANGED
|
@@ -12,6 +12,7 @@ import updateNotifier from "update-notifier";
|
|
|
12
12
|
import fs3 from "fs";
|
|
13
13
|
import path5 from "path";
|
|
14
14
|
import { Ecto } from "ecto";
|
|
15
|
+
import { Hashery } from "hashery";
|
|
15
16
|
import { Writr } from "writr";
|
|
16
17
|
|
|
17
18
|
// src/api-parser.ts
|
|
@@ -571,55 +572,52 @@ var DoculaConsole = class {
|
|
|
571
572
|
console.log(
|
|
572
573
|
` ${green("build")} Build the project. By default just npx docula will build the project if it finds a ./site folder`
|
|
573
574
|
);
|
|
575
|
+
console.log(
|
|
576
|
+
` ${green("dev")} Build, watch, and serve the project`
|
|
577
|
+
);
|
|
578
|
+
console.log(` ${green("start")} Build and serve the project`);
|
|
574
579
|
console.log(
|
|
575
580
|
` ${green("serve")} Serve the project as a local website`
|
|
576
581
|
);
|
|
577
582
|
console.log(` ${green("help")} Print this help`);
|
|
578
583
|
console.log(` ${green("version")} Print the version`);
|
|
579
584
|
console.log();
|
|
580
|
-
console.log(bold(cyan("
|
|
585
|
+
console.log(bold(cyan(" Common Options:")));
|
|
581
586
|
console.log(
|
|
582
|
-
` ${yellow("--
|
|
583
|
-
);
|
|
584
|
-
console.log(
|
|
585
|
-
` ${yellow("-s, --site")} Set the path where site files are located`
|
|
586
|
-
);
|
|
587
|
-
console.log();
|
|
588
|
-
console.log(bold(cyan(" Arguments build:")));
|
|
589
|
-
console.log(
|
|
590
|
-
` ${yellow("-w, --watch")} watch for changes and rebuild`
|
|
587
|
+
` ${yellow("-s, --site")} Set the path where site files are located`
|
|
591
588
|
);
|
|
592
589
|
console.log(
|
|
593
590
|
` ${yellow("-c, --clean")} Clean the output directory before building`
|
|
594
591
|
);
|
|
595
|
-
console.log(
|
|
596
|
-
` ${yellow("-s, --site")} Set the path where site files are located`
|
|
597
|
-
);
|
|
598
592
|
console.log(
|
|
599
593
|
` ${yellow("-o, --output")} Set the output directory. Default is ./site/dist`
|
|
600
594
|
);
|
|
601
595
|
console.log(
|
|
602
|
-
` ${yellow("-
|
|
596
|
+
` ${yellow("-p, --port")} Set the port number. Default is 3000`
|
|
603
597
|
);
|
|
604
598
|
console.log(
|
|
605
|
-
` ${yellow("-
|
|
599
|
+
` ${yellow("-w, --watch")} Watch for changes and rebuild`
|
|
606
600
|
);
|
|
607
601
|
console.log();
|
|
608
|
-
console.log(bold(cyan("
|
|
602
|
+
console.log(bold(cyan(" Init Options:")));
|
|
609
603
|
console.log(
|
|
610
|
-
` ${yellow("
|
|
604
|
+
` ${yellow("--typescript")} Generate TypeScript config file (docula.config.ts)`
|
|
611
605
|
);
|
|
612
606
|
console.log(
|
|
613
|
-
` ${yellow("
|
|
607
|
+
` ${yellow("--javascript")} Generate JavaScript config file (docula.config.mjs)`
|
|
614
608
|
);
|
|
609
|
+
console.log();
|
|
610
|
+
console.log(bold(cyan(" Build / Dev Options:")));
|
|
615
611
|
console.log(
|
|
616
|
-
` ${yellow("-
|
|
612
|
+
` ${yellow("-t, --templatePath")} Set the custom template to use`
|
|
617
613
|
);
|
|
618
614
|
console.log(
|
|
619
|
-
` ${yellow("-
|
|
615
|
+
` ${yellow("-T, --template")} Set the built-in template name (e.g., modern, classic)`
|
|
620
616
|
);
|
|
617
|
+
console.log();
|
|
618
|
+
console.log(bold(cyan(" Serve Options:")));
|
|
621
619
|
console.log(
|
|
622
|
-
` ${yellow("-
|
|
620
|
+
` ${yellow("-b, --build")} Build the site before serving`
|
|
623
621
|
);
|
|
624
622
|
}
|
|
625
623
|
parseProcessArgv(argv) {
|
|
@@ -632,7 +630,28 @@ var DoculaConsole = class {
|
|
|
632
630
|
};
|
|
633
631
|
}
|
|
634
632
|
getCommand(argv) {
|
|
633
|
+
const flagsWithValues = /* @__PURE__ */ new Set([
|
|
634
|
+
"-s",
|
|
635
|
+
"--site",
|
|
636
|
+
"-o",
|
|
637
|
+
"--output",
|
|
638
|
+
"-p",
|
|
639
|
+
"--port",
|
|
640
|
+
"-t",
|
|
641
|
+
"--templatePath",
|
|
642
|
+
"-T",
|
|
643
|
+
"--template"
|
|
644
|
+
]);
|
|
645
|
+
let skipNext = false;
|
|
635
646
|
for (const argument of argv) {
|
|
647
|
+
if (skipNext) {
|
|
648
|
+
skipNext = false;
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (flagsWithValues.has(argument)) {
|
|
652
|
+
skipNext = true;
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
636
655
|
switch (argument) {
|
|
637
656
|
case "init": {
|
|
638
657
|
return "init";
|
|
@@ -643,7 +662,15 @@ var DoculaConsole = class {
|
|
|
643
662
|
case "serve": {
|
|
644
663
|
return "serve";
|
|
645
664
|
}
|
|
646
|
-
case "
|
|
665
|
+
case "dev": {
|
|
666
|
+
return "dev";
|
|
667
|
+
}
|
|
668
|
+
case "start": {
|
|
669
|
+
return "start";
|
|
670
|
+
}
|
|
671
|
+
case "help":
|
|
672
|
+
case "-h":
|
|
673
|
+
case "--help": {
|
|
647
674
|
return "help";
|
|
648
675
|
}
|
|
649
676
|
case "version": {
|
|
@@ -662,7 +689,8 @@ var DoculaConsole = class {
|
|
|
662
689
|
clean: false,
|
|
663
690
|
build: false,
|
|
664
691
|
port: void 0,
|
|
665
|
-
typescript: false
|
|
692
|
+
typescript: false,
|
|
693
|
+
javascript: false
|
|
666
694
|
};
|
|
667
695
|
for (let i = 0; i < argv.length; i++) {
|
|
668
696
|
const argument = argv[i];
|
|
@@ -720,6 +748,10 @@ var DoculaConsole = class {
|
|
|
720
748
|
arguments_.typescript = true;
|
|
721
749
|
break;
|
|
722
750
|
}
|
|
751
|
+
case "--javascript": {
|
|
752
|
+
arguments_.javascript = true;
|
|
753
|
+
break;
|
|
754
|
+
}
|
|
723
755
|
}
|
|
724
756
|
}
|
|
725
757
|
return arguments_;
|
|
@@ -875,6 +907,18 @@ var Github = class {
|
|
|
875
907
|
// src/options.ts
|
|
876
908
|
import path3 from "path";
|
|
877
909
|
import process3 from "process";
|
|
910
|
+
function trimSlashes(value) {
|
|
911
|
+
let start = 0;
|
|
912
|
+
let end = value.length;
|
|
913
|
+
while (start < end && value[start] === "/") start++;
|
|
914
|
+
while (end > start && value[end - 1] === "/") end--;
|
|
915
|
+
return value.slice(start, end);
|
|
916
|
+
}
|
|
917
|
+
function trimTrailingSlashes(value) {
|
|
918
|
+
let end = value.length;
|
|
919
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
920
|
+
return value.slice(0, end);
|
|
921
|
+
}
|
|
878
922
|
var DoculaOptions = class {
|
|
879
923
|
/**
|
|
880
924
|
* Name of the built-in template to use (e.g., "modern", "classic")
|
|
@@ -887,7 +931,7 @@ var DoculaOptions = class {
|
|
|
887
931
|
/**
|
|
888
932
|
* Path to the output directory
|
|
889
933
|
*/
|
|
890
|
-
output =
|
|
934
|
+
output = "";
|
|
891
935
|
/**
|
|
892
936
|
* Path to the site directory
|
|
893
937
|
*/
|
|
@@ -928,10 +972,9 @@ var DoculaOptions = class {
|
|
|
928
972
|
*/
|
|
929
973
|
enableReleaseChangelog = true;
|
|
930
974
|
/**
|
|
931
|
-
*
|
|
932
|
-
* and the home.hbs template is not rendered.
|
|
975
|
+
* Number of changelog entries to display per page on the changelog index.
|
|
933
976
|
*/
|
|
934
|
-
|
|
977
|
+
changelogPerPage = 20;
|
|
935
978
|
/**
|
|
936
979
|
* When true, generates llms.txt and llms-full.txt files for the built site.
|
|
937
980
|
*/
|
|
@@ -948,9 +991,23 @@ var DoculaOptions = class {
|
|
|
948
991
|
*/
|
|
949
992
|
autoUpdateIgnores = true;
|
|
950
993
|
/**
|
|
951
|
-
*
|
|
952
|
-
*
|
|
994
|
+
* Base URL path prefix for all generated paths (e.g., "/docs").
|
|
995
|
+
* When set, all asset and navigation URLs are prefixed with this path.
|
|
996
|
+
*/
|
|
997
|
+
baseUrl = "";
|
|
998
|
+
/**
|
|
999
|
+
* Output subdirectory and URL segment for documentation pages.
|
|
1000
|
+
* Set to empty string to place docs at the output root.
|
|
1001
|
+
*/
|
|
1002
|
+
docsPath = "docs";
|
|
1003
|
+
/**
|
|
1004
|
+
* Output subdirectory and URL segment for API reference pages.
|
|
1005
|
+
*/
|
|
1006
|
+
apiPath = "api";
|
|
1007
|
+
/**
|
|
1008
|
+
* Output subdirectory and URL segment for changelog pages.
|
|
953
1009
|
*/
|
|
1010
|
+
changelogPath = "changelog";
|
|
954
1011
|
/**
|
|
955
1012
|
* Cookie-based authentication. When set, shows a Login/Logout button
|
|
956
1013
|
* in the header based on whether a JWT cookie is present.
|
|
@@ -1005,6 +1062,9 @@ var DoculaOptions = class {
|
|
|
1005
1062
|
if (options) {
|
|
1006
1063
|
this.parseOptions(options);
|
|
1007
1064
|
}
|
|
1065
|
+
if (!this.output) {
|
|
1066
|
+
this.output = path3.join(this.sitePath, "dist");
|
|
1067
|
+
}
|
|
1008
1068
|
}
|
|
1009
1069
|
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
1010
1070
|
parseOptions(options) {
|
|
@@ -1047,8 +1107,8 @@ var DoculaOptions = class {
|
|
|
1047
1107
|
if (options.enableReleaseChangelog !== void 0 && typeof options.enableReleaseChangelog === "boolean") {
|
|
1048
1108
|
this.enableReleaseChangelog = options.enableReleaseChangelog;
|
|
1049
1109
|
}
|
|
1050
|
-
if (options.
|
|
1051
|
-
this.
|
|
1110
|
+
if (options.changelogPerPage !== void 0 && typeof options.changelogPerPage === "number" && options.changelogPerPage > 0) {
|
|
1111
|
+
this.changelogPerPage = options.changelogPerPage;
|
|
1052
1112
|
}
|
|
1053
1113
|
if (options.enableLlmsTxt !== void 0 && typeof options.enableLlmsTxt === "boolean") {
|
|
1054
1114
|
this.enableLlmsTxt = options.enableLlmsTxt;
|
|
@@ -1062,6 +1122,18 @@ var DoculaOptions = class {
|
|
|
1062
1122
|
if (options.cache && typeof options.cache === "object" && options.cache.github !== null && typeof options.cache.github === "object" && typeof options.cache.github.ttl === "number") {
|
|
1063
1123
|
this.cache = options.cache;
|
|
1064
1124
|
}
|
|
1125
|
+
if (options.baseUrl !== void 0 && typeof options.baseUrl === "string") {
|
|
1126
|
+
this.baseUrl = trimTrailingSlashes(options.baseUrl);
|
|
1127
|
+
}
|
|
1128
|
+
if (options.docsPath !== void 0 && typeof options.docsPath === "string") {
|
|
1129
|
+
this.docsPath = trimSlashes(options.docsPath);
|
|
1130
|
+
}
|
|
1131
|
+
if (options.apiPath !== void 0 && typeof options.apiPath === "string") {
|
|
1132
|
+
this.apiPath = trimSlashes(options.apiPath);
|
|
1133
|
+
}
|
|
1134
|
+
if (options.changelogPath !== void 0 && typeof options.changelogPath === "string") {
|
|
1135
|
+
this.changelogPath = trimSlashes(options.changelogPath);
|
|
1136
|
+
}
|
|
1065
1137
|
if (options.allowedAssets && Array.isArray(options.allowedAssets)) {
|
|
1066
1138
|
this.allowedAssets = options.allowedAssets;
|
|
1067
1139
|
}
|
|
@@ -1076,6 +1148,9 @@ var DoculaOptions = class {
|
|
|
1076
1148
|
this.headerLinks = validLinks;
|
|
1077
1149
|
}
|
|
1078
1150
|
}
|
|
1151
|
+
if (!options.output && !this.output) {
|
|
1152
|
+
this.output = path3.join(this.sitePath, "dist");
|
|
1153
|
+
}
|
|
1079
1154
|
}
|
|
1080
1155
|
};
|
|
1081
1156
|
|
|
@@ -1113,6 +1188,8 @@ var DoculaBuilder = class {
|
|
|
1113
1188
|
_options = new DoculaOptions();
|
|
1114
1189
|
_ecto;
|
|
1115
1190
|
_console = new DoculaConsole();
|
|
1191
|
+
_hash = new Hashery();
|
|
1192
|
+
onReleaseChangelog;
|
|
1116
1193
|
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
1117
1194
|
constructor(options, engineOptions) {
|
|
1118
1195
|
if (options) {
|
|
@@ -1131,6 +1208,29 @@ var DoculaBuilder = class {
|
|
|
1131
1208
|
this.options.sitePath,
|
|
1132
1209
|
this.options.template
|
|
1133
1210
|
);
|
|
1211
|
+
const previousManifest = this.loadBuildManifest(this.options.sitePath);
|
|
1212
|
+
const currentConfigHash = this.hashOptions();
|
|
1213
|
+
const currentTemplateHash = this.hashTemplateDirectory(resolvedTemplatePath);
|
|
1214
|
+
const validManifest = previousManifest?.configHash === currentConfigHash ? previousManifest : void 0;
|
|
1215
|
+
const currentDocHashes = this.hashSourceFiles(
|
|
1216
|
+
`${this.options.sitePath}/docs`
|
|
1217
|
+
);
|
|
1218
|
+
const currentChangelogHashes = this.hashSourceFiles(
|
|
1219
|
+
`${this.options.sitePath}/changelog`
|
|
1220
|
+
);
|
|
1221
|
+
const currentAssetHashes = {};
|
|
1222
|
+
if (validManifest && fs3.existsSync(this.options.output) && validManifest.templateHash === currentTemplateHash && this.recordsEqual(validManifest.docs, currentDocHashes) && this.recordsEqual(validManifest.changelog, currentChangelogHashes)) {
|
|
1223
|
+
const assetsChanged = this.hasAssetsChanged(
|
|
1224
|
+
this.options.sitePath,
|
|
1225
|
+
validManifest.assets
|
|
1226
|
+
);
|
|
1227
|
+
if (!assetsChanged) {
|
|
1228
|
+
this._console.success("No changes detected, skipping build");
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
const cachedDocs = validManifest ? this.loadCachedDocuments(this.options.sitePath) : /* @__PURE__ */ new Map();
|
|
1233
|
+
const cachedChangelog = validManifest ? this.loadCachedChangelog(this.options.sitePath) : /* @__PURE__ */ new Map();
|
|
1134
1234
|
const doculaData = {
|
|
1135
1235
|
siteUrl: this.options.siteUrl,
|
|
1136
1236
|
siteTitle: this.options.siteTitle,
|
|
@@ -1141,21 +1241,42 @@ var DoculaBuilder = class {
|
|
|
1141
1241
|
githubPath: this.options.githubPath,
|
|
1142
1242
|
sections: this.options.sections,
|
|
1143
1243
|
openApiUrl: this.options.openApiUrl,
|
|
1144
|
-
|
|
1244
|
+
hasReadme: fs3.existsSync(`${this.options.sitePath}/README.md`),
|
|
1145
1245
|
themeMode: this.options.themeMode,
|
|
1146
1246
|
cookieAuth: this.options.cookieAuth,
|
|
1147
1247
|
headerLinks: this.options.headerLinks,
|
|
1148
|
-
enableLlmsTxt: this.options.enableLlmsTxt
|
|
1248
|
+
enableLlmsTxt: this.options.enableLlmsTxt,
|
|
1249
|
+
baseUrl: this.options.baseUrl,
|
|
1250
|
+
docsPath: this.options.docsPath,
|
|
1251
|
+
apiPath: this.options.apiPath,
|
|
1252
|
+
changelogPath: this.options.changelogPath,
|
|
1253
|
+
docsUrl: this.buildUrlPath(this.options.baseUrl, this.options.docsPath),
|
|
1254
|
+
apiUrl: this.buildUrlPath(this.options.baseUrl, this.options.apiPath),
|
|
1255
|
+
changelogUrl: this.buildUrlPath(
|
|
1256
|
+
this.options.baseUrl,
|
|
1257
|
+
this.options.changelogPath
|
|
1258
|
+
)
|
|
1149
1259
|
};
|
|
1260
|
+
const readmePath = `${this.options.sitePath}/README.md`;
|
|
1261
|
+
if (doculaData.hasReadme) {
|
|
1262
|
+
currentAssetHashes["README.md"] = this.hashFile(readmePath);
|
|
1263
|
+
}
|
|
1150
1264
|
if (!doculaData.openApiUrl && fs3.existsSync(`${doculaData.sitePath}/api/swagger.json`)) {
|
|
1151
|
-
doculaData.openApiUrl =
|
|
1265
|
+
doculaData.openApiUrl = this.buildUrlPath(
|
|
1266
|
+
this.options.baseUrl,
|
|
1267
|
+
this.options.apiPath,
|
|
1268
|
+
"swagger.json"
|
|
1269
|
+
);
|
|
1152
1270
|
}
|
|
1153
1271
|
if (this.options.githubPath) {
|
|
1154
1272
|
doculaData.github = await this.getGithubData(this.options.githubPath);
|
|
1155
1273
|
}
|
|
1156
1274
|
doculaData.documents = this.getDocuments(
|
|
1157
1275
|
`${doculaData.sitePath}/docs`,
|
|
1158
|
-
doculaData
|
|
1276
|
+
doculaData,
|
|
1277
|
+
cachedDocs,
|
|
1278
|
+
validManifest?.docs ?? {},
|
|
1279
|
+
currentDocHashes
|
|
1159
1280
|
);
|
|
1160
1281
|
doculaData.sections = this.getSections(
|
|
1161
1282
|
`${doculaData.sitePath}/docs`,
|
|
@@ -1164,14 +1285,31 @@ var DoculaBuilder = class {
|
|
|
1164
1285
|
doculaData.hasDocuments = doculaData.documents?.length > 0;
|
|
1165
1286
|
doculaData.hasFeed = doculaData.hasDocuments;
|
|
1166
1287
|
const changelogPath = `${doculaData.sitePath}/changelog`;
|
|
1167
|
-
const fileChangelogEntries = this.getChangelogEntries(
|
|
1288
|
+
const fileChangelogEntries = this.getChangelogEntries(
|
|
1289
|
+
changelogPath,
|
|
1290
|
+
cachedChangelog,
|
|
1291
|
+
validManifest?.changelog ?? {},
|
|
1292
|
+
currentChangelogHashes
|
|
1293
|
+
);
|
|
1168
1294
|
const hasChangelogTemplate = await this.getTemplateFile(resolvedTemplatePath, "changelog") !== void 0;
|
|
1169
1295
|
let allChangelogEntries = [...fileChangelogEntries];
|
|
1170
1296
|
if (this._options.enableReleaseChangelog && hasChangelogTemplate && doculaData.github?.releases && Array.isArray(doculaData.github.releases) && doculaData.github.releases.length > 0) {
|
|
1171
|
-
|
|
1297
|
+
let releaseEntries = this.getReleasesAsChangelogEntries(
|
|
1172
1298
|
// biome-ignore lint/suspicious/noExplicitAny: GitHub release objects
|
|
1173
1299
|
doculaData.github.releases
|
|
1174
1300
|
);
|
|
1301
|
+
if (this.onReleaseChangelog) {
|
|
1302
|
+
try {
|
|
1303
|
+
releaseEntries = await this.onReleaseChangelog(
|
|
1304
|
+
releaseEntries,
|
|
1305
|
+
this._console
|
|
1306
|
+
);
|
|
1307
|
+
} catch (error) {
|
|
1308
|
+
this._console.error(
|
|
1309
|
+
`onReleaseChangelog error: ${error.message}`
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1175
1313
|
allChangelogEntries = [...allChangelogEntries, ...releaseEntries];
|
|
1176
1314
|
}
|
|
1177
1315
|
allChangelogEntries.sort((a, b) => {
|
|
@@ -1198,17 +1336,21 @@ var DoculaBuilder = class {
|
|
|
1198
1336
|
doculaData.hasApi = Boolean(
|
|
1199
1337
|
doculaData.openApiUrl && doculaData.templates?.api
|
|
1200
1338
|
);
|
|
1339
|
+
doculaData.lastModified = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1201
1340
|
this._console.step("Building pages...");
|
|
1202
|
-
if (
|
|
1341
|
+
if (doculaData.hasReadme) {
|
|
1342
|
+
await this.buildIndexPage(doculaData);
|
|
1343
|
+
this._console.fileBuilt("index.html");
|
|
1344
|
+
} else if (doculaData.hasDocuments) {
|
|
1203
1345
|
await this.buildDocsHomePage(doculaData);
|
|
1204
1346
|
this._console.fileBuilt("index.html");
|
|
1205
|
-
} else if (
|
|
1347
|
+
} else if (doculaData.hasApi) {
|
|
1348
|
+
await this.buildApiHomePage(doculaData);
|
|
1349
|
+
this._console.fileBuilt("index.html");
|
|
1350
|
+
} else {
|
|
1206
1351
|
this._console.error(
|
|
1207
|
-
"
|
|
1352
|
+
"No content found for the home page. Add a README.md, docs/ folder, or api/swagger.json to your site directory."
|
|
1208
1353
|
);
|
|
1209
|
-
} else {
|
|
1210
|
-
await this.buildIndexPage(doculaData);
|
|
1211
|
-
this._console.fileBuilt("index.html");
|
|
1212
1354
|
}
|
|
1213
1355
|
await this.buildSiteMapPage(doculaData);
|
|
1214
1356
|
this._console.fileBuilt("sitemap.xml");
|
|
@@ -1228,34 +1370,55 @@ var DoculaBuilder = class {
|
|
|
1228
1370
|
if (doculaData.hasApi) {
|
|
1229
1371
|
this._console.step("Building API page...");
|
|
1230
1372
|
await this.buildApiPage(doculaData);
|
|
1231
|
-
this._console.fileBuilt(
|
|
1373
|
+
this._console.fileBuilt(`${this.options.apiPath}/index.html`);
|
|
1232
1374
|
}
|
|
1233
1375
|
if (doculaData.hasChangelog) {
|
|
1234
1376
|
this._console.step("Building changelog...");
|
|
1235
1377
|
await this.buildChangelogPage(doculaData);
|
|
1236
|
-
this._console.fileBuilt(
|
|
1378
|
+
this._console.fileBuilt(`${this.options.changelogPath}/index.html`);
|
|
1237
1379
|
await this.buildChangelogEntryPages(doculaData);
|
|
1238
1380
|
for (const entry of doculaData.changelogEntries ?? []) {
|
|
1239
|
-
this._console.fileBuilt(
|
|
1381
|
+
this._console.fileBuilt(
|
|
1382
|
+
`${this.options.changelogPath}/${entry.slug}/index.html`
|
|
1383
|
+
);
|
|
1240
1384
|
}
|
|
1241
1385
|
}
|
|
1242
1386
|
const siteRelativePath = this.options.sitePath;
|
|
1387
|
+
const previousAssets = validManifest?.assets ?? {};
|
|
1243
1388
|
this._console.step("Copying assets...");
|
|
1244
|
-
if (
|
|
1389
|
+
if (!this.hashAssetAndCheckSkip(
|
|
1390
|
+
`${siteRelativePath}/favicon.ico`,
|
|
1391
|
+
`${this.options.output}/favicon.ico`,
|
|
1392
|
+
"favicon.ico",
|
|
1393
|
+
previousAssets,
|
|
1394
|
+
currentAssetHashes
|
|
1395
|
+
)) {
|
|
1245
1396
|
await fs3.promises.copyFile(
|
|
1246
1397
|
`${siteRelativePath}/favicon.ico`,
|
|
1247
1398
|
`${this.options.output}/favicon.ico`
|
|
1248
1399
|
);
|
|
1249
1400
|
this._console.fileCopied("favicon.ico");
|
|
1250
1401
|
}
|
|
1251
|
-
if (
|
|
1402
|
+
if (!this.hashAssetAndCheckSkip(
|
|
1403
|
+
`${siteRelativePath}/logo.svg`,
|
|
1404
|
+
`${this.options.output}/logo.svg`,
|
|
1405
|
+
"logo.svg",
|
|
1406
|
+
previousAssets,
|
|
1407
|
+
currentAssetHashes
|
|
1408
|
+
)) {
|
|
1252
1409
|
await fs3.promises.copyFile(
|
|
1253
1410
|
`${siteRelativePath}/logo.svg`,
|
|
1254
1411
|
`${this.options.output}/logo.svg`
|
|
1255
1412
|
);
|
|
1256
1413
|
this._console.fileCopied("logo.svg");
|
|
1257
1414
|
}
|
|
1258
|
-
if (
|
|
1415
|
+
if (!this.hashAssetAndCheckSkip(
|
|
1416
|
+
`${siteRelativePath}/logo_horizontal.png`,
|
|
1417
|
+
`${this.options.output}/logo_horizontal.png`,
|
|
1418
|
+
"logo_horizontal.png",
|
|
1419
|
+
previousAssets,
|
|
1420
|
+
currentAssetHashes
|
|
1421
|
+
)) {
|
|
1259
1422
|
await fs3.promises.copyFile(
|
|
1260
1423
|
`${siteRelativePath}/logo_horizontal.png`,
|
|
1261
1424
|
`${this.options.output}/logo_horizontal.png`
|
|
@@ -1263,30 +1426,51 @@ var DoculaBuilder = class {
|
|
|
1263
1426
|
this._console.fileCopied("logo_horizontal.png");
|
|
1264
1427
|
}
|
|
1265
1428
|
if (fs3.existsSync(`${resolvedTemplatePath}/css`)) {
|
|
1266
|
-
this.
|
|
1429
|
+
this.copyDirectoryWithHashing(
|
|
1267
1430
|
`${resolvedTemplatePath}/css`,
|
|
1268
|
-
`${this.options.output}/css
|
|
1431
|
+
`${this.options.output}/css`,
|
|
1432
|
+
"css",
|
|
1433
|
+
previousAssets,
|
|
1434
|
+
currentAssetHashes
|
|
1269
1435
|
);
|
|
1270
1436
|
this._console.fileCopied("css/");
|
|
1271
1437
|
}
|
|
1272
1438
|
if (fs3.existsSync(`${resolvedTemplatePath}/js`)) {
|
|
1273
|
-
this.
|
|
1439
|
+
this.copyDirectoryWithHashing(
|
|
1274
1440
|
`${resolvedTemplatePath}/js`,
|
|
1275
|
-
`${this.options.output}/js
|
|
1441
|
+
`${this.options.output}/js`,
|
|
1442
|
+
"js",
|
|
1443
|
+
previousAssets,
|
|
1444
|
+
currentAssetHashes
|
|
1276
1445
|
);
|
|
1277
1446
|
this._console.fileCopied("js/");
|
|
1278
1447
|
}
|
|
1279
|
-
if (
|
|
1448
|
+
if (!this.hashAssetAndCheckSkip(
|
|
1449
|
+
`${siteRelativePath}/variables.css`,
|
|
1450
|
+
`${this.options.output}/css/variables.css`,
|
|
1451
|
+
"variables.css",
|
|
1452
|
+
previousAssets,
|
|
1453
|
+
currentAssetHashes
|
|
1454
|
+
)) {
|
|
1280
1455
|
await fs3.promises.copyFile(
|
|
1281
1456
|
`${siteRelativePath}/variables.css`,
|
|
1282
1457
|
`${this.options.output}/css/variables.css`
|
|
1283
1458
|
);
|
|
1284
1459
|
this._console.fileCopied("css/variables.css");
|
|
1285
1460
|
}
|
|
1286
|
-
|
|
1461
|
+
const swaggerPath = `${siteRelativePath}/api/swagger.json`;
|
|
1462
|
+
if (fs3.existsSync(swaggerPath)) {
|
|
1463
|
+
currentAssetHashes["api/swagger.json"] = this.hashFile(swaggerPath);
|
|
1464
|
+
}
|
|
1465
|
+
this.copyPublicFolder(
|
|
1466
|
+
siteRelativePath,
|
|
1467
|
+
this.options.output,
|
|
1468
|
+
validManifest?.assets ?? {},
|
|
1469
|
+
currentAssetHashes
|
|
1470
|
+
);
|
|
1287
1471
|
this.copyContentAssets(
|
|
1288
1472
|
`${doculaData.sitePath}/changelog`,
|
|
1289
|
-
`${this.options.output}
|
|
1473
|
+
`${this.options.output}/${this.options.changelogPath}`
|
|
1290
1474
|
);
|
|
1291
1475
|
if (doculaData.documents?.length) {
|
|
1292
1476
|
this.copyDocumentSiblingAssets(doculaData);
|
|
@@ -1295,6 +1479,18 @@ var DoculaBuilder = class {
|
|
|
1295
1479
|
this._console.step("Building LLM files...");
|
|
1296
1480
|
}
|
|
1297
1481
|
await this.buildLlmsFiles(doculaData);
|
|
1482
|
+
this.ensureCacheInGitignore(this.options.sitePath);
|
|
1483
|
+
const newManifest = {
|
|
1484
|
+
version: 1,
|
|
1485
|
+
configHash: currentConfigHash,
|
|
1486
|
+
templateHash: currentTemplateHash,
|
|
1487
|
+
docs: currentDocHashes,
|
|
1488
|
+
changelog: currentChangelogHashes,
|
|
1489
|
+
assets: currentAssetHashes
|
|
1490
|
+
};
|
|
1491
|
+
this.saveBuildManifest(this.options.sitePath, newManifest);
|
|
1492
|
+
this.saveCachedDocuments(this.options.sitePath, doculaData.documents ?? []);
|
|
1493
|
+
this.saveCachedChangelog(this.options.sitePath, fileChangelogEntries);
|
|
1298
1494
|
const endTime = Date.now();
|
|
1299
1495
|
const executionTime = endTime - startTime;
|
|
1300
1496
|
this._console.success(`Build completed in ${executionTime}ms`);
|
|
@@ -1382,16 +1578,30 @@ var DoculaBuilder = class {
|
|
|
1382
1578
|
const sitemapPath = `${data.output}/sitemap.xml`;
|
|
1383
1579
|
const urls = [{ url: data.siteUrl }];
|
|
1384
1580
|
if (data.documents?.length) {
|
|
1385
|
-
urls.push({ url: `${data.siteUrl}/feed.xml` });
|
|
1581
|
+
urls.push({ url: `${data.siteUrl}${data.baseUrl}/feed.xml` });
|
|
1386
1582
|
}
|
|
1387
1583
|
if (data.openApiUrl && data.templates?.api) {
|
|
1388
|
-
urls.push({
|
|
1584
|
+
urls.push({
|
|
1585
|
+
url: `${data.siteUrl}${data.apiUrl}`
|
|
1586
|
+
});
|
|
1389
1587
|
}
|
|
1390
1588
|
if (data.hasChangelog && data.templates?.changelog) {
|
|
1391
|
-
urls.push({
|
|
1589
|
+
urls.push({
|
|
1590
|
+
url: `${data.siteUrl}${data.changelogUrl}`
|
|
1591
|
+
});
|
|
1592
|
+
const perPage = this.options.changelogPerPage;
|
|
1593
|
+
const totalPages = Math.max(
|
|
1594
|
+
1,
|
|
1595
|
+
Math.ceil((data.changelogEntries ?? []).length / perPage)
|
|
1596
|
+
);
|
|
1597
|
+
for (let page = 2; page <= totalPages; page++) {
|
|
1598
|
+
urls.push({
|
|
1599
|
+
url: `${data.siteUrl}${data.changelogUrl}/page/${page}`
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1392
1602
|
for (const entry of data.changelogEntries ?? []) {
|
|
1393
1603
|
urls.push({
|
|
1394
|
-
url: `${data.siteUrl}
|
|
1604
|
+
url: `${data.siteUrl}${data.changelogUrl}/${entry.slug}`
|
|
1395
1605
|
});
|
|
1396
1606
|
}
|
|
1397
1607
|
}
|
|
@@ -1400,7 +1610,7 @@ var DoculaBuilder = class {
|
|
|
1400
1610
|
if (urlPath.endsWith("index.html")) {
|
|
1401
1611
|
urlPath = urlPath.slice(0, -10);
|
|
1402
1612
|
}
|
|
1403
|
-
urls.push({ url: `${data.siteUrl}${urlPath}` });
|
|
1613
|
+
urls.push({ url: `${data.siteUrl}${data.baseUrl}${urlPath}` });
|
|
1404
1614
|
}
|
|
1405
1615
|
let xml = '<?xml version="1.0" encoding="UTF-8"?>';
|
|
1406
1616
|
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
|
@@ -1418,8 +1628,14 @@ var DoculaBuilder = class {
|
|
|
1418
1628
|
return;
|
|
1419
1629
|
}
|
|
1420
1630
|
const feedPath = `${data.output}/feed.xml`;
|
|
1421
|
-
const channelLink = this.buildAbsoluteSiteUrl(
|
|
1422
|
-
|
|
1631
|
+
const channelLink = this.buildAbsoluteSiteUrl(
|
|
1632
|
+
data.siteUrl,
|
|
1633
|
+
`${data.baseUrl}/`
|
|
1634
|
+
);
|
|
1635
|
+
const feedUrl = this.buildAbsoluteSiteUrl(
|
|
1636
|
+
data.siteUrl,
|
|
1637
|
+
`${data.baseUrl}/feed.xml`
|
|
1638
|
+
);
|
|
1423
1639
|
let xml = '<?xml version="1.0" encoding="UTF-8"?>';
|
|
1424
1640
|
xml += '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
|
|
1425
1641
|
xml += "<channel>";
|
|
@@ -1432,7 +1648,7 @@ var DoculaBuilder = class {
|
|
|
1432
1648
|
const itemTitle = document.navTitle || document.title || document.urlPath;
|
|
1433
1649
|
const itemLink = this.buildAbsoluteSiteUrl(
|
|
1434
1650
|
data.siteUrl,
|
|
1435
|
-
this.normalizePathForUrl(document.urlPath)
|
|
1651
|
+
`${data.baseUrl}${this.normalizePathForUrl(document.urlPath)}`
|
|
1436
1652
|
);
|
|
1437
1653
|
const summary = document.description || this.summarizeMarkdown(new Writr(document.content).body);
|
|
1438
1654
|
xml += "<item>";
|
|
@@ -1490,7 +1706,7 @@ var DoculaBuilder = class {
|
|
|
1490
1706
|
lines.push(data.siteDescription);
|
|
1491
1707
|
lines.push("");
|
|
1492
1708
|
lines.push(
|
|
1493
|
-
`- [Full LLM Content](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1709
|
+
`- [Full LLM Content](${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.baseUrl}/llms-full.txt`)})`
|
|
1494
1710
|
);
|
|
1495
1711
|
lines.push("");
|
|
1496
1712
|
lines.push("## Documentation");
|
|
@@ -1498,7 +1714,7 @@ var DoculaBuilder = class {
|
|
|
1498
1714
|
for (const document of documents) {
|
|
1499
1715
|
const documentUrl = this.buildAbsoluteSiteUrl(
|
|
1500
1716
|
data.siteUrl,
|
|
1501
|
-
this.normalizePathForUrl(document.urlPath)
|
|
1717
|
+
`${data.baseUrl}${this.normalizePathForUrl(document.urlPath)}`
|
|
1502
1718
|
);
|
|
1503
1719
|
const description = document.description ? ` - ${document.description}` : "";
|
|
1504
1720
|
lines.push(`- [${document.navTitle}](${documentUrl})${description}`);
|
|
@@ -1510,7 +1726,7 @@ var DoculaBuilder = class {
|
|
|
1510
1726
|
lines.push("## API Reference");
|
|
1511
1727
|
if (data.hasApi) {
|
|
1512
1728
|
lines.push(
|
|
1513
|
-
`- [API Documentation](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1729
|
+
`- [API Documentation](${this.buildAbsoluteSiteUrl(data.siteUrl, data.apiUrl)})`
|
|
1514
1730
|
);
|
|
1515
1731
|
} else {
|
|
1516
1732
|
lines.push("- Not available.");
|
|
@@ -1519,12 +1735,12 @@ var DoculaBuilder = class {
|
|
|
1519
1735
|
lines.push("## Changelog");
|
|
1520
1736
|
if (data.hasChangelog) {
|
|
1521
1737
|
lines.push(
|
|
1522
|
-
`- [Changelog](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1738
|
+
`- [Changelog](${this.buildAbsoluteSiteUrl(data.siteUrl, data.changelogUrl)})`
|
|
1523
1739
|
);
|
|
1524
1740
|
for (const entry of changelogEntries.slice(0, 20)) {
|
|
1525
1741
|
const date = entry.formattedDate || entry.date || "No date";
|
|
1526
1742
|
lines.push(
|
|
1527
|
-
`- [${entry.title}](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1743
|
+
`- [${entry.title}](${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.changelogUrl}/${entry.slug}`)}) (${date})`
|
|
1528
1744
|
);
|
|
1529
1745
|
}
|
|
1530
1746
|
} else {
|
|
@@ -1542,7 +1758,7 @@ var DoculaBuilder = class {
|
|
|
1542
1758
|
lines.push(data.siteDescription);
|
|
1543
1759
|
lines.push("");
|
|
1544
1760
|
lines.push(
|
|
1545
|
-
`Source Index: ${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1761
|
+
`Source Index: ${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.baseUrl}/llms.txt`)}`
|
|
1546
1762
|
);
|
|
1547
1763
|
lines.push("");
|
|
1548
1764
|
lines.push("## Documentation");
|
|
@@ -1550,7 +1766,7 @@ var DoculaBuilder = class {
|
|
|
1550
1766
|
for (const document of documents) {
|
|
1551
1767
|
const documentUrl = this.buildAbsoluteSiteUrl(
|
|
1552
1768
|
data.siteUrl,
|
|
1553
|
-
this.normalizePathForUrl(document.urlPath)
|
|
1769
|
+
`${data.baseUrl}${this.normalizePathForUrl(document.urlPath)}`
|
|
1554
1770
|
);
|
|
1555
1771
|
const markdownBody = new Writr(document.content).body.trim();
|
|
1556
1772
|
lines.push("");
|
|
@@ -1568,7 +1784,9 @@ var DoculaBuilder = class {
|
|
|
1568
1784
|
lines.push("");
|
|
1569
1785
|
lines.push("## API Reference");
|
|
1570
1786
|
if (data.hasApi) {
|
|
1571
|
-
lines.push(
|
|
1787
|
+
lines.push(
|
|
1788
|
+
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl, data.apiUrl)}`
|
|
1789
|
+
);
|
|
1572
1790
|
lines.push("");
|
|
1573
1791
|
const localOpenApiSpec = await this.getSafeLocalOpenApiSpec(data);
|
|
1574
1792
|
if (localOpenApiSpec) {
|
|
@@ -1590,13 +1808,13 @@ var DoculaBuilder = class {
|
|
|
1590
1808
|
lines.push("## Changelog");
|
|
1591
1809
|
if (data.hasChangelog && changelogEntries.length > 0) {
|
|
1592
1810
|
lines.push(
|
|
1593
|
-
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1811
|
+
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl, data.changelogUrl)}`
|
|
1594
1812
|
);
|
|
1595
1813
|
for (const entry of changelogEntries) {
|
|
1596
1814
|
lines.push("");
|
|
1597
1815
|
lines.push(`### ${entry.title}`);
|
|
1598
1816
|
lines.push(
|
|
1599
|
-
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1817
|
+
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.changelogUrl}/${entry.slug}`)}`
|
|
1600
1818
|
);
|
|
1601
1819
|
if (entry.formattedDate || entry.date) {
|
|
1602
1820
|
lines.push(`Date: ${entry.formattedDate || entry.date}`);
|
|
@@ -1613,6 +1831,16 @@ var DoculaBuilder = class {
|
|
|
1613
1831
|
lines.push("");
|
|
1614
1832
|
return lines.join("\n");
|
|
1615
1833
|
}
|
|
1834
|
+
buildUrlPath(...segments) {
|
|
1835
|
+
const cleaned = segments.filter((s) => Boolean(s)).map((s) => {
|
|
1836
|
+
let start = 0;
|
|
1837
|
+
let end = s.length;
|
|
1838
|
+
while (start < end && s[start] === "/") start++;
|
|
1839
|
+
while (end > start && s[end - 1] === "/") end--;
|
|
1840
|
+
return s.slice(start, end);
|
|
1841
|
+
});
|
|
1842
|
+
return `/${cleaned.filter(Boolean).join("/")}`;
|
|
1843
|
+
}
|
|
1616
1844
|
buildAbsoluteSiteUrl(siteUrl, urlPath) {
|
|
1617
1845
|
const normalizedSiteUrl = siteUrl.endsWith("/") ? siteUrl.slice(0, -1) : siteUrl;
|
|
1618
1846
|
const normalizedPath = urlPath.startsWith("/") ? urlPath : `/${urlPath}`;
|
|
@@ -1756,10 +1984,10 @@ var DoculaBuilder = class {
|
|
|
1756
1984
|
}
|
|
1757
1985
|
async buildDocsHomePage(data) {
|
|
1758
1986
|
if (!data.templates?.docPage) {
|
|
1759
|
-
throw new Error("No docPage template found for
|
|
1987
|
+
throw new Error("No docPage template found for docs home page");
|
|
1760
1988
|
}
|
|
1761
1989
|
if (!data.documents?.length) {
|
|
1762
|
-
throw new Error("No documents found for
|
|
1990
|
+
throw new Error("No documents found for docs home page");
|
|
1763
1991
|
}
|
|
1764
1992
|
const indexPath = `${data.output}/index.html`;
|
|
1765
1993
|
await fs3.promises.mkdir(data.output, { recursive: true });
|
|
@@ -1797,7 +2025,9 @@ var DoculaBuilder = class {
|
|
|
1797
2025
|
async buildDocsPages(data) {
|
|
1798
2026
|
if (data.templates && data.documents?.length) {
|
|
1799
2027
|
const documentsTemplate = `${data.templatePath}/${data.templates.docPage}`;
|
|
1800
|
-
|
|
2028
|
+
const resolvedDocsPath = data.docsPath;
|
|
2029
|
+
const docsOutputDir = resolvedDocsPath ? `${data.output}/${resolvedDocsPath}` : `${data.output}`;
|
|
2030
|
+
await fs3.promises.mkdir(docsOutputDir, { recursive: true });
|
|
1801
2031
|
data.sidebarItems = this.generateSidebarItems(data);
|
|
1802
2032
|
const promises = data.documents.map(async (document) => {
|
|
1803
2033
|
const folder = document.urlPath.split("/").slice(0, -1).join("/");
|
|
@@ -1817,14 +2047,13 @@ var DoculaBuilder = class {
|
|
|
1817
2047
|
throw new Error("No templates found");
|
|
1818
2048
|
}
|
|
1819
2049
|
}
|
|
1820
|
-
async
|
|
2050
|
+
async renderApiContent(data) {
|
|
1821
2051
|
if (!data.openApiUrl || !data.templates?.api) {
|
|
1822
|
-
|
|
2052
|
+
throw new Error("No API template or openApiUrl found");
|
|
1823
2053
|
}
|
|
1824
|
-
const apiPath = `${data.output}/api/index.html`;
|
|
1825
|
-
const apiOutputPath = `${data.output}/api`;
|
|
1826
|
-
await fs3.promises.mkdir(apiOutputPath, { recursive: true });
|
|
1827
2054
|
const swaggerSource = `${data.sitePath}/api/swagger.json`;
|
|
2055
|
+
const apiOutputPath = `${data.output}/${data.apiPath}`;
|
|
2056
|
+
await fs3.promises.mkdir(apiOutputPath, { recursive: true });
|
|
1828
2057
|
if (fs3.existsSync(swaggerSource)) {
|
|
1829
2058
|
await fs3.promises.copyFile(
|
|
1830
2059
|
swaggerSource,
|
|
@@ -1855,14 +2084,27 @@ var DoculaBuilder = class {
|
|
|
1855
2084
|
}
|
|
1856
2085
|
}
|
|
1857
2086
|
const apiTemplate = `${data.templatePath}/${data.templates.api}`;
|
|
1858
|
-
|
|
2087
|
+
return this._ecto.renderFromFile(
|
|
1859
2088
|
apiTemplate,
|
|
1860
2089
|
{ ...data, specUrl: data.openApiUrl, apiSpec },
|
|
1861
2090
|
data.templatePath
|
|
1862
2091
|
);
|
|
2092
|
+
}
|
|
2093
|
+
async buildApiPage(data) {
|
|
2094
|
+
if (!data.openApiUrl || !data.templates?.api) {
|
|
2095
|
+
return;
|
|
2096
|
+
}
|
|
2097
|
+
const apiPath = `${data.output}/${data.apiPath}/index.html`;
|
|
2098
|
+
const apiContent = await this.renderApiContent(data);
|
|
1863
2099
|
await fs3.promises.writeFile(apiPath, apiContent, "utf8");
|
|
1864
2100
|
}
|
|
1865
|
-
|
|
2101
|
+
async buildApiHomePage(data) {
|
|
2102
|
+
const indexPath = `${data.output}/index.html`;
|
|
2103
|
+
await fs3.promises.mkdir(data.output, { recursive: true });
|
|
2104
|
+
const apiContent = await this.renderApiContent(data);
|
|
2105
|
+
await fs3.promises.writeFile(indexPath, apiContent, "utf8");
|
|
2106
|
+
}
|
|
2107
|
+
getChangelogEntries(changelogPath, cachedEntries, previousHashes, currentHashes) {
|
|
1866
2108
|
const entries = [];
|
|
1867
2109
|
if (!fs3.existsSync(changelogPath)) {
|
|
1868
2110
|
return entries;
|
|
@@ -1872,6 +2114,16 @@ var DoculaBuilder = class {
|
|
|
1872
2114
|
const filePath = `${changelogPath}/${file}`;
|
|
1873
2115
|
const stats = fs3.statSync(filePath);
|
|
1874
2116
|
if (stats.isFile() && (file.endsWith(".md") || file.endsWith(".mdx"))) {
|
|
2117
|
+
if (cachedEntries && previousHashes && currentHashes) {
|
|
2118
|
+
const slug = path5.basename(file, path5.extname(file));
|
|
2119
|
+
const hash = currentHashes[file] ?? this.hashFile(filePath);
|
|
2120
|
+
const prevHash = previousHashes[file];
|
|
2121
|
+
const cached = cachedEntries.get(slug);
|
|
2122
|
+
if (cached && prevHash === hash) {
|
|
2123
|
+
entries.push(cached);
|
|
2124
|
+
continue;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
1875
2127
|
const entry = this.parseChangelogEntry(filePath);
|
|
1876
2128
|
entries.push(entry);
|
|
1877
2129
|
}
|
|
@@ -1898,7 +2150,7 @@ var DoculaBuilder = class {
|
|
|
1898
2150
|
const matterData = writr.frontMatter;
|
|
1899
2151
|
const markdownContent = writr.body;
|
|
1900
2152
|
const fileName = path5.basename(filePath, path5.extname(filePath));
|
|
1901
|
-
const slug = fileName
|
|
2153
|
+
const slug = fileName;
|
|
1902
2154
|
const isMdx = filePath.endsWith(".mdx");
|
|
1903
2155
|
const tag = matterData.tag;
|
|
1904
2156
|
const tagClass = tag ? tag.toLowerCase().replace(/\s+/g, "-") : void 0;
|
|
@@ -1917,6 +2169,7 @@ var DoculaBuilder = class {
|
|
|
1917
2169
|
day: "numeric"
|
|
1918
2170
|
});
|
|
1919
2171
|
}
|
|
2172
|
+
const previewImage = matterData.previewImage;
|
|
1920
2173
|
return {
|
|
1921
2174
|
title: matterData.title ?? fileName,
|
|
1922
2175
|
date: dateString,
|
|
@@ -1926,9 +2179,73 @@ var DoculaBuilder = class {
|
|
|
1926
2179
|
slug,
|
|
1927
2180
|
content: markdownContent,
|
|
1928
2181
|
generatedHtml: new Writr(markdownContent).renderSync({ mdx: isMdx }),
|
|
1929
|
-
|
|
2182
|
+
preview: this.generateChangelogPreview(markdownContent, 500, isMdx),
|
|
2183
|
+
previewImage,
|
|
2184
|
+
urlPath: `/${this.options.changelogPath}/${slug}/index.html`,
|
|
2185
|
+
lastModified: fs3.statSync(filePath).mtime.toISOString().split("T")[0]
|
|
1930
2186
|
};
|
|
1931
2187
|
}
|
|
2188
|
+
generateChangelogPreview(markdown, maxLength = 500, mdx = false) {
|
|
2189
|
+
const minLength = 300;
|
|
2190
|
+
let cleaned = markdown.split("\n").filter((line) => !/^#{1,6}\s/.test(line)).join("\n");
|
|
2191
|
+
cleaned = cleaned.replace(/^\n+/, "");
|
|
2192
|
+
cleaned = cleaned.replace(/!\[[^\]]*\]\([^)]*\)/g, "");
|
|
2193
|
+
cleaned = cleaned.replace(/\[([^\]]*)\]\([^)]*\)/g, "$1");
|
|
2194
|
+
cleaned = cleaned.replace(/^\n+/, "").trim();
|
|
2195
|
+
if (cleaned.length <= minLength) {
|
|
2196
|
+
return new Writr(cleaned).renderSync({ mdx });
|
|
2197
|
+
}
|
|
2198
|
+
const searchArea = cleaned.slice(0, maxLength);
|
|
2199
|
+
let splitIndex = -1;
|
|
2200
|
+
let pos = searchArea.lastIndexOf("\n\n");
|
|
2201
|
+
while (pos >= 0) {
|
|
2202
|
+
if (pos >= minLength) {
|
|
2203
|
+
splitIndex = pos;
|
|
2204
|
+
break;
|
|
2205
|
+
}
|
|
2206
|
+
if (splitIndex === -1) {
|
|
2207
|
+
splitIndex = pos;
|
|
2208
|
+
}
|
|
2209
|
+
pos = searchArea.lastIndexOf("\n\n", pos - 1);
|
|
2210
|
+
}
|
|
2211
|
+
if (splitIndex === -1) {
|
|
2212
|
+
const lastNewline = searchArea.lastIndexOf("\n");
|
|
2213
|
+
if (lastNewline >= minLength) {
|
|
2214
|
+
const nextLine = cleaned.slice(lastNewline + 1);
|
|
2215
|
+
if (/^[-*]\s/.test(nextLine) || /^\d+\.\s/.test(nextLine)) {
|
|
2216
|
+
splitIndex = lastNewline;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
if (splitIndex === -1) {
|
|
2220
|
+
const lines = searchArea.split("\n");
|
|
2221
|
+
let charCount = 0;
|
|
2222
|
+
let lastItemEnd = -1;
|
|
2223
|
+
for (const line of lines) {
|
|
2224
|
+
const lineEnd = charCount + line.length;
|
|
2225
|
+
if (lineEnd <= maxLength && (/^[-*]\s/.test(line) || /^\d+\.\s/.test(line))) {
|
|
2226
|
+
if (charCount > 0 && charCount >= minLength) {
|
|
2227
|
+
lastItemEnd = charCount - 1;
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
charCount = lineEnd + 1;
|
|
2231
|
+
}
|
|
2232
|
+
if (lastItemEnd > 0) {
|
|
2233
|
+
splitIndex = lastItemEnd;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
if (splitIndex > 0) {
|
|
2238
|
+
const truncated2 = cleaned.slice(0, splitIndex).trim();
|
|
2239
|
+
return new Writr(truncated2).renderSync({ mdx });
|
|
2240
|
+
}
|
|
2241
|
+
let truncated = cleaned.slice(0, maxLength);
|
|
2242
|
+
const lastSpace = truncated.lastIndexOf(" ");
|
|
2243
|
+
if (lastSpace > 0) {
|
|
2244
|
+
truncated = truncated.slice(0, lastSpace);
|
|
2245
|
+
}
|
|
2246
|
+
truncated += "...";
|
|
2247
|
+
return new Writr(truncated).renderSync({ mdx });
|
|
2248
|
+
}
|
|
1932
2249
|
convertReleaseToChangelogEntry(release) {
|
|
1933
2250
|
const tagName = release.tag_name ?? "";
|
|
1934
2251
|
const slug = tagName.replace(/\./g, "-");
|
|
@@ -1960,7 +2277,9 @@ var DoculaBuilder = class {
|
|
|
1960
2277
|
slug,
|
|
1961
2278
|
content: body,
|
|
1962
2279
|
generatedHtml: new Writr(body).renderSync(),
|
|
1963
|
-
|
|
2280
|
+
preview: this.generateChangelogPreview(body),
|
|
2281
|
+
urlPath: `/${this.options.changelogPath}/${slug}/index.html`,
|
|
2282
|
+
lastModified: dateString
|
|
1964
2283
|
};
|
|
1965
2284
|
}
|
|
1966
2285
|
getReleasesAsChangelogEntries(releases) {
|
|
@@ -1977,16 +2296,41 @@ var DoculaBuilder = class {
|
|
|
1977
2296
|
if (!data.hasChangelog || !data.templates?.changelog) {
|
|
1978
2297
|
return;
|
|
1979
2298
|
}
|
|
1980
|
-
const
|
|
1981
|
-
const
|
|
1982
|
-
|
|
2299
|
+
const allEntries = data.changelogEntries ?? [];
|
|
2300
|
+
const perPage = this.options.changelogPerPage;
|
|
2301
|
+
const totalPages = Math.max(1, Math.ceil(allEntries.length / perPage));
|
|
1983
2302
|
const changelogTemplate = `${data.templatePath}/${data.templates.changelog}`;
|
|
1984
|
-
const
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
2303
|
+
const promises = [];
|
|
2304
|
+
for (let page = 1; page <= totalPages; page++) {
|
|
2305
|
+
const startIndex = (page - 1) * perPage;
|
|
2306
|
+
const pageEntries = allEntries.slice(startIndex, startIndex + perPage);
|
|
2307
|
+
const changelogOutputBase = `${data.output}/${data.changelogPath}`;
|
|
2308
|
+
const outputPath = page === 1 ? changelogOutputBase : `${changelogOutputBase}/page/${page}`;
|
|
2309
|
+
const indexPath = `${outputPath}/index.html`;
|
|
2310
|
+
const paginationData = {
|
|
2311
|
+
...data,
|
|
2312
|
+
entries: pageEntries,
|
|
2313
|
+
currentPage: page,
|
|
2314
|
+
totalPages,
|
|
2315
|
+
hasPagination: totalPages > 1,
|
|
2316
|
+
hasNextPage: page < totalPages,
|
|
2317
|
+
hasPrevPage: page > 1,
|
|
2318
|
+
nextPageUrl: page < totalPages ? `${data.changelogUrl}/page/${page + 1}/` : "",
|
|
2319
|
+
prevPageUrl: page > 1 ? page === 2 ? `${data.changelogUrl}/` : `${data.changelogUrl}/page/${page - 1}/` : ""
|
|
2320
|
+
};
|
|
2321
|
+
promises.push(
|
|
2322
|
+
(async () => {
|
|
2323
|
+
await fs3.promises.mkdir(outputPath, { recursive: true });
|
|
2324
|
+
const content = await this._ecto.renderFromFile(
|
|
2325
|
+
changelogTemplate,
|
|
2326
|
+
paginationData,
|
|
2327
|
+
data.templatePath
|
|
2328
|
+
);
|
|
2329
|
+
await fs3.promises.writeFile(indexPath, content, "utf8");
|
|
2330
|
+
})()
|
|
2331
|
+
);
|
|
2332
|
+
}
|
|
2333
|
+
await Promise.all(promises);
|
|
1990
2334
|
}
|
|
1991
2335
|
async buildChangelogEntryPages(data) {
|
|
1992
2336
|
if (!data.hasChangelog || !data.templates?.changelogEntry || !data.changelogEntries?.length) {
|
|
@@ -1994,7 +2338,7 @@ var DoculaBuilder = class {
|
|
|
1994
2338
|
}
|
|
1995
2339
|
const entryTemplate = `${data.templatePath}/${data.templates.changelogEntry}`;
|
|
1996
2340
|
const promises = data.changelogEntries.map(async (entry) => {
|
|
1997
|
-
const entryOutputPath = `${data.output}
|
|
2341
|
+
const entryOutputPath = `${data.output}/${data.changelogPath}/${entry.slug}`;
|
|
1998
2342
|
await fs3.promises.mkdir(entryOutputPath, { recursive: true });
|
|
1999
2343
|
const entryContent = await this._ecto.renderFromFile(
|
|
2000
2344
|
entryTemplate,
|
|
@@ -2007,11 +2351,16 @@ var DoculaBuilder = class {
|
|
|
2007
2351
|
await Promise.all(promises);
|
|
2008
2352
|
}
|
|
2009
2353
|
generateSidebarItems(data) {
|
|
2010
|
-
let sidebarItems =
|
|
2354
|
+
let sidebarItems = (data.sections ?? []).map(
|
|
2355
|
+
(section) => ({
|
|
2356
|
+
...section,
|
|
2357
|
+
children: section.children ? [...section.children] : void 0
|
|
2358
|
+
})
|
|
2359
|
+
);
|
|
2011
2360
|
for (const document of data.documents ?? []) {
|
|
2012
2361
|
if (document.isRoot) {
|
|
2013
2362
|
sidebarItems.unshift({
|
|
2014
|
-
path: document.urlPath.replace("index.html", "")
|
|
2363
|
+
path: `${data.baseUrl}${document.urlPath.replace("index.html", "")}`,
|
|
2015
2364
|
name: document.navTitle,
|
|
2016
2365
|
order: document.order
|
|
2017
2366
|
});
|
|
@@ -2033,7 +2382,7 @@ var DoculaBuilder = class {
|
|
|
2033
2382
|
}
|
|
2034
2383
|
sidebarItems[sectionIndex].children ??= [];
|
|
2035
2384
|
sidebarItems[sectionIndex].children.push({
|
|
2036
|
-
path: document.urlPath.replace("index.html", "")
|
|
2385
|
+
path: `${data.baseUrl}${document.urlPath.replace("index.html", "")}`,
|
|
2037
2386
|
name: document.navTitle,
|
|
2038
2387
|
order: document.order
|
|
2039
2388
|
});
|
|
@@ -2056,27 +2405,49 @@ var DoculaBuilder = class {
|
|
|
2056
2405
|
);
|
|
2057
2406
|
return sidebarItems;
|
|
2058
2407
|
}
|
|
2059
|
-
getDocuments(sitePath, doculaData) {
|
|
2408
|
+
getDocuments(sitePath, doculaData, cachedDocs, previousDocHashes, currentDocHashes) {
|
|
2060
2409
|
let documents = [];
|
|
2061
2410
|
if (fs3.existsSync(sitePath)) {
|
|
2062
|
-
documents = this.getDocumentInDirectory(
|
|
2411
|
+
documents = this.getDocumentInDirectory(
|
|
2412
|
+
sitePath,
|
|
2413
|
+
sitePath,
|
|
2414
|
+
cachedDocs,
|
|
2415
|
+
previousDocHashes,
|
|
2416
|
+
currentDocHashes
|
|
2417
|
+
);
|
|
2063
2418
|
doculaData.sections = this.getSections(sitePath, this.options);
|
|
2064
2419
|
for (const section of doculaData.sections) {
|
|
2065
2420
|
const sectionPath = `${sitePath}/${section.path}`;
|
|
2066
|
-
const sectionDocuments = this.getDocumentInDirectory(
|
|
2421
|
+
const sectionDocuments = this.getDocumentInDirectory(
|
|
2422
|
+
sectionPath,
|
|
2423
|
+
sitePath,
|
|
2424
|
+
cachedDocs,
|
|
2425
|
+
previousDocHashes,
|
|
2426
|
+
currentDocHashes
|
|
2427
|
+
);
|
|
2067
2428
|
documents = [...documents, ...sectionDocuments];
|
|
2068
2429
|
}
|
|
2069
2430
|
}
|
|
2070
2431
|
return documents;
|
|
2071
2432
|
}
|
|
2072
|
-
getDocumentInDirectory(sitePath) {
|
|
2433
|
+
getDocumentInDirectory(sitePath, docsRootPath, cachedDocs, previousDocHashes, currentDocHashes) {
|
|
2073
2434
|
const documents = [];
|
|
2074
2435
|
const documentList = fs3.readdirSync(sitePath);
|
|
2075
2436
|
if (documentList.length > 0) {
|
|
2076
2437
|
for (const document of documentList) {
|
|
2077
2438
|
const documentPath = `${sitePath}/${document}`;
|
|
2439
|
+
const relativeKey = path5.relative(docsRootPath, documentPath);
|
|
2078
2440
|
const stats = fs3.statSync(documentPath);
|
|
2079
2441
|
if (stats.isFile() && (document.endsWith(".md") || document.endsWith(".mdx"))) {
|
|
2442
|
+
if (cachedDocs && previousDocHashes && currentDocHashes) {
|
|
2443
|
+
const hash = currentDocHashes[relativeKey] ?? this.hashFile(documentPath);
|
|
2444
|
+
const prevHash = previousDocHashes[relativeKey];
|
|
2445
|
+
const cached = cachedDocs.get(relativeKey);
|
|
2446
|
+
if (cached && prevHash === hash) {
|
|
2447
|
+
documents.push(cached);
|
|
2448
|
+
continue;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2080
2451
|
const documentData = this.parseDocumentData(documentPath);
|
|
2081
2452
|
documents.push(documentData);
|
|
2082
2453
|
}
|
|
@@ -2133,13 +2504,19 @@ var DoculaBuilder = class {
|
|
|
2133
2504
|
const isMdx = documentPath.endsWith(".mdx");
|
|
2134
2505
|
const fileExtension = isMdx ? ".mdx" : ".md";
|
|
2135
2506
|
const documentsFolderIndex = documentPath.lastIndexOf("/docs/");
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2507
|
+
const relativePath = documentPath.slice(documentsFolderIndex + 6);
|
|
2508
|
+
const docsPrefix = this.options.docsPath ? `/${this.options.docsPath}` : "";
|
|
2509
|
+
let urlPath = `${docsPrefix}/${relativePath}`.replace(
|
|
2510
|
+
fileExtension,
|
|
2511
|
+
"/index.html"
|
|
2512
|
+
);
|
|
2513
|
+
const isRoot = !relativePath.includes("/");
|
|
2514
|
+
if (isRoot) {
|
|
2515
|
+
if (relativePath === "index.md" || relativePath === "index.mdx") {
|
|
2516
|
+
urlPath = `${docsPrefix}/${relativePath}`.replace(
|
|
2517
|
+
fileExtension,
|
|
2518
|
+
".html"
|
|
2519
|
+
);
|
|
2143
2520
|
}
|
|
2144
2521
|
}
|
|
2145
2522
|
if (!this.hasTableOfContents(markdownContent)) {
|
|
@@ -2166,7 +2543,8 @@ ${markdownContent.slice(firstH2)}`;
|
|
|
2166
2543
|
}),
|
|
2167
2544
|
documentPath,
|
|
2168
2545
|
urlPath,
|
|
2169
|
-
isRoot
|
|
2546
|
+
isRoot,
|
|
2547
|
+
lastModified: fs3.statSync(documentPath).mtime.toISOString().split("T")[0]
|
|
2170
2548
|
};
|
|
2171
2549
|
}
|
|
2172
2550
|
hasTableOfContents(markdown) {
|
|
@@ -2200,9 +2578,45 @@ ${markdownContent.slice(firstH2)}`;
|
|
|
2200
2578
|
return resolvedTemplatePath;
|
|
2201
2579
|
}
|
|
2202
2580
|
const overrideFiles = this.listFilesRecursive(overrideDir);
|
|
2203
|
-
if (fs3.existsSync(cacheDir)
|
|
2204
|
-
this.
|
|
2205
|
-
|
|
2581
|
+
if (fs3.existsSync(cacheDir)) {
|
|
2582
|
+
const diff = this.getChangedOverrides(
|
|
2583
|
+
overrideDir,
|
|
2584
|
+
cacheDir,
|
|
2585
|
+
overrideFiles
|
|
2586
|
+
);
|
|
2587
|
+
if (diff) {
|
|
2588
|
+
const hasChanges = diff.added.length > 0 || diff.changed.length > 0 || diff.removed.length > 0;
|
|
2589
|
+
if (!hasChanges) {
|
|
2590
|
+
this._console.step("Using cached template overrides...");
|
|
2591
|
+
return cacheDir;
|
|
2592
|
+
}
|
|
2593
|
+
this._console.step("Updating template overrides...");
|
|
2594
|
+
for (const file of diff.added) {
|
|
2595
|
+
this._console.info(`Template override added: ${file}`);
|
|
2596
|
+
const targetPath = path5.join(cacheDir, file);
|
|
2597
|
+
fs3.mkdirSync(path5.dirname(targetPath), { recursive: true });
|
|
2598
|
+
fs3.copyFileSync(path5.join(overrideDir, file), targetPath);
|
|
2599
|
+
}
|
|
2600
|
+
for (const file of diff.changed) {
|
|
2601
|
+
this._console.info(`Template override changed: ${file}`);
|
|
2602
|
+
const targetPath = path5.join(cacheDir, file);
|
|
2603
|
+
fs3.mkdirSync(path5.dirname(targetPath), { recursive: true });
|
|
2604
|
+
fs3.copyFileSync(path5.join(overrideDir, file), targetPath);
|
|
2605
|
+
}
|
|
2606
|
+
for (const file of diff.removed) {
|
|
2607
|
+
this._console.info(`Template override removed: ${file}`);
|
|
2608
|
+
const cachedPath = path5.join(cacheDir, file);
|
|
2609
|
+
const originalPath = path5.join(resolvedTemplatePath, file);
|
|
2610
|
+
if (fs3.existsSync(originalPath)) {
|
|
2611
|
+
fs3.copyFileSync(originalPath, cachedPath);
|
|
2612
|
+
} else if (fs3.existsSync(cachedPath)) {
|
|
2613
|
+
fs3.unlinkSync(cachedPath);
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
const manifestPath2 = path5.join(cacheDir, ".manifest.json");
|
|
2617
|
+
fs3.writeFileSync(manifestPath2, JSON.stringify(diff.currentHashes));
|
|
2618
|
+
return cacheDir;
|
|
2619
|
+
}
|
|
2206
2620
|
}
|
|
2207
2621
|
if (overrideFiles.length > 0) {
|
|
2208
2622
|
this._console.step("Applying template overrides...");
|
|
@@ -2217,8 +2631,12 @@ ${markdownContent.slice(firstH2)}`;
|
|
|
2217
2631
|
fs3.mkdirSync(cacheDir, { recursive: true });
|
|
2218
2632
|
this.copyDirectory(resolvedTemplatePath, cacheDir);
|
|
2219
2633
|
this.copyDirectory(overrideDir, cacheDir);
|
|
2634
|
+
const currentHashes = {};
|
|
2635
|
+
for (const file of overrideFiles) {
|
|
2636
|
+
currentHashes[file] = this.hashFile(path5.join(overrideDir, file));
|
|
2637
|
+
}
|
|
2220
2638
|
const manifestPath = path5.join(cacheDir, ".manifest.json");
|
|
2221
|
-
fs3.writeFileSync(manifestPath, JSON.stringify(
|
|
2639
|
+
fs3.writeFileSync(manifestPath, JSON.stringify(currentHashes));
|
|
2222
2640
|
return cacheDir;
|
|
2223
2641
|
}
|
|
2224
2642
|
ensureCacheInGitignore(sitePath) {
|
|
@@ -2245,34 +2663,43 @@ ${entry}
|
|
|
2245
2663
|
this._console.info("Created .gitignore with .cache");
|
|
2246
2664
|
}
|
|
2247
2665
|
}
|
|
2248
|
-
|
|
2666
|
+
getChangedOverrides(overrideDir, cacheDir, overrideFiles) {
|
|
2249
2667
|
const manifestPath = path5.join(cacheDir, ".manifest.json");
|
|
2250
2668
|
if (!fs3.existsSync(manifestPath)) {
|
|
2251
|
-
return
|
|
2669
|
+
return void 0;
|
|
2252
2670
|
}
|
|
2671
|
+
let previousHashes;
|
|
2253
2672
|
try {
|
|
2254
|
-
|
|
2673
|
+
previousHashes = JSON.parse(
|
|
2255
2674
|
fs3.readFileSync(manifestPath, "utf8")
|
|
2256
2675
|
);
|
|
2257
|
-
if (previousFiles.length !== overrideFiles.length || !previousFiles.every((f, i) => f === overrideFiles[i])) {
|
|
2258
|
-
return false;
|
|
2259
|
-
}
|
|
2260
2676
|
} catch {
|
|
2261
|
-
return
|
|
2677
|
+
return void 0;
|
|
2262
2678
|
}
|
|
2679
|
+
const currentHashes = {};
|
|
2263
2680
|
for (const file of overrideFiles) {
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2681
|
+
currentHashes[file] = this.hashFile(path5.join(overrideDir, file));
|
|
2682
|
+
}
|
|
2683
|
+
const added = [];
|
|
2684
|
+
const changed = [];
|
|
2685
|
+
const removed = [];
|
|
2686
|
+
for (const file of overrideFiles) {
|
|
2687
|
+
if (!(file in previousHashes)) {
|
|
2688
|
+
added.push(file);
|
|
2689
|
+
} else if (currentHashes[file] !== previousHashes[file]) {
|
|
2690
|
+
changed.push(file);
|
|
2268
2691
|
}
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
if (
|
|
2272
|
-
|
|
2692
|
+
}
|
|
2693
|
+
for (const file of Object.keys(previousHashes)) {
|
|
2694
|
+
if (!overrideFiles.includes(file)) {
|
|
2695
|
+
removed.push(file);
|
|
2273
2696
|
}
|
|
2274
2697
|
}
|
|
2275
|
-
return
|
|
2698
|
+
return { added, changed, removed, currentHashes };
|
|
2699
|
+
}
|
|
2700
|
+
hashFile(filePath) {
|
|
2701
|
+
const content = fs3.readFileSync(filePath);
|
|
2702
|
+
return this._hash.toHashSync(content);
|
|
2276
2703
|
}
|
|
2277
2704
|
listFilesRecursive(dir, prefix = "") {
|
|
2278
2705
|
const results = [];
|
|
@@ -2316,16 +2743,23 @@ ${entry}
|
|
|
2316
2743
|
}
|
|
2317
2744
|
}
|
|
2318
2745
|
}
|
|
2319
|
-
copyPublicFolder(sitePath, output) {
|
|
2746
|
+
copyPublicFolder(sitePath, output, previousAssets, currentAssets) {
|
|
2320
2747
|
const publicPath = `${sitePath}/public`;
|
|
2321
2748
|
if (!fs3.existsSync(publicPath)) {
|
|
2322
2749
|
return;
|
|
2323
2750
|
}
|
|
2324
2751
|
this._console.step("Copying public folder...");
|
|
2325
2752
|
const resolvedOutput = path5.resolve(output);
|
|
2326
|
-
this.copyPublicDirectory(
|
|
2753
|
+
this.copyPublicDirectory(
|
|
2754
|
+
publicPath,
|
|
2755
|
+
output,
|
|
2756
|
+
publicPath,
|
|
2757
|
+
resolvedOutput,
|
|
2758
|
+
previousAssets,
|
|
2759
|
+
currentAssets
|
|
2760
|
+
);
|
|
2327
2761
|
}
|
|
2328
|
-
copyPublicDirectory(source, target, basePath, output) {
|
|
2762
|
+
copyPublicDirectory(source, target, basePath, output, previousAssets, currentAssets) {
|
|
2329
2763
|
const files = fs3.readdirSync(source);
|
|
2330
2764
|
for (const file of files) {
|
|
2331
2765
|
const sourcePath = `${source}/${file}`;
|
|
@@ -2341,8 +2775,21 @@ ${entry}
|
|
|
2341
2775
|
}
|
|
2342
2776
|
if (stat.isDirectory()) {
|
|
2343
2777
|
fs3.mkdirSync(targetPath, { recursive: true });
|
|
2344
|
-
this.copyPublicDirectory(
|
|
2778
|
+
this.copyPublicDirectory(
|
|
2779
|
+
sourcePath,
|
|
2780
|
+
targetPath,
|
|
2781
|
+
basePath,
|
|
2782
|
+
output,
|
|
2783
|
+
previousAssets,
|
|
2784
|
+
currentAssets
|
|
2785
|
+
);
|
|
2345
2786
|
} else {
|
|
2787
|
+
const assetKey = `public/${relativePath}`;
|
|
2788
|
+
const hash = this.hashFile(sourcePath);
|
|
2789
|
+
currentAssets[assetKey] = hash;
|
|
2790
|
+
if (previousAssets[assetKey] === hash && fs3.existsSync(targetPath)) {
|
|
2791
|
+
continue;
|
|
2792
|
+
}
|
|
2346
2793
|
fs3.mkdirSync(target, { recursive: true });
|
|
2347
2794
|
fs3.copyFileSync(sourcePath, targetPath);
|
|
2348
2795
|
this._console.fileCopied(relativePath);
|
|
@@ -2397,6 +2844,214 @@ ${entry}
|
|
|
2397
2844
|
}
|
|
2398
2845
|
return results;
|
|
2399
2846
|
}
|
|
2847
|
+
loadBuildManifest(sitePath) {
|
|
2848
|
+
const manifestPath = path5.join(
|
|
2849
|
+
sitePath,
|
|
2850
|
+
".cache",
|
|
2851
|
+
"build",
|
|
2852
|
+
"manifest.json"
|
|
2853
|
+
);
|
|
2854
|
+
if (!fs3.existsSync(manifestPath)) {
|
|
2855
|
+
return void 0;
|
|
2856
|
+
}
|
|
2857
|
+
try {
|
|
2858
|
+
const data = JSON.parse(
|
|
2859
|
+
fs3.readFileSync(manifestPath, "utf8")
|
|
2860
|
+
);
|
|
2861
|
+
if (data.version !== 1) {
|
|
2862
|
+
return void 0;
|
|
2863
|
+
}
|
|
2864
|
+
return data;
|
|
2865
|
+
} catch {
|
|
2866
|
+
return void 0;
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
saveBuildManifest(sitePath, manifest) {
|
|
2870
|
+
const dir = path5.join(sitePath, ".cache", "build");
|
|
2871
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
2872
|
+
fs3.writeFileSync(path5.join(dir, "manifest.json"), JSON.stringify(manifest));
|
|
2873
|
+
}
|
|
2874
|
+
hashOptions() {
|
|
2875
|
+
const relevant = {
|
|
2876
|
+
siteUrl: this.options.siteUrl,
|
|
2877
|
+
siteTitle: this.options.siteTitle,
|
|
2878
|
+
siteDescription: this.options.siteDescription,
|
|
2879
|
+
githubPath: this.options.githubPath,
|
|
2880
|
+
template: this.options.template,
|
|
2881
|
+
templatePath: this.options.templatePath,
|
|
2882
|
+
enableLlmsTxt: this.options.enableLlmsTxt,
|
|
2883
|
+
changelogPerPage: this.options.changelogPerPage,
|
|
2884
|
+
enableReleaseChangelog: this.options.enableReleaseChangelog,
|
|
2885
|
+
sections: this.options.sections,
|
|
2886
|
+
openApiUrl: this.options.openApiUrl,
|
|
2887
|
+
themeMode: this.options.themeMode,
|
|
2888
|
+
cookieAuth: this.options.cookieAuth,
|
|
2889
|
+
headerLinks: this.options.headerLinks,
|
|
2890
|
+
baseUrl: this.options.baseUrl,
|
|
2891
|
+
docsPath: this.options.docsPath,
|
|
2892
|
+
apiPath: this.options.apiPath,
|
|
2893
|
+
changelogPath: this.options.changelogPath
|
|
2894
|
+
};
|
|
2895
|
+
return this._hash.toHashSync(JSON.stringify(relevant));
|
|
2896
|
+
}
|
|
2897
|
+
hashTemplateDirectory(templatePath) {
|
|
2898
|
+
if (!fs3.existsSync(templatePath)) {
|
|
2899
|
+
return "";
|
|
2900
|
+
}
|
|
2901
|
+
const files = this.listFilesRecursive(templatePath);
|
|
2902
|
+
const hashes = files.map((f) => this.hashFile(path5.join(templatePath, f)));
|
|
2903
|
+
return this._hash.toHashSync(hashes.join(""));
|
|
2904
|
+
}
|
|
2905
|
+
loadCachedDocuments(sitePath) {
|
|
2906
|
+
const cachePath = path5.join(sitePath, ".cache", "build", "documents.json");
|
|
2907
|
+
if (!fs3.existsSync(cachePath)) {
|
|
2908
|
+
return /* @__PURE__ */ new Map();
|
|
2909
|
+
}
|
|
2910
|
+
try {
|
|
2911
|
+
const data = JSON.parse(fs3.readFileSync(cachePath, "utf8"));
|
|
2912
|
+
return new Map(Object.entries(data));
|
|
2913
|
+
} catch {
|
|
2914
|
+
return /* @__PURE__ */ new Map();
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
saveCachedDocuments(sitePath, documents) {
|
|
2918
|
+
const dir = path5.join(sitePath, ".cache", "build");
|
|
2919
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
2920
|
+
const docsRoot = path5.join(sitePath, "docs");
|
|
2921
|
+
const map = {};
|
|
2922
|
+
for (const doc of documents) {
|
|
2923
|
+
const relativeKey = path5.relative(docsRoot, doc.documentPath);
|
|
2924
|
+
map[relativeKey] = doc;
|
|
2925
|
+
}
|
|
2926
|
+
fs3.writeFileSync(path5.join(dir, "documents.json"), JSON.stringify(map));
|
|
2927
|
+
}
|
|
2928
|
+
loadCachedChangelog(sitePath) {
|
|
2929
|
+
const cachePath = path5.join(sitePath, ".cache", "build", "changelog.json");
|
|
2930
|
+
if (!fs3.existsSync(cachePath)) {
|
|
2931
|
+
return /* @__PURE__ */ new Map();
|
|
2932
|
+
}
|
|
2933
|
+
try {
|
|
2934
|
+
const data = JSON.parse(fs3.readFileSync(cachePath, "utf8"));
|
|
2935
|
+
return new Map(Object.entries(data));
|
|
2936
|
+
} catch {
|
|
2937
|
+
return /* @__PURE__ */ new Map();
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
saveCachedChangelog(sitePath, entries) {
|
|
2941
|
+
const dir = path5.join(sitePath, ".cache", "build");
|
|
2942
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
2943
|
+
const map = {};
|
|
2944
|
+
for (const entry of entries) {
|
|
2945
|
+
map[entry.slug] = entry;
|
|
2946
|
+
}
|
|
2947
|
+
fs3.writeFileSync(path5.join(dir, "changelog.json"), JSON.stringify(map));
|
|
2948
|
+
}
|
|
2949
|
+
hashSourceFiles(dir) {
|
|
2950
|
+
const hashes = {};
|
|
2951
|
+
if (!fs3.existsSync(dir)) {
|
|
2952
|
+
return hashes;
|
|
2953
|
+
}
|
|
2954
|
+
const files = this.listFilesRecursive(dir);
|
|
2955
|
+
for (const file of files) {
|
|
2956
|
+
const fullPath = path5.join(dir, file);
|
|
2957
|
+
hashes[file] = this.hashFile(fullPath);
|
|
2958
|
+
}
|
|
2959
|
+
return hashes;
|
|
2960
|
+
}
|
|
2961
|
+
recordsEqual(a, b) {
|
|
2962
|
+
const keysA = Object.keys(a);
|
|
2963
|
+
const keysB = Object.keys(b);
|
|
2964
|
+
if (keysA.length !== keysB.length) {
|
|
2965
|
+
return false;
|
|
2966
|
+
}
|
|
2967
|
+
for (const key of keysA) {
|
|
2968
|
+
if (a[key] !== b[key]) {
|
|
2969
|
+
return false;
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
return true;
|
|
2973
|
+
}
|
|
2974
|
+
hasAssetsChanged(sitePath, previousAssets) {
|
|
2975
|
+
const assetFiles = [
|
|
2976
|
+
"favicon.ico",
|
|
2977
|
+
"logo.svg",
|
|
2978
|
+
"logo_horizontal.png",
|
|
2979
|
+
"variables.css",
|
|
2980
|
+
"api/swagger.json",
|
|
2981
|
+
"README.md"
|
|
2982
|
+
];
|
|
2983
|
+
for (const file of assetFiles) {
|
|
2984
|
+
const filePath = path5.join(sitePath, file);
|
|
2985
|
+
if (fs3.existsSync(filePath)) {
|
|
2986
|
+
const hash = this.hashFile(filePath);
|
|
2987
|
+
if (previousAssets[file] !== hash) {
|
|
2988
|
+
return true;
|
|
2989
|
+
}
|
|
2990
|
+
} else if (previousAssets[file]) {
|
|
2991
|
+
return true;
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
const publicPath = path5.join(sitePath, "public");
|
|
2995
|
+
if (fs3.existsSync(publicPath)) {
|
|
2996
|
+
const publicHashes = this.hashSourceFiles(publicPath);
|
|
2997
|
+
for (const [file, hash] of Object.entries(publicHashes)) {
|
|
2998
|
+
if (previousAssets[`public/${file}`] !== hash) {
|
|
2999
|
+
return true;
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
return false;
|
|
3004
|
+
}
|
|
3005
|
+
/**
|
|
3006
|
+
* Hashes the source file, records it in currentAssets, and returns
|
|
3007
|
+
* whether the copy can be skipped (unchanged from previous build).
|
|
3008
|
+
*/
|
|
3009
|
+
hashAssetAndCheckSkip(sourcePath, targetPath, assetKey, previousAssets, currentAssets) {
|
|
3010
|
+
if (!fs3.existsSync(sourcePath)) {
|
|
3011
|
+
return true;
|
|
3012
|
+
}
|
|
3013
|
+
const hash = this.hashFile(sourcePath);
|
|
3014
|
+
currentAssets[assetKey] = hash;
|
|
3015
|
+
if (previousAssets[assetKey] === hash && fs3.existsSync(targetPath)) {
|
|
3016
|
+
return true;
|
|
3017
|
+
}
|
|
3018
|
+
return false;
|
|
3019
|
+
}
|
|
3020
|
+
copyDirectoryWithHashing(source, target, prefix, previousAssets, currentAssets) {
|
|
3021
|
+
if (!fs3.existsSync(source)) {
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
3024
|
+
const files = fs3.readdirSync(source);
|
|
3025
|
+
for (const file of files) {
|
|
3026
|
+
if (file.startsWith(".")) {
|
|
3027
|
+
continue;
|
|
3028
|
+
}
|
|
3029
|
+
const sourcePath = `${source}/${file}`;
|
|
3030
|
+
const targetPath = `${target}/${file}`;
|
|
3031
|
+
const assetKey = prefix ? `${prefix}/${file}` : file;
|
|
3032
|
+
const stat = fs3.lstatSync(sourcePath);
|
|
3033
|
+
if (stat.isSymbolicLink()) {
|
|
3034
|
+
continue;
|
|
3035
|
+
}
|
|
3036
|
+
if (stat.isDirectory()) {
|
|
3037
|
+
this.copyDirectoryWithHashing(
|
|
3038
|
+
sourcePath,
|
|
3039
|
+
targetPath,
|
|
3040
|
+
assetKey,
|
|
3041
|
+
previousAssets,
|
|
3042
|
+
currentAssets
|
|
3043
|
+
);
|
|
3044
|
+
} else {
|
|
3045
|
+
const hash = this.hashFile(sourcePath);
|
|
3046
|
+
currentAssets[assetKey] = hash;
|
|
3047
|
+
if (previousAssets[assetKey] === hash && fs3.existsSync(targetPath)) {
|
|
3048
|
+
continue;
|
|
3049
|
+
}
|
|
3050
|
+
fs3.mkdirSync(target, { recursive: true });
|
|
3051
|
+
fs3.copyFileSync(sourcePath, targetPath);
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
2400
3055
|
copyContentAssets(sourcePath, targetPath) {
|
|
2401
3056
|
if (!fs3.existsSync(sourcePath)) {
|
|
2402
3057
|
return;
|
|
@@ -2426,8 +3081,8 @@ ${entry}
|
|
|
2426
3081
|
};
|
|
2427
3082
|
|
|
2428
3083
|
// src/init.ts
|
|
2429
|
-
var doculaconfigmjs = "
|
|
2430
|
-
var doculaconfigts = "aW1wb3J0IHR5cGUgeyBEb2N1bGFPcHRpb25zIH0gZnJvbSAnZG9jdWxhJzsKCmV4cG9ydCBjb25zdCBvcHRpb25zOiBQYXJ0aWFsPERvY3VsYU9wdGlvbnM+
|
|
3084
|
+
var doculaconfigmjs = "ZXhwb3J0IGNvbnN0IG9wdGlvbnMgPSB7CglvdXRwdXQ6ICcuL2Rpc3QnLAoJc2l0ZVBhdGg6ICcuL3NpdGUnLAoJZ2l0aHViUGF0aDogJ2phcmVkd3JheS9kb2N1bGEnLAoJc2l0ZVRpdGxlOiAnRG9jdWxhJywKCXNpdGVEZXNjcmlwdGlvbjogJ0JlYXV0aWZ1bCBXZWJzaXRlIGZvciBZb3VyIFByb2plY3RzJywKCXNpdGVVcmw6ICdodHRwczovL2RvY3VsYS5vcmcnLAoJLy8gb3BlbkFwaVVybDogJy9hcGkvc3dhZ2dlci5qc29uJywKCS8vIGVuYWJsZVJlbGVhc2VDaGFuZ2Vsb2c6IHRydWUsCgkvLyBlbmFibGVMbG1zVHh0OiB0cnVlLAoJLy8gdGhlbWVNb2RlOiAnbGlnaHQnLAp9Owo=";
|
|
3085
|
+
var doculaconfigts = "aW1wb3J0IHR5cGUgeyBEb2N1bGFPcHRpb25zIH0gZnJvbSAnZG9jdWxhJzsKCmV4cG9ydCBjb25zdCBvcHRpb25zOiBQYXJ0aWFsPERvY3VsYU9wdGlvbnM+ID0gewoJb3V0cHV0OiAnLi9kaXN0JywKCXNpdGVQYXRoOiAnLi9zaXRlJywKCWdpdGh1YlBhdGg6ICdqYXJlZHdyYXkvZG9jdWxhJywKCXNpdGVUaXRsZTogJ0RvY3VsYScsCglzaXRlRGVzY3JpcHRpb246ICdCZWF1dGlmdWwgV2Vic2l0ZSBmb3IgWW91ciBQcm9qZWN0cycsCglzaXRlVXJsOiAnaHR0cHM6Ly9kb2N1bGEub3JnJywKCS8vIG9wZW5BcGlVcmw6ICcvYXBpL3N3YWdnZXIuanNvbicsCgkvLyBlbmFibGVSZWxlYXNlQ2hhbmdlbG9nOiB0cnVlLAoJLy8gZW5hYmxlTGxtc1R4dDogdHJ1ZSwKCS8vIHRoZW1lTW9kZTogJ2xpZ2h0JywKfTsK";
|
|
2431
3086
|
var faviconico = "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";
|
|
2432
3087
|
var logopng = "iVBORw0KGgoAAAANSUhEUgAAAxEAAAHXCAYAAADDSdfmAAAACXBIWXMAACxLAAAsSwGlPZapAAAFw2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDMgNzkuOTY5MGE4N2ZjLCAyMDI1LzAzLzA2LTIwOjUwOjE2ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjYuNiAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjUtMDUtMThUMTM6MzM6NTgtMDc6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDI1LTA1LTE4VDEzOjM2OjE5LTA3OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDI1LTA1LTE4VDEzOjM2OjE5LTA3OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5YTc4ZDY2Ny02NjAzLTQwNmUtYTViZC02MjYzMTNjY2VmY2QiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MGJkNzg5ZDMtYzhhMy00YjI3LTg0MTQtNDMzMzk2ZTgzZWQ4IiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MGJkNzg5ZDMtYzhhMy00YjI3LTg0MTQtNDMzMzk2ZTgzZWQ4Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowYmQ3ODlkMy1jOGEzLTRiMjctODQxNC00MzMzOTZlODNlZDgiIHN0RXZ0OndoZW49IjIwMjUtMDUtMThUMTM6MzM6NTgtMDc6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNi42IChNYWNpbnRvc2gpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5YTc4ZDY2Ny02NjAzLTQwNmUtYTViZC02MjYzMTNjY2VmY2QiIHN0RXZ0OndoZW49IjIwMjUtMDUtMThUMTM6MzY6MTktMDc6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNi42IChNYWNpbnRvc2gpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkbQgEQAAGtJSURBVHja7Z0H2BzVebYP6r13IQkJGRBNNAGmGHCJe28xLvFvx524JXacxIlbHNyCiR3bsROMsWMDNuDecSg2TaIIIZCEQBX19hX1Av95psirZcvM7PS57+t6r+/b3dmZ2bOzM+8z5y1HPfXUUwYAAAAAACAofRgCAAAAAABARAAAAAAAACICAAAAAAAQEQAAAAAAgIgAAAAAAABEBAAAAAAAACICAAAAAAAQEQAAAAAAgIgAAAAAAABEBAAAAAAAICIAAAAAAAARAQAAAAAAgIgAAAAAAABEBAAAAAAAICIAAAAAAAARAQAAAAAAiAgAAAAAAEBEAAAAAAAAICIAAAAAAAARAQAAAAAAiAgAAAAAAEBEAAAAAAAAIgIAAAAAAAARAQAAAAAAiAgAAAAAAEBEAAAAAAAAIgIAAAAAABARAAAAAACAiAAAAAAAAEBEAAAAAAAAIgIAAAAAABARAAAAAACAiAAAAAAAAEQEAAAAAAAgIgAAAAAAABARAAAAAACAiAAAAAAAAEQEAAAAAAAgIgAAAAAAABEBAAAAAACICAAAAAAAAEQEAAAAAAAkQL+87+CZp154+P+jjjrqaa/XP9fucZjlomwvzn3Iet15GPM0152H93GshN+HQYMGmfXr15tFixaZgQMHFun8e5m171nr5lIUipda0xd9QxF29sknnzQDBgwwI0eONE899VQmv6mynGdYN+su+3VUfPryjyEiAACgKZda+6q1sdY+xXCE4svWBlv7P2vbGQ4AgGwgnAkAIF3ebe373v+ftPZOhiQwv7R2rLUp1v7k/Q8AAIgIAIBS8wFr36h77pvW/pKhacvPrb2o5vEca3dYm8XQAAAgIgAAyiwgrmzy2rXW3sEQtRQQL2nw/ERrdyIkAAAQEQAAZeSDLQSEz7eMG+oEf0Z5e79oIiAQEgAAiAgAgFILiC8HXFahTp9myBwmeeLgxQGWRUgAACAiAABKwwdCCAiff7Z2jbX+FR63M63dbW1eiPcgJAAAEBEAAKUQEFdGfO9brN1l7RkVHLe3WbvX2owI7/WFBFWbAAAQEQAAlRIQProbf7+111dkzAZZ+x9rV3W4HoQEAAAiAgCgkgLCZ5i16zzHeniJx+yZ1uZbe3tM65tgKP8KAICIAABoxlFHHWUOHjxoDh065PxfIgFRi0J8NCvxgpJ9faq+dLlxZw5OiXnd5EgAACAiAAAaIwExfPhwM3ToUOf/DHlbQgLCZ7a1Xxu323UZQnWe7wmjjyW4DV9IjOGXAgCAiAAAOMyBAwfMqFGjzIgRI7IUEcpbuCqlbV1q7RFrn7A2pIBf2WnWbrL2GxP/7EMzIfFHhAQAACICAOAwOQhneo1x8xbSZIC1T3pi4oPWBhfgqzrV2tXWHrD2ypS3faK1262N5BcDAICIAADImout/SjD7asM6pc9MfEha6NyOEZneuLhQWtvzXA/TrL2B2t9097wwIEDTZ8+XG4BABEBAADGnGfckJw8cIy1K6wt9/6emfH+yFF/rbWfGrfnw1tzMk4al5vTvvYhIAAAEQEAAOIEzxkdmLP9GmfcGQk57grfea+1mSlu/yJrX7D2uLUfWntZDr+7i63dmOYGn3rqKX4xAFA6+jEEAAChmGbtFpP/PIQLPdtnbYG13xq3d4I6Ye+NaRuTrD3buH0eVG2pKB22X2HtGmt/xeEMAICIAICKoju9qtKUAmM8ATGpQMOj2ZILPBNbrC21do9xZwxWWnvCe35rk/ereZtmOdRzQXkYyi8403s8tKCHzVusbbL2UX5BAACICACoIH379jWjR482vb29SZ8vbzPF79Ew3rML657X4O1s8rlHmPyFbsXBR6xts/b5JAWuLAeNEAEAEBEAALVOWr9+/czYsWPN6tWrk9zUr6ydXOKhHO5Z1fictS5r30zq2JQ9+eST/FgBoFSQWA0ApRASCTeaU5fo5zHSpeW/rL0qKRHRv39/RAQAICIAAPIqJBKqgvNF43aJhnJzg7VzC3RcAgAgIgAAOkUx5wnEnatc6t8xutU4hIxbweoYhgIAABEBABVg//79Zty4cU5ydYxVmjT7cAWjWymUQK7+GiMZCgAARAQAlBzFm8ecwPos4+ZBQPVQH5A/GHdmomMGDhxIZSYAQEQAAOQROWkSD4cOHYrDYVPvg18wqpVGPTB+GMtFtg+XWQBARAAA5F5MdIjCWW421Sx1CkfyGmtf6GQFSqimKhMAICIAAHKKX0pz8uTJnVbC+bm1mYwoeKgZ3bs6OSZlVGcCAEQEAEBeT2Z9+nTqsF1l3FwIgFrUQ+L5iAgAAEQEAJQQvx5/xJCmv7f2NkYRmvBja7PDvkmhTAgIAEBEAADkGJV5HTt2bJQyr6+09jlGEFow2Lg9JIaEeZNmIQAAEBEAADlGd3z79u0btkPwHGs/YvQgAKradVOYNwwYMIDyrgCAiAAAyDty2EaODNwnbJi131jry8hBQJQb8e9BRS2VmQAAEQEAkHP8RFZ1rg7ovCnOfTojByH5sLU3BzkWSaoGAEQEAEBBhMTBgweDhJAoB+K5jBhE5Bprp7c6DhVah4gAAEQEAEAB8JOrx4wZ0yq5+nXGrcYEEBWp1F8aNySuIX5+DgAAIgIAIOcESK4+ztr3GSmIgcmmRaI1SdUAgIgAACgQctxGjBjR0K8zbkdq6m5CXDzP2ieaCVoAAEQEAEABqE2ubuDEfce4MxEAcfJJU9PRWkn9/fv3d4zqTACAiAAAKJCQUHJ1He+w9gZGBxLiemtjD19Y+/RxDAAAEQEAUBAUznTo0CHHvJj0k619i5GBBFFzkh/XClnCmQCg7BAbDFAsRlsbZG24tVHecxO8GwJ6flzNDQIlfva3pjJFA73Het73bnS7fqi1ib7vE2I/1KBtl7VNxq1Uc1TN8zusbfXOL9reNmu93us7rW339kvL7LW221vmkLUtnQ6QZiGGDRtmhgwZIiHRx3Jj2Q4CVZ7at2+/81mVSD5w4EDTv3+/XCby+qJO+3tg/34j37r/gP52nweYfv36mhL52hda+xdrn455vfrtjvF+TxO858Z6v92nvOf8a7l+y0O837x+i5O89z9Z85sf7J0Lwo58X+/3ur7Bb35nzblA+9LlnQeMty+bvOV6a57f7O3XNm+9AICIAIAAqDTkeE8IjK35O7zm+RHec0M8cTDYe19/7/8y/X57PYeix3M6tnjP+QJkiyc+erznumr+bqx1QuRgjxo1yulcvXHjxq8NHjy4FHkQCo/ZvXu32bp1u/18I82kyRPN8OHDzK5du8zGDZvM5s1bzJgxo62AGpqLWHxf0GzZvNX5TqYePcWMmT7VET3bt+0w655Y79ytnzBxvPPZSnLn/lP2c/xuwIABd+vzN/hMozxHf7T3/xjv72jvd6+/I73nh3q/+wHe776Pdy4oC7u937wEyH7v97zTExk93t8uT2z4Nx+6vJsP/o2KA1xKABARAGVBTv9kzyGY7DkFkzyb6NkEz0GQSBjIkDkM9/6O9P7OCvi+vZ5j4d8J3eyJiqUTJkwYu379+nfrLnjRm3717dvHioRtZsCA/uYd73qreeWrX2pmz55lBg0ZZPbt3WdWr1xtfvbTX5vrvn+D2bRps5k4cUKmQkIOtGZJNm7cZM466wzzhje91jz3eReb4SOGW8FwlNnZu8vc8ae7zLXfv9HcftufnL4egwcPKnwisvbfCqIf9u/f/3Pe73+K93eiJwiGecd4X37yhwWR32sjaPd4/ZB3eUJDtsETIPrtr/HOBxs80aFzwlrDTAdAMuf6vF9Yzzz1wiMuTI0uVmEeh1kuyvbi3Ies152HMU9z3QGeU7jQDPtYTsE0zyk4Ro6CfW6q5zDIQRjFsZLt96n/JRzWrFljli1b5jynkJ8iCgndud+0cbMZP2Gc+ca3vmzmnXNm02UXPbjYXPaej5gVj68wU6ZMdsKIsnGmnzLrnlhn3vbXbzb/9oVPtkwyvvKKr5vPf/YKM378ODNg4IDCij1frA4fPvxplZmy/k2V5TwTYd2aqdhmH3d7YmK993eDfW6d91j2RIXGhHXn+DoqPn35xwpz3mMmAuBIJnp3xI71/tffGdZmGzfEYBy/m/wjB072jGc8wwwdOtQsXrzY7NmzxwwaNKhwn6Wnp8cMGz7UfP+6/zHHz2kdmXXq3JPND354lXnlS95gdmzfYUaOGpm6Uy7BsH7dOvPGN7/OfO5L7dMDPvjh95qnrOj4/OVXmKlTpxTu+9H46liTSFUujj4/pV1zg0I//Zng45sso1mNbZ6YeNzaak9orK6xXQwlACICQGj6/DhPGMhrOcF7PNMTCiMYomKjOzxy5JRDMGnSJCfJ+qGHHjJbt251/i9SJ+GuHd3m8i9+qq2A8Dn66Cnmnz/59+bdf/0BM2Jk+odyV1e3OXb2TGcGIigf+rv3OeFNC+bfb8aNG1sosSp0TPnHlZ6jU3WhGOqZbh6dW68RzZ/zsZZ4JoGxyhMcMhQjICIASojyEuZ4AmGa97/KfY7zXoOSo7vEEhIKMZk3b55ZsmSJE+LkNwPLe+jMzp27zPEnHGde95evDvW+l7zsBea0M041y5YsN6NGj0x9ny97/zvN4MGDQ73vLW+91Nx1x3znOymCE+6LBc0+aIbLn/2Cct2PMG4Om0w3m15Z85pfdeoJaw95AkOzGUutKYaSPAxARAAUAHkrJxl3ulrhR6d4j/0cBaiyF2AdPYUyDRgwwMydO9eMGDHCERP79u3LfZ5ET3ePk5A8dGg4h1whNaefMdc8cN+iVEWExnKgHedWeRvNOOXUE528D1Vy0neVdwGhXBUJCO1rVrknkCkKlTras/oZDBV3WGVtsbVHjDtjob+PMWyAiADIjkmeSDjes3O9k/gkhgZaCYn9+/c7zt7s2bOdPAmFN2mWIuwd8/Q8crvffY4y02dOi/T2adOmHu7DkNaN/f37D5jRY0aZiRPCT/SNnzjeHG33eekjy3IrImrzH3QMSawhIKDJdWpSnbhQGVtVjXrY2v3WHjXu7IWEBrMWgIgASOBErFuayl04y9rpxg1LImcBIgkJOYDqq6A8CTmBDz74oNmyZUtu8yTktO7dsy/Se/fs2euFBqW3v3KqJSQOHDwY+r0H7PtUrrZP3z65FRAyP//BFxTkP0BApIxnePaimuclLFZZu8O4oVASGQ9Y28eQASICIBjqEzDPuHkLZxj3Ds408+f+AQCxISEhR/Ccc84xDz/8sFm1apVz9ztXeRLWN+3bp69ZsXxFpLevXLkq9Rh9dc3evm27Hc815oQ54Xr8qfncmjVPON9L3miU//BUiVptQ6ZM9uyZdcJipbXbjJtfoZmLhxgqQEQAuMzxRIMSndUMRLkMJDtDOv65dQj37t3rCIfTTjvNSbxeunSp85ycxLw4iKNHjzILH3jIca6nTz868Pt2bO8y99x1rxmZQXUmjd0tN99mXvDC54Z6359uv8t0d/c4HbfzJiDU/0HiRiKT8CVIUVicV/OcGukt1E/FExZ3GbdyFEBm9GEIIKXj7FnW3mvt+9aWG/euyjXWPmLcWQcEBKQuJJQnoQRr9ZM4++yznfwI5UnkhYGDBjodqP/zK98M9b5v/dfVzmzA0Awccgmfn9z0C7Ns6aOB36OysN++6ntmxIj8TDz64UoSmpqBkJBAQECGqATty6x9wdpPPSFxn7XPW3uLcW/EAaQKMxGQBOropdmFudZ0O/JE44YmAeROSPh5EhMmTDDnnnuuWbRokdm8ebMzI6EKPFnOSmjbEydNMN+/5npzyiknmjf/1RvavudnP/m1+fpX/9tMGD8uk30fPGSw6d3Ua973rg+b62/6rhk7dkzL5Q8ePGjea5d9Yu06M/XoKebJQ9mXSfXHTaJS5gsKgBwx2rMzvMfKoVBjvD9au9PafOMmbQMkBjMREJdoeJ61v7P2G2sK4v6dtS9aez4CAoqAnyehfhLHHnusM0OhcqNZJ87qTriaxn3s7z5hvvylrzl9GBqhhOZvfv0q8/73fcSZwRg0OJvu3HK2J06cYB5evNS89hVvNvfcfW/TZZc88qh58xveYW7+7f+ZKVMm50JA+PkPSrz3BQT5D1AABhq3J9LbrV1lbZFxZyv+x9rbjBs6DBArR+X95HjmqRf+eWcbXMzrn2v3OMxyUbYX5z5kve4Wz0l8nm/tbGvPtY814zA5iTFP8vtM8jvnWMn++4yybp0PFfcux33FihXmkUcecZzKrPMkVPVI1ZY2b9psTj9zrnnxS19g5px4vBk+fJgjfpYve9z86pe/M/Pvuc+MGTPKcYCzvnOuKkubN24x/fr3c/Ijnvf8Z5ux48Y4szvbt+0wt9/6J/OrX/zO7NjRZSZPmXR4/LMWEApbknjQcdBoDJM6NpP8TZXlPMO6O1q3flyKMdRMxR/tY1WDepzxztd1VHz68o8hIhARpXMM1ZPhAmsX2+eU3zC9KI4hIgIREWY5nRN9R3Ljxo1OGdidO3c6j7OcldC2tW/KH+jp6XV6FQwePMgpi7p7zx5HUCgfQYIjL+d17YuS1SUaNKszzO6jnuvt3el8HlfwDLHOerb76882SDzqe241hogI1l2SdSv8SSVlf2Hc6k832+d6GG9ERBjIiYBmqM6iQpTOsfZy406TcrxA6anNk5g4caI577zzHCGxadMmZ0ZCDmZWjq4YNWqkY0rylQ0dMsSM7zfuacvlAT8xedLkic5+Kf9BTfSUQO076nkQEELfbW3+A/0foOQo/GmuZ0KVnh70RIVmKe5liAARAWFQ2dWLrL3QuKFKdIGGSiMhIcdS/SSWLFliHnvsMWeWQo5x1s66woJkRRJnChHKk9iRWJCY0Xfsf6fkP0BFUYXE53omFPqkHEeVlP2ttR6GCBARUI9OGGpy8yrjJl5xTADUOL5+P4lTTjnFKfWp5nR6TuFEUFxq8x8kxqi+BHAEx3n2fmubjVvt6VfW/uAJDAAcxgqiMKUXW7vYuDMOMxkSgNZCQvH8cjJnzZrlCAmFN/X09OSyuzK0pjb/wQ9PI3wJoCUTrL3EswPGbXp3g3GTtO9ieBARUG5UqP1Fnmh4tiFMCSC0kJCjqUZ06iehPImFCxeaDRs2HL6TTRhMMQSEkHjwZ5KYgQAIhWIS53kmHjZu87tbrN3M8CAioByM9USDkqIv8R4DQIcoT0JOaG2ehEREHvIkoLWAkBiU6FMYE98VQCyc5Nk/WnvM2o+N2ycKQYGIgILhzzggHAASojZP4tRTTzXDhw83Dz30kNmzZ48jLiB/aLZBQq82/4HwJYDYmW3tI54t9wTF7xEUiAjIL0M84fB6hANAekJC5Ur9PAk1d1N4E3kS+cPPf1D4kh+WBgCJ8wxrH/XMFxQ/MeRQlIo+DEFhUXL0t4w7ffgja69BQACki99PYvz48eaCCy4wU6ZMcR6rfwN3urMXDzK3Kd/gw836ACAzQXGncXtR/L21UxgWRASky1nWPmvcVvVqCPMOa5MZFoBsUcK1nFXlSRx//PFm//79jiEkshMQGnuFl6k3Bf0fAHLDqdY+54kJJWO/07jVnwARAQkgkfA+4zZ8WWDc5KVZDAtAfvDzJDQzMXfuXHPWWWc5pUOVJwHpCwiNvcLKEBAA+T1tGrfU/DetLbX2XeNGWECBICciv6iy0pu8H9VIhgMg/0JC/SQUyjRz5kynn8T9999vuru7D4fTQPICQpWX/AR38h8ACsFoa2+258g3GzdE+zpr11p7hKHJN8xE5AtVNvi4p8rVGfJSBARAsYSEHFnlRYwbN85ceOGFZurUqU64E3kSyYqH2gZy/nMAUFg/6CFrvzFu0RjK3iEioAWabVBy9GJrn7F2PEMCUGwkJJQnce6555o5c+aQJ5GggKjNf9DsAwICoBT+6fONOyuh6k7/Zu1EhgURAS5TrP2ttUXGTZJWdaWBDAtAOfDzJDQDoTyJefPmkSeRgIDQmEpA0DUcoLQcbe0fPH9JpWJfypDkA3Ii0ucca28xbr7DCIYDoNxColGeRFdXF3kSMQgI5T9otsd/DAClpq+1V3j2sLWrrf2vtU0MTTYwE5EeUs6/tna3tfciIACqIyTq8ySmTZtGnkQH4qG2gRwCAqCSnGTtS8bNIf2KtdMYEkRE2Rhl7QPGTRD6mbUXMCQA1UVCQnH76idx0kknObMU+/btQ0iEEBB+/oNmISjfCoCfZe1vrD1g3NzS5zAkiIiiM824CdLLrF1p7WSGBADkAEs0aAbi1FNPNWeffbbjDGtWAtoLCOU9kP8AAE1QbunNxm1i9zqGAxFRNOZY+5pxaxurRBldGAHgaULi4MGDjnA45phjnPCmUaNGOY9xjJsLCIkthTBp/Oj/AAAtuNja9Z4vplmKwQwJIiLPnGXt28atHKB8h2EMCQC0c4wV3jRmzBjzrGc9y0yfPp08iQZj5Oc/KAzMfw4AIAC6sfsVT0z8o7WxDAkiIm/i4fvWFlj7f4ZqVwAQEj9PQv0kTjnlFGeWgjyJP5dvVfI04UsA0AHH2PPpZ42bhP0JxAQiIk/i4VKGAwCi4udJKMlaIkJ5EhIVVc6T8AWExkF/ERAAEAPjrH3SuPmqiAlEROqcgXgAgCSEhMKY/DyJiy66yAlz0ixF1RxoP/9BAsIvjwsAECNj7bmlVkyMZEgQEUlygrVvWLsP8QAASTrQEg5KtFaehASFOlwrxKkK4U36/BIPEhEAAEmLCePOTCw2bgJ2f4YEEREnU6x93rh9Ht7NcABAGmhGQo608iRUCrbseRL+bIMSqMl/AICUOdq4CdjqNfGXDAciolMGGDeTXxn9HzUkTANAitTmSZx88snmvPPOc+7Qa5aijAJCeQ8SEOQ/AECGqAv2tcbtM3ERw4GIiMLrjVuqVZn8xMkBQGZCws+TUPnXiy++2IwbN650eRKaeSD/AQByxMXWbjVuDuxJDAciIgiquPQLa9dZO57hAIA8IMd6586dTp6EEq5nzZpVmjwJCQiZ/zkBAHKEcmAfNG5Y+wiGAxHRCHWV/qpxKy69mOEAgLwhsaAZCTnc55xzjpk7d64zS7F3797CCQmJBe2zcj4QEACQc3SSUli7cmPfwnAgImp5q3Gz8i/jUACAvAuJ2n4SypNQHkHR8iT0OSQeCF8CgAIx3do11n5u7VSGo9oi4hTvQLja2ngOAwAoigOuGQgJhxkzZphLLrnEjB8/vjB5Ekqc1gxE1btxA0BheYm1hdb+zVAStpIi4uPGjXF7Cb8FACgitXkSSriePXu2E+6U5zwJCQjClwCgBOgk+w/W5puKV3Gqkog409rd1j7jHQAAAMW9inl5EvqrfhJnnnlmLvMk/PAlyrcCQMk4zbhVnL5ubTgiorz8q7V7rZ3DMQ8AZRIS+/fvd3IlTjrpJHPhhReaQYMG5SZPojb/AQCgpOfh99g/91t7LiKiXJxo3KYh/8RhDgBlFRKagVB407Rp08yzn/1sJ09Cj5988snsLi59+jgGAFABZlv7vbUvIiLKgZShch8u5tgGgCog4TBixAgn4fq4445zQptUzSntmQCJB2YfAKCC/J1xQ+dPREQUE3WZ/p5xY9T6cTwDQJWoz5NQHoKa06Xl1BO+BABVxp7/FDqvm9jvQUQUi3ON2zTuTRzGAFDRC5iTJ6FZCOVJqMv1kCFDUsmTIHwJAMBBN7F1M/s71oYgIvKPFN9d1p7BsQsAVRcSyodQeNPUqVOdPImJEyc6QiKJPAltDwEBAPA0/sraHdbmICJyer209l+e4gMAgBokJIYPH+70k1CehEKb4uwnofUQvgQA0PQceZpxG9S9GhGRL8ZZ+4O1d3GYAgA0dvL9nAjlScybN8+ZjYgjTwIBAQAQiAHWbrD2j4iIfKCpIWXAX8KxCQDQ2tmv7SehWYlhw4Y5sxSdrBMAAELxWWtXISKy5TnGTaA+luMRACCY069+EsqLUJ7Ec57zHDNlypTD/STCiAIEBABAZN5m7VfWhiIi0udV1m4uw+ADAGSBhMPQoUOdGYk5c+Y4lZw0U9FOHBC+BAAQCy+0dqu10YiI9Hi3tRs59gAAouPnSQjlSZxzzjnO/2n2kwAAqDhnWbvH2nRERPIoefobHHMAAPEICc0+SDiceOKJseRJAABAKNSW4E++kCjaTZzcd3TetWvXBPvnndY+02hw659r9/iweqqraR5k3UHXH9c+dLLu+ufj+rxpj3mQ9wR5X7P9jDLmQdYd9X1Ra+1HPfEEGYMg49ZsH6Ic41GOlaDfZVzHYdR9ajcO9X+jHCutxqHZPqmrtcq/Tp482dx9991m5cqVThlY5VDUvz/N7zit4yftc03U30+QMQjznijnjU7ONWG/yzDfSavx7XTdcZ+b4jxOgp6P8+ZfRPU3ovwmst5+gHGcZv9/2J6Hn7d//37l+x5CRMQl0Z7xjJfaP++1ttcO8qCwJ7SgP4Kgy0R5X9CTbprr7mSfOh1zOSzt1hNkmSgXMX+9jdat1/xlmm231WudXFib7VftOLRaJsg+1b6/1XONvqf65cLsd1oEOb6CfMdBjp0ojlOjscrDONV+vkGDBpnRo0ebnp4eM3jwYGdmYvfu3Q3PH3Edm52MQbPvpd341u5XFueaIEQ91wT5bQY9X0Qdk0bfid/kMIvzf7sxabX/Qcau3fmh0fajnAfCfCdRrtNJ+hN584vi8u/i8kOtOOl/4MCBv920adNH7cOViIiYOP/886+1f35kbZi1sVJs1o6zNsvaZO/vDO+1jk5yaZPlPuRh2/V/g/yvv/X73m499e8Lso1GF79m6223nmbrDfL5gvwfdv863V6YsfT3r/ZiGWTMO9lemsdKp9+FPzZxfL5O9s8PbVKC9RlnnKGbN2bVqlVOOViJClV0ajV+cR1DnR53ce5jfWfvuI69KPsY5D1+l/I4xr7VvrfbRrPP7jvA9WKi3f42EiBh9jHM7z7t4znMeSPoPuK75Hr7K6ytsrbO2lrv8VJr26xtsbbXion9pkDkXkTs1m0wlx5r6609ZNzSWLVM9OwYaydZO9Ha0Z7YmGIgd4Q9SUdxxjvZXth9ynrbnd6xjXqXNcj+NboLHPdx0MmxkuW209i/dtv2k6wHDhzoJFifddZZTjjT8uXLzbZt25zE6+nTpzszEn6n67C/iaQ+Q1q/1bDffZz7mLexi+pMRZkB9Lfjh5AE3cdmM4BVOO4gcxSKtNyztZ7PKqGwwdoT1naV6cP2K8nn2OTZIms/q3lepbOmWjve2hmeqFBviVOt9eVYzwdhQ0WCLB90nXGuK6ttRw21Yf+KMzZJ/kY0y6Byr+pkPWPGDKchnWz48OHOzMStt97qzE6ccMIJpm/fvs5rSd2xC/ueNLaRhZNW5bHrdBscd5Aimj142LizCxIL93lCYY21A1UYgH4l/3w7PFtsjiwNKyGhTPjzrJ3siYzT+T0UT1DgEOfPKY17XYjG+I9Bv/GcZhcmTZpkzj77bDNq1CjT29vr5EL429D/Bw4cMAsWLDA7duxwxMSQIUPMnyeIcWRxZMv7/ZT1O4VIdFu719rj1uZbe9Daak9IVJZ+Ff3cj3t2S81zJ1ibbe0ST1SocPo4fjfZiYUyOsRlcUoRZcUVjfpfwkA5EKrIdNppp5n+/fs7pV0bhZ7pNYWTKLxJCdcKeVKehIREfex5lRzZTkEEGL7TlMYOIqGZhSXWHrB2mycY1jMsiIhmLPXsF95jlZZV0vbFxg2FUlOQmQxTvkUFTmn5BQWiMfoyel0hSuL00093QpSU5+BXYGoW+y4RofCmrVu3mltuucXJm1CehHIp/DyJqjmyVb6bzQxSuQVuRbnTuKFJt1pb6PmDTzIsiIiobPbsbu+xqkNphuIia880bigUSdslEBSE9hTTIUY0ht+28h9UtlVhSVOnTnVEQG31LN9hqU3mrK1Dr9wJiZA77rjDmZWYM2eOIzA0q9EsmRVHtrqOLDNICIcco/wFzTL81rizDssYEkREkuz0Drr7vMdK2p5j7UXW5ll7lrVBDFP6zlKVnFIc4mqJxjj2z89/kPM/YcIEc+aZZzr5D5p9aFSpqZb6xkp+LwnNPixcuNAREgqHapUngSNbHUeWGaRyH3cFZ5VxbworjF0doh9hSBARWaKE7Ts9E8cYN+zp5dbONW4lKKiYU4pDnPz+IYzCHY/Kf5DNnj3bnHzyyaZfv34N8x98p6RV4yv/OeVJqFLTihUrnHX5wkQzG632F0cWR5YZpHT3seJIMCgJWlU7NdvQy5AgIvKscmU3WRto7UxrL7N2gbXzGZ50HVwc4nI4xHkXjXkUbrXLyqnXbIJmC4499lhnBkHP1QuNZs5KfThT7etar0Kj1Evi9ttvd3Ispk2b5pSAlWhp1qUXRzY5EAF8PxVH/cRutfZr7+9ShgQRUURUSL12lkIN8F5q7dme0aMiA6ceh7h4DnGRhFveRKPCi+Tkz5071ynjqnAmhTU1a/7XbOah/vn6xwplUk7E/PnznRKxqvjkd8AO2lgMRxYRwAwSwiEiqph0u7WfGDdMaR1DgogoGw979jnjlpF9gScq/gKxgEOcR4e4yMIoL4I1q7FRorQEw/jx450ZCFVV8vMV6mcHmiVD++Kh9vVW4U3qdq1ZjsWLFzt5EqeeeqrTY8KvBIUjW35Hlhmk6CA0QqPuz0qIvsG4N2t34GYiIqrCY9b+07MTjZtDoeTsCxgaHOKi7R+VrfIjGv38Bznzs2bNMieeeKKTt6CKTI1mFJqJCYmQekHRTDzUrkfbknBYu3ats00JmDFjxhxO4MaRxZFlBindfSwZKm7zK+OGjN9sbRseU/b0YQgyRdUBLrd2oXFzKL5k3OYm0MR5SWqZMMtlte0k9i+Lcc7Ltsu2f/5df80CnHLKKY7ToedqZx+aOSKNXmsWytTss+h55UkovEndre+++25HUKiakwRGECcIR7Z8jiziMdz7O/1OS8jvrb3buDddX2/tegREfmAmIj/c79k/WnuOtTdae4Vx+1MgKAjtKf3+MYsSff+ULK38B1VfmjhxoiMe/G7SfnJ0vWPSrjpT7XtbiaBGr6mfhBKs77//fie8SXkSEhh6rllOBo5s8iACTOm+05KiG6w3WrvOUIoVEQGhOGDtN55Nt/Zqa68zbtnYSguEvDvEhPakOzaIsj/nP6j/gwSEZgEUSlTv3LfKgWgmJvyZhaDCofZ5vd/Pk1i2bJlTBlb7p3AnCR4c2WjvIR/CVPY7rYBQUUGan1r7rrXfeb4QICKgA9ZY+7Jnl1h7i7XXmJLPTuCUVtMhRjQGX6ffJVpO+syZM83xxx/vPFebyBxUODR6rp1ICPK81queFAplWrdunZMboTAr9ZPQfrb7nDiy5XJkmUGKTslnNxTC/b/WrrW2ErevWJATURzUNOX/Gbdc7D+ZirRor1I8fBAnLo1tp/29VDUfpJP988WC7u4rgVpOhkKFmjkg9U5I0Odq96NZfkS70rD6q/AmhTUtWLDAERSapajPk8CRLZ8jyyxIuPdXLB9C0RaKsphr7d8QEIgISIc13g9OP7xLjVsfGbFQMqe0Sg4xojHc/klAyCk/44wzzPTp0x3xoBmJdkIgrJhoJhLaJVc36yuhUCb1qXjwwQfNo48+6ogIdb4O4yzhyObfkWUGqVziMWbUDO5rxi0k80JrPzKELSEiIBN021HTfxcZN9RJCUhPVmkAqCpUfIcY4fb0ZZotr/wH5ROo/4MEhF8+tb4ka1xiIg7xUB82NWDAAEc4PPbYY46YUElaVW/CkS2uk4kIqJQIiIpufn7C2snWLjNuERlAREBOuNXaG6zNMW7+xO4yCQQc4uI6xGURjVl9d/57NNMgh1v5DyrhKme8PkE5bIhSGDHRiXiof04zEBIOGzZscKo3dXd3O7MUnXwvOLLRt8HYle/7yRHKd3iPtVOsfdraWtw1RATkl0etfdi49ZQ/Y21r2T4gDnE5969Iwi3tbSuBWsvNmTPHKZWqmYdm+Q9xiYkkxEP9834lKQmJJ554omGeBI5ssRxZZpDSfU+Oude4ZeoVdv1fxg1jAkQEFITV1v7FuFOHUv9byiQQcIjTFR40rcvuGFT+g+7Sa/Zh6tSpzmPNSkRtIBdk+XbJ1Z2Ih/rXJBy0vYcfftgJcVKFKc2yNNoHRED5HFlmQUonNHzxMM/aDwz5DogIKDSbjBuHqKnEws1MENrD/hVBUCRxDPrdpseNG+cICJVFVfiS70QkEbbU7LUwlZnCzl4IiQbZihUrzOLFi52ZFz9PAhGQ7/1i7PK3jQzFw5tqxAMgIqBkYsKfmZCYKFzOBKE9+dl2lqE9VRCNmmmQzZgxw5x00kmH8x86LdPaavmg4UxRS722Wo+2rRkICYctW7Y4CdfKk9DjZuOJI5vufnUCIiDf30+HLKkRD9/H1UJEQDXEhHpNfK3sYgGnFFFWNNGo5Gk51Mp9mDVrlpP/oOdahS/FlQPRbD1hBEUnYsMXEqo49dBDD5n169c7AipMngSObPzbIB8in8daxqjakhKm5yIeEBFQPVYZt8yaajX/pOgfBqe0+XLMohRDNPrN4pRsrOZxkyZNOqL/Q1CHP8xMQ7PXah/LsY+71Gu71/w8iWXLljkhTnpdna9xZKspThi7XAmNHca9EeknTJPzgIiACqNaza+09nLjxjQWUiDglOZz28xkBFtGsw3KAxg7dqwjIEaMGPG0/Ic48h3Cridt8VD7nESDZiHWrl1rli5d6szG6HHc4Mjm25FlBilXKHrBD4nuwn0CRAT4/My4MY1/Y21dXneSJODyj03VRKNmGtTFedq0aeb44493nGclVDdyIuLKd4giJtISD7XP+eFN27Ztc6o39fT0OLMU9Q3sEAH53QahUPkWaQG51dr5xo1eWI+7BIgIaMZ/WjvV2hV5FwuE9uTPIUYYhUN31xXvf+yxx5rp06c7YqK2fGs7cRBUBERdTyfJ0p2Ih0bhTRJWS5YsMRs3bnSElsYNR7a4AqhTGLtUWGnt7dYusXYn7hEgIiAI2639rbXzrP0pDzuEQ8z+lUm4yWlQ+JLyHzT7MH78eOexRERclZXCzEK0EhNBnf5OxUY7ASIhIR5//HGzatWqhnkSOLLF2S/GLtdCQxv7nHHzHr6NSwSICIjCXdYutPZ+k6NmdTjE+XKIyybckt62X21pzJgxTgWmoUOHOnfZ6x2sOGYawgqHTku9RhEbQdej/ZJo6N+/v9mwYYN59NFHHeEVNk8CR7Z8QoMZpFjRjMMzrf2DtV7cIEBEQKd81bghTtcVVSwwk8H+5UFQaKZBImLKlClm5syZTkiOHOF2Tn2nMw1RxETc4iGIoGgnNpwLVp8+zqxEV1eXU72pUZ5EnCAC8jleef9OCxjWJMHwIePmPtyD2wOICIiTjdbeYNx29mvyupM4xMkLI5rWRVvO7/9wzDHHmKlTpx6ekUiqslKcy8ctHsKsv9nzEg4qgbt8+XKzadOmI/IkuJtdbgGEgIqdn1g7zdqVuDqAiIAkUTv7TOIkCe0ptzAqq2iszX9QArXCmCQeJCKCNJBLUhy0W77VjEGS4iHITIVQaJP+X716tVMKVkTpJ4EjS2nYio6dej68z7hl3lfg3gAiAtKgy7gVGzQzsSmLHSC0J33xxCxK+GUkFFRtafTo0Y6AkJDQ3XM9H9SpT0IctFvef5x0snQcy2v2QWJCsxFqTCfBpsc4ssXeBjNIifMra6db+zouDSAiIAuUI6FciR9lKRZIUi7/tosmyvTYz39Q52mVb9Vzfv5DraMeJnQpi5mJIE5/lk3p/McKb1J+xGOPPWZ6e3sjN6bDkS23AGKmxukwrdyHF1tbjRsDiAjIks3WXmfcCk57k94YMwWMTRFEo9//QQ3kJCIkJiQqmjkLSZdpjbJ8WKc/rlKvUbcrJBw09itXrjRbtmxxQpuUh5IjBw4RQChUZp/LstC4lZeuxHUBRATkCVVwUl+JB9PaIOE1+dk2MxlHCojBgwebGTNmmJEjRx7u/xBGNHQiBOIUE1nlO3SyXT9PYt26dY7F1U+CfIjibKPKM0gt+Iq1s63dh7sCiAjIIw9Ym2fta2lvOEunlNCecu5f2M+hi70EhISDwpcGDRp0RPWlLMq0xikm0g5ZiroeoVkgCYdt27Y5SdcSckETrnFkyyuAOqWg+RBd1i619gHjhjIBICIgt+gkdZlxE69jCW8itCd9h5iZjHDL+J2mJ0yY4JRvVQiNBEQQ5z1pIRBHdaY0xUNcoU/6DhTetHPnTqfDtfIk/FkKHNliigBmkEKjfg+afbgW1wQQEVAkVAJWTWseycIBxyEuvzDKy/6p+pLufKuB3Lhx4xxBUZv/kHWZ1qjrCOKoJyEeggiKMGJDwkGCTiVgNTOh76o2TwJHtlz7VdYZpAj8l3cNXo47AogIKCL3Gze86cakNoBDnB/xlBfhlua2/fyHo48+2gwfPvxw/4e8VFbqtAt2HpKlw6yj2X5KSEg4bNy40WzYsMF53m9MlxOHDxGQ889elO9UbzNuNMB7rB3CDQFEBBSZ3dZeY+0zeXCai+YQx/l5aFoX37b9/g/Kf9AMhMJmasu3tnLW8yImgqwnLic+D30l/H4SXV1dTsK1BF+zPAnyIconAso6g1SHFPJzTAZ5iYCIAEiSf7H2ZpNingShPfnZvzI1rfMbxY0dO9bJgdDyEhStnIC8iYkw60nC6c8iz8L/KyGxe/du88QTT5hdu3YdzpPAkS23CEiDjPfxLmtnWbsFdwMQEVBG/tfas61tLItDnOb+JSU8mEUJjnIddEd74sSJThfq2vyHOIVAGg3kgq4nSac/qzwLCQd9b+vXrzfbt293Qp2S6idBKFRxtlHgfIgfWLvQ2nrcDEBEQJnx75YsSGLlhPZ0vn+MzdOX00Vfsw0q26rmcUOHDnUe15ZvzVNlpU67YPuzLXlNlu5kuz4Sg3q8detWs3nzZmcMGuVJ4MiWaxt5/k4jbvPz1t5oyH8ARARUhHXWLrD2yyQEQhGc0iz2rwjbzuNMhi7mcqqHDRvmhC8pjr5R+dY8iYkgz3faJ6JTJz4tsdFqu34/CZV/VdK132k8j45spyACyvf9GDeB+mO4FICIgKqhLNSXWLs6a+c/S4eYpnX53j+/0pJCl5QDIerLt2YhJjqdaWi3jXYOeF6SpcPuS6PX/I7W+/btM5s2bXLyJfS43XFCPkS59qsoM0g118/XGhKoAREBFedt1r6cF8cVhz19UZbXmQyJBcXJSzyofKsERaPyrXmrrBRHb4pmy+YtWTrO2QsJB33nW7ZsMd3d3U/Lk8CRLbcISPI9MbPH2vOt3YD7AIgIAGM+bAJOyeIQ52fbZZ7JkDM5cOBAp3mc8iBq8x+SFgdxiYm4tpuWEx+HeAi6jmbP+3kSO3bscBrTSTQGSbguuyPLLEjywi7gNjcbNxT4VtwGyAv9GALIAUoO22dCzkoEKc0Y1zJRHWL2L/rnyGLbEhBKnB4xYoTzntrwpXpxEvS5JJZPY7tyoJuVSw0q2Fo592HeE8d2gyzvf2aVf5V4VCibqjn5ZXxxZKslAnL0/UhAXGRtKe4C5AlmIiAvXGnt3Z04xGktE2a5rLbNTEa4ZfxQJTWQk/mCotHFv2hlWqMuXz9mRUiWjmN5CQmFN6mBoKo37dmz5/AsRZ4d7E5ABJg8f6fLjDsDgYAARARAC75p7XVpOJJldojLun9JNa3z+z+MGjXKmYXw8x9aXfizLNOapogpYrJ0XMvrmNCYKLxJFZwazczkxZElH6K0AmixJyCW4x4AIgKgPT9qJSRIUs6PeCrDtiUgBgwY4AgI5UEobMUXEHE65HGWaU1DxDQar6IlS8exXV84SER0dXU5Y9MoT4KYfkRA1Pe0QALiEmtbcQsAEQEQTki8pSoOMU3r0h8bIbEwePBgR0DornNt+FKWZVrz0riunVOep2TpJEOl9FjHh8KaJCQkNP1Zigo4soiAbETaKgQEICIAovM941ZuSt1xLYLDTtO66Mv4Mw0KXVITOV3IG+U/JCkm4lxP3GKidiYiaGWjouQ7dLIeCQflSagE7N69ewOFN1EattwiIKH3KIn6RQgIQEQAdIaqNX0k705p1tumaV3wZfxwFIkHzULU9n5Iy6nPQ3nYduvIoxMfx/KdrkcJ1xofhTepMV2jZehxUHkR0Mk2dli72NoSLv9QBCjxCnnnS9YmNBITYZ3SrMqtUuq1s88R17YlGOQEDhky5GnhS2mWaY1rPXEs36xkbDuxFld51STKtMa9jkZCXeMmEeGXBA57TJMPUVoR0Mny6kT9IgQEICIA4uWj1sYat8N1bpzSImw7if0rmjDy/ypxWs3j/IpMSfV8aCUawjj2aYqJRk5Nszv3WTvxaW231fJ+crXCmyROJUwlUOuT8gvoyCYiNAiFCvSel1q7m8s9FAnCmaAovN3ar4I4j0GcgKDOQtzLRHWI2b9on0MXbS0v8aDwJVFbvrWslZU6Wb7R82VLlo5reYkJCVI1p5OgqK3cRI+D6FRw7N5qj6vf1R7XrQwAEQEQnpdbu7+qDnEW2y5yZSs//0HiQWVc5ex10rStSJWV4sjVKEqydNZ9JXSM+eFNSrgO4+hRGrZ8AirCNj5u7Rou74CIAEiWg9ZeYm1j1RziIgmjPOyfLuTKe9AMhP62mn2I4pDntbJSJ8vXPl/E5nBZbtev1CQRoVKwrcaQ0rDlFlAhl/+2tc9yaQdEBEA6bLD2Chz25IRR0WcydIFWfLqf/1BbgalTh7wIlZXimkEpkhOfdVM6/3+JiQMHDjhCQsedH95EPkRpRUAn77nVuGG6AIgIgBS5x9qlhPaUUxhFXa9/97d///5O+FIjByapfIciiImw74kSslTlpnQ+/syXZiUkKJIKbSIUqtBjt8bayzo5J5MjAYgIgOhca+3zRXKI87h/ZWpa5wsIv0pOs0o5Ue/W511MxJ2rUdVk6TiEj/9Xyda+kOi0n0TZHOxOKMHYvcpaL5dxKDqUeIUi8zFrpxi3tjblVmNcpmilXhU2ojvA9euJq4dDvYOQ9zKtcWy3lXjLavki9pWQiJCglcBNw2EmFCr3AuqN9vi4L6mbT63KDAMgIqBQpHCH6nXGbc4zLU6nNI9OM03rGi+nvxIQQRz9KKIhjmZuSYuJOLfrj2lSfSLSduLT2m6rffErg0lItDu+KQ2b7vUm5bH7irUf4BlAWSCcCYrOLmuvCXqXJo7lwixPgnSy29YMhF9is9PKSkUu0xr3doPkRtS/3u65sMuHXUdW2w2yvH+M+rMSZRUB5EO0fI8ayX0g6QsiuRKAiIDC08p5SYD51j4cp0NM07r8759fVjOqI13mykpxiJJW30nVkqXjWN6v1KRZCVkZRUCehEbOxMlO4+ZBJA4CAhARAOH5srVfVNVhr9pMhh8SUpUyrVlsN+idfprSBV++tpJYECe1xOVNE3lPpze+EnzPXxm3PHlqMCMBiAgoHCnPQNTzJmtbi+YQZyU88i6M4jjmqlpZKe59L4sTH7fw6WS7GuP6HiZ0eo6+jRzv4zfsn5uyuCAiICBpSKyGMtFt7VJrvwtyciVJOfrnyKKyVW0seZgk41avlbWyUhyJ382eJ1naxDpmeXTo8yxOCjZ2y+13/96sL4z150+AuGAmAmI7OWc4A1HL7+0J8ythT7BxLBP3urLadh5nMprFkOcl9KeT5fMYXkW+QzxJ3VHWU2YRUMF8iNfnQUD4yf3MTEDcMBMBsdzZyYmA8PmgtRdbO7aMpV7zuH9JzGTooifx4N9Bi2umodVrWcxMZLXdZs/VCooguSlRn4tz+ay2m8SsSdRzKqFQyYuTkNv8jLUH8nJR9MVElKR+gKbXaYYAOhEQOZqBOGLXrL0xzIU9ynJhlq/qTEaUbfv/Hzx40LEyV1ZKa9+jLB9HZaYqJEu325cw++nfMUYEJPOeOG6YBeRha/+SS6evD24fICIgJwIix9xj7T/SdtjTFh5R9i/PYU+1AkJ3zOqr2ZStslKSZVrjFD1VceI72W6nY1b7Wm339bRDc/IqAgoWCnVpXi+MhDYBIgIQEMH4qLW1lFvNz7bbNY5T6NL+/fsPT7kXobJSHGIiye1G3c8qO/F5mGXp16+fY2k43JSG7ex6WMe/W1uU5wsjQgIQEYCAaM9+a+/KwiFutAwJ0q3HRrMP+/btc4REqzj9vIqJMnXBTsOZpq9E++U1I9G/f/+2OUTkQ0TfRsz7uMbax4pygaztpg6AiIDExUMBTza/tvaTPDjNeXHY4/wcnW7bd5gOHDjgCIh2SaV5FhNZi5iw62i2//W9C6rsxOdhuxISAwcOfJqzhwjIpdB4j7WDhXEA7THlG0ICokB1JkjsJJwj3m/thdYGNrqY11aiSbv3QdwVjeLcdtKVo/za5RIPmoWod6KKUFkpyapQSX/Wdu9p5UyHEYx5qHgUdfk89LPwfysSEgr1028FEZCf99TwC2u/KmKIkIRqSa71gIiAvImHgs5A1LLWuOX2/jUphzjvDnta+xd0Od35kjO0d+9eJ//BrxiSFwe76GVamzmoUURP1Z34NPez2bK1QkK/FYkJ/zlEQHb7VfO//rmsyBdJhc35BS2o4ARB4UiBljQKbSgolxs3XpVSryltu9kyukApfGn37t1NL1hFKtNatvCq+u+QZOnk9zPoevT9DBgwwAwePPhwCAoiIPn9CsAXrK0u+rVex5nEBAAiAjrCj40ukx6y9qG0HPa0hUcR9s+3PXv2mF27dh2+k0plpXyJCf//ZncjSZbOtiStvh+FnwwZMsT5G+Q8TT5E9G0EeP9Ga58qw0XST7SuDW8CQERAJAFRwtjIm6zdnZbDzkxGzYnGc0glHiQimoVhUFkp2RmUKOIJJz6Z7XYyZr4AHzp0qBPi5J+v0+4pwSyIw8et7SnT9V/HlsoLJxVmC4gIKLmAKDEfzsIZr3LTOj//oaenx0mirr3DTWWldHo+xFHutapOfNbiod1vT6FNmpUQYc/diICOt7HM2lVlvFD6QoLKTYCIgEDoAlRyASHusvabIjjsRW9a5wsICQcJCAmJZnHcRb5bX9ZcDZz4/Ido+d/doEGDzLBhwwKFNyECYl2+MD0hoo4VTekAEQGBBERV7jbYz/mxRgmkcTvsSQmPIsyi+BeenTt3OgJC410fY1+mu/VZiYk0tosTH20/0wzR0vlbCdcjRoxw/qpgQbueK60cZkKhArHAdNiDqAhCoja0CQARAU87SVRJQHgX3wetXRun05ymU5/ltoMs498N7erqcnIgaivLpOlgF7myUh5yNXDiowulLEK09JvTb2/48OFOiFPS53VCocxHquQr6NgiRwIQEVBpAVHDJ5K6o1/VUq/6Xxca1bDfsWOH0wOifiqcykrhl097u1GTq0mWzn6WxQ9lkpDQrETtc/XfLSKgo2380dptVbto6vxe39MHEBFQYQFRYZZb+3HSDnucjn2e988XEOr9sH37dif/wS8TmOXd+iKLibyIGJz4ZIVP3ALNFw5Kth41apQTiqLwpqjXiZKKgE6X/0xVL5w6nmrP7YCIAAREVflsGg572Uu9+rMN3d3dzgxEo/yHpB3dMpZpzVrE4MRnLx6C7mOj1yQcVP519OjRTuJ1bZ5EK4eZfIi2LLL2+yr7Dzq/S0wgJKAfQ1C9E4AuJiRJOdznXQyeF8RxbneyjGuZKGS1f7qQqPt0ffhSrRPa7ELdqMpMp8tnsd2o62i1/0luN+jyjRzbMAI0juWz2m6YfUl6u52Mmc71umssIdHb2+tYu1mMIA52lUOhLJ/i+mkOz0Zo1tlPwAZEBFRAQHD34Ai+GEREZOmwh3Xs09i2H74k4aDwJeVB+HemsnDq03aw41hH1iKm1fI48fELn6S322x5zTpL3I8cOdL5jWrG0BcXSV9v8vieDrexwrhNS/EnvM7pfh8gHWcICUQEVEBAwBFoJmKhtdOSctizEB5hCbNtf7ZBdzX98KVaAZHFXfOstpvkTEOWYsJ/PshsBE58vPuZxHb98796SfTv39/53Ur41wuJKLMNFQuFupJL5pHj5JeARUhUE3IiKoAuHgiIllwZ1hHp1GFPa5kon6PV8n6ZP80+bNu27bCooExrObtg14oJkqWLX5LWz5MYP368UwZWj9POjyuw0Nhp7btcLpsLCbpbIyKghAKCJOq2XG9tS5qOfRJCIOmmdX6Vl02bNjk9IHTBSKuBXB4d7LJ3wcaJT34/sxBofiiThIRCnHR9CNPlusL5EBIQ3VwuERKAiKiUgGB6sS17rV2dpMMeJ2lv27847Nmzx2zYsMFpINeuMkeRmqol4dRnLWLi2PcqOPFZi4eg64h7u35/IJWAHTdu3OFZirgc8pKGQn2NS2UwIUEJWEQEFPzHjIAIzX8n7bAXsWmd7irpgqBkzPXr1zdMoK5i6E+nvSmK0gW77E58lUO0/FLfako3adIkJ1dCce1JO+WdXtsyEhr/Z+0RLpPBxg4hgYgABETVeMzazUk541Gd/7DEuX/+RWDz5s2OCT0X9wxBke/WlzVXIy1nmjyLbGd3hISD+khMmTLFSbxWyeYg/SSiOOUFDoX6FpfIcOOpawW9JBARUEABkaSTWnKuysphj2t7cW3br7ah2QclUTfKf0jaIc/r3fqwDnnRcjWaVW3CiY/fic+LQPM7zE+cONGMHTv2iGIcZZxtCPke5cv9jMtjNCExYMAA8iRKDCVeS4AuCH7DF+iIn1rbbm1MlUu9SkAo70H5DwpfUphDK+ey2WtFaaoWtodDUcq0Ri2F265ZYDsBSl+JYpak9ZuQKkdCjp9mH31xEcYhL2E+hApv7OHyGE1IUAK23DATUXDx4N9FogJTLOhC8cMwF+c4vr80lgmynO4W6WSvmYe1a9c6YQ16XLXKSknse1qfNc7wKioeRdtup2MWdj/jHGP/eqKqTUcffbRTDlbngYyd+KyFxg+4NHYmJIRfuQkQEZAjAUH+Q+xcm6ZjH7cQiLqMTvB6TrMPCmHyp6LTcFzzKibKlqsRdBvN3l82Jz5r8dDpfia5XQkH9ZGYNm2ak3itx1FuVJUgFGqptbu4LMaDf50BRATkQEAwPZgIf7T2eJIOe9zHQafLKHRBYUurV682W7duPaLWd1WaqpWxslJc+1lWJ548i9bL+6FMmpGYMGFCoKalJSwNyyxEAkLCL9ABiAjIQEBIOPh3hhAQsaMz2w1JioW8zGTofwmInTt3mpUrV5qenh7ncaMY+jI3VYv6ucocXoUTT4iWkGjQ8aCEa81K6OZCfXhTWonQHZ3Uo+/jj7kkJuB4eqGzWRwLELMoZAiKhYSDf2JHQCSGLhx/H4fgy2MStdblzzZs2bLFCV8SEhBJJOoGWU8WSclZbTeuBPU0krBbiVSSpZPfz6Q/a5D16JqjmUo1ptM5QucLv+Fk0GtQQfMhHrS2mMthMvjhsn5RGPyZggpChqAY+I4kJVxTYb61Ve2+j7DfXxzLRFlX/fJyBMQTTzzhmHM3oUkDuao0VSO86umvcSeeWZZaJCSGDBlijjnmGEdQtMuTyGvidYj3UNY1QSgBi4iAlMSDr9bbxaNCfOc3az+P2/lPQlSE3bZO2Pv27TOPP/64U8JR4sGvwFTFpmp0wX4q8PGKE5+tE59113CZhIMcvhkzZpjJkyc7IsLvcp3D/g6d8ksuhckLCb8ELEICEQEJ4VdgglT5TRpOfVqCws9/6O7uNsuXL3fyH+r7P6ThkFNZKdoYZyXYyurEZy0e4hrnOARa2O9K1yKZRITEhBzAZmVg4xABGYVCrTTujDSkICQEQqKYkBORY/w7P8QLZsJtxms81+r7iTufIe6mdbrY+yfnjRs3mnXr1jmvqf67//6qNlVLYrtRm+7lKVcjiJMaVsAmtR7yLJLfbqPn/OIeY8aMMYMGDTJr1qwxvb29zo2JVueRJIVDHI5s3U0kvNmU0fHjV53E7ykGzETkWJ3708T8kDJhlyckCl3q1U+WXrVqlXOhF4pDbTSzRWWl5JcvQq5GMyeOikeEaNWfc5QnoX4Ss2fPdjpd63Fa/SQSzof4A5fAbPwevwQsICIgokPoCwhCmDLnD0mKhaRLvWq2QfkPjz76qDMLUX9yrnpTtTyKibyNMU48eRbtXvPzJGbOnOn0lPBnKdqduzLsQN3uPXvsn9u5/GUnJHSd0qwEoU35h3CmnEEH6lwRy4Uk7VKvuqDrBLx9+3an/4OEhARF7UW1yKE/SW63bGVao6zDv4g3ik8uS9nSNJevQqiUX3ZcIkIVnDTzqfOOXwkuZRHQ6SlbuRBbuPxlKyR0fPnhTYQ2ISIggKNJB+rc8ZC1FdZmderYJyEW6pfT/35Mskq3rl271nmu/kIe1qnNwtHNq4Pd6fJFEWw48cVy4vOwXR1PCmcaO3askyfhN7BslCcRpwhIIBTqVi59+cC/IYZvlOPviCHIXjwI1HZu+WO7C22Qi3Ecx0i7ZSQWdKJ97LHHnDuB/nOt8gj8iyiVlcjVaJYH0ex4K0PZ0riXj6tKVNLbTTJESzMQmo04/vjjzYQJExxhoZmKZvuXw9Kwd3PZywe1JWA1O0p4EyICGlygKeGafxERxamPSyC0W17P6c7fnj17zCOPPOLkP+juje7i1B9XNFVL9rMWZYyDCJtOy6KSLJ2NE5/GfrZbj58noYRrNafzu17778lxPoQKalDaNWdCQtT2NIL8QDhTxj8OZiByT9sLSto5D7XHj5+AtnXrVqf/Q23+Q/1JOC+hP43eQ65GPsOr2onXMKI472VLo+wnIVrNX/Obo06bNs2ZmVCDy7179z7t/BSzCOh0+QXGLe0NOfSX/NkISsAiIiqNX79fAqLVHR3IBY9YU3OFqUG/2zQEhZ/roOVWr17tmP9cs5NrXsREkOfz4GCXIVcj6tjjxBffic+DQNN1Tjc2/DwJhVp2dXUdPnclIAI6fc+dXPLyLSQ0G6Hjyk/mh2whnCkjAdEqRhRyhW6n3V9/ccy61Kvu5ukYWrJkiXNh9itZ1J5sswr9idIfIY7tJv1Zq9QFu9ExV6WypYRKxTvGEhJDhw41J510ktPp2s+TiOpIJvieB7nk5V9I1F7vEBLZwkxEygKCKgOF5F5rL43j++90BsLPf1DVk6VLl5ru7m5HUNS+L8936+mCXZwu2K0ELnfioy2f1XbzMLsjISHHTwnXEhSq3iQx4c+exikcIgoNvekRLnfFERM6niRGuSmLiCi9eNABTw+IwrIwDoHQiaDQXyUqSjAocXrZsmWH8x/y6uhm7WDHGfqTBxGTlmCrfT1oGVjEAyFa7V7T+csPQZk+fbqTJ6HzWKM8iYzyIVYhIornW/nJ1vhWiIhSK2YERKFZatywpr5JJEgHOX78GOIVK1Y4CYr+jER9OApN1ZLJ1UhDxORRsOHEl8eJz4tA8/Mkxo0bZwYPHuzMqKoxZqMbInGKhgDv0XmeMokF861EbS8JEq7ThZyIhFWyULk7DuxC85i1tWEupmGWabecxIJE6MMPP+zcufMb8HRSGrWKZVo77eGQtzFOOleDsqXJ72eV8yz8fhJz5851Ol3rcbuwlIRnKB7gUldcMeGXgNX1EdKDmYgEBYSUsQwKz5P2+3zUnpyOafedx1mZyZ9tUN6DBISqmuhxkDATQn/ogh11u+1ycsIIYO7EM8vS6nnlROiGyIknnujkSahIhMREbZ5EihWbHuZSV2wh4Sdc67jixi0iotD4U2tSxRzIpTg5qWrHX4QRkVEFhV8PW9P769atcwSETooSELUnyywd3aI42EUOr8pasOHEl9+Jz+q7rX1dM/W6Vs6cOdMMHz7cOd/t3r378PkuCeHQZPnlXO3Kcb3WjAQh5IgIhxHDR9adeWruYuzbZ3bv2Z2r6SsqMJUP73tcHkYghBUU/nI6bvz8B4Uu+eVbFTtcuw6aqhW/slLeBRtOPOIhre9W5z0lWI8fP97MmzfPLF682GzZssU578UhGgK8p9faCq525blm1+ZJ5GrfjPZtQHnGOu81dk847qTD/0sszDvzmWbQoMH24Dhgxo6ZYKYdPcPs27f3SIFhP1Lvzp5UHfnaCkzULS4lz7X2+0YXpLj+F5p90KyDLqKahZCg8KtP4IhE20+cvXDr0HlTx+GwYcM6SrDGiSdEK+zyOt40A6FjUAnXaqKp858cwlpnsFlvk6jnXftYVZlO4jJXPjEhn0yzXWnfbG4kFpz9efKQ6e7ZftinPXjooNmydYPruHrs6N6KiIjzIGjGiBEjzcwZs83evXvM0VOnmxNOONns2b3LvqePecaxJzgOmNPQxltFUjMXtQ3kiMMrLbOtLTHe7F2bC5IJuoz/vz/bsGPHDvPggw861UqUdFh1R6ys4S55djr92TCFlkQ5NzOehGh1srxf/1/iYdWqVY6Y8IVtszyJds8H+P+n1l7BZa6c6DvWrEQS/lk7sVArFLRpPd/Tu6Pt/iIiUhARLT2+Wcc7J51JE6eYOSecYnZbcTF27HgzbeoMs2//3sOib//+zoSFLyB0gCIeSo0Kma+0NjnKhavVRc/Pf1i7dq156KGHjsh/qILT0KmjhWMW72f1HTaJiE7zI3Diq/d7jGu7uibrxsqmTZuc8+LOnTsPhzeFmGEIei7+D2sf5DJXTupv9Haynn79BhwOevHFQk/vdufmtSMWtq13hEUQsYCIyLGIaIQ/cyHhcNaZzzSDBw0xI+1z044+5ghhETQUihmIynGftTMi3OVq+L/Mb7Kk/Ae/fKt/x4279cWO8y6qg6hzmkRsvYjAied3kMV3K+Gwa9cuR0io0abOj7rxEmbGN8AyH7J2JZe48osJP5G/nb/mJmj3N3379H2aYOjbt7/p6t5qdu/ZZZ87GFksICIKJiIaCovhVlgc82dhMWTwUPv4WDNgwEArDg46wqJ+toL8h8pyk7VXthMIQS5efuyvyhkqfOmJJ55wLo5+/kNRLvA4UeUbY38mYsSIEYmKWZz48h5/cW7XP1fq7yOPPOIUm9B50i8DG0M+hP681toNXOLKLyL8G7/1QqJ+lqGPFaq7dvU4swtJCgZERMFFRCNmzzrOXkQHmYkTp5gTTzjFDB40+PBshfIqdjl5F0dRgal6fNX+Xi4LIyIaCQo//2Hbtm3m/vvvd/Ig9LhdSB1368nVSOOz+iJi1KhRT6tsUnUnnuMtm9+0nychW7lypVMGVo5gkDyJgP9fYO0OLnHVERMKQdeNYs0q9O/X/2mzDHv37TG9O7vM/gP7Ut8/RETBRUQ9CoOadcwzzNgx45zqUAP6D3TUKVSOj9nfy+WNfuxBRYSm4XVXTVVHNAOhmYhG9dAJ/SmGmCjjGPsiYvTo0YdFBONNiFbW363Q+dPPk3jggQdMb29vwzyJdjdy6p7XxVyVmR7lElctIaE8hu6eHWbj5jWOT5fGLAMiooIiopazz3qmufR1bzObt2ziV1g93mJ/L9e0u1A1+r9+Sr4+/yHK8c/depzbJLZZKyKCJlZzLCGI0/xuVblOidYSEhs2bDg8k9tOODQREZutHWetm0tcddB3P3zYSLNk+UKzfuPq3O1bUaBjdWhR04c8iOqyI0zjuNrldNFTF9aFCxc6VZgkKBrlPzQ7mdBUjS7YaXXB9vMgao9hnHic+Dxs10eJ1hIO5557rnNTZvny5c4sRaM8iQDsstbD5a1a6Pq7c1eP2d61hcFARKQpIsiBqDBb2omFeqdMd8eGDh1qNm/ebO677z7T1dV1uP9DmAtdEOcv72Ki1T7mycGuumCrdcJw4nHis/5umy2nDtfKkZg7d65TSWzRokVmz549jrgIcm6tWUZhBdwZrBh9+vR1kqX37t3NYCAiAFKhx7vYHNXswlZ7N1cXON0ZUyKgZiDU/0EColPaOYV5cLCTnGlIS0xUXbA1E7o48cyyZCUe6t+j5FiF3x177LFOh3WFN3V3dzszva2O/zq2c2mrHv5NvrA39KBOjDEEAIHZYQJMe/v5D5ouVfL0Pffc41zs/ATAOE+CrWZBGsX/BnkuieWz2m4n6wjyfJ7GOInjo95payQ0WjmSQZb3n2vmeCa93aDryGq7ce1n0tuN67sKi0SEwpsmTJhgLrjgAjN58mQndLS+slgLEBEAEWEmIiTqH+HHshPaVDn2WNvf7s6Fwpd0UVP51jD5D52ICf+CHOQ1Qn/I1Wi3nihN5sIuzwxAOssXZXanU3TO1bnWz5NQ8YraPIkW58+dXNqqh3ueYxw6hZmIkDy8ZJHZsHG900cCKkePaTAT4YsKTY1qSl35D7fddpsjIBS+VNtdNfmTYjYzE0W8Wx/Xvqc1xmG+807Xk6cZgLhmKopyJ75qsztx4edJ6DhWnsS8efOcc7LyJJqJZw9KLQJEhJmIkGzbtsX09HSZSZOmOp2soVJofvypRhck5T+oLKa6qSouV+FLEhRZxFpytz788mXJ1Yhju0E6prd7jTvxzLIEeS0JIeHnScyaNcs5B6ugxfbt250Z4mZv49JWPeyZzrnBB53BTETYAevT1/Tr159EnOrSXXth9PMfdDLSxWr+/PnOBSxohZCkxQR366uVqxHndrkTH327nY5Z2P0sa75D5Ls9Xp7E+PHjzbOe9Swzbdo0p6+Enm+wT9u4rFXQlzuqj9m7dw8D0SHMRACEY2vtAz//YcGCBU74ksRDkvkPUcVErfBp91oZ7tYXOVej1T6mPcaNHMOoz7V7jXyH8MsXZbtZ4edJnHfeeU4Z2KVLlzbqJ0FidRWd3779zdZt67khjIgASJW+OunoQiTBsHHjRmf2Qf0fNHVe7/DlCZqqhf9cVQyv6qSsK2VLyyseiiIc6vfL7ydx+umnm5EjRzozxqreVFMtDz+oolAcBxGR2YHXJ8OpWsjWEffzHx599FGnAtOhQ4cyy39IQ0zkycEmVyO976RVmA1OPHkWRXHCtI8HDhxwztN+PwnNHO/YscMRElzHK+3NMQSIiAwGrV+/wwbVEhCaBtfFSBchTY3rGMhD/kNVxUSrfcyDiCny7A9OfDGd+LIlS8clJHSMKy9i3Lhx5pJLLjH33nuvWb16tXNTCCFRPfr22R+mlwggIuLjySefcqZDd+7aycmnSiedvn0VYztRDeTWrFmTavnWNMREpw45lZXiWz7LMdaFNUhiNU48syxFRNdu5Umcf/75Tp6EPZcPQ0hUzYd70owbO9Fs2rqmLssREBGJO1xPmt/+/hfmvHMuMT29XebgoYPmKKbEKoFCmDZt2nSZvehMbJL/MMGa6gge8my8tZHWDlibqFVYG25trPf/CGuDvecG5klQcLe+2rkaQR7jxOfDia9YyJIaw/Va22uty9pBaxu817YYt3reAGsbvWX7eaZeELv8z6M8CZ3P58yZo/CmBWURSBBMQIweNcZs37HN7OjewoAgItJ3shYvecA54ZxvhUR3b7c5dEg+IiegKtC3b9/bdfGJiWGe6BjlCYqxnqCY4NkUa5M8G21tnCdKEBM5EDFlzdXAiWeWJWWnWgfeZuPeE5YwWGdtvfd4vfecKij1eP/LdluL3KhJn01hqfv27aM6T0UFxA9vusbs2k2zckRERjz0yP3OiciZkejxZiS4k1FqEqh7vtOzIB1TB3hiYrInLjSzMdPaDGvHegJjmnROWcREK8c7DyKmCrkaWTj9iIdSiodeTxxILCy3ttraCuPOHmzwLJPAEkRElQTEWLPNCogfWQGxe88uBgURkS2LHr7P+YuQgBTYb22NZ41QWNQsz6ZaO8XayZ7omOGJkEKJibw72Gnse5aCDSeeEK0IbPfEwmPWHrG21Hu8whMOAJkJiO1dCAhERE6FhBPahJCA7FDrzYc9q0UzE8d5phmLc62d4ImNoVmKiTCON7ka6Qk2nHhCtAKyzrup8YC1+dbWeqJhPadjyJeAGGN2dCMgEBE5FxLMSEAOUYL3Es9qkYiYY+14a8/y/p6QppgI6tBSWSl9wdaqOhNOfPJOfA5DlpSw/Li1e63dYdxZhYXe8wA5FxDbzQ9vREAgInIuJHRJPh8hAcVghWe/tHaF99wZnpC4yLgzFie2O0cQ+hNe9OQtvCpISBNOfDpOfI7Eg/K0llm72dqDxp1tWMtpExAQgIhIiIeskNA5+ryzERJQSO737AfeY+VUzPVExTO9x7GKiTw42ORqHPla0DwJnPhS5Tvs0CXMEw0SDHcbKuhDoQXEWE9AfBcBgYgoDosWe6FNCAkoPos9+773WDMV86y92Nppxq0G1ZFznScHmy7Y7ddfRie+wuJBv+3/s3abJxrIZYASCYhtnoCgjCsiAiEBkAf8mYpvGrfHxSXGzad4kXFDn2J3yKmsFN/yUdaDE5/9dmMMMVOZVTVW+6lxE6Hv5pQG5RUQhDAhIsoiJNTZ+iBCAkqFbu/83LOP6FC39lxPUJwTt0NOZaXw+x5VsOXVmS66E5/RLIv6MvzJ2q+MG6pEmVVAQAAiojhCQg3pLnZnJBASUF7u9OzT1k73BMVrjRv+VBgxkbWIyUuuhl+dCSc+GeGT8Ha7rP3B2k3Wfm/chm4AJRcQY0xXt9uJGgGBiCiRkFBFvKf+XP4VIQHl5wHPvmjcGYq/sPaXxi0jm9u79eRq4MRnJZRiWM8B4+Y33GDt18bt4QBQIQGx3VwvAbEbAYGIKJ2QqOsjgZCA6uDPUHzSuLMTr7f2UmsT83a3nlyNI6szNeoTgROfzvIh1qOKSqqmpjyHJZxuAAEBiAiEBEAZudmzsdZeY+2N1i6kC3b4z5VGWFft47I68QUVDyrHqlyk73m/J4DKCogdXdvND3+MgEBEVERIHOUJiW6EBFSXbcat8CQ73xMTr7XO7Lg4HGO6YHe2PE58utsNsQ41ffuutesN4UqAgDBd3TvIgUBEVIsHa2YkEBIA5g7PPmntTdb+n3VmT05STCTpkJelC3azxOqKO/FZbVcJ0v9j3FwHAASEJyCuv/E7CIiM6cMQZCMk7rznFjNyxCjTr1+/hncAASqGSlFeYe0Uay+z9sv67smNHN1GzzV7Pux6Olk+7Dqy2m6r5Rs5to1Cnlo52kGW959r5mgnvd2w6+h0PwNut8valcZt6vhqBAQAAiKPMBORoZDwy78yIwFwBH7/CVV2eo91ct/o+ld0wU47vIpk6dRnWRSm9C1rVxlClgAaC4ibEBCICLBC4l7nL0ICoCF+ZacveGLirfbv4E4dcrpgt15eF+swgqJkTnxWQmmZJx7+27idpQGgmYAgiTo3EM6UAyFx5z23EtoE0ByVsXyvcUOd/sPanryF/pQxvKrW2Y0j7CeOEKQoy2ex3RDreMTaO60pD+gKBAQAAgIRAQgJgPh53NoHa8TEgSKIiaxFTNR1lMGJz3GexVJPPJxq3NmHg/y8ARAQiAjoUEiMRkgABBMTc619OwsHu/a5MEnSeRMTYRO8SZbueLsbrH3EO3YlHg7xcwZAQCAiICYhcYsZgZAACII69L7d2unWfpiVmAjyfJ7Cq8KIhhI68bHuZ4j17LT2WWsnWvuStf38fAEQEIgIiF1I3IWQAAjDQmuvt/Zc4/acyOxufZlyNUrmxMe2fATh8w3jhuB93LilWwEAAYGIAIQEQI74g7ULrL3b2vo4HfI4ZhryJiZarSegc0y+Q+vXfmbtTOMWBVjFzxMAAYGIgBSFxK2OkOjbFyEBEIJvGvfO75fjdsiLUFkpyAxK0G2EdeLTEA8hnPistrvS2l9ae7m1+/k5AoQTED9EQCAiIA4hscAREiNHIiQAQrLd2oeNmy/xy7gd8ip0wY7iTFc0Wfrw8Bm3p8lp1q7nJwgQTUDsQkAgIiB+IdEPIQEQloXWXmLtr61ti9shz2tlpTz2iUjaic8qz8Lj1554+HtrPfzsABAQiAjIj5CYf6sZMXIUQgIgGlcZt6zm1Uk45HmsrJSXPhFJO/FZ5Vl47LZ2mbUXWVvEzwwggoDokYC4BgGBiIDEhMRDCAmADlln7W3WXmbcuPXYHfIydMHWhV2vBc0xqFiydC3XGrfT9Nf4aQF0ICBulIDYyaAgIiBZIXEvQgKgc35u7QzjJmAHcrrzJibS2G4enfgM8x1q2WHtLdYubSRGAQABgYgAhARAeekybinYV1nblDcxkWUX7FoHOi8Vj+KqzNSheBA/tnaqte/xEwLoQEB0IyAQEZChkLjNCgmqNgF0iJxC5Upc22yBqnXB1kW+kZioYLL0Eb6Ptb/xROcT/GwAOhEQXU4fCAQEIgIyExJujgTlXwE6RjMRCk15t+csJi4m8t4FO2snPuNk6Xru9oTmf/JTAYhDQFxNHwhEBCAkAErFNz1ncUGrharSBbuiydL1XGntQmuL+XkAICAAEVE+IXHPLQgJgHiQs3i+CXDXuUpdsJN04nOSLF1Pr7XXWPuQtYP8LAAQEICIKKeQWHwvna0B4uOAcePf32pahDd16tTnvQt20k58jvId6lH4kjqd38hPAaBzAdHd4+ZAICAQEZBbIbEAIQEQL9cYtxTskiALl60Ldpp9IqIsn4B4EN8wbvjS4xz+APEIiOtulIAgiRoRAQgJgIr9rKyda0LclS5DF+xGDnnJkqUb8T5r7zWELwEgIAARUVUhcff8W80ohARAXPQYNz7+02HfWOQu2CVOlq5no7WLrH2dQx0gPgFxPQICEQHFY6FXtQkhARArn7D2RhMgT6KIYqLV8yVJlm7EXdbOsnY7hzdAvAKCPhCICCi6kBiBkACIkR8Yt3rTxihvLkIX7Pru1SVJlm6EQtQ0A7GOwxoAAQGICKgTEnciJADiRtV7dPf6/qgrKEIX7JLlO9TzOeOGqB3gcAZAQAAiAhrgJFsvILQJIGZ09/pZ1n7ZyUry2gU7C/EQdB0xcJm1f+AQBohTQHQjIBARUEbIkQBIBBU9f4m1qzpdUR67YNc68SURD+K11r7GoQsQp4DQDMTVCIgK0o8hqI6QEM88+2LT1b3DHDp0MKmLNEDV+Gtrm6z9Yxxiwneig7zWbPk41tPI6W8lNoI+H2U9MaAKWy+3diuHK0DcAoIZCEQEICQAICr/ZK3X2uVxrCyqCAgqMlqtp1Gp1zBOfxhBkYJ4EEqCf4Fxe34AAAICEBEQXUgcZYXERQgJgHhRsq5mJL4d1wrDioB2IiPMetqFG3UiKFIQDj7qPE0FJoAYBcQoCYheBAQgIioqJObLdWBGAiB+rvb+fjvOlbaqmhRmFiKImIhDKORAPIhHPQGxkcMSID4B0SMBcQMCAkisrrCQINkaIEEh8eqkVp5FedicJ0s34h5r5yEgAOITEKMREICIAIQEQOLcZO1FSW4gaTFRUPHgC4hnW9vGYQgQn4AghAkQEYCQAEiHXyctJJIUE/WVmgogHmoFxG4OP4CYBYRmIHYhIAARAU2ERD+EBEDhhEScYkJOQyshkHJn6TAsQEAAJCggmIEARAS0EhIjERIASQiJN6W1sbga1xVg1qGWxxEQAAgISBeqM8ERQsJ6AuaZ8y4y3d3bzcFDh6jaBBAP37c2wMRctamdmGgkBpq9FkRIhH09JVZYu9AaXg5AjAKip7fbXH/jNQgIaAozEXCkkFg039y14DYzcuQY069vX2YkAOJDVZvenfZGo85M5HzmwUd9OS6wtoHDCyBeAXGdkqh39TIogIgAhARADvimtX/MYsNhxYT/fE7Fg+i29jwEBEDMAqKnCwEBiAhASADkkMutfTmrjUftEZHD0MaXWnuIwwkAAQGICMixkKD8K0CsfNjadVnugC8Yms1A5FQ4+LzK2h85jABiFBAKYbqJJGpAREDMQoI+EgCx8wZrt+dhR+rFRM4LKiiv5MccPgAxC4gbr6YPBCAiIAEhMR8hAZAAL7S2NC87066DdQ74V+PmlQAAAgIQEVAIIfEQMxIACaC+BkoO3pGnnWpVHjZDrrX2zxwyAHELCDpRAyICkhYShDYBJMET1l7OMLRE3agvZRgAkhAQJFEDIgIQEgBFRUnCb2YYmoqsv2AYAOIWEFcjIAARAQgJgBLwv9a+yDA8jVda62IYAOIWEIQwASICMhISdy+4HSEBEC8ftfZLhuEwqmB1L8MAEKeAIAcCEBGQMQ8suscKCWYkAGLmddZWMgzmSybjXhoA5RQQhDABIgJyISTmIyQA4kUVm9SN+ckKj8HN1j7CoQCAgABEBCAkACA4D5vqJlqvM25HagBAQAAiAhASABCSH1j7agU/92us4e0AICAAEQEICQCIyPv106rQ5/1ba3fztQMgIAARAQgJBgWgM15hbU8FPudPrV3B1w2AgABEBCAkEBIAnbPG2ltK/hmVB/FGvmqAeATE9QgIQEQAQgIALDdYu6rEn09lbXfxNQNEFxCjagTETgQEICIAIQEAHu+0tryEn+tT1u7k6wXoTED0IiAAEQEICQBo5CsYt3JRmbjD2if5agEQEICIAGgsJO69HSEB0DmLTHmasB2wdilfKUCnAqIHAQGICCixkHjwHoQEQDx8ydqtJfgc7zBu0jgAdCQgrkZAACICKiAkFiAkAGLgr6wdKvD+/8raNXyNAAgIQEQABBMSixASADGgO/jvLOi+77D2Jr5CAAQEICIAEBIA6fNt497RLxp/7QkJAIggIHbuREAAIgIQEggJgM7QbMSBAu3vT6zdxNcGEE1A9FoBcd0NCAhARABCAiEB0Bnq9PzBguzrTuMmUwNARAFxPQICEBEACAmAmPi6tT8VYD//xtpWvi4ABAQgIgDiExKHy7/2RUgAhEd5Bnn+4dxm7Tt8TQAICEBEAMQrJA6Xfx2DkAAIzzJrn8rpvunH/Ha+IgAEBCAiAJIREosQEgAdIBHxWE7363G+HgAEBCAiABIVEvcgJACi8rac7c/jJr8zJAD5FhA3fgcBAYgIgDDcj5AAiMofrf0oR/vzLr4SgAgCQjMQ9i8AIgIAIQGQFqqCtCcH+/Fja3/g6wCIICCYgQBEBABCAiBlNln7eMb7sN/aZXwVAAgIQEQAZCck7kVIAITkCpNtkvWnra3nawAIJiB2OjkQCAhARADEKyQeREgAROC9GW13lbXLGX6A4ALiOgmInQgIQEQAICQAsuf31n6TwXY/LP+I4QcIICB6ERCAiABASADkj/ebdDtZ327chGoAQEAAIgIgb0LijwgJgGAst/aNFLf3AYYcIICAUAjTTfSBAEQEQMpC4m6EBEBw/slaGp7K96wtZLgBAggINZKjDwQgIgCyERJ3E9oEEIQua/+a8DYOeWIFABAQgIgAyDcPENoEEJR/N8mWXP2ytbUMM0BrAXE9AgIQEQD5gNAmgEBopuAfElp3l7VPMcQA7QVELwICEBEACAmAgvFda48msN7PW9vJ8AI0FxCqwoSAAEQEAEICoKh8JOb1bbR2JcMK0FpAUMYVEBEAeRcS9yEkAFrwM2v3xri+T1jby7ACNBMQ30FAACICoBBCYiEzEgBt+HhM63nC2lUMJ0ArAUEIEyAiAIojJAhtAmjFb008sxEqG3uI4QRAQAAiAgAhAVANOp2N0CzE/zCMAAgIQEQAICQAqoNmIxZ08H5mIQCOEBCj6QMBiAgAhARAJfjniO9jFgLgaQKilz4QgIgAQEgAVIKosxHMQgAgIAAQEYCQAKgwYWcjmIUAOEJA7ERAACICACEBUDk0G3FfiOX/zTALAQgIL4laAoJO1ICIAEBIAFSTLwZcbpuhLwQgIA5XYUJAACICACHBoECVud7aowGW+3dr+xkuQED0EMIEgIiAKguJ+QgJAJ8r2ry+29o3GCaotIAYOdrs2oWAAEBEQOW5DyEB4KMwpU0tXpeA6GKYoNICYnevue4GBAQAIgLAExKENgGYg9a+2uQ1JVJ/hSECBAQCAgARAVADORIADt+0tqvB8z+0tobhgUoKiFEICABEBEAbITH/PoQEVJqt1r7T4PkvMjRQSQEx0m0kd92N1yAgABARAM25byFCAipPfUjTHdYeYFigkgJil9eJurebQQFARAAgJABasMzaL2sef4EhgUoLCGYgABARAOGExJ8QElBV/t37u9razxgOqJyA2L3TXH8TAgKgHf0YAoBGQuIu5++Zpz/TdHfvYECgStxirdfaTxgKqJKAGDZsuCsg1Im6FwEBgIgA6EBI9OnT15xy4ulml72wAFSIN1lbzjBAVRg4cJDZvXuX+dFPvouAAAjIUYRqAAAAAABAGMiJAAAAAAAARAQAAAAAACAiAAAAAAAAEQEAAAAAAIgIAAAAAABARAAAAAAAACAiAAAAAAAAEQEAAAAAAIgIAAAAAABARAAAAAAAACICAAAAAAAQEQAAAAAAAIgIAAAAAABARAAAAAAAACICAAAAAAAQEQAAAAAAgIgAAAAAAABEBAAAAAAAACICAAAAAAAQEQAAAAAAgIgAAAAAAABEBAAAAAAAICIAAAAAAAAQEQAAAAAAgIgAAAAAAABEBAAAAAAAICIAAAAAAAARAQAAAAAAiAgAAAAAAABEBAAAAAAAICIAAAAAAAARAQAAAAAAiAgAAAAAAEBEAAAAAAAAIgIAAAAAAAARAQAAAAAAiAgAAAAAAEBEAAAAAAAAIgIAAAAAABARAAAAAACAiAAAAAAAAEBEAAAAAAAAIgIAAAAAABARAAAAAACAiAAAAAAAAEQEAAAAAACAy/8HAeJQDog75ZwAAAAASUVORK5CYII=";
|
|
2433
3088
|
|
|
@@ -2534,7 +3189,7 @@ var Docula = class {
|
|
|
2534
3189
|
}
|
|
2535
3190
|
if (this._configFileModule.onPrepare) {
|
|
2536
3191
|
try {
|
|
2537
|
-
await this._configFileModule.onPrepare(this.options);
|
|
3192
|
+
await this._configFileModule.onPrepare(this.options, this._console);
|
|
2538
3193
|
} catch (error) {
|
|
2539
3194
|
this._console.error(error.message);
|
|
2540
3195
|
}
|
|
@@ -2542,18 +3197,37 @@ var Docula = class {
|
|
|
2542
3197
|
if (consoleProcess.args.template) {
|
|
2543
3198
|
this.options.template = consoleProcess.args.template;
|
|
2544
3199
|
}
|
|
3200
|
+
if (consoleProcess.args.templatePath) {
|
|
3201
|
+
this.options.templatePath = consoleProcess.args.templatePath;
|
|
3202
|
+
}
|
|
2545
3203
|
if (consoleProcess.args.output) {
|
|
2546
3204
|
this.options.output = consoleProcess.args.output;
|
|
3205
|
+
} else {
|
|
3206
|
+
const configOptions = this._configFileModule.options;
|
|
3207
|
+
if (!configOptions?.output) {
|
|
3208
|
+
this.options.output = path6.join(this.options.sitePath, "dist");
|
|
3209
|
+
}
|
|
2547
3210
|
}
|
|
2548
3211
|
if (consoleProcess.args.port !== void 0 && !Number.isNaN(consoleProcess.args.port)) {
|
|
2549
3212
|
this.options.port = consoleProcess.args.port;
|
|
2550
3213
|
}
|
|
2551
3214
|
switch (consoleProcess.command) {
|
|
2552
3215
|
case "init": {
|
|
2553
|
-
|
|
2554
|
-
this.
|
|
2555
|
-
|
|
2556
|
-
|
|
3216
|
+
if (consoleProcess.args.typescript && consoleProcess.args.javascript) {
|
|
3217
|
+
this._console.error(
|
|
3218
|
+
"Cannot use both --typescript and --javascript flags. Please choose one."
|
|
3219
|
+
);
|
|
3220
|
+
break;
|
|
3221
|
+
}
|
|
3222
|
+
let useTypeScript;
|
|
3223
|
+
if (consoleProcess.args.typescript) {
|
|
3224
|
+
useTypeScript = true;
|
|
3225
|
+
} else if (consoleProcess.args.javascript) {
|
|
3226
|
+
useTypeScript = false;
|
|
3227
|
+
} else {
|
|
3228
|
+
useTypeScript = this.detectTypeScript();
|
|
3229
|
+
}
|
|
3230
|
+
this.generateInit(this.options.sitePath, useTypeScript);
|
|
2557
3231
|
break;
|
|
2558
3232
|
}
|
|
2559
3233
|
case "help": {
|
|
@@ -2564,16 +3238,23 @@ var Docula = class {
|
|
|
2564
3238
|
this._console.log(this.getVersion());
|
|
2565
3239
|
break;
|
|
2566
3240
|
}
|
|
3241
|
+
case "dev": {
|
|
3242
|
+
const devBuilder = await this.runBuild(consoleProcess.args.clean);
|
|
3243
|
+
this.watch(this.options, devBuilder);
|
|
3244
|
+
await this.serve(this.options);
|
|
3245
|
+
break;
|
|
3246
|
+
}
|
|
3247
|
+
case "start": {
|
|
3248
|
+
const startBuilder = await this.runBuild(consoleProcess.args.clean);
|
|
3249
|
+
if (consoleProcess.args.watch) {
|
|
3250
|
+
this.watch(this.options, startBuilder);
|
|
3251
|
+
}
|
|
3252
|
+
await this.serve(this.options);
|
|
3253
|
+
break;
|
|
3254
|
+
}
|
|
2567
3255
|
case "serve": {
|
|
2568
3256
|
if (consoleProcess.args.build || consoleProcess.args.watch) {
|
|
2569
|
-
|
|
2570
|
-
fs4.rmSync(this.options.output, { recursive: true, force: true });
|
|
2571
|
-
}
|
|
2572
|
-
if (consoleProcess.args.clean) {
|
|
2573
|
-
this.cleanCache(this.options.sitePath);
|
|
2574
|
-
}
|
|
2575
|
-
const builder = new DoculaBuilder(this.options);
|
|
2576
|
-
await builder.build();
|
|
3257
|
+
const builder = await this.runBuild(consoleProcess.args.clean);
|
|
2577
3258
|
if (consoleProcess.args.watch) {
|
|
2578
3259
|
this.watch(this.options, builder);
|
|
2579
3260
|
}
|
|
@@ -2582,18 +3263,32 @@ var Docula = class {
|
|
|
2582
3263
|
break;
|
|
2583
3264
|
}
|
|
2584
3265
|
default: {
|
|
2585
|
-
|
|
2586
|
-
fs4.rmSync(this.options.output, { recursive: true, force: true });
|
|
2587
|
-
}
|
|
2588
|
-
if (consoleProcess.args.clean) {
|
|
2589
|
-
this.cleanCache(this.options.sitePath);
|
|
2590
|
-
}
|
|
2591
|
-
const builder = new DoculaBuilder(this.options);
|
|
2592
|
-
await builder.build();
|
|
3266
|
+
await this.runBuild(consoleProcess.args.clean);
|
|
2593
3267
|
break;
|
|
2594
3268
|
}
|
|
2595
3269
|
}
|
|
2596
3270
|
}
|
|
3271
|
+
async runBuild(clean) {
|
|
3272
|
+
if (clean && fs4.existsSync(this.options.output)) {
|
|
3273
|
+
fs4.rmSync(this.options.output, { recursive: true, force: true });
|
|
3274
|
+
}
|
|
3275
|
+
if (clean) {
|
|
3276
|
+
this.cleanCache(this.options.sitePath);
|
|
3277
|
+
}
|
|
3278
|
+
const builder = new DoculaBuilder(this.options);
|
|
3279
|
+
if (this._configFileModule.onReleaseChangelog) {
|
|
3280
|
+
builder.onReleaseChangelog = this._configFileModule.onReleaseChangelog;
|
|
3281
|
+
}
|
|
3282
|
+
await builder.build();
|
|
3283
|
+
return builder;
|
|
3284
|
+
}
|
|
3285
|
+
/**
|
|
3286
|
+
* Detect if the current project uses TypeScript by checking for tsconfig.json
|
|
3287
|
+
* @returns {boolean}
|
|
3288
|
+
*/
|
|
3289
|
+
detectTypeScript() {
|
|
3290
|
+
return fs4.existsSync(path6.join(process4.cwd(), "tsconfig.json"));
|
|
3291
|
+
}
|
|
2597
3292
|
/**
|
|
2598
3293
|
* Generate the init files
|
|
2599
3294
|
* @param {string} sitePath
|
|
@@ -2672,7 +3367,10 @@ var Docula = class {
|
|
|
2672
3367
|
this._console.info(`File changed: ${filename}, rebuilding...`);
|
|
2673
3368
|
try {
|
|
2674
3369
|
await builder.build();
|
|
2675
|
-
this._console.success(
|
|
3370
|
+
this._console.success(`Rebuild complete`);
|
|
3371
|
+
this._console.banner(
|
|
3372
|
+
`\u{1F987} at http://localhost:${options.port}`
|
|
3373
|
+
);
|
|
2676
3374
|
} catch (error) {
|
|
2677
3375
|
this._console.error(`Rebuild failed: ${error.message}`);
|
|
2678
3376
|
} finally {
|
|
@@ -2690,6 +3388,9 @@ var Docula = class {
|
|
|
2690
3388
|
if (filename && outputRelative && !outputRelative.startsWith("..") && (String(filename) === outputRelative || String(filename).startsWith(`${outputRelative}${path6.sep}`))) {
|
|
2691
3389
|
return;
|
|
2692
3390
|
}
|
|
3391
|
+
if (filename && (String(filename) === ".cache" || String(filename).startsWith(`.cache${path6.sep}`))) {
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
2693
3394
|
if (isBuilding) {
|
|
2694
3395
|
pendingRebuild = true;
|
|
2695
3396
|
return;
|
|
@@ -2746,6 +3447,7 @@ var Docula = class {
|
|
|
2746
3447
|
}
|
|
2747
3448
|
};
|
|
2748
3449
|
export {
|
|
3450
|
+
DoculaConsole,
|
|
2749
3451
|
DoculaOptions,
|
|
2750
3452
|
Writr2 as Writr,
|
|
2751
3453
|
Docula as default
|
|
@@ -2757,4 +3459,5 @@ export {
|
|
|
2757
3459
|
/* v8 ignore next 9 -- @preserve */
|
|
2758
3460
|
/* v8 ignore next 4 -- @preserve */
|
|
2759
3461
|
/* v8 ignore start -- @preserve */
|
|
3462
|
+
/* v8 ignore next 8 -- @preserve */
|
|
2760
3463
|
/* v8 ignore stop -- @preserve */
|