diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..387b5d7ef --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,428 @@ +# Changelog + +## [Unreleased](https://github.com/unfoldingWord/uw-content-validation/tree/HEAD) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/2.1.4...HEAD) + +**Closed issues:** + +- Check repos for files not in manifest [\#99](https://github.com/unfoldingWord/uw-content-validation/issues/99) + +**Merged pull requests:** + +- Bump dns-packet from 1.3.1 to 1.3.4 [\#176](https://github.com/unfoldingWord/uw-content-validation/pull/176) ([dependabot[bot]](https://github.com/apps/dependabot)) + +## [2.1.4](https://github.com/unfoldingWord/uw-content-validation/tree/2.1.4) (2021-06-11) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/2.1.3...2.1.4) + +**Implemented enhancements:** + +- Unable to find/load errors should show filepath [\#170](https://github.com/unfoldingWord/uw-content-validation/issues/170) + +**Fixed bugs:** + +- Failing to detect bad OrigQuote [\#174](https://github.com/unfoldingWord/uw-content-validation/issues/174) + +**Closed issues:** + +- Update USFM Grammar package [\#83](https://github.com/unfoldingWord/uw-content-validation/issues/83) + +**Merged pull requests:** + +- New.2.1.4 [\#175](https://github.com/unfoldingWord/uw-content-validation/pull/175) ([RobH123](https://github.com/RobH123)) +- New.2.1.3 [\#173](https://github.com/unfoldingWord/uw-content-validation/pull/173) ([RobH123](https://github.com/RobH123)) + +## [2.1.3](https://github.com/unfoldingWord/uw-content-validation/tree/2.1.3) (2021-05-24) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/2.1.2...2.1.3) + +## [2.1.2](https://github.com/unfoldingWord/uw-content-validation/tree/2.1.2) (2021-04-29) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/2.1.1...2.1.2) + +**Fixed bugs:** + +- Failing to detect duplicate TN IDs [\#169](https://github.com/unfoldingWord/uw-content-validation/issues/169) + +**Closed issues:** + +- The validator should report an error if the occurrence number is greater than the number of occurrences of the string in the verse text [\#120](https://github.com/unfoldingWord/uw-content-validation/issues/120) + +**Merged pull requests:** + +- Correct two important bugs plus some small improvements [\#167](https://github.com/unfoldingWord/uw-content-validation/pull/167) ([RobH123](https://github.com/RobH123)) + +## [2.1.1](https://github.com/unfoldingWord/uw-content-validation/tree/2.1.1) (2021-04-13) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/2.1.0...2.1.1) + +**Fixed bugs:** + +- Fix wrong missing link errors in TA repo check [\#162](https://github.com/unfoldingWord/uw-content-validation/issues/162) + +**Closed issues:** + +- Handle new TSV filename style [\#157](https://github.com/unfoldingWord/uw-content-validation/issues/157) +- Improve notices like "Unable to find TA link" [\#154](https://github.com/unfoldingWord/uw-content-validation/issues/154) + +**Merged pull requests:** + +- Fix small bugs, plus some improvements [\#166](https://github.com/unfoldingWord/uw-content-validation/pull/166) ([RobH123](https://github.com/RobH123)) + +## [2.1.0](https://github.com/unfoldingWord/uw-content-validation/tree/2.1.0) (2021-04-07) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/2.0.0...2.1.0) + +**Implemented enhancements:** + +- Improve Notes warnings when OccurrenceNote contains two or more TA links [\#150](https://github.com/unfoldingWord/uw-content-validation/issues/150) + +**Merged pull requests:** + +- Handle new TSV filename style; other small fixes [\#155](https://github.com/unfoldingWord/uw-content-validation/pull/155) ([RobH123](https://github.com/RobH123)) + +## [2.0.0](https://github.com/unfoldingWord/uw-content-validation/tree/2.0.0) (2021-03-03) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.1.2...2.0.0) + +**Implemented enhancements:** + +- Combine READMEs and LICENSEs in success messages [\#144](https://github.com/unfoldingWord/uw-content-validation/issues/144) +- Liven filename in demos if no line number available [\#143](https://github.com/unfoldingWord/uw-content-validation/issues/143) + +**Fixed bugs:** + +- Get en\_twl repo check demo working properly [\#108](https://github.com/unfoldingWord/uw-content-validation/issues/108) + +**Closed issues:** + +- Update for new TSV formats [\#146](https://github.com/unfoldingWord/uw-content-validation/issues/146) +- Check year in license.md [\#138](https://github.com/unfoldingWord/uw-content-validation/issues/138) +- Catch TN issues that were only caught by tX [\#137](https://github.com/unfoldingWord/uw-content-validation/issues/137) +- Catch TW link issues that were caught only by tX [\#136](https://github.com/unfoldingWord/uw-content-validation/issues/136) +- Add repoCode to all functions used by the app [\#131](https://github.com/unfoldingWord/uw-content-validation/issues/131) +- BPs demo is hard to use [\#125](https://github.com/unfoldingWord/uw-content-validation/issues/125) +- Rename notice `extract` field to `excerpt` [\#124](https://github.com/unfoldingWord/uw-content-validation/issues/124) +- No two \w fields should touch [\#102](https://github.com/unfoldingWord/uw-content-validation/issues/102) +- Are TA internal links being checked? [\#96](https://github.com/unfoldingWord/uw-content-validation/issues/96) +- Check LICENSE/README in BP [\#88](https://github.com/unfoldingWord/uw-content-validation/issues/88) +- Seeing messages with odd information [\#66](https://github.com/unfoldingWord/uw-content-validation/issues/66) +- Miscellaneous [\#63](https://github.com/unfoldingWord/uw-content-validation/issues/63) + +**Merged pull requests:** + +- New version with changed API for updated TSV formats [\#147](https://github.com/unfoldingWord/uw-content-validation/pull/147) ([RobH123](https://github.com/RobH123)) + +## [1.1.2](https://github.com/unfoldingWord/uw-content-validation/tree/1.1.2) (2021-02-10) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.1.1...1.1.2) + +**Implemented enhancements:** + +- Change of Verbiage on Content Validation file [\#118](https://github.com/unfoldingWord/uw-content-validation/issues/118) + +**Fixed bugs:** + +- Handle links to TN with IDs [\#78](https://github.com/unfoldingWord/uw-content-validation/issues/78) + +**Merged pull requests:** + +- Next round of improvements to markdown checks [\#142](https://github.com/unfoldingWord/uw-content-validation/pull/142) ([RobH123](https://github.com/RobH123)) + +## [1.1.1](https://github.com/unfoldingWord/uw-content-validation/tree/1.1.1) (2021-02-01) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.1.0...1.1.1) + +**Implemented enhancements:** + +- Catch misspelling of USFM attributes [\#132](https://github.com/unfoldingWord/uw-content-validation/issues/132) + +**Merged pull requests:** + +- Allow TN links with IDs and more varieties of Bible links [\#140](https://github.com/unfoldingWord/uw-content-validation/pull/140) ([RobH123](https://github.com/RobH123)) + +## [1.1.0](https://github.com/unfoldingWord/uw-content-validation/tree/1.1.0) (2021-01-25) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.0.3...1.1.0) + +**Merged pull requests:** + +- Fix bugs [\#130](https://github.com/unfoldingWord/uw-content-validation/pull/130) ([RobH123](https://github.com/RobH123)) +- Next set of improvements [\#123](https://github.com/unfoldingWord/uw-content-validation/pull/123) ([RobH123](https://github.com/RobH123)) + +## [1.0.3](https://github.com/unfoldingWord/uw-content-validation/tree/1.0.3) (2021-01-18) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.0.2...1.0.3) + +## [1.0.2](https://github.com/unfoldingWord/uw-content-validation/tree/1.0.2) (2021-01-15) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.0.1...1.0.2) + +**Merged pull requests:** + +- Prevent 621 punct at end for UGNT ellipsis [\#128](https://github.com/unfoldingWord/uw-content-validation/pull/128) ([RobH123](https://github.com/RobH123)) + +## [1.0.1](https://github.com/unfoldingWord/uw-content-validation/tree/1.0.1) (2021-01-07) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/1.0.0...1.0.1) + +**Closed issues:** + +- Fix manifest file errors in TN repo check [\#107](https://github.com/unfoldingWord/uw-content-validation/issues/107) + +**Merged pull requests:** + +- Fix failing to disable notices when called from tC Create [\#117](https://github.com/unfoldingWord/uw-content-validation/pull/117) ([RobH123](https://github.com/RobH123)) + +## [1.0.0](https://github.com/unfoldingWord/uw-content-validation/tree/1.0.0) (2021-01-05) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.9.4-beta1...1.0.0) + +**Merged pull requests:** + +- Bug fixes [\#113](https://github.com/unfoldingWord/uw-content-validation/pull/113) ([RobH123](https://github.com/RobH123)) + +## [0.9.4-beta1](https://github.com/unfoldingWord/uw-content-validation/tree/0.9.4-beta1) (2021-01-01) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.9.3...0.9.4-beta1) + +**Closed issues:** + +- Find a way to remove unwanted notices from package results [\#109](https://github.com/unfoldingWord/uw-content-validation/issues/109) +- Consider renaming demo `ignoreDisabledNoticesFlag` [\#101](https://github.com/unfoldingWord/uw-content-validation/issues/101) +- Check for files starting with newline [\#97](https://github.com/unfoldingWord/uw-content-validation/issues/97) + +**Merged pull requests:** + +- fix npm publish package [\#112](https://github.com/unfoldingWord/uw-content-validation/pull/112) ([mandolyte](https://github.com/mandolyte)) + +## [0.9.3](https://github.com/unfoldingWord/uw-content-validation/tree/0.9.3) (2020-12-31) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.9.2...0.9.3) + +**Closed issues:** + +- v0.9.2 fails to compile in tc-create-app [\#70](https://github.com/unfoldingWord/uw-content-validation/issues/70) +- Only one occurrence of double spaces found - should have found three [\#69](https://github.com/unfoldingWord/uw-content-validation/issues/69) +- Should not consider quote character as beginning of word [\#68](https://github.com/unfoldingWord/uw-content-validation/issues/68) +- Crash and lots of assertion errors - v0.9.1 [\#67](https://github.com/unfoldingWord/uw-content-validation/issues/67) +- Original Languages should not be validated [\#53](https://github.com/unfoldingWord/uw-content-validation/issues/53) + +**Merged pull requests:** + +- fixes for undefineds and material-table [\#72](https://github.com/unfoldingWord/uw-content-validation/pull/72) ([mandolyte](https://github.com/mandolyte)) +- More cumulative improvements [\#71](https://github.com/unfoldingWord/uw-content-validation/pull/71) ([RobH123](https://github.com/RobH123)) + +## [0.9.2](https://github.com/unfoldingWord/uw-content-validation/tree/0.9.2) (2020-11-25) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.9.1...0.9.2) + +**Merged pull requests:** + +- Next set of improvements [\#65](https://github.com/unfoldingWord/uw-content-validation/pull/65) ([RobH123](https://github.com/RobH123)) + +## [0.9.1](https://github.com/unfoldingWord/uw-content-validation/tree/0.9.1) (2020-11-22) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.9.0...0.9.1) + +**Closed issues:** + +- Version 0.8.16: Ambiguous error message [\#61](https://github.com/unfoldingWord/uw-content-validation/issues/61) + +**Merged pull requests:** + +- Start work on next version [\#64](https://github.com/unfoldingWord/uw-content-validation/pull/64) ([RobH123](https://github.com/RobH123)) +- Prepare for v0.9.0 release [\#62](https://github.com/unfoldingWord/uw-content-validation/pull/62) ([RobH123](https://github.com/RobH123)) +- Start on suggestions; allow disabling of known issues [\#59](https://github.com/unfoldingWord/uw-content-validation/pull/59) ([RobH123](https://github.com/RobH123)) + +## [0.9.0](https://github.com/unfoldingWord/uw-content-validation/tree/0.9.0) (2020-11-10) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.16...0.9.0) + +**Fixed bugs:** + +- checkTN\_TSVDataRow\(\) does not validate tA links [\#37](https://github.com/unfoldingWord/uw-content-validation/issues/37) +- checkTN\_TSVDataRow\(\) does not validate verse links: [\#35](https://github.com/unfoldingWord/uw-content-validation/issues/35) + +**Closed issues:** + +- Version 0.8.16: Type error message is in notice [\#60](https://github.com/unfoldingWord/uw-content-validation/issues/60) +- checkTN\_TSVDataRow\(\) does not warn that occurrence notes does not match SupportReference [\#38](https://github.com/unfoldingWord/uw-content-validation/issues/38) +- Untangle Yarn and Yalc [\#24](https://github.com/unfoldingWord/uw-content-validation/issues/24) + +## [0.8.16](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.16) (2020-10-26) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.15...0.8.16) + +**Merged pull requests:** + +- Small improvements to checks [\#58](https://github.com/unfoldingWord/uw-content-validation/pull/58) ([RobH123](https://github.com/RobH123)) +- Get annotation checks working, plus some small fixes [\#57](https://github.com/unfoldingWord/uw-content-validation/pull/57) ([RobH123](https://github.com/RobH123)) + +## [0.8.15](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.15) (2020-10-07) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.15-alpha.1...0.8.15) + +**Implemented enhancements:** + +- Tighten TA ref checks in TN as per Perry Oakes spec [\#56](https://github.com/unfoldingWord/uw-content-validation/pull/56) ([RobH123](https://github.com/RobH123)) + +**Merged pull requests:** + +- Improve USFM and TN link checking, etc. [\#55](https://github.com/unfoldingWord/uw-content-validation/pull/55) ([RobH123](https://github.com/RobH123)) +- Move stuff back out of core and of NPM [\#52](https://github.com/unfoldingWord/uw-content-validation/pull/52) ([RobH123](https://github.com/RobH123)) + +## [0.8.15-alpha.1](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.15-alpha.1) (2020-10-07) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.14...0.8.15-alpha.1) + +## [0.8.14](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.14) (2020-10-06) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.14-alpha.5...0.8.14) + +**Closed issues:** + +- Validation notices on empty support references [\#54](https://github.com/unfoldingWord/uw-content-validation/issues/54) + +## [0.8.14-alpha.5](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.14-alpha.5) (2020-10-06) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.14-alpha3...0.8.14-alpha.5) + +**Closed issues:** + +- Code directly fetches unconditionally original language files [\#51](https://github.com/unfoldingWord/uw-content-validation/issues/51) + +## [0.8.14-alpha3](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.14-alpha3) (2020-09-30) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.13...0.8.14-alpha3) + +**Merged pull requests:** + +- fix exports to work from importing app [\#49](https://github.com/unfoldingWord/uw-content-validation/pull/49) ([mandolyte](https://github.com/mandolyte)) +- Better checking of USFM, TN, and all nested quotes & brackets [\#41](https://github.com/unfoldingWord/uw-content-validation/pull/41) ([RobH123](https://github.com/RobH123)) + +## [0.8.13](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.13) (2020-09-28) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.12...0.8.13) + +**Implemented enhancements:** + +- Update book package checker to get tN file names from manifest. [\#48](https://github.com/unfoldingWord/uw-content-validation/issues/48) +- checkTN\_TSVDataRow\(\) should warn if only white space in occurrenceNote [\#46](https://github.com/unfoldingWord/uw-content-validation/issues/46) +- checkTN\_TSVDataRow\(\) should warn if link has language code rather than \* [\#39](https://github.com/unfoldingWord/uw-content-validation/issues/39) + +**Fixed bugs:** + +- checkTN\_TSVDataRow\(\) gives Duplicate errors on invalid links [\#36](https://github.com/unfoldingWord/uw-content-validation/issues/36) +- checkTN\_TSVDataRow\(\) does not check that chapter and verse match [\#23](https://github.com/unfoldingWord/uw-content-validation/issues/23) + +**Closed issues:** + +- Core functions not recognized as functions on import [\#50](https://github.com/unfoldingWord/uw-content-validation/issues/50) + +## [0.8.12](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.12) (2020-09-24) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.11...0.8.12) + +**Closed issues:** + +- Limit validation to checks for the selected books only [\#44](https://github.com/unfoldingWord/uw-content-validation/issues/44) +- Absent fields from ULT and UST [\#28](https://github.com/unfoldingWord/uw-content-validation/issues/28) +- Publish content-validation on npmjs [\#3](https://github.com/unfoldingWord/uw-content-validation/issues/3) + +**Merged pull requests:** + +- remove checkRepo export [\#43](https://github.com/unfoldingWord/uw-content-validation/pull/43) ([mandolyte](https://github.com/mandolyte)) +- Feature/add unit tests [\#40](https://github.com/unfoldingWord/uw-content-validation/pull/40) ([PhotoNomad0](https://github.com/PhotoNomad0)) +- Improve demos [\#33](https://github.com/unfoldingWord/uw-content-validation/pull/33) ([RobH123](https://github.com/RobH123)) + +## [0.8.11](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.11) (2020-09-23) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.12-alpha...0.8.11) + +## [0.8.12-alpha](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.12-alpha) (2020-09-23) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.12-alpha.2...0.8.12-alpha) + +## [0.8.12-alpha.2](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.12-alpha.2) (2020-09-23) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.12-alpha.3...0.8.12-alpha.2) + +## [0.8.12-alpha.3](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.12-alpha.3) (2020-09-23) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.10...0.8.12-alpha.3) + +**Closed issues:** + +- Fix non-English bible names? [\#45](https://github.com/unfoldingWord/uw-content-validation/issues/45) +- Export problem from NPM package [\#42](https://github.com/unfoldingWord/uw-content-validation/issues/42) +- Certain fields are absent from ULT and UST [\#27](https://github.com/unfoldingWord/uw-content-validation/issues/27) +- Convert console assertions into validation messages [\#25](https://github.com/unfoldingWord/uw-content-validation/issues/25) +- Data orientation of validation results [\#14](https://github.com/unfoldingWord/uw-content-validation/issues/14) + +## [0.8.10](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.10) (2020-09-18) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.9-alpha...0.8.10) + +**Closed issues:** + +- Make various columns narrower or wider [\#34](https://github.com/unfoldingWord/uw-content-validation/issues/34) + +## [0.8.9-alpha](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.9-alpha) (2020-09-15) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.9-alpha.2...0.8.9-alpha) + +## [0.8.9-alpha.2](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.9-alpha.2) (2020-09-15) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.9...0.8.9-alpha.2) + +## [0.8.9](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.9) (2020-09-15) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/0.8.9_alpha1...0.8.9) + +**Merged pull requests:** + +- Feature/add cache control [\#32](https://github.com/unfoldingWord/uw-content-validation/pull/32) ([PhotoNomad0](https://github.com/PhotoNomad0)) +- Various improvements [\#31](https://github.com/unfoldingWord/uw-content-validation/pull/31) ([RobH123](https://github.com/RobH123)) + +## [0.8.9_alpha1](https://github.com/unfoldingWord/uw-content-validation/tree/0.8.9_alpha1) (2020-09-14) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/$npm_package_version...0.8.9_alpha1) + +**Closed issues:** + +- Add capability in CV for app to pass in getFile\(\) function [\#17](https://github.com/unfoldingWord/uw-content-validation/issues/17) +- Use of IndexedDB [\#16](https://github.com/unfoldingWord/uw-content-validation/issues/16) +- Problems with using NPM component [\#9](https://github.com/unfoldingWord/uw-content-validation/issues/9) + +**Merged pull requests:** + +- Improved checks after user feedback \(video\) [\#30](https://github.com/unfoldingWord/uw-content-validation/pull/30) ([RobH123](https://github.com/RobH123)) +- API change with rowID & fieldName added to notices [\#29](https://github.com/unfoldingWord/uw-content-validation/pull/29) ([RobH123](https://github.com/RobH123)) +- fixes for redefined exports [\#26](https://github.com/unfoldingWord/uw-content-validation/pull/26) ([mandolyte](https://github.com/mandolyte)) + +## [$npm_package_version](https://github.com/unfoldingWord/uw-content-validation/tree/$npm_package_version) (2020-09-09) + +[Full Changelog](https://github.com/unfoldingWord/uw-content-validation/compare/9565bf8babc8031e03b0b4453e55d9ea5c70f740...$npm_package_version) + +**Merged pull requests:** + +- Feature/Enable Unit Tests [\#22](https://github.com/unfoldingWord/uw-content-validation/pull/22) ([PhotoNomad0](https://github.com/PhotoNomad0)) +- fix for import error [\#21](https://github.com/unfoldingWord/uw-content-validation/pull/21) ([mandolyte](https://github.com/mandolyte)) +- Upgrade packages; start looking at cypress tests [\#20](https://github.com/unfoldingWord/uw-content-validation/pull/20) ([RobH123](https://github.com/RobH123)) +- Add SG pages for new core fns; many other noticeList fixes [\#19](https://github.com/unfoldingWord/uw-content-validation/pull/19) ([RobH123](https://github.com/RobH123)) +- Finish moving demo code to core; more work on notice fields [\#18](https://github.com/unfoldingWord/uw-content-validation/pull/18) ([RobH123](https://github.com/RobH123)) +- Feature \#17/Performance improvements for checking [\#15](https://github.com/unfoldingWord/uw-content-validation/pull/15) ([PhotoNomad0](https://github.com/PhotoNomad0)) +- Rename some files and functions to be more standard [\#13](https://github.com/unfoldingWord/uw-content-validation/pull/13) ([RobH123](https://github.com/RobH123)) +- Feature cn 28 add cv to bpa [\#12](https://github.com/unfoldingWord/uw-content-validation/pull/12) ([mandolyte](https://github.com/mandolyte)) +- Update my ToDo list [\#11](https://github.com/unfoldingWord/uw-content-validation/pull/11) ([RobH123](https://github.com/RobH123)) +- see issue 9 [\#10](https://github.com/unfoldingWord/uw-content-validation/pull/10) ([mandolyte](https://github.com/mandolyte)) +- Update with refactoring and fixes [\#8](https://github.com/unfoldingWord/uw-content-validation/pull/8) ([RobH123](https://github.com/RobH123)) +- Convert noticeList from arrays to objects [\#6](https://github.com/unfoldingWord/uw-content-validation/pull/6) ([RobH123](https://github.com/RobH123)) +- Fix failing check as suggested by BruceM [\#5](https://github.com/unfoldingWord/uw-content-validation/pull/5) ([RobH123](https://github.com/RobH123)) +- Bump websocket-extensions from 0.1.3 to 0.1.4 [\#1](https://github.com/unfoldingWord/uw-content-validation/pull/1) ([dependabot[bot]](https://github.com/apps/dependabot)) + + + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* diff --git a/README.md b/README.md index 7de87e877..962eb1438 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ There is provision for checking to be altered and/or sped-up when the calling ap - `taRepoUsername`, `taRepoBranchName`: these two fields can be used to specify the username/organisation and/or the branch/tag name for fetching the TA files for checking - `taRepoLanguageCode`, and `taRepoSectionName`: can be used to specify how the `SupportReference` field is checked in TA—defaults are 'en' and 'translate' - `twRepoUsername`, `twRepoBranchName`: these two fields can be used to specify the username/organisation and/or the branch/tag name for fetching the TW files for checking -- `excerptLength`: an integer which defines how long excerpts of lines containing errors should be—the default is 15 characters—the package attempts to place the error in the middle of the excerpt +- `excerptLength`: an integer which defines how long excerpts of lines containing errors should be—the default is 20 characters—the package attempts to place the error in the middle of the excerpt - `cutoffPriorityLevel`: an integer which can define notices to not be detected—defaults to 0 so none are dropped. Note that this will also affect the `suggestion` response. (Only partially implemented at present, so drops some but not all low priority notices.) - `suppressNoticeDisablingFlag`: Defaults to `false`, i.e., to removing (thus suppressing) notices for warnings which are expected in certain files and hence we don’t want them displayed. Note that this is always set to `true` for the demos (because they suppress these notices later—see the `showDisabledNoticesFlag` below). @@ -140,13 +140,13 @@ There is a list of open issues at [[https://github.com/unfoldingWord/uw-content- 1. Checking of general markdown and naked links (esp. in plain text and markdown files) 1. Work through all [Issues](https://github.com/unfoldingWord/uw-content-validation/issues) 1. Work through all `ToDo`s in code -1. Standardise parameters according to best practice (i.e., dereferencing, etc.)—might be too late now??? -1. Document the API with (JsDoc) +1. Standardise parameters according to best practice (i.e., dereferencing, etc.)—might be too late now coz it would affect API presented to users??? +1. Document the API (with JsDoc) 1. Improve general documentation in the code and readMe files 1. Is our `RepoCheck` the same as `ResourceContainerCheck`? Or is the latter more specific? 1. Understand and standardise React stuff in the demos, e.g., e.g., withStyles, etc. 1. Check for and remove left-over (but unused) code from the source projects that the original code was copied from -1. Remove all debug code and console logging, and to consider possible speed and memory optimizations +1. Remove all debug code and console logging, and to consider possible speed and memory optimizations (incl. async and/or multi-worker operations) 1. Add a Scripture Burrito check (once Door43 has that available). Known bugs: diff --git a/noticeList.txt b/noticeList.txt index 875856df6..103f8bc22 100644 --- a/noticeList.txt +++ b/noticeList.txt @@ -1,492 +1,517 @@ -Last updated 2021-05-24 15:18:39.038077 by makeNoticeList.py -Got 490 notices: - checkRepoResult.noticeList.push( 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: givenLocation, extra: repoCode from checkRepo.js line 267 - languageCode === 'en' || languageCode === 'fr' ? 490 : 190, "Expected header field to contain a mixed-case string", fieldName: `\\$marker`, excerpt: rest, C, V, location: lineLocation from usfm-text-check.js line 971 - marker === 's5' ? 111 : 809, `$marker === 's5' ? 'Deprecated' : 'Unexpected' '\\$marker' marker at start of line`, C, V, lineNumber, characterIndex: 1, location: lineLocation from usfm-text-check.js line 999 - `"`.indexOf(line[0]) < 0 ? 880 : 180, C, V, "Expected line to start with backslash", lineNumber: n, characterIndex: 0, excerpt: line[0], location: ourLocation from usfm-text-check.js line 1,126 - C === '1' ? 657 : 457, C, V, "Paragraph marker expected before first verse", lineNumber: n, characterIndex: 1, details: `'\\$marker' after '\\$lastMarker'`, location: ourLocation from usfm-text-check.js line 1,219 - thisPriority, `Mismatched $leftChar$rightChar characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from field-text-check.js line 404 - thisPriority, thisMessage, excerpt: regexResultArray[0], location: ourLocation from field-text-check.js line 419 - foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(` $foundQuoteSegment`) === -1?909: 389, "Seems original language quote might not start at the beginning of a word", details, characterIndex: 0, excerpt, location from orig-quote-check.js line 284 - foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(followingRegex) === -1? 908: 388, "Seems original language quote might not finish at the end of a word", details, characterIndex: foundQuoteSegment.length, excerpt, location from orig-quote-check.js line 300 - leftChar === '“' ? 162 : 462, `Mismatched $leftChar$rightChar characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from plain-text-check.js line 245 - 999, "checkRepo function FAILED", repoName, excerpt: checkRepoError, location: repoName from RepoCheck.js line 114 - 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: manifestLocation, extra: repoCode from checkBookPackage.js line 187 - 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: markdownLocation, extra: repoCode from checkBookPackage.js line 252 - 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: repoLocation, extra: repoCode from checkBookPackage.js line 411 - 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: generalLocation, extra: repoCode from checkBookPackage.js line 623 - 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: generalLocation, extra: repoCode from checkBookPackage.js line 649 - 996, "Unable to load", details: `username=$username error=$cBPgfError`, repoName, filename: STANDARD_MANIFEST_FILENAME, location: manifestLocation, extra: repoCode from checkBookPackage.js line 191 - 996, "Unable to load", details: `username=$username error=$cBPgfError`, username, repoName, filename, location: markdownLocation, extra: repoCode from checkBookPackage.js line 256 - 996, "Unable to load", details, repoCode, repoName, filename, location: repoLocation, extra: repoCode from checkBookPackage.js line 415 - 996, "Unable to load", details, bookID, location: generalLocation, extra: repoCode from checkBookPackage.js line 625 - 996, "Unable to load", details, bookID, C, V, filename: thisPath, location: `$generalLocation $thisPath`, extra: repoCode from checkBookPackage.js line 653 - 996, "Unable to load", details: `username=$username error=$cRgfError`, bookID: ourBookID, filename: thisFilename, location: `$givenLocation $thisFilepath`, extra: repoName from checkRepo.js line 271 - 995, "File extension is not recognized, so treated as plain text.", filename, location: filename from checkFileContents.js line 103 - 993, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from field-text-check.js line 122 - 993, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 141 - 992, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from field-text-check.js line 128 - 992, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 145 - 991, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from field-text-check.js line 134 - 991, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 149 - 990, "Unable to load file", details: `username=$username`, repoName, filename ], elapsedSeconds: 0 ; from FileCheck.js line 68 - 989, "Unable to find/load repository", location: ourLocation from checkRepo.js line 196 - 988, "Bad TSV header", details: `expected '$EXPECTED_TN_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from tn-tsv9-table-check.js line 125 - 988, "Bad TSV header", details: `expected '$EXPECTED_TWL_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from twl-tsv6-table-check.js line 117 - 988, "Bad TSV header", details: `expected '$EXPECTED_NOTES_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from notes-tsv7-table-check.js line 117 - 988, "Bad TSV header", details: `expected '$EXPECTED_QUESTIONS_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from questions-tsv7-table-check.js line 117 - 987, C, V, "Expected \\id line to start with book identifier", lineNumber: n, characterIndex: 4, excerpt, location: ourLocation from usfm-text-check.js line 1,203 - 986, "Repository doesn’t seem to exist", details: `username=$username`, location: givenLocation, extra: repoName from checkRepo.js line 176 - 985, `Field does not match schema $errorObject.keyword`, details: errorObject.message, fieldName: errorObject.dataPath, location: ourLocation from manifest-text-check.js line 709 - 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_TWL_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from twl-tsv6-row-check.js line 429 - 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_TN_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 506 - 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_QUESTIONS_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from questions-tsv7-row-check.js line 509 - 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_NOTES_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 554 - 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_TN_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 252 - 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_TWL_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 241 - 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_NOTES_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 241 - 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_QUESTIONS_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 241 - 979, "Invalid book identifier passed to checkTWL_TSV6DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from twl-tsv6-row-check.js line 257 - 979, "Invalid book identifier passed to checkTN_TSV9DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from tn-tsv9-row-check.js line 298 - 979, "Invalid book identifier passed to checkQuestionsTSV7DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from questions-tsv7-row-check.js line 312 - 979, "Invalid book identifier passed to checkNotesTSV7DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from notes-tsv7-row-check.js line 345 - 978, "Wrong book identifier", details: `expected '$bookID'`, fieldName: 'Book', rowID, excerpt: B, location: ourRowLocation from tn-tsv9-row-check.js line 310 - 977, "Missing book identifier", characterIndex: 0, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 313 - 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Reference', rowID, excerpt: C, location: ourRowLocation from twl-tsv6-row-check.js line 275 - 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Chapter', rowID, excerpt: C, location: ourRowLocation from tn-tsv9-row-check.js line 318 - 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Reference', rowID, excerpt: C, location: ourRowLocation from questions-tsv7-row-check.js line 330 - 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Reference', rowID, excerpt: C, location: ourRowLocation from notes-tsv7-row-check.js line 363 - 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from twl-tsv6-row-check.js line 311 - 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Verse', excerpt: V, location: ourRowLocation from tn-tsv9-row-check.js line 350 - 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 366 - 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from notes-tsv7-row-check.js line 399 - 956, "Got empty manifest file", repoName, filename: STANDARD_MANIFEST_FILENAME, location: manifestLocation, extra: `$repoCode MANIFEST` from checkBookPackage.js line 212 - 956, "Got empty markdown file", repoName, filename, location: markdownLocation, extra: repoCode from checkBookPackage.js line 286 - 950, "tC cannot yet process '*' language code", characterIndex, excerpt, location: ourLocation from notes-links-check.js line 352 - 950, "tC cannot yet process '*' language code", characterIndex, excerpt, location: ourLocation from notes-links-check.js line 521 - 947, "Missing manifest.yaml", location: ourLocation, extra: `$repoName MANIFEST` from checkRepo.js line 296 - 946, "Missing LICENSE.md", location: ourLocation, extra: `$repoName LICENSE` from checkRepo.js line 294 - 944, `USFM3 Grammar Check ($strictnessString mode) doesn’t pass`, filename, location: ourLocation from BCS-usfm-grammar-check.js line 195 - 943, `USFM3 toJSON Check doesn’t pass`, location: ourLocation from usfm-js-check.js line 91 - 942, "USFM Grammar check fails", location from usfm-text-check.js line 1,253 - 939, "Key is missing for project", details: keyName, excerpt: JSON.stringify(projectEntry), location: ourLocation from manifest-text-check.js line 721 - 938, `Unable to find project file mentioned in manifest`, excerpt: projectFilepath, location: ourLocation from manifest-text-check.js line 738 - 937, `Linked project file seems empty`, excerpt: projectFilepath, location: ourLocation from manifest-text-check.js line 740 - 936, `Error loading manifest project link`, details: trcGCerror, excerpt: projectFilepath, location: ourLocation from manifest-text-check.js line 742 - 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 237 - 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 226 - 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 226 - 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 226 - 931, "Missing row ID field", fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 332 - 931, "Missing row ID field", fieldName: 'Verse', location: ourRowLocation from tn-tsv9-row-check.js line 371 - 931, "Missing row ID field", fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 387 - 931, "Missing row ID field", fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 420 - 929, "'projects' key is missing", location: ourLocation from manifest-text-check.js line 674 - 928, "'dublin_core' key is missing", location: ourLocation from manifest-text-check.js line 672 - 920, yamlError.message, location: ourLocation ) from yaml-text-check.js line 175 - 919, "Missing OrigWords field", fieldName: 'OrigWords', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 368 - 919, "Missing OrigQuote field", fieldName: 'OrigQuote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 424 - 919, "Missing Quote field", fieldName: 'Quote', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 424 - 919, "Missing Quote field", fieldName: 'Quote', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 485 - 917, "Unable to find duplicate original language quote in verse text", details: `occurrence=$occurrenceString but $actualOccurrencesText occurrence$actualNumOccurrences === 1 ? '' : 's' found, passage ►$verseText◄`, excerpt, location: ourLocation from orig-quote-check.js line 483 - 916, "Unable to find original language quote in verse text", details: "quote which starts with a space" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 333 - 916, "Unable to find original language quote in verse text", details: "quote which ends with a space" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 336 - 916, "Unable to find original language quote in verse text", details: "quote which starts with 'word joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 339 - 916, "Unable to find original language quote in verse text", details: "quote which ends with 'word joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 342 - 916, "Unable to find original language quote in verse text", details: "quote which starts with 'zero-width space'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 345 - 916, "Unable to find original language quote in verse text", details: "quote which ends with 'zero-width space'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 348 - 916, "Unable to find original language quote in verse text", details: "quote which starts with 'zero-width joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 351 - 916, "Unable to find original language quote in verse text", details: "quote which ends with 'zero-width joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 354 - 916, "Unable to find original language quote in verse text", details: noBreakSpaceText ? noBreakSpaceText : `passage ►$fullVerseText◄`, excerpt, location: ourLocation from orig-quote-check.js line 357 - 914, "Unable to find original language quote portion in the right place in the verse text", details: `passage ►$verseText◄`, excerpt, location: ourLocation from orig-quote-check.js line 460 - 912, 'Missing | character in \\w line', lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 678 - 911, 'Missing | character in \\w field', details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 734 - 911, 'Missing | character in \\+w field', details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 755 - 903, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ourLocation from usfm-text-check.js line 1,068 - 902, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$generalLocation` ); return checkBookPackageResult; from checkBookPackage.js line 317 - 900, "Bad parameter: should be given a valid book abbreviation", excerpt: bookIDList, location: ` (not '$bookIDList')` from checkBookPackages.js line 76 - 895, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 107 - 889, `Unable to find/load TA article`, details: `linked from TN $fieldName`, excerpt: fieldText, location: `$ourLocation $filepath` from ta-reference-check.js line 109 - 888, `Error loading TA article`, details: `linked from TN $fieldName`, excerpt: fieldText, location: `$ourLocation $filepath: $trcGCerror` from ta-reference-check.js line 114 - 887, `TA article seems empty`, details: `linked from TN $fieldName`, excerpt: fieldText, location: `$ourLocation $filepath` from ta-reference-check.js line 111 - 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 374 - 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 430 - 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 480 - 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 543 - 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 369 - 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 425 - 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 475 - 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 538 - 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 376 - 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 432 - 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 482 - 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 545 - 883, `Unable to find/load TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 309 - 883, `Unable to find/load TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 594 - 882, `Error loading TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 306 - 882, `Error loading TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 591 - 881, `TW article seems empty`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 312 - 881, `TW article seems empty`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 597 - 879, `Badly formatted Resource Container link`, excerpt: fieldText, location: `$ourLocation $filepath` from ta-reference-check.js line 96 - 875, "Unexpected USFM field", details, lineNumber, C, V, excerpt, location: lineLocation from usfm-text-check.js line 802 - 873, `Mismatched $opener$closer fields`, excerpt: `(left=$lCount.toLocaleString(), right=$rCount.toLocaleString())`, location: fileLocation from usfm-text-check.js line 572 - 869, "Chapter number out of range", C: chapterNumberString, excerpt: `$bookID $chapterNumberString`, location: CVlocation from usfm-text-check.js line 422 - 868, "Verse number out of range", C: chapterNumberString, V: verseNumberString, excerpt: `$bookID $chapterNumberString:$verseNumberString`, location: CVlocation from usfm-text-check.js line 461 - 867, C: chapterNumberString, V: `$v`, "Verse appears to be missing", location: CVlocation from usfm-text-check.js line 475 - 866, C: chapterNumberString, V: `$v`, "Verse seems to have no text", location: CVlocation from usfm-text-check.js line 480 - 857, "Unexpected first original \\w attribute", details: "expected 'lemma'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 850 - 856, "Unexpected second original \\w attribute", details: "expected 'strong'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 853 - 855, "Unexpected third original \\w attribute", details: "expected 'x-morph'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 856 - 854, "Unexpected fourth original \\w attribute", details: "expected 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 859 - 854, "Unexpected fifth original \\w attribute", details: "expected second 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 862 - 854, "Unexpected sixth original \\w attribute", details: "expected third 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 865 - 853, "Unexpected extra original \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 867 - 852, "Unexpected original \\w x-morph language prefix", details: "Expected 'He,' 'Ar,' or 'Gr,'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 871 - 851, bookID === 'OBS' ? "Unable to load OBS story text" : "Unable to load original language verse text", location: ourLocation from orig-quote-check.js line 431 - 849, `Unexpected '$badCharCombination' character combination`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 373 - 848, "Unexpected first translation \\w attribute", details: "expected 'x-occurrence'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 877 - 847, "Unexpected second translation \\w attribute", details: "expected 'x-occurrences'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 880 - 846, "Unexpected extra translation \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 882 - 845, `Mismatched [[ ]] link characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from notes-links-check.js line 1,217 - 844, `Mismatched [[rc:// ]] link characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from notes-links-check.js line 1,221 - 843, `Mismatched [ ]( ) link characters`, details: `left=$leftCount.toLocaleString(), middle=$middleCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from notes-links-check.js line 1,228 - 839, "Unexpected first \\k-s attribute", details: "expected 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 901 - 838, "Unexpected extra \\k-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 903 - 837, "Seems too few original \\w attributes", details: `Expected 3-4 attributes but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 887 - 836, "Seems too few translation \\w attributes", details: `Expected two attributes but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 889 - 835, "Seems too few original \\k-s attributes", details: `Expected one attribute but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 906 - 834, "Seems too few translation \\zaln-s attributes", details: `Expected six attributes but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 938 - 833, "Unexpected extra \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 935 - 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 234 - 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 223 - 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 223 - 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 223 - 830, "Unexpected first \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 918 - 829, "Unexpected second \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 921 - 828, "Unexpected third \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 924 - 827, "Unexpected fourth \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 927 - 826, "Unexpected fifth \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 930 - 825, "Unexpected sixth \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 933 - 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 280 - 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 323 - 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 335 - 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 368 - 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 285 - 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 328 - 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 340 - 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 373 - 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 298 - 822, "Expected field to contain an integer", lineNumber, characterIndex: 3, excerpt: `\\c $rest`, C, V, location: lineLocation from usfm-text-check.js line 963 - 822, "Expected field to contain an integer", characterIndex: 3, excerpt: `\\v $rest`, C, V, location: lineLocation from usfm-text-check.js line 967 - 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 338 - 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 353 - 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 386 - 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 304 - 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 343 - 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 359 - 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 392 - 820, "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:$V$ourRowLocation` from twl-tsv6-row-check.js line 307 - 820, "Missing chapter number", rowID, fieldName: 'Chapter', location: ` ?:$V$ourRowLocation` from tn-tsv9-row-check.js line 346 - 820, "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:$V$ourRowLocation` from questions-tsv7-row-check.js line 362 - 820, "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:$V$ourRowLocation` from notes-tsv7-row-check.js line 395 - 819, "Missing compulsory USFM line", excerpt: `missing \\$compulsoryMarker`, location: fileLocation from usfm-text-check.js line 602 - 815, "Divider without surrounding snippet", location: ourLocation from orig-quote-check.js line 473 - 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from twl-tsv6-row-check.js line 316 - 814, "Invalid zero verse number", rowID, fieldName: 'Verse', excerpt: V, location: ourRowLocation from tn-tsv9-row-check.js line 355 - 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 371 - 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from notes-tsv7-row-check.js line 404 - 813, "Invalid large verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from twl-tsv6-row-check.js line 320 - 813, "Invalid large verse number", rowID, fieldName: 'Verse', excerpt: V, location: ourRowLocation from tn-tsv9-row-check.js line 359 - 813, "Invalid large verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 375 - 813, "Invalid large verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from notes-tsv7-row-check.js line 408 - 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 322 - 812, "Unable to check verse number", rowID, fieldName: 'Verse', location: ourRowLocation from tn-tsv9-row-check.js line 361 - 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 377 - 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 410 - 811, "Bad verse number", rowID, fieldName: 'Reference', location: ` '$V'$ourRowLocation` from twl-tsv6-row-check.js line 326 - 811, "Bad verse number", rowID, fieldName: 'Verse', location: ` '$V'$ourRowLocation` from tn-tsv9-row-check.js line 365 - 811, "Bad verse number", rowID, fieldName: 'Reference', location: ` '$V'$ourRowLocation` from questions-tsv7-row-check.js line 381 - 811, "Bad verse number", rowID, fieldName: 'Reference', location: ` '$V'$ourRowLocation` from notes-tsv7-row-check.js line 414 - 810, "Missing verse number", rowID, fieldName: 'Reference', location: ` after $C:?$ourRowLocation` from twl-tsv6-row-check.js line 329 - 810, "Missing verse number", rowID, fieldName: 'Verse', location: ` after $C:?$ourRowLocation` from tn-tsv9-row-check.js line 368 - 810, "Missing verse number", rowID, fieldName: 'Reference', location: ` after $C:?$ourRowLocation` from questions-tsv7-row-check.js line 384 - 810, "Missing verse number", rowID, fieldName: 'Reference', location: ` after $C:?$ourRowLocation` from notes-tsv7-row-check.js line 417 - 799, "Missing TWLink field", fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 417 - 798, "Field doesn’t contain expected TW link", details: `should start with 'rc://*/tw/dict/bible/'`, fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 401 - 797, "Field doesn’t contain proper TW link", details: `should be 'kt', 'names', or 'other'`, fieldName: 'TWLink', rowID, characterIndex, excerpt, location: ourRowLocation from twl-tsv6-row-check.js line 408 - 796, "Field is only whitespace", fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 398 - 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from twl-tsv6-row-check.js line 382 - 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from tn-tsv9-row-check.js line 438 - 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from questions-tsv7-row-check.js line 438 - 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from notes-tsv7-row-check.js line 499 - 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 387 - 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 443 - 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 443 - 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 504 - 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from tn-tsv9-table-check.js line 230 - 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from twl-tsv6-table-check.js line 219 - 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from notes-tsv7-table-check.js line 219 - 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from questions-tsv7-table-check.js line 219 - 789, "Should have a SupportReference when OccurrenceNote has a TA link", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from tn-tsv9-row-check.js line 487 - 789, "Should have a SupportReference when Note has a TA link", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from notes-tsv7-row-check.js line 534 - 788, "Only 'Just-In-Time Training' TA articles allowed here", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 399 - 788, "Only 'Just-In-Time Training' TA articles allowed here", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 459 - 787, "Link to TA should also be in OccurrenceNote", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 404 - 787, "Link to TA should also be in Note", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 464 - 786, "Shouldn’t have multiple TA links in OccurrenceNote", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from tn-tsv9-row-check.js line 485 - 786, "Shouldn’t have multiple TA links in Note", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from notes-tsv7-row-check.js line 532 - 783, `Unable to find/load general link`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,179 - 781, `Linked general article seems empty`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,182 - 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 335 - 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 374 - 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 390 - 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 423 - 777, `Bad punctuation nesting: $char closing character doesn’t match`, details, lineNumber: n, characterIndex, excerpt, location: ourLocation from plain-text-check.js line 205 - 776, 'Unexpected " straight quote character', details, lineNumber, C, V, excerpt, location: lineLocation from usfm-text-check.js line 789 - 775, "Unexpected ' straight quote character", details, lineNumber, C, V, excerpt, location: lineLocation from usfm-text-check.js line 794 - 774, `Unexpected $char closing character (no matching opener)`, lineNumber: n, characterIndex, excerpt, location: ourLocation from plain-text-check.js line 212 - 773, `Unexpected trailing zero-width joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 173 - 772, `Unexpected trailing word-joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 168 - 771, `Unexpected leading zero-width joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 151 - 770, `Unexpected leading word-joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 147 - 769, C, V, "Verse bridge numbers not in ascending order", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, Math.max(9, excerptLength))$rest.length > excerptLength ? '…' : '' ($firstV → $secondV)`, location: ourLocation from usfm-text-check.js line 1,179 - 768, `At end of text with unclosed $char opening character`, details, lineNumber: n, characterIndex: x, excerpt, location: ourLocation from plain-text-check.js line 230 - 766, C, V, "Bridged verse numbers didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, Math.max(9, excerptLength))$rest.length > excerptLength ? '…' : '' ($lastV → $firstV)`, location: ourLocation from usfm-text-check.js line 1,181 - 765, "Unexpected link", characterIndex, excerpt, location: ourLocation from field-text-check.js line 446 - 764, C, V, "Chapter number didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : '' ($lastC ? lastC : '0' → $C)`, location: ourLocation from usfm-text-check.js line 1,152 - 763, C, V, "Verse number didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : '' ($lastV ? lastV : '0' → $V)`, location: ourLocation from usfm-text-check.js line 1,165 - 762, "Unable to convert verse bridge numbers to integers", C: chapterNumberString, V: verseNumberString, characterIndex: 3, excerpt: verseNumberString, location: `$CVlocation with $usfmVIerror` from usfm-text-check.js line 449 - 762, C, V, "Unable to convert verse bridge numbers to integers", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, Math.max(9, excerptLength))$rest.length > excerptLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,175 - 761, C, V, "Verse number didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$restRest.substring(0, excerptHalfLength)$restRest.length > excerptHalfLength ? '…' : '' ($lastV ? lastV : '0' → $V)`, location: ourLocation from usfm-text-check.js line 1,196 - 752, "Verse numbers of markdown TN link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,114 - 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from twl-tsv6-row-check.js line 373 - 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from tn-tsv9-row-check.js line 429 - 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from questions-tsv7-row-check.js line 429 - 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from notes-tsv7-row-check.js line 490 - 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 364 - 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 420 - 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 420 - 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 481 - 749, "Markdown image link seems faulty", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 236 - 749, "Markdown image link seems faulty", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 257 - 748, "Error fetching markdown image link", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 245 - 748, "Error fetching markdown image link", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 266 - 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from tn-tsv9-table-check.js line 110 - 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from twl-tsv6-table-check.js line 101 - 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from notes-tsv7-table-check.js line 101 - 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from questions-tsv7-table-check.js line 101 - 746, "Unexpected tag", details: thisTag, excerpt: tags, fieldName: 'Tags', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 411 - 746, "Unexpected tag", details: thisTag, excerpt: tags, fieldName: 'Tags', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 444 - 745, C, V, `Wrong '$B' book identifier (expected '$bookID')`, rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 180 - 744, C, V, "Missing book identifier", rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 183 - 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 648 - 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $givenCint`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 714 - 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 843 - 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 895 - 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,003 - 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,055 - 743, "Chapter numbers of markdown TN link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,108 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 654 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 720 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $V2`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 757 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1a vs $V2`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 796 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 849 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1a vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 901 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1a vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 953 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,009 - 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,061 - 741, "Verse numbers of markdown Bible link range out of order", details: `$V1a to $V1b`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 801 - 741, "Verse numbers of markdown Bible link range out of order", details: `$V1a to $V1b`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 907 - 741, "Verse numbers of markdown Bible link range out of order", details: `$V1a to $V1b`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 959 - 740, "Unrecognized tag", details: `found '$thisTag' but expected 'keyterm' or 'name'`, excerpt: tags, fieldName: 'Tags', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 355 - 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from tn-tsv9-table-check.js line 207 - 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from twl-tsv6-table-check.js line 196 - 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from notes-tsv7-table-check.js line 196 - 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from questions-tsv7-table-check.js line 196 - 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 226 - 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 215 - 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 215 - 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 215 - 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from tn-tsv9-table-check.js line 194 - 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from twl-tsv6-table-check.js line 183 - 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from notes-tsv7-table-check.js line 183 - 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from questions-tsv7-table-check.js line 183 - 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 198 - 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 187 - 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 187 - 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 187 - 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 200 - 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 189 - 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 189 - 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 189 - 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 204 - 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from tn-tsv9-table-check.js line 216 - 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 193 - 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from twl-tsv6-table-check.js line 205 - 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 193 - 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from notes-tsv7-table-check.js line 205 - 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 193 - 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from questions-tsv7-table-check.js line 205 - 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from tn-tsv9-table-check.js line 220 - 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from twl-tsv6-table-check.js line 209 - 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from notes-tsv7-table-check.js line 209 - 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from questions-tsv7-table-check.js line 209 - 724, C, V, "Unable to convert chapter number to integer", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,148 - 723, C, V, "Unable to convert verse number to integer", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,161 - 720, C, V, "Unable to convert internal verse number to integer", lineNumber: n, characterIndex: 3, excerpt: `$restRest.substring(0, excerptHalfLength)$restRest.length > excerptHalfLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,192 - 716, `Misplaced $rightChar character`, excerpt: regexResultArray[0], location: ourLocation from field-text-check.js line 427 - 711, "Expected compulsory content", C, V, lineNumber, characterIndex: marker.length, location: ` after \\$marker marker$lineLocation` from usfm-text-check.js line 996 - 703, C, V, "Unexpected CarriageReturn character", lineNumber: n, characterIndex, excerpt, location: ourLocation from usfm-text-check.js line 1,112 - 669, "Unexpected language code in link", details: `resource language code is '$languageCode'`, excerpt: Lg, location: ourLocation from notes-links-check.js line 630 - 656, "Bad chapter number in markdown TN link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,130 - 655, "Bad story number in markdown OBS help link", details: `$linkBookCode $linkChapterInt vs $numStories chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 662 - 655, "Bad chapter number in markdown Bible help link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 676 - 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $givenCint vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 736 - 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 773 +Last updated 2021-07-06 17:41:11.943053 by makeNoticeList.py +Got 515 notices: + repoCode === 'SN' || repoCode === 'SQ' ? 196 : 996, "Unable to load", details, repoCode, repoName, filename, location: repoLocation, extra: repoCode from checkBookPackage.js line 434 + checkRepoResult.noticeList.push( 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: givenLocation, extra: repoCode from checkRepo.js line 284 + expectedMarker === 'mt1' ? 921 : 519, "Missing expected USFM line", excerpt: `missing \\$expectedMarker`, location: fileLocation from usfm-text-check.js line 621 + languageCode === 'en' || languageCode === 'fr' ? 490 : 190, "Expected header field to contain a mixed-case string", fieldName: `\\$marker`, excerpt: rest, C, V, location: lineLocation from usfm-text-check.js line 1,028 + marker === 's5' ? 111 : 809, `$marker === 's5' ? 'Deprecated' : 'Unexpected' '\\$marker' marker at start of line`, C, V, lineNumber, characterIndex: 1, location: lineLocation from usfm-text-check.js line 1,056 + line[0] === ' ' || line[0] === '"' ? 180 : 880, C, V, "Expected line to start with backslash", lineNumber: n, characterIndex: 0, excerpt: line[0], location: ourLocation from usfm-text-check.js line 1,196 + C === '1' ? 657 : 457, C, V, "Paragraph marker expected before first verse", lineNumber: n, characterIndex: 1, details: `'\\$marker' after '\\$lastMarker'`, location: ourLocation from usfm-text-check.js line 1,289 + thisPriority, `Mismatched $leftChar$rightChar characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from field-text-check.js line 419 + thisPriority, thisMessage, excerpt: regexResultArray[0], location: ourLocation from field-text-check.js line 434 + foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(` $foundQuoteSegment`) === -1 ? 909 : 389, "Seems original language quote might not start at the beginning of a word", details, characterIndex: 0, excerpt, location from orig-quote-check.js line 294 + foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(followingRegex) === -1 ? 908 : 388, "Seems original language quote might not finish at the end of a word", details, characterIndex: foundQuoteSegment.length, excerpt, location from orig-quote-check.js line 314 + leftChar === '“' ? 162 : 462, `Mismatched $leftChar$rightChar characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from plain-text-check.js line 249 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1 === 'Song of Solomon' ? 'Unexpected' : 'Unknown' Bible book name in TN RC link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 669 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1 === 'Song of Solomon' ? 'Unexpected' : 'Unknown' Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 733 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown' Bible book name in relative Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 881 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown' Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 937 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown' Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 1,001 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown' Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 1,054 + optionalB1 === 'Song of Solomon' ? 43 : 143, `$optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown' Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 1,112 + 999, "checkRepo function FAILED", repoName, excerpt: checkRepoError, location: repoName from RepoCheck.js line 118 + 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: manifestLocation, extra: repoCode from checkBookPackage.js line 194 + 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: markdownLocation, extra: repoCode from checkBookPackage.js line 259 + 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: repoLocation, extra: repoCode from checkBookPackage.js line 430 + 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: generalLocation, extra: repoCode from checkBookPackage.js line 646 + 997, "Repository doesn’t exist", details, username, repoCode, repoName, location: generalLocation, extra: repoCode from checkBookPackage.js line 672 + 996, "Unable to load", details: `username=$username error=$cBPgfError`, repoName, filename: STANDARD_MANIFEST_FILENAME, location: manifestLocation, extra: repoCode from checkBookPackage.js line 198 + 996, "Unable to load", details: `username=$username error=$cBPgfError`, username, repoName, filename, location: markdownLocation, extra: repoCode from checkBookPackage.js line 263 + 996, "Unable to load", details, bookID, location: generalLocation, extra: repoCode from checkBookPackage.js line 648 + 996, "Unable to load", details, bookID, C, V, filename: thisPath, location: `$generalLocation $thisPath`, extra: repoCode from checkBookPackage.js line 676 + 996, "Unable to load", details: `username=$username error=$cRgfError`, bookID: ourBookID, filename: thisFilename, location: `$givenLocation $thisFilepath`, extra: repoName from checkRepo.js line 288 + 995, "File extension is not recognized, so treated as plain text.", filename, location: filename from checkFileContents.js line 107 + 994, "USFM file must start with a valid \\id line", lineNumber: 1, location: ourLocation from usfm-text-check.js line 1,155 + 993, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from field-text-check.js line 127 + 993, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 145 + 992, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from field-text-check.js line 133 + 992, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 149 + 991, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from field-text-check.js line 139 + 991, "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 153 + 990, "Unable to load file", details: `username=$username`, repoName, filename ], elapsedSeconds: 0 ; from FileCheck.js line 66 + 989, "Unable to find/load repository", location: ourLocation from checkRepo.js line 212 + 988, "Bad TSV header", details: `expected '$EXPECTED_TN_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from tn-tsv9-table-check.js line 130 + 988, "Bad TSV header", details: `expected '$EXPECTED_TWL_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from twl-tsv6-table-check.js line 122 + 988, "Bad TSV header", details: `expected '$EXPECTED_NOTES_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from notes-tsv7-table-check.js line 122 + 988, "Bad TSV header", details: `expected '$EXPECTED_QUESTIONS_HEADING_LINE'`, excerpt: lines[0], lineNumber: 1, location: ourLocation from questions-tsv7-table-check.js line 122 + 987, C, V, "Expected \\id line to start with book identifier", lineNumber: n, characterIndex: 4, excerpt, location: ourLocation from usfm-text-check.js line 1,273 + 986, "Repository doesn’t seem to exist", details: `username=$username`, location: givenLocation, extra: repoName from checkRepo.js line 192 + 985, `Field does not match schema $errorObject.keyword`, details: errorObject.message, fieldName: errorObject.dataPath, location: ourLocation from manifest-text-check.js line 727 + 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_TWL_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from twl-tsv6-row-check.js line 435 + 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_TN_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 510 + 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_QUESTIONS_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from questions-tsv7-row-check.js line 503 + 984, `Found wrong number of TSV fields (expected $NUM_EXPECTED_NOTES_TSV_FIELDS)`, details: `Found $fields.length field$fields.length === 1 ? '' : 's'`, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 516 + 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_TN_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 257 + 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_TWL_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 246 + 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_NOTES_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 246 + 983, `Wrong number of tabbed fields (expected $NUM_EXPECTED_QUESTIONS_TSV_FIELDS)`, excerpt: `Found $fields.length field$fields.length === 1 ? '' : 's'`, C, V, rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 246 + 979, "Invalid book identifier passed to checkTWL_TSV6DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from twl-tsv6-row-check.js line 264 + 979, "Invalid book identifier passed to checkTN_TSV9DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from tn-tsv9-row-check.js line 303 + 979, "Invalid book identifier passed to checkQuestionsTSV7DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from questions-tsv7-row-check.js line 272 + 979, "Invalid book identifier passed to checkNotesTSV7DataRow", location: ` '$bookID' in first parameter: $tlcNCerror` from notes-tsv7-row-check.js line 304 + 978, "Wrong book identifier", details: `expected '$bookID'`, fieldName: 'Book', rowID, excerpt: B, location: ourRowLocation from tn-tsv9-row-check.js line 315 + 977, "Missing book identifier", characterIndex: 0, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 318 + 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Reference', rowID, excerpt: C, location: ourRowLocation from twl-tsv6-row-check.js line 282 + 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Chapter', rowID, excerpt: C, location: ourRowLocation from tn-tsv9-row-check.js line 323 + 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Reference', rowID, excerpt: C, location: ourRowLocation from questions-tsv7-row-check.js line 293 + 976, "Wrong chapter number", details: `expected '$givenC'`, fieldName: 'Reference', rowID, excerpt: C, location: ourRowLocation from notes-tsv7-row-check.js line 322 + 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from twl-tsv6-row-check.js line 318 + 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Verse', excerpt: V, location: ourRowLocation from tn-tsv9-row-check.js line 355 + 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 330 + 975, "Wrong verse number", details: `expected '$givenV' to be inside range`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 353 + 975, "Wrong verse number", details: `expected '$givenV'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from notes-tsv7-row-check.js line 358 + 956, "Got empty manifest file", repoName, filename: STANDARD_MANIFEST_FILENAME, location: manifestLocation, extra: `$repoCode MANIFEST` from checkBookPackage.js line 219 + 956, "Got empty markdown file", repoName, filename, location: markdownLocation, extra: repoCode from checkBookPackage.js line 293 + 950, "tC cannot yet process '*' language code", characterIndex, excerpt, location: ourLocation from notes-links-check.js line 377 + 950, "tC cannot yet process '*' language code", characterIndex, excerpt, location: ourLocation from notes-links-check.js line 547 + 947, "Missing manifest.yaml", location: ourLocation, extra: `$repoName MANIFEST` from checkRepo.js line 313 + 946, "Missing LICENSE.md", location: ourLocation, extra: `$repoName LICENSE` from checkRepo.js line 311 + 944, `USFM3 Grammar Check ($strictnessString mode) doesn’t pass`, filename, location: ourLocation from BCS-usfm-grammar-check.js line 226 + 943, `USFM3 toJSON Check doesn’t pass`, location: ourLocation from usfm-js-check.js line 95 + 939, "Key is missing for project", details: keyName, excerpt: JSON.stringify(projectEntry), location: ourLocation from manifest-text-check.js line 742 + 938, `Unable to find project file mentioned in manifest`, excerpt: projectFilepath, location: ourLocation from manifest-text-check.js line 767 + 937, `Linked project file seems empty`, excerpt: projectFilepath, location: ourLocation from manifest-text-check.js line 769 + 936, `Error loading manifest project link`, details: trcGCerror, excerpt: projectFilepath, location: ourLocation from manifest-text-check.js line 771 + 934, "'language' key or 'idenfier' subkey is missing", location: ourLocation from manifest-text-check.js line 697 + 933, "Manifest' language' 'identifier' doesn't match", details: `expected '$languageCode' but manifest has '$languageIdentifier'`, location: ourLocation from manifest-text-check.js line 694 + 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 242 + 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 231 + 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 231 + 932, C, V, "Missing row ID", fieldName: 'ID', lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 231 + 931, "Missing row ID field", fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 339 + 931, "Missing row ID field", fieldName: 'Verse', location: ourRowLocation from tn-tsv9-row-check.js line 376 + 931, "Missing row ID field", fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 374 + 931, "Missing row ID field", fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 379 + 930, "'relation' key is missing", location: ourLocation from manifest-text-check.js line 808 + 929, "'projects' key is missing", location: ourLocation from manifest-text-check.js line 680 + 928, "'dublin_core' key is missing", location: ourLocation from manifest-text-check.js line 678 + 920, yamlError.message, location: ourLocation ) from yaml-text-check.js line 179 + 919, "Missing OrigWords field", fieldName: 'OrigWords', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 375 + 919, "Missing OrigQuote field", fieldName: 'OrigQuote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 429 + 919, "Missing Quote field", fieldName: 'Quote', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 411 + 919, "Missing Quote field", fieldName: 'Quote', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 444 + 917, "Unable to find duplicate original language quote in verse text", details: `occurrence=$occurrenceString but $actualOccurrencesText occurrence$actualNumOccurrences === 1 ? '' : 's' found, passage ►$verseText◄`, excerpt, location: ourLocation from orig-quote-check.js line 497 + 916, "Unable to find original language quote in verse text", details: "quote which starts with a space" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 347 + 916, "Unable to find original language quote in verse text", details: "quote which ends with a space" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 350 + 916, "Unable to find original language quote in verse text", details: "quote which starts with 'word joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 353 + 916, "Unable to find original language quote in verse text", details: "quote which ends with 'word joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 356 + 916, "Unable to find original language quote in verse text", details: "quote which starts with 'zero-width space'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 359 + 916, "Unable to find original language quote in verse text", details: "quote which ends with 'zero-width space'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 362 + 916, "Unable to find original language quote in verse text", details: "quote which starts with 'zero-width joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 365 + 916, "Unable to find original language quote in verse text", details: "quote which ends with 'zero-width joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation from orig-quote-check.js line 368 + 916, "Unable to find original language quote in verse text", details: noBreakSpaceText ? noBreakSpaceText : `verse text ►$fullVerseText◄`, excerpt, location: ourLocation from orig-quote-check.js line 371 + 914, "Unable to find original language quote portion in the right place in the verse text", details: `verse text ►$verseText◄`, excerpt, location: ourLocation from orig-quote-check.js line 474 + 912, 'Missing | character in \\w line', lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 718 + 911, 'Missing | character in \\w field', details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 774 + 911, 'Missing | character in \\+w field', details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 795 + 905, "Unexpected Hebrew cantillation mark in lemma field", details: `Found $match.length '$match'`, lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 915 + 903, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ourLocation from usfm-text-check.js line 1,128 + 902, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$generalLocation` ); return checkBookPackageResult; from checkBookPackage.js line 324 + 901, "Unexpected reference field", details: "expected C:V", fieldName: 'Reference', rowID, excerpt: reference, location: ourRowLocation from questions-tsv7-row-check.js line 288 + 900, "Bad parameter: should be given a valid book abbreviation", excerpt: bookIDList, location: ` (not '$bookIDList')` from checkBookPackages.js line 79 + 895, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 112 + 889, `Unable to find/load TA article`, details: `linked from TN $fieldName`, excerpt: fieldText, location: `$ourLocation $filepath` from ta-reference-check.js line 111 + 888, `Error loading TA article`, details: `linked from TN $fieldName`, excerpt: fieldText, location: `$ourLocation $filepath: $trcGCerror` from ta-reference-check.js line 116 + 887, `TA article seems empty`, details: `linked from TN $fieldName`, excerpt: fieldText, location: `$ourLocation $filepath` from ta-reference-check.js line 113 + 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 399 + 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 456 + 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 506 + 886, `Unable to find/load TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 569 + 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 394 + 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 451 + 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 501 + 885, `Error loading TA article`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 564 + 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 401 + 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 458 + 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 508 + 884, `TA article seems empty`, details: `$taRepoUsername $taRepoName $taRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 571 + 883, `Unable to find/load TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 334 + 883, `Unable to find/load TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 621 + 882, `Error loading TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 331 + 882, `Error loading TW article`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath: $trcGCerror` from notes-links-check.js line 618 + 881, `TW article seems empty`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 337 + 881, `TW article seems empty`, details: `$twRepoUsername $twRepoName $twRepoBranch $filepath`, excerpt: totalLink, location: `$ourLocation $filepath` from notes-links-check.js line 624 + 879, `Badly formatted Resource Container link`, excerpt: fieldText, location: `$ourLocation $filepath` from ta-reference-check.js line 98 + 875, "Unexpected USFM field", details, lineNumber, C, V, excerpt, location: lineLocation from usfm-text-check.js line 842 + 873, `Mismatched $opener$closer fields`, excerpt: `(left=$lCount.toLocaleString(), right=$rCount.toLocaleString())`, location: fileLocation from usfm-text-check.js line 584 + 869, "Chapter number out of range", C: chapterNumberString, excerpt: `$bookID $chapterNumberString`, location: CVlocation from usfm-text-check.js line 434 + 868, "Verse number out of range", C: chapterNumberString, V: verseNumberString, excerpt: `$bookID $chapterNumberString:$verseNumberString`, location: CVlocation from usfm-text-check.js line 473 + 867, C: chapterNumberString, V: `$v`, "Verse appears to be missing", location: CVlocation from usfm-text-check.js line 487 + 866, C: chapterNumberString, V: `$v`, "Verse seems to have no text", location: CVlocation from usfm-text-check.js line 492 + 857, "Unexpected first original \\w attribute", details: "expected 'lemma'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 893 + 856, "Unexpected second original \\w attribute", details: "expected 'strong'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 896 + 855, "Unexpected third original \\w attribute", details: "expected 'x-morph'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 899 + 854, "Unexpected fourth original \\w attribute", details: "expected 'x-tw'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 902 + 854, "Unexpected fifth original \\w attribute", details: "expected second 'x-tw'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 905 + 854, "Unexpected sixth original \\w attribute", details: "expected third 'x-tw'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 908 + 853, "Unexpected extra original \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 910 + 852, "Unexpected original \\w x-morph language prefix", details: "Expected 'He,' 'Ar,' or 'Gr,'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 920 + 851, bookID === 'OBS' ? "Unable to load OBS story text" : "Unable to load original language verse text", location: ourLocation from orig-quote-check.js line 445 + 849, `Unexpected '$badCharCombination' character combination`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 378 + 848, "Unexpected first translation \\w attribute", details: "expected 'x-occurrence'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 926 + 847, "Unexpected second translation \\w attribute", details: "expected 'x-occurrences'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 929 + 846, "Unexpected extra translation \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation from usfm-text-check.js line 931 + 845, `Mismatched [[ ]] link characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from notes-links-check.js line 1,290 + 844, `Mismatched [[rc:// ]] link characters`, details: `left=$leftCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from notes-links-check.js line 1,294 + 843, `Mismatched [ ]( ) link characters`, details: `left=$leftCount.toLocaleString(), middle=$middleCount.toLocaleString(), right=$rightCount.toLocaleString()`, location: ourLocation from notes-links-check.js line 1,301 + 839, "Unexpected first \\k-s attribute", details: "expected 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 958 + 838, "Unexpected extra \\k-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 960 + 837, "Seems too few original \\w attributes", details: `Expected 3-4 attributes but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 936 + 836, "Seems too few translation \\w attributes", details: `Expected two attributes but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 938 + 835, "Seems too few original \\k-s attributes", details: `Expected one attribute but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 963 + 834, "Seems too few translation \\zaln-s attributes", details: `Expected six attributes but only found $attributeCounter`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation from usfm-text-check.js line 995 + 833, "Unexpected extra \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 992 + 832, `Seems project file is missing from the manifest`, excerpt: repoFilepath, location: ourLocation from manifest-text-check.js line 791 + 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 239 + 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 228 + 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 228 + 831, C, V, `Duplicate '$rowID' ID`, fieldName: 'ID', rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 228 + 830, "Unexpected first \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 975 + 829, "Unexpected second \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 978 + 828, "Unexpected third \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 981 + 827, "Unexpected fourth \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 984 + 826, "Unexpected fifth \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 987 + 825, "Unexpected sixth \\zaln-s attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation from usfm-text-check.js line 990 + 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 287 + 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 328 + 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 298 + 824, `Invalid zero chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 327 + 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 292 + 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 333 + 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 303 + 823, `Invalid large chapter number`, excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 332 + 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 305 + 822, "Expected field to contain an integer", lineNumber, characterIndex: 3, excerpt: `\\c $rest`, C, V, location: lineLocation from usfm-text-check.js line 1,020 + 822, "Expected field to contain an integer", characterIndex: 3, excerpt: `\\v $rest`, C, V, location: lineLocation from usfm-text-check.js line 1,024 + 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 343 + 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 316 + 822, "Unable to check chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 345 + 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 311 + 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Chapter', location: ourRowLocation from tn-tsv9-row-check.js line 348 + 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 322 + 821, "Bad chapter number", excerpt: C, rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 351 + 820, "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:$V$ourRowLocation` from twl-tsv6-row-check.js line 314 + 820, "Missing chapter number", rowID, fieldName: 'Chapter', location: ` ?:$V$ourRowLocation` from tn-tsv9-row-check.js line 351 + 820, "Missing chapter number", rowID, fieldName: 'Reference', excerpt: `?:$V`, location: ourRowLocation from questions-tsv7-row-check.js line 325 + 820, "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:$V$ourRowLocation` from notes-tsv7-row-check.js line 354 + 817, `UHB 'relation' is missing`, details: JSON.stringify(relationList), location: ourLocation from manifest-text-check.js line 811 + 816, `UGNT 'relation' is missing`, details: JSON.stringify(relationList), location: ourLocation from manifest-text-check.js line 813 + 815, "Divider without surrounding snippet", location: ourLocation from orig-quote-check.js line 487 + 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from twl-tsv6-row-check.js line 323 + 814, "Invalid zero verse number", rowID, fieldName: 'Verse', excerpt: V, location: ourRowLocation from tn-tsv9-row-check.js line 360 + 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 335 + 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 357 + 814, "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from notes-tsv7-row-check.js line 363 + 813, "Invalid large verse number", details: `$bookID chapter $C only has $numVersesThisChapter verses`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from twl-tsv6-row-check.js line 327 + 813, "Invalid large verse number", details: `$bookID chapter $C only has $numVersesThisChapter verses`, rowID, fieldName: 'Verse', excerpt: V, location: ourRowLocation from tn-tsv9-row-check.js line 364 + 813, "Invalid large verse number", details: `$bookID chapter $C only has $numVersesThisChapter verses`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 339 + 813, "Invalid large verse number", details: `$bookID chapter $C only has $numVersesThisChapter verses`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 361 + 813, "Invalid large verse number", details: `$bookID chapter $C only has $numVersesThisChapter verses`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from notes-tsv7-row-check.js line 367 + 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from twl-tsv6-row-check.js line 329 + 812, "Unable to check verse number", rowID, fieldName: 'Verse', location: ourRowLocation from tn-tsv9-row-check.js line 366 + 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 341 + 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from questions-tsv7-row-check.js line 363 + 812, "Unable to check verse number", rowID, fieldName: 'Reference', location: ourRowLocation from notes-tsv7-row-check.js line 369 + 811, "Bad verse number", rowID, fieldName: 'Reference', location: ` '$V'$ourRowLocation` from twl-tsv6-row-check.js line 333 + 811, "Bad verse number", rowID, fieldName: 'Verse', location: ` '$V'$ourRowLocation` from tn-tsv9-row-check.js line 370 + 811, "Bad verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 345 + 811, "Bad verse number", rowID, fieldName: 'Reference', location: ` '$V'$ourRowLocation` from notes-tsv7-row-check.js line 373 + 810, "Missing verse number", rowID, fieldName: 'Reference', location: ` after $C:?$ourRowLocation` from twl-tsv6-row-check.js line 336 + 810, "Missing verse number", rowID, fieldName: 'Verse', location: ` after $C:?$ourRowLocation` from tn-tsv9-row-check.js line 373 + 810, "Missing verse number", rowID, fieldName: 'Reference', location: ` after $C:?$ourRowLocation` from questions-tsv7-row-check.js line 371 + 810, "Missing verse number", rowID, fieldName: 'Reference', location: ` after $C:?$ourRowLocation` from notes-tsv7-row-check.js line 376 + 808, "Bad verse range", details: "Too many hyphens", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 348 + 808, "Bad verse range", details: "Second digits should be greater", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 355 + 808, "Bad verse range", details: "Should be digits", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation from questions-tsv7-row-check.js line 366 + 805, "Unexpected Hebrew dagesh after vowel", details: `Found $match.length '$match'`, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 662 + 799, "Missing TWLink field", fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 423 + 798, "Field doesn’t contain expected TW link", details: `should start with 'rc://*/tw/dict/bible/'`, fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 407 + 797, "Field doesn’t contain proper TW link", details: `should be 'kt', 'names', or 'other'`, fieldName: 'TWLink', rowID, characterIndex, excerpt, location: ourRowLocation from twl-tsv6-row-check.js line 414 + 796, "Field is only whitespace", fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 404 + 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from twl-tsv6-row-check.js line 388 + 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from tn-tsv9-row-check.js line 442 + 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from questions-tsv7-row-check.js line 424 + 792, `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from notes-tsv7-row-check.js line 457 + 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 393 + 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 447 + 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 429 + 791, `Missing occurrence field`, fieldName: 'Occurrence', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 462 + 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from tn-tsv9-table-check.js line 235 + 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from twl-tsv6-table-check.js line 224 + 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from notes-tsv7-table-check.js line 224 + 790, C, V, "Missing verse number", rowID, lineNumber: n + 1, location: ` after $C:$lastV$ourLocation` from questions-tsv7-table-check.js line 224 + 789, "Should have a SupportReference when OccurrenceNote has a TA link", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from tn-tsv9-row-check.js line 491 + 789, "Should have a SupportReference when Note has a TA link", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from notes-tsv7-row-check.js line 496 + 788, "Only 'Just-In-Time Training' TA articles allowed here", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 404 + 788, "Only 'Just-In-Time Training' TA articles allowed here", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 418 + 787, "Link to TA should also be in OccurrenceNote", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from tn-tsv9-row-check.js line 409 + 787, "Link to TA should also be in Note", fieldName: 'SupportReference', excerpt: supportReference, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 423 + 786, "Shouldn’t have multiple TA links in OccurrenceNote", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from tn-tsv9-row-check.js line 489 + 786, "Shouldn’t have multiple TA links in Note", details, rowID, fieldName: 'OccurrenceNote', excerpt, location: ourRowLocation from notes-tsv7-row-check.js line 494 + 785, "Unexpected trailing whitespace in link field", excerpt, characterIndex: fieldText.length - 1, location: ourLocation from notes-links-check.js line 247 + 784, "Unexpected leading whitespace in link field", excerpt, characterIndex: 0, location: ourLocation from notes-links-check.js line 243 + 783, `Unable to find/load general link`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,252 + 781, `Linked general article seems empty`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,255 + 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 342 + 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 379 + 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 377 + 778, "Row ID should be exactly 4 characters", details: `not $rowID.length`, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 382 + 777, `Bad punctuation nesting: $char closing character doesn’t match`, details, lineNumber: n, characterIndex, excerpt, location: ourLocation from plain-text-check.js line 209 + 776, 'Unexpected " straight quote character', details, lineNumber, C, V, excerpt, location: lineLocation from usfm-text-check.js line 829 + 775, "Unexpected ' straight quote character", details, lineNumber, C, V, excerpt, location: lineLocation from usfm-text-check.js line 834 + 774, `Unexpected $char closing character (no matching opener)`, lineNumber: n, characterIndex, excerpt, location: ourLocation from plain-text-check.js line 216 + 773, `Unexpected trailing zero-width joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 178 + 772, `Unexpected trailing word-joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 173 + 771, `Unexpected leading zero-width joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 156 + 770, `Unexpected leading word-joiner`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 152 + 769, C, V, "Verse bridge numbers not in ascending order", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, Math.max(9, excerptLength))$rest.length > excerptLength ? '…' : '' ($firstV → $secondV)`, location: ourLocation from usfm-text-check.js line 1,249 + 768, `At end of text with unclosed $char opening character`, details, lineNumber: n, characterIndex: x, excerpt, location: ourLocation from plain-text-check.js line 234 + 766, C, V, "Bridged verse numbers didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, Math.max(9, excerptLength))$rest.length > excerptLength ? '…' : '' ($lastV → $firstV)`, location: ourLocation from usfm-text-check.js line 1,251 + 765, "Unexpected link", characterIndex, excerpt, location: ourLocation from field-text-check.js line 461 + 764, C, V, "Chapter number didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : '' ($lastC ? lastC : '0' → $C)`, location: ourLocation from usfm-text-check.js line 1,222 + 763, C, V, "Verse number didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : '' ($lastV ? lastV : '0' → $V)`, location: ourLocation from usfm-text-check.js line 1,235 + 762, "Unable to convert verse bridge numbers to integers", C: chapterNumberString, V: verseNumberString, characterIndex: 3, excerpt: verseNumberString, location: `$CVlocation with $usfmVIerror` from usfm-text-check.js line 461 + 762, C, V, "Unable to convert verse bridge numbers to integers", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, Math.max(9, excerptLength))$rest.length > excerptLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,245 + 761, C, V, "Verse number didn’t increment correctly", lineNumber: n, characterIndex: 3, excerpt: `$restRest.substring(0, excerptHalfLength)$restRest.length > excerptHalfLength ? '…' : '' ($lastV ? lastV : '0' → $V)`, location: ourLocation from usfm-text-check.js line 1,266 + 752, "Verse numbers of markdown TN link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,184 + 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from twl-tsv6-row-check.js line 380 + 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from tn-tsv9-row-check.js line 434 + 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from questions-tsv7-row-check.js line 416 + 751, "Invalid zero occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation from notes-tsv7-row-check.js line 449 + 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 371 + 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 425 + 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 407 + 750, "Missing occurrence field when we have an original quote", fieldName: 'Occurrence', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 440 + 749, "Markdown image link seems faulty", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 261 + 749, "Markdown image link seems faulty", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 282 + 748, "Error fetching markdown image link", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 270 + 748, "Error fetching markdown image link", excerpt: fetchLink, location: ourLocation from notes-links-check.js line 291 + 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from tn-tsv9-table-check.js line 115 + 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from twl-tsv6-table-check.js line 106 + 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from notes-tsv7-table-check.js line 106 + 747, "Bad function call: should be given a valid book abbreviation", excerpt: bookID, location: ` (not '$bookID')$ourLocation` from questions-tsv7-table-check.js line 106 + 746, "Unexpected tag", details: thisTag, excerpt: tags, fieldName: 'Tags', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 398 + 746, "Unexpected tag", details: thisTag, excerpt: tags, fieldName: 'Tags', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 403 + 745, C, V, `Wrong '$B' book identifier (expected '$bookID')`, rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 185 + 744, C, V, "Missing book identifier", rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 188 + 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 678 + 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $givenCint`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 749 + 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 889 + 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 946 + 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,063 + 743, "Chapter numbers of markdown Bible link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,121 + 743, "Chapter numbers of markdown TN link don’t match", details: `$C1 vs $linkChapterInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,178 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 684 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 755 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $V2`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 795 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1a vs $V2`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 837 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 895 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1a vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 952 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1a vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,010 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,069 + 742, "Verse numbers of markdown Bible link don’t match", details: `$V1 vs $linkVerseInt`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,127 + 741, "Verse numbers of markdown Bible link range out of order", details: `$V1a to $V1b`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 842 + 741, "Verse numbers of markdown Bible link range out of order", details: `$V1a to $V1b`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 958 + 741, "Verse numbers of markdown Bible link range out of order", details: `$V1a to $V1b`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,016 + 740, "Unrecognized tag", details: `found '$thisTag' but expected 'keyterm' or 'name'`, excerpt: tags, fieldName: 'Tags', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 362 + 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from tn-tsv9-table-check.js line 212 + 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from twl-tsv6-table-check.js line 201 + 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from notes-tsv7-table-check.js line 201 + 739, C, V, "Missing chapter number", rowID, lineNumber: n + 1, location: ` after $lastC:$V$ourLocation` from questions-tsv7-table-check.js line 201 + 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 231 + 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 220 + 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 220 + 738, C, V, "Bad verse number", rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 220 + 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from tn-tsv9-table-check.js line 199 + 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from twl-tsv6-table-check.js line 188 + 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from notes-tsv7-table-check.js line 188 + 737, C, V, "Invalid large chapter number", rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from questions-tsv7-table-check.js line 188 + 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 203 + 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 192 + 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 192 + 736, C, V, "Receding chapter number", details: `'$C' after '$lastC'`, rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 192 + 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 205 + 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 194 + 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 194 + 735, C, V, "Advancing chapter number", details: `'$C' after '$lastC'`.rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 194 + 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from tn-tsv9-table-check.js line 209 + 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from tn-tsv9-table-check.js line 221 + 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from twl-tsv6-table-check.js line 198 + 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from twl-tsv6-table-check.js line 210 + 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from notes-tsv7-table-check.js line 198 + 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from notes-tsv7-table-check.js line 210 + 734, C, V, "Bad chapter number", rowID, lineNumber: n + 1, location: ourLocation from questions-tsv7-table-check.js line 198 + 734, C, V, "Invalid large verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from questions-tsv7-table-check.js line 210 + 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from tn-tsv9-table-check.js line 225 + 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from twl-tsv6-table-check.js line 214 + 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from notes-tsv7-table-check.js line 214 + 733, C, V, "Receding verse number", details: `'$V' after '$lastV for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from questions-tsv7-table-check.js line 214 + 724, C, V, "Unable to convert chapter number to integer", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,218 + 723, C, V, "Unable to convert verse number to integer", lineNumber: n, characterIndex: 3, excerpt: `$rest.substring(0, excerptHalfLength)$rest.length > excerptHalfLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,231 + 720, C, V, "Unable to convert internal verse number to integer", lineNumber: n, characterIndex: 3, excerpt: `$restRest.substring(0, excerptHalfLength)$restRest.length > excerptHalfLength ? '…' : ''`, location: ourLocation from usfm-text-check.js line 1,262 + 719, "USFM file is recommended to have \\ide line", lineNumber: ideIndex + 1, location: ourLocation from usfm-text-check.js line 1,159 + 716, `Misplaced $rightChar character`, excerpt: regexResultArray[0], location: ourLocation from field-text-check.js line 442 + 711, "Expected compulsory content", C, V, lineNumber, characterIndex: marker.length, location: ` after \\$marker marker$lineLocation` from usfm-text-check.js line 1,053 + 703, C, V, "Unexpected CarriageReturn character", lineNumber: n, characterIndex, excerpt, location: ourLocation from usfm-text-check.js line 1,182 + 674, "Field contains HTML
field(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found—should be '\\n' instead`, fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 436 + 674, "Field contains HTML
field(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found—should be '\\n' instead`, fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 465 + 674, "Field contains HTML
field(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found—should be '\\n' instead`, fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 469 + 669, "Unexpected language code in link", details: `resource language code is '$languageCode'`, excerpt: Lg, location: ourLocation from notes-links-check.js line 658 + 656, "Bad chapter number in markdown TN link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,203 + 655, "Bad story number in markdown OBS help link", details: `$linkBookCode $linkChapterInt vs $numStories chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 692 + 655, "Bad chapter number in markdown Bible help link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 709 + 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $givenCint vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 774 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 814 - 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 865 - 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 923 - 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,025 - 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,077 - 654, "Bad verse number in markdown TN link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,132 - 653, "Bad frame number in markdown OBS help link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numFramesThisStory verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 664 - 653, "Bad verse number in markdown Bible help link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 678 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $givenCint:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 738 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 775 + 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 858 + 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 914 + 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 977 + 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,088 + 655, "Bad chapter number in markdown Bible link", details: `$linkBookCode $linkChapterInt vs $numChaptersThisBook chapters`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,146 + 654, "Bad verse number in markdown TN link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,205 + 653, "Bad frame number in markdown OBS help link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numFramesThisStory verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 694 + 653, "Bad verse number in markdown Bible help link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 711 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $givenCint:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 776 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 816 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 867 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 925 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $givenC:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 975 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,027 - 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,079 - 649, "Unusual [[ ]] link(s)—not a recognized TA or TW link", details: `need to carefully check $leftoverLinksList2.length === 1 ? '"' + leftoverLinksList2[0] + '"' : JSON.stringify(leftoverLinksList2)`, location: ourLocation from notes-links-check.js line 1,209 - 648, "Unusual [ ]( ) link(s)—not a recognized Bible or TA, TN, or TW link", details: `need to carefully check $leftoverLinksList1.length === 1 ? '"' + leftoverLinksList1[0] + '"' : JSON.stringify(leftoverLinksList1)`, location: ourLocation from notes-links-check.js line 1,201 - 644, "USFM3 Grammar Check (relaxed mode) doesn’t pass either", location: fileLocation from usfm-text-check.js line 259 - 638, "Only found whitespace", location: ourLocation from field-text-check.js line 113 - 638, "Only found whitespace", location: ourLocation from plain-text-check.js line 133 - 603, "USFM marker doesn’t end with space", C, V, lineNumber, characterIndex, excerpt, location: ourLocation from usfm-text-check.js line 1,082 - 601, "Unable to load", details: `username=$username error=$gcUHBerror`, OBSPathname, location: ourLocation, extra: OBSRepoName from orig-quote-check.js line 121 - 601, "Unable to load", details: `username=$username error=$gcUHBerror`, filename, location: ourLocation, extra: originalLanguageRepoName from orig-quote-check.js line 154 - 601, "Unable to load", details: `username=$username error=$gcUGNTerror`, filename, location: ourLocation, extra: originalLanguageRepoName from orig-quote-check.js line 162 - 600, `$regexResultsArray.length link target$regexResultsArray.length === 1 ? ' is' : 's are' still being checked…`, location: ourLocation from field-link-check.js line 171 - 583, "Unexpected newLine character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 241 - 582, "Unexpected carriageReturn character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 247 - 581, "Unexpected non-break space (uA0) character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 253 - 580, "Unexpected narrow non-break space (u202F) character", excerpt, location: ourLocation ; from field-text-check.js line 259 - 555, "Possible missing chapter number in markdown Bible link", excerpt: totalLink, location: ourLocation from notes-links-check.js line 708 - 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from tn-tsv9-table-check.js line 214 - 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from twl-tsv6-table-check.js line 203 - 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from notes-tsv7-table-check.js line 203 - 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from questions-tsv7-table-check.js line 203 - 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from tn-tsv9-table-check.js line 192 - 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from twl-tsv6-table-check.js line 181 - 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from notes-tsv7-table-check.js line 181 - 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from questions-tsv7-table-check.js line 181 - 539, "File starts with empty line", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 155 - 538, "File ends without newline character", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 160 - 519, "Missing expected USFM line", excerpt: `missing \\$expectedMarker`, location: fileLocation from usfm-text-check.js line 606 - 518, "Missing expected USFM line", excerpt: `missing \\$expectedMarker`, location: fileLocation from usfm-text-check.js line 614 - 517, "Missing expected USFM line", excerpt: `missing \\$expectedMarker`, location: fileLocation from usfm-text-check.js line 610 - 450, "Resource container link should have '*' language code", details: `not '$foundLanguageCode'`, characterIndex, excerpt, location: ourLocation from notes-links-check.js line 347 - 450, "Resource container link should have '*' language code", details: `not '$foundLanguageCode'`, characterIndex, excerpt, location: ourLocation from notes-links-check.js line 516 - 444, "Shouldn’t have consecutive word fields without a space", details: badCount > 1 ? details + `$badCount occurrences found in line` : details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 648 - 441, `Unknown linkType parameter`, excerpt: linkType from field-link-check.js line 153 - 439, "Error fetching link", location: ` $fetchLink` from field-link-check.js line 45 - 438, `Blank field / missing link (expected $linkOptions.expectedCount link$linkOptions.expectedCount === 1 ? "" : "s")`, location: ourLocation from field-link-check.js line 125 - 401, `Unexpected content after \\$marker marker`, C, V, lineNumber, characterIndex: marker.length, excerpt: rest, location: lineLocation from usfm-text-check.js line 994 - 399, C, V, "Useless paragraph marker", lineNumber: n, characterIndex: 1, details: `'\\$lastMarker' before '\\$marker'`, location: ourLocation from usfm-text-check.js line 1,216 - 378, `Possible mismatched '$thisField' markdown formatting pairs`, details: `$count.toLocaleString() total occurrence$count === 1 ? '' : 's'`, characterIndex, excerpt, location: ourLocation from markdown-text-check.js line 380 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 395 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'SupportReference', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 408 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'GLQuote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 450 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'OccurrenceNote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 465 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 450 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 475 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'SupportReference', characterIndex, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 469 - 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 511 - 373, "Field is only whitespace", fieldName: 'SupportReference', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 392 - 373, "Field is only whitespace", fieldName: 'GLQuote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 453 - 373, "Field is only whitespace", fieldName: 'OccurrenceNote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 468 - 373, "Field is only whitespace", fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 453 - 373, "Field is only whitespace", fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 478 - 373, "Field is only whitespace", fieldName: 'SupportReference', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 450 - 373, "Field is only whitespace", fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 514 - 348, "Markdown image link has no title text", excerpt: totalLink, location: ourLocation from notes-links-check.js line 255 - 312, 'Possible unclosed footnote', details, lineNumber, C, V, location: lineLocation from usfm-text-check.js line 702 - 301, `Unexpected whitespace after \\$marker marker`, C, V, lineNumber, characterIndex: marker.length, excerpt: rest, location: lineLocation from usfm-text-check.js line 992 - 287, `Not enough links (expected $linkOptions.expectedCount link$linkOptions.expectedCount === 1 ? "" : "s")`, location: ` (only found $regexResultsArray.length)$ourLocation` from field-link-check.js line 167 - 282, "Nesting of header levels seems confused", details: `recent indent levels=$JSON.stringify(indentLevels) but now $numLeadingSpaces`, lineNumber: n, characterIndex: 0, location: ourLocation ; from markdown-text-check.js line 332 - 274, "Missing OccurrenceNote field", fieldName: 'OccurrenceNote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 492 - 274, "Missing Question field", fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 470 - 274, "Missing Response field", fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 495 - 274, "Missing Note field", fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 540 - 256, "Possibly missing current copyright year", details: `possibly expecting '$fullYearString'`, username, repoName, filename, location: markdownLocation, extra: repoCode from checkBookPackage.js line 279 - 252, "Markdown headers should be preceded by a blank line", lineNumber: n, location: ourLocation ; from markdown-text-check.js line 282 - 251, "Markdown headers should be followed by a blank line", lineNumber: n, location: ourLocation ; from markdown-text-check.js line 288 - 250, "Multiple blank lines are not expected in markdown", lineNumber: n, location: ourLocation ; from markdown-text-check.js line 349 - 224, "Multiple unexpected double spaces", details: `$doubleCount occurrences—only first is displayed`, excerpt, location: ourLocation ; from field-text-check.js line 231 - 218, "Using deprecated USFM marker", excerpt: `\\$deprecatedMarker`, location: fileLocation from usfm-text-check.js line 617 - 199, "Markdown image link has no alternative text", excerpt: totalLink, location: ourLocation from notes-links-check.js line 234 - 199, "Markdown image link has no alternative text", excerpt: totalLink, location: ourLocation from notes-links-check.js line 253 - 195, `Unexpected $punctChar character at start of line`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 324 - 193, `Unexpected $punctChar character at end of line`, excerpt, location: ourLocation ; from field-text-check.js line 360 - 192, `Unexpected space after $punctChar character`, excerpt, location: ourLocation ; from field-text-check.js line 342 - 191, `Unexpected $punctChar character after space`, excerpt, location: ourLocation ; from field-text-check.js line 313 - 179, "Unexpected space before ellipse character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 269 - 178, "Unexpected space after ellipse character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 275 - 177, `Unexpected doubled $punctChar characters`, excerpt, location: ourLocation ; from field-text-check.js line 294 - 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 342 - 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 381 - 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 397 - 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 430 - 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 344 - 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 383 - 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 399 - 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 432 - 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 346 - 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 385 - 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 401 - 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 434 - 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 348 - 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 387 - 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 403 - 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 436 - 172, "Header levels should only increment by one", lineNumber: n, characterIndex: 0, location: ourLocation ; from markdown-text-check.js line 301 - 159, "Should use proper ellipse character (not periods)", characterIndex, excerpt, location: ourLocation from orig-quote-check.js line 392 - 158, `Unexpected space(s) beside divider $discontiguousDivider`, characterIndex, excerpt, location: ourLocation from orig-quote-check.js line 401 - 156, "Unexpected space(s) beside ellipse characters", characterIndex, excerpt, location: ourLocation from orig-quote-check.js line 415 - 152, "Should http link be https", excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,190 - 148, "'checking' key is missing", location: ourLocation from manifest-text-check.js line 676 - 144, "Unknown Bible book name in TN link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 1,099 - 143, "Unknown Bible book name in TN RC link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 639 - 143, "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 698 - 143, "Unknown Bible book name in relative Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 835 - 143, "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 886 - 143, "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 944 - 143, "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 994 - 143, "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 1,046 - 138, "File ends with additional blank line(s)", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 165 - 124, "Unexpected double spaces", excerpt, location: ourLocation ; from field-text-check.js line 229 - 111, `Bad options for checkFieldLinks: expectedCount=$linkOptions.expectedCount but allowedCount=$linkOptions.allowedCount` from field-link-check.js line 135 - 110, `Unexpected leading spaces`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 142 - 109, `Unexpected leading space`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 144 - 107, "Unexpected leading line break", characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 183 - 104, "Unexpected trailing line break", characterIndex: fieldText.length - 1, excerpt, location: ourLocation from field-text-check.js line 216 - 103, `USFMGrammar: $warningString.trim()`, location from usfm-text-check.js line 1,257 - 102, `USFMGrammar: $warningString`, location: fileLocation from usfm-text-check.js line 253 - 101, `USFMGrammar: $warningString`, filename, location: ourLocation from BCS-usfm-grammar-check.js line 203 - 95, "Unexpected trailing space(s)", excerpt, location: ourLocation ; from field-text-check.js line 195 - 94, "Unexpected trailing space(s) before break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 203 - 93, "Unexpected trailing space(s) before line break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 208 - 87, C, V, "Expected \\toc2 line to follow \\toc1", lineNumber: n, characterIndex: 1, details: `not '\\$lastMarker'`, location: ourLocation from usfm-text-check.js line 1,209 - 87, C, V, "Expected \\toc3 line to follow \\toc2", lineNumber: n, characterIndex: 1, details: `not '\\$lastMarker'`, location: ourLocation from usfm-text-check.js line 1,211 - 82, `Error loading general link`, details: "please double-check link—there may be no problem", excerpt: totalLink, location: `$ourLocation: $trcGCerror` from notes-links-check.js line 1,175 - 67, C: chapterNumberString, V: `$v`, "Verse appears to be left out", location: CVlocation from usfm-text-check.js line 473 - 64, "Unexpected leading space(s) after break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 157 - 63, "Unexpected leading space(s) after line break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 162 - 50, "Is this quote/occurrence correct???", details: `Occurrence=$occurrence`, excerpt: fieldText, location: ourLocation from orig-quote-check.js line 441 - 32, `Untested general/outside link`, details: "please manually double-check link—probably no problem", excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,156 - 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from tn-tsv9-table-check.js line 264 - 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from twl-tsv6-table-check.js line 253 - 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from notes-tsv7-table-check.js line 253 - 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from questions-tsv7-table-check.js line 253 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 860 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 916 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 979 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $givenC:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,032 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,090 + 653, "Bad verse number in markdown Bible link", details: `$linkBookCode $linkChapterInt:$linkVerseInt vs $numVersesThisChapter verses`, excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,148 + 649, "Unusual [[ ]] link(s)—not a recognized TA or TW link", details: `need to carefully check $leftoverLinksList2.length === 1 ? '"' + leftoverLinksList2[0] + '"' : JSON.stringify(leftoverLinksList2)`, location: ourLocation from notes-links-check.js line 1,282 + 648, "Unusual [ ]( ) link(s)—not a recognized Bible or TA, TN, or TW link", details: `need to carefully check $leftoverLinksList1.length === 1 ? '"' + leftoverLinksList1[0] + '"' : JSON.stringify(leftoverLinksList1)`, location: ourLocation from notes-links-check.js line 1,274 + 644, "USFM3 Grammar Check (relaxed mode) doesn’t pass either", location: fileLocation from usfm-text-check.js line 271 + 638, "Only found whitespace", location: ourLocation from field-text-check.js line 118 + 638, "Only found whitespace", location: ourLocation from plain-text-check.js line 137 + 619, "USFM \\ide field is recommended to be set to 'UTF-8'", lineNumber: ideIndex + 1, characterIndex: 5, excerpt: lines[ideIndex], location: ourLocation from usfm-text-check.js line 1,161 + 603, "USFM marker doesn’t end with space", C, V, lineNumber, characterIndex, excerpt, location: ourLocation from usfm-text-check.js line 1,142 + 601, "Unable to load", details: `username=$username error=$gcUHBerror`, OBSPathname, location: ourLocation, extra: OBSRepoName from orig-quote-check.js line 124 + 601, "Unable to load", details: `username=$username error=$gcUHBerror`, filename, location: ourLocation, extra: originalLanguageRepoName from orig-quote-check.js line 164 + 601, "Unable to load", details: `username=$username error=$gcUGNTerror`, filename, location: ourLocation, extra: originalLanguageRepoName from orig-quote-check.js line 172 + 600, `$regexResultsArray.length link target$regexResultsArray.length === 1 ? ' is' : 's are' still being checked…`, location: ourLocation from field-link-check.js line 177 + 583, "Unexpected newLine character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 246 + 582, "Unexpected carriageReturn character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 252 + 581, "Unexpected non-break space (uA0) character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 258 + 580, "Unexpected narrow non-break space (u202F) character", excerpt, location: ourLocation ; from field-text-check.js line 264 + 555, "Possible missing chapter number in markdown Bible link", excerpt: totalLink, location: ourLocation from notes-links-check.js line 743 + 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from tn-tsv9-table-check.js line 219 + 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from twl-tsv6-table-check.js line 208 + 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from notes-tsv7-table-check.js line 208 + 552, C, V, "Invalid zero verse number", details: `for chapter $C`, rowID, lineNumber: n + 1, excerpt: V, location: ourLocation from questions-tsv7-table-check.js line 208 + 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from tn-tsv9-table-check.js line 197 + 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from twl-tsv6-table-check.js line 186 + 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from notes-tsv7-table-check.js line 186 + 551, C, V, `Invalid zero chapter number`, rowID, lineNumber: n + 1, excerpt: C, location: ourLocation from questions-tsv7-table-check.js line 186 + 539, "File starts with empty line", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 159 + 538, "File ends without newline character", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 164 + 518, "Missing expected USFM line", excerpt: `missing \\$expectedMarker`, location: fileLocation from usfm-text-check.js line 629 + 517, "Missing expected USFM line", excerpt: `missing \\$expectedMarker`, location: fileLocation from usfm-text-check.js line 625 + 450, "Resource container link should have '*' language code", details: `not '$foundLanguageCode'`, characterIndex, excerpt, location: ourLocation from notes-links-check.js line 372 + 450, "Resource container link should have '*' language code", details: `not '$foundLanguageCode'`, characterIndex, excerpt, location: ourLocation from notes-links-check.js line 542 + 444, "Shouldn’t have consecutive word fields without a space", details: badCount > 1 ? details + `$badCount occurrences found in line` : details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 676 + 443, "Shouldn’t have a footnote after a space", details: badCount > 1 ? details + `$badCount occurrences found in line` : details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 684 + 442, "Shouldn’t have a cross-reference after a space", details: badCount > 1 ? details + `$badCount occurrences found in line` : details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation from usfm-text-check.js line 689 + 441, `Unknown linkType parameter`, excerpt: linkType from field-link-check.js line 159 + 439, "Error fetching link", location: ` $fetchLink` from field-link-check.js line 49 + 438, `Blank field / missing link (expected $linkOptions.expectedCount link$linkOptions.expectedCount === 1 ? "" : "s")`, location: ourLocation from field-link-check.js line 131 + 401, `Unexpected content after \\$marker marker`, C, V, lineNumber, characterIndex: marker.length, excerpt: rest, location: lineLocation from usfm-text-check.js line 1,051 + 399, C, V, "Useless paragraph marker", lineNumber: n, characterIndex: 1, details: `'\\$lastMarker' before '\\$marker'`, location: ourLocation from usfm-text-check.js line 1,286 + 378, `Possible mismatched '$thisField' markdown formatting pairs`, details: `$count.toLocaleString() total occurrence$count === 1 ? '' : 's'`, characterIndex, excerpt, location: ourLocation from markdown-text-check.js line 390 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'TWLink', rowID, location: ourRowLocation from twl-tsv6-row-check.js line 401 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'SupportReference', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 413 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'GLQuote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 454 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'OccurrenceNote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 469 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 440 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 469 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'SupportReference', characterIndex, rowID, location: ourRowLocation from notes-tsv7-row-check.js line 428 + 374, "Field contains zero-width space(s)", details: `$charCount occurrence$charCount === 1 ? '' : 's' found`, fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 473 + 373, "Field is only whitespace", fieldName: 'SupportReference', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 397 + 373, "Field is only whitespace", fieldName: 'GLQuote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 457 + 373, "Field is only whitespace", fieldName: 'OccurrenceNote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 472 + 373, "Field is only whitespace", fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 443 + 373, "Field is only whitespace", fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 472 + 373, "Field is only whitespace", fieldName: 'SupportReference', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 409 + 373, "Field is only whitespace", fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 476 + 348, "Markdown image link has no title text", excerpt: totalLink, location: ourLocation from notes-links-check.js line 280 + 312, 'Possible unclosed footnote', details, lineNumber, C, V, location: lineLocation from usfm-text-check.js line 742 + 301, `Unexpected whitespace after \\$marker marker`, C, V, lineNumber, characterIndex: marker.length, excerpt: rest, location: lineLocation from usfm-text-check.js line 1,049 + 287, `Not enough links (expected $linkOptions.expectedCount link$linkOptions.expectedCount === 1 ? "" : "s")`, location: ` (only found $regexResultsArray.length)$ourLocation` from field-link-check.js line 173 + 282, "Nesting of header levels seems confused", details: `recent indent levels=$JSON.stringify(indentLevels) but now $numLeadingSpaces`, lineNumber: n, characterIndex: 0, location: ourLocation ; from markdown-text-check.js line 342 + 274, "Missing OccurrenceNote field", fieldName: 'OccurrenceNote', rowID, location: ourRowLocation from tn-tsv9-row-check.js line 496 + 274, "Missing Question field", fieldName: 'Question', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 460 + 274, "Missing Response field", fieldName: 'Response', rowID, location: ourRowLocation from questions-tsv7-row-check.js line 489 + 274, "Missing Note field", fieldName: 'Note', rowID, location: ourRowLocation from notes-tsv7-row-check.js line 502 + 256, "Possibly missing current copyright year", details: `possibly expecting '$fullYearString'`, username, repoName, filename, location: markdownLocation, extra: repoCode from checkBookPackage.js line 286 + 252, "Markdown headers should be preceded by a blank line", lineNumber: n, location: ourLocation ; from markdown-text-check.js line 292 + 251, "Markdown headers should be followed by a blank line", lineNumber: n, location: ourLocation ; from markdown-text-check.js line 298 + 250, "Multiple blank lines are not expected in markdown", lineNumber: n, location: ourLocation ; from markdown-text-check.js line 359 + 224, "Multiple unexpected double spaces", details: `$doubleCount occurrences—only first is displayed`, excerpt, location: ourLocation ; from field-text-check.js line 236 + 218, "Using deprecated USFM marker", excerpt: `\\$deprecatedMarker`, location: fileLocation from usfm-text-check.js line 632 + 199, "Markdown image link has no alternative text", excerpt: totalLink, location: ourLocation from notes-links-check.js line 259 + 199, "Markdown image link has no alternative text", excerpt: totalLink, location: ourLocation from notes-links-check.js line 278 + 195, `Unexpected $punctChar character at start of line`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 329 + 193, `Unexpected $punctChar character at end of line`, excerpt, location: ourLocation ; from field-text-check.js line 365 + 192, `Unexpected space after $punctChar character`, excerpt, location: ourLocation ; from field-text-check.js line 347 + 191, `Unexpected $punctChar character after space`, excerpt, location: ourLocation ; from field-text-check.js line 318 + 179, "Unexpected space before ellipse character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 274 + 178, "Unexpected space after ellipse character", characterIndex, excerpt, location: ourLocation from field-text-check.js line 280 + 177, `Unexpected doubled $punctChar characters`, excerpt, location: ourLocation ; from field-text-check.js line 299 + 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 349 + 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 386 + 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 384 + 176, "Row ID should start with a lowercase letter", characterIndex: 0, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 389 + 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 351 + 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 388 + 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 386 + 175, "Row ID should end with a lowercase letter or digit", characterIndex: 3, rowID, fieldName: 'ID', excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 391 + 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 353 + 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 390 + 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 388 + 174, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 1, rowID, excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 393 + 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from twl-tsv6-row-check.js line 355 + 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from tn-tsv9-row-check.js line 392 + 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from questions-tsv7-row-check.js line 390 + 173, "Row ID characters should only be lowercase letters, digits, or hypen", fieldName: 'ID', characterIndex: 2, rowID, excerpt: rowID, location: ourRowLocation from notes-tsv7-row-check.js line 395 + 172, "Header levels should only increment by one", lineNumber: n, characterIndex: 0, location: ourLocation ; from markdown-text-check.js line 311 + 159, "Should use proper ellipse character (not periods)", characterIndex, excerpt, location: ourLocation from orig-quote-check.js line 406 + 158, `Unexpected space(s) beside divider $discontiguousDivider`, characterIndex, excerpt, location: ourLocation from orig-quote-check.js line 415 + 156, "Unexpected space(s) beside ellipse characters", characterIndex, excerpt, location: ourLocation from orig-quote-check.js line 429 + 152, "Should http link be https", excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,263 + 148, "'checking' key is missing", location: ourLocation from manifest-text-check.js line 682 + 144, "Unknown Bible book name in TN link", details: totalLink, excerpt: optionalB1, location: ourLocation from notes-links-check.js line 1,169 + 138, "File ends with additional blank line(s)", characterIndex, excerpt, location: ourLocation from plain-text-check.js line 169 + 124, "Unexpected double spaces", excerpt, location: ourLocation ; from field-text-check.js line 234 + 111, `Bad options for checkFieldLinks: expectedCount=$linkOptions.expectedCount but allowedCount=$linkOptions.allowedCount` from field-link-check.js line 141 + 110, `Unexpected leading spaces`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 147 + 109, `Unexpected leading space`, characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 149 + 107, "Unexpected leading line break", characterIndex: 0, excerpt, location: ourLocation from field-text-check.js line 188 + 104, "Unexpected trailing line break", characterIndex: fieldText.length - 1, excerpt, location: ourLocation from field-text-check.js line 221 + 102, `USFMGrammar: $warningString`, location: fileLocation from usfm-text-check.js line 265 + 101, `USFMGrammar: $warningString`, filename, location: ourLocation from BCS-usfm-grammar-check.js line 234 + 95, "Unexpected trailing space(s)", excerpt, location: ourLocation ; from field-text-check.js line 200 + 94, "Unexpected trailing space(s) before break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 208 + 93, "Unexpected trailing space(s) before line break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 213 + 92, `Unexpected leading zero`, characterIndex, excerpt, location: ourLocation from field-text-check.js line 388 + 87, C, V, "Expected \\toc2 line to follow \\toc1", lineNumber: n, characterIndex: 1, details: `not '\\$lastMarker'`, location: ourLocation from usfm-text-check.js line 1,279 + 87, C, V, "Expected \\toc3 line to follow \\toc2", lineNumber: n, characterIndex: 1, details: `not '\\$lastMarker'`, location: ourLocation from usfm-text-check.js line 1,281 + 82, `Error loading general link`, details: "please double-check link—there may be no problem", excerpt: totalLink, location: `$ourLocation: $trcGCerror` from notes-links-check.js line 1,248 + 67, C: chapterNumberString, V: `$v`, "Verse appears to be left out", location: CVlocation from usfm-text-check.js line 485 + 64, "Unexpected leading space(s) after break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 162 + 63, "Unexpected leading space(s) after line break", characterIndex, excerpt, location: ourLocation from field-text-check.js line 167 + 50, "Is this quote/occurrence correct???", details: `Occurrence=$occurrence`, excerpt: fieldText, location: ourLocation from orig-quote-check.js line 455 + 32, `Untested general/outside link`, details: "please manually double-check link—probably no problem", excerpt: totalLink, location: ourLocation from notes-links-check.js line 1,229 + 25, "Note: skipped running BCS USFMGrammar checker for large book", details: `$numChapters chapters ($kB.toLocaleString() KB)`, location: ourLocation from usfm-text-check.js line 1,344 + 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from tn-tsv9-table-check.js line 269 + 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from twl-tsv6-table-check.js line 258 + 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from notes-tsv7-table-check.js line 258 + 20, "Note that 'disableAllLinkFetchingFlag' was set so link targets were not checked", location: ourLocation from questions-tsv7-table-check.js line 258 diff --git a/package.json b/package.json index 6181dba27..8f71e4345 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "uw-content-validation", "description": "Functions for Checking Door43.org Scriptural Content/Resources.", - "version": "2.1.4", + "version": "2.1.5", "private": false, "homepage": "https://unfoldingword.github.io/uw-content-validation/", "repository": { diff --git a/src/__tests__/__snapshots__/book-package-check.test.js.snap b/src/__tests__/__snapshots__/book-package-check.test.js.snap index 788c6bd81..6361a49df 100644 --- a/src/__tests__/__snapshots__/book-package-check.test.js.snap +++ b/src/__tests__/__snapshots__/book-package-check.test.js.snap @@ -122,40 +122,6 @@ Object { "repoName": "hbo_uhb", "username": "unfoldingWord", }, - Object { - "C": "1", - "V": "8", - "bookID": "RUT", - "branch": "master", - "excerpt": "Q␣␣יַ֣עַשׂ*", - "extra": "UHB", - "fieldName": "from \\\\f", - "filename": "08-RUT.usfm", - "lineNumber": 136, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", - "username": "unfoldingWord", - }, - Object { - "C": "1", - "V": "8", - "bookID": "RUT", - "branch": "master", - "excerpt": "Q יַ֣עַשׂ*", - "extra": "UHB", - "fieldName": "from \\\\f", - "filename": "08-RUT.usfm", - "lineNumber": 136, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", - "username": "unfoldingWord", - }, Object { "C": "1", "V": "19", @@ -212,41 +178,42 @@ Object { }, Object { "C": "2", - "V": "1", + "V": "4", "bookID": "RUT", "branch": "master", - "excerpt": "K␣␣מידע*", + "characterIndex": 0, + "excerpt": "| x-tw=\\"rc…", "extra": "UHB", - "fieldName": "from \\\\f", + "fieldName": "\\\\k-s", "filename": "08-RUT.usfm", - "lineNumber": 367, + "lineNumber": 414, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, + "message": "Unexpected space after | character", + "priority": 192, "repoCode": "UHB", "repoName": "hbo_uhb", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "1", + "C": "4", + "V": "11", "bookID": "RUT", "branch": "master", - "excerpt": "K מידע*", + "details": "Expected 3-4 attributes but only found 2", + "excerpt": "\\\\w שֵׁ֖ם|lemma=\\"שֵׁם\\" strong=\\"H8034\\"\\\\w*", "extra": "UHB", - "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 367, + "lineNumber": 1195, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, + "message": "Seems too few original \\\\w attributes", + "priority": 837, "repoCode": "UHB", "repoName": "hbo_uhb", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "4", + "C": "4", + "V": "11", "bookID": "RUT", "branch": "master", "characterIndex": 0, @@ -254,7 +221,7 @@ Object { "extra": "UHB", "fieldName": "\\\\k-s", "filename": "08-RUT.usfm", - "lineNumber": 414, + "lineNumber": 1196, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected space after | character", "priority": 192, @@ -263,688 +230,590 @@ Object { "username": "unfoldingWord", }, Object { - "C": "3", - "V": "3", "bookID": "RUT", "branch": "master", - "excerpt": "Q␣␣שִׂמְלֹת…", "extra": "UHB", - "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 773, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, + "message": "USFMGrammar: Attribute value empty for lemma", + "priority": 102, "repoCode": "UHB", "repoName": "hbo_uhb", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "3", + "details": "username=unfoldingWord", + "extra": "TWL", + "location": " in TWL in en RUT book package from unfoldingWord master branch", + "message": "Repository doesn’t exist", + "priority": 997, + "repoCode": "TWL", + "repoName": "en_twl", + "username": "unfoldingWord", + }, + Object { + "C": "0", + "V": "1", "bookID": "RUT", "branch": "master", - "excerpt": "…ְלֹתַ֛יִךְ*", - "extra": "UHB", - "fieldName": "from \\\\f", + "characterIndex": 33, + "excerpt": "…tr Tue Mar 03 2020 1…", + "extra": "LT", + "fieldName": "\\\\id", "filename": "08-RUT.usfm", - "lineNumber": 773, + "lineNumber": 1, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "3", + "C": "2", + "V": "1", "bookID": "RUT", "branch": "master", - "excerpt": "K␣␣ו⁠ירדתי*", - "extra": "UHB", + "excerpt": "…ew␣Ketiv)␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 776, + "lineNumber": 754, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "3", + "C": "2", + "V": "7", "bookID": "RUT", "branch": "master", - "excerpt": "K ו⁠ירדתי*", - "extra": "UHB", + "excerpt": "…uncertain␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 776, + "lineNumber": 944, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { "C": "3", - "V": "4", + "V": "3", "bookID": "RUT", "branch": "master", - "excerpt": "K␣␣ו⁠שכבתי*", - "extra": "UHB", + "excerpt": "…rew␣Qere)␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 796, + "lineNumber": 1651, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { "C": "3", - "V": "4", + "V": "15", "bookID": "RUT", "branch": "master", - "excerpt": "K ו⁠שכבתי*", - "extra": "UHB", + "excerpt": "…uscripts)␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 796, + "lineNumber": 2024, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "12", + "C": "4", + "V": "4", "bookID": "RUT", "branch": "master", - "details": "2 occurrences—only first is displayed", - "excerpt": "K␣␣כי*␣␣אם*", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "line marker='\\\\w'", + "excerpt": "it,'", + "extra": "LT", "filename": "08-RUT.usfm", - "lineNumber": 898, + "lineNumber": 2218, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Multiple unexpected double spaces", - "priority": 224, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected ' straight quote character", + "priority": 775, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "12", + "C": "4", + "V": "4", "bookID": "RUT", "branch": "master", - "excerpt": "K כי* אם*", - "extra": "UHB", + "excerpt": "…uscripts)␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 898, + "lineNumber": 2283, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected space after * character", - "priority": 192, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "12", + "C": "4", + "V": "4", "bookID": "RUT", "branch": "master", - "excerpt": "K כי* אם*", - "extra": "UHB", + "excerpt": "…rew␣Qere)␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 898, + "lineNumber": 2284, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "14", + "C": "4", + "V": "5", "bookID": "RUT", "branch": "master", - "excerpt": "K␣␣מרגלת⁠ו*", - "extra": "UHB", + "excerpt": "…ew␣Ketiv)␣", + "extra": "LT", "fieldName": "from \\\\f", "filename": "08-RUT.usfm", - "lineNumber": 927, + "lineNumber": 2329, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "14", "bookID": "RUT", "branch": "master", - "excerpt": "K מרגלת⁠ו*", - "extra": "UHB", - "fieldName": "from \\\\f", + "characterIndex": 311926, + "excerpt": "…*\\\\zaln-e\\\\*\\\\zaln-e\\\\*.", + "extra": "LT", "filename": "08-RUT.usfm", - "lineNumber": 927, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "File ends without newline character", + "priority": 538, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "14", "bookID": "RUT", "branch": "master", - "excerpt": "Q␣␣ב⁠טרום*", - "extra": "UHB", - "fieldName": "from \\\\f", + "characterIndex": 54, + "details": "'‘' opened on line 2217 character 179", + "excerpt": "…\\\\zaln-e\\\\*.”", + "extra": "LT", "filename": "08-RUT.usfm", - "lineNumber": 931, + "lineNumber": 2274, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Bad punctuation nesting: ” closing character doesn’t match", + "priority": 777, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "14", "bookID": "RUT", "branch": "master", - "excerpt": "Q ב⁠טרום*", - "extra": "UHB", - "fieldName": "from \\\\f", + "characterIndex": 178, + "details": "2 unclosed sets", + "excerpt": "…zaln-e\\\\*,␣‘\\\\zaln-s␣|…", + "extra": "LT", "filename": "08-RUT.usfm", - "lineNumber": 931, + "lineNumber": 2217, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "At end of text with unclosed ‘ opening character", + "priority": 768, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "15", "bookID": "RUT", "branch": "master", - "excerpt": "Or␣perhaps␣␣וַתָּבֹא…", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "left=4, right=3", + "extra": "LT", "filename": "08-RUT.usfm", - "lineNumber": 954, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Mismatched ‘’ characters", + "priority": 462, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "15", "bookID": "RUT", "branch": "master", - "excerpt": "… וַתָּבֹא*", - "extra": "UHB", - "fieldName": "from \\\\f", + "extra": "LT", "filename": "08-RUT.usfm", - "lineNumber": 954, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "USFMGrammar: Attribute value empty for x-lemma", + "priority": 102, + "repoCode": "LT", + "repoName": "en_ult", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "4", + "C": "0", + "V": "1", "bookID": "RUT", "branch": "master", - "excerpt": "Or␣perhaps␣␣תִגְאַל*", - "extra": "UHB", - "fieldName": "from \\\\f", + "characterIndex": 33, + "excerpt": "…tr Tue Mar 03 2020 1…", + "extra": "ST", + "fieldName": "\\\\id", "filename": "08-RUT.usfm", - "lineNumber": 1061, + "lineNumber": 1, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "4", + "C": "1", + "V": "3", "bookID": "RUT", "branch": "master", - "excerpt": "…s תִגְאַל*", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Naomi's", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1061, + "lineNumber": 110, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected ' straight quote character", + "priority": 775, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "4", + "C": "1", + "V": "8", "bookID": "RUT", "branch": "master", - "excerpt": "Q␣␣וְאֵֽדְע…", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "line marker='\\\\zaln-s'", + "excerpt": "…s-in-law,␣\\"Each", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1065, + "lineNumber": 244, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "4", + "C": "1", + "V": "8", "bookID": "RUT", "branch": "master", - "excerpt": "…ְאֵֽדְעָה֙*", - "extra": "UHB", - "fieldName": "from \\\\f", + "excerpt": "…rs-in-law, \\"Each", + "extra": "ST", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1065, + "lineNumber": 244, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "5", + "C": "1", + "V": "8", "bookID": "RUT", "branch": "master", - "excerpt": "K␣␣קניתי*", - "extra": "UHB", - "fieldName": "from \\\\f", + "characterIndex": 271, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "extra": "ST", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1088, + "lineNumber": 244, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "5", + "C": "1", + "V": "8", "bookID": "RUT", "branch": "master", - "excerpt": "K קניתי*", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "line marker='\\\\w'", + "excerpt": "mother's", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1088, + "lineNumber": 255, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected ' straight quote character", + "priority": 775, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "6", + "C": "1", + "V": "9", "bookID": "RUT", "branch": "master", - "excerpt": "Q␣␣לִגְאָל*", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "line marker='\\\\zaln-s'", + "excerpt": "home.\\"", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1099, + "lineNumber": 298, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected double spaces", - "priority": 124, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "6", + "C": "1", + "V": "10", "bookID": "RUT", "branch": "master", - "excerpt": "Q לִגְאָל*", - "extra": "UHB", - "fieldName": "from \\\\f", + "details": "line marker='\\\\w'", + "excerpt": "said,␣\\"No!", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1099, + "lineNumber": 311, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected * character at end of line", - "priority": 193, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "11", + "C": "1", + "V": "10", "bookID": "RUT", "branch": "master", - "details": "Expected 3-4 attributes but only found 2", - "excerpt": "\\\\w שֵׁ֖ם|lemma=\\"שֵׁם\\" strong=\\"H8034\\"\\\\w*", - "extra": "UHB", + "excerpt": "said, \\"No!", + "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1195, + "lineNumber": 311, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Seems too few original \\\\w attributes", - "priority": 837, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "11", + "C": "1", + "V": "10", "bookID": "RUT", "branch": "master", - "characterIndex": 0, - "excerpt": "| x-tw=\\"rc…", - "extra": "UHB", - "fieldName": "\\\\k-s", + "characterIndex": 61, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "extra": "ST", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1196, + "lineNumber": 311, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected space after | character", - "priority": 192, - "repoCode": "UHB", - "repoName": "hbo_uhb", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { + "C": "1", + "V": "10", "bookID": "RUT", "branch": "master", - "extra": "UHB", + "details": "line marker='\\\\w'", + "excerpt": "relatives.\\"", + "extra": "ST", "filename": "08-RUT.usfm", + "lineNumber": 319, "location": " in en RUT book package from unfoldingWord master branch", - "message": "USFMGrammar: Attribute value empty for lemma", - "priority": 102, - "repoCode": "UHB", - "repoName": "hbo_uhb", - "username": "unfoldingWord", - }, - Object { - "details": "username=unfoldingWord", - "extra": "TWL", - "location": " in TWL in en RUT book package from unfoldingWord master branch", - "message": "Repository doesn’t exist", - "priority": 997, - "repoCode": "TWL", - "repoName": "en_twl", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "1", + "C": "1", + "V": "11", "bookID": "RUT", "branch": "master", - "excerpt": "…ew␣Ketiv)␣", - "extra": "LT", - "fieldName": "from \\\\f", + "details": "line marker='\\\\zaln-s'", + "excerpt": "said,␣\\"No,", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 754, + "lineNumber": 325, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "7", + "C": "1", + "V": "11", "bookID": "RUT", "branch": "master", - "excerpt": "…uncertain␣", - "extra": "LT", - "fieldName": "from \\\\f", + "excerpt": "said, \\"No,", + "extra": "ST", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 944, + "lineNumber": 325, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "3", - "V": "3", + "C": "1", + "V": "11", "bookID": "RUT", "branch": "master", - "excerpt": "…rew␣Qere)␣", - "extra": "LT", - "fieldName": "from \\\\f", + "characterIndex": 173, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "extra": "ST", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1651, + "lineNumber": 325, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "15", - "bookID": "RUT", - "branch": "master", - "excerpt": "…uscripts)␣", - "extra": "LT", - "fieldName": "from \\\\f", - "filename": "08-RUT.usfm", - "lineNumber": 2024, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "4", + "C": "1", + "V": "13", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "it,'", - "extra": "LT", - "filename": "08-RUT.usfm", - "lineNumber": 2218, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, - "repoCode": "LT", - "repoName": "en_ult", - "username": "unfoldingWord", - }, - Object { - "C": "4", - "V": "4", - "bookID": "RUT", - "branch": "master", - "excerpt": "…uscripts)␣", - "extra": "LT", - "fieldName": "from \\\\f", - "filename": "08-RUT.usfm", - "lineNumber": 2283, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", - "username": "unfoldingWord", - }, - Object { - "C": "4", - "V": "4", - "bookID": "RUT", - "branch": "master", - "excerpt": "…rew␣Qere)␣", - "extra": "LT", - "fieldName": "from \\\\f", - "filename": "08-RUT.usfm", - "lineNumber": 2284, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", - "username": "unfoldingWord", - }, - Object { - "C": "4", - "V": "5", - "bookID": "RUT", - "branch": "master", - "excerpt": "…ew␣Ketiv)␣", - "extra": "LT", - "fieldName": "from \\\\f", - "filename": "08-RUT.usfm", - "lineNumber": 2329, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, - "repoCode": "LT", - "repoName": "en_ult", - "username": "unfoldingWord", - }, - Object { - "bookID": "RUT", - "branch": "master", - "characterIndex": 311926, - "excerpt": "…*\\\\zaln-e\\\\*\\\\zaln-e\\\\*.", - "extra": "LT", - "filename": "08-RUT.usfm", - "location": " in en RUT book package from unfoldingWord master branch", - "message": "File ends without newline character", - "priority": 538, - "repoCode": "LT", - "repoName": "en_ult", - "username": "unfoldingWord", - }, - Object { - "bookID": "RUT", - "branch": "master", - "characterIndex": 54, - "details": "'‘' opened on line 2217 character 179", - "excerpt": "…\\\\zaln-e\\\\*.”", - "extra": "LT", + "excerpt": "mine.\\"", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 2274, + "lineNumber": 430, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Bad punctuation nesting: ” closing character doesn’t match", - "priority": 777, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { + "C": "1", + "V": "15", "bookID": "RUT", "branch": "master", - "characterIndex": 178, - "details": "2 unclosed sets", - "excerpt": "…zaln-e\\\\*,␣‘\\\\zaln-s␣|…", - "extra": "LT", + "details": "line marker='\\\\w'", + "excerpt": "her,␣\\"Look!", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 2217, + "lineNumber": 456, "location": " in en RUT book package from unfoldingWord master branch", - "message": "At end of text with unclosed ‘ opening character", - "priority": 768, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { + "C": "1", + "V": "15", "bookID": "RUT", "branch": "master", - "details": "left=4, right=3", - "extra": "LT", + "excerpt": "her, \\"Look!", + "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", + "lineNumber": 456, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Mismatched ‘’ characters", - "priority": 462, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { + "C": "1", + "V": "15", "bookID": "RUT", "branch": "master", - "extra": "LT", + "characterIndex": 51, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "extra": "ST", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", + "lineNumber": 456, "location": " in en RUT book package from unfoldingWord master branch", - "message": "USFMGrammar: Attribute value empty for x-lemma", - "priority": 102, - "repoCode": "LT", - "repoName": "en_ult", + "message": "Unexpected \\" character after space", + "priority": 191, + "repoCode": "ST", + "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "3", + "V": "15", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "Naomi's", + "excerpt": "her!\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 110, + "lineNumber": 472, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "8", + "V": "16", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "…s-in-law,␣\\"Each", + "excerpt": "replied,␣\\"No!", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 244, + "lineNumber": 477, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -954,14 +823,14 @@ Object { }, Object { "C": "1", - "V": "8", + "V": "16", "bookID": "RUT", "branch": "master", - "excerpt": "…rs-in-law, \\"Each", + "excerpt": "replied, \\"No!", "extra": "ST", "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 244, + "lineNumber": 477, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -971,15 +840,15 @@ Object { }, Object { "C": "1", - "V": "8", + "V": "16", "bookID": "RUT", "branch": "master", - "characterIndex": 271, + "characterIndex": 176, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 244, + "lineNumber": 477, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -989,31 +858,14 @@ Object { }, Object { "C": "1", - "V": "8", + "V": "17", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "mother's", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 255, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "1", - "V": "9", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "home.\\"", + "excerpt": "die.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 298, + "lineNumber": 546, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1023,14 +875,14 @@ Object { }, Object { "C": "1", - "V": "10", + "V": "19", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "said,␣\\"No!", + "excerpt": "…xclaimed,␣\\"It", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 311, + "lineNumber": 601, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1040,14 +892,14 @@ Object { }, Object { "C": "1", - "V": "10", + "V": "19", "bookID": "RUT", "branch": "master", - "excerpt": "said, \\"No!", + "excerpt": "exclaimed, \\"It", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 311, + "lineNumber": 601, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1057,15 +909,15 @@ Object { }, Object { "C": "1", - "V": "10", + "V": "19", "bookID": "RUT", "branch": "master", - "characterIndex": 61, + "characterIndex": 57, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 311, + "lineNumber": 601, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1075,14 +927,14 @@ Object { }, Object { "C": "1", - "V": "10", + "V": "19", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "relatives.\\"", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Naomi!\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 319, + "lineNumber": 609, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1092,14 +944,14 @@ Object { }, Object { "C": "1", - "V": "11", + "V": "20", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "said,␣\\"No,", - "extra": "ST", + "details": "line marker='\\\\w'", + "excerpt": "them,␣\\"You", + "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 325, + "lineNumber": 613, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1109,14 +961,14 @@ Object { }, Object { "C": "1", - "V": "11", + "V": "20", "bookID": "RUT", "branch": "master", - "excerpt": "said, \\"No,", + "excerpt": "them, \\"You", "extra": "ST", - "fieldName": "from \\\\zaln-s", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 325, + "lineNumber": 613, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1126,15 +978,15 @@ Object { }, Object { "C": "1", - "V": "11", + "V": "20", "bookID": "RUT", "branch": "master", - "characterIndex": 173, + "characterIndex": 52, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\zaln-s", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 325, + "lineNumber": 613, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1144,50 +996,51 @@ Object { }, Object { "C": "1", - "V": "13", + "V": "20", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "mine.\\"", + "excerpt": "means␣'pleasant.…", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 430, + "lineNumber": 623, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "her,␣\\"Look!", + "excerpt": "means 'pleasant…", "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 456, + "lineNumber": 623, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "excerpt": "her, \\"Look!", + "characterIndex": 52, + "excerpt": "…*\\\\zaln-e\\\\* '\\\\zaln-s …", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 456, + "lineNumber": 623, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", + "message": "Unexpected ' character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", @@ -1195,118 +1048,117 @@ Object { }, Object { "C": "1", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "characterIndex": 51, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "means␣'bitter.'", "extra": "ST", - "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 456, + "lineNumber": 630, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "her!\\"", + "excerpt": "means 'bitter.'", "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 472, + "lineNumber": 630, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "16", + "V": "20", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "replied,␣\\"No!", + "characterIndex": 52, + "excerpt": "…*\\\\zaln-e\\\\* '\\\\zaln-s …", "extra": "ST", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 477, + "lineNumber": 630, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "1", - "V": "16", + "V": "21", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"No!", + "details": "line marker='\\\\zaln-s'", + "excerpt": "badly.\\"", "extra": "ST", - "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 477, + "lineNumber": 670, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "16", + "C": "2", + "V": "1", "bookID": "RUT", "branch": "master", - "characterIndex": 176, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "Naomi's", "extra": "ST", - "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 477, + "lineNumber": 717, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "17", + "C": "2", + "V": "1", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "die.\\"", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Elimelek's", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 546, + "lineNumber": 729, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "19", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "…xclaimed,␣\\"It", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Naomi,␣\\"Let", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 601, + "lineNumber": 741, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1315,15 +1167,15 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "19", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", - "excerpt": "exclaimed, \\"It", + "excerpt": "Naomi, \\"Let", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 601, + "lineNumber": 741, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1332,16 +1184,16 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "19", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", - "characterIndex": 57, + "characterIndex": 165, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 601, + "lineNumber": 741, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1350,15 +1202,15 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "19", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Naomi!\\"", + "details": "line marker='\\\\w'", + "excerpt": "…ermission.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 609, + "lineNumber": 766, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1367,15 +1219,15 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "them,␣\\"You", + "excerpt": "replied,␣\\"Go", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 613, + "lineNumber": 768, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1384,15 +1236,15 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", - "excerpt": "them, \\"You", + "excerpt": "replied, \\"Go", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 613, + "lineNumber": 768, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1401,16 +1253,16 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", - "characterIndex": 52, + "characterIndex": 64, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 613, + "lineNumber": 768, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1419,119 +1271,118 @@ Object { "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "2", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "means␣'pleasant.…", + "excerpt": "daughter.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 623, + "lineNumber": 771, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "3", "bookID": "RUT", "branch": "master", - "excerpt": "means 'pleasant…", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Elimelek's", "extra": "ST", - "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 623, + "lineNumber": 802, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", - "priority": 191, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "4", "bookID": "RUT", "branch": "master", - "characterIndex": 52, - "excerpt": "…*\\\\zaln-e\\\\* '\\\\zaln-s …", + "details": "line marker='\\\\zaln-s'", + "excerpt": "saying,␣\\"May", "extra": "ST", - "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 623, + "lineNumber": 814, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "4", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "means␣'bitter.'", + "excerpt": "saying, \\"May", "extra": "ST", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 630, + "lineNumber": 814, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "4", "bookID": "RUT", "branch": "master", - "excerpt": "means 'bitter.'", + "characterIndex": 175, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 630, + "lineNumber": 814, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", + "message": "Unexpected \\" character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "20", + "C": "2", + "V": "4", "bookID": "RUT", "branch": "master", - "characterIndex": 52, - "excerpt": "…*\\\\zaln-e\\\\* '\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "you!\\"", "extra": "ST", - "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 630, + "lineNumber": 818, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "1", - "V": "21", + "C": "2", + "V": "4", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "badly.\\"", + "details": "line marker='\\\\w'", + "excerpt": "replied,␣\\"May", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 670, + "lineNumber": 820, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1541,48 +1392,49 @@ Object { }, Object { "C": "2", - "V": "1", + "V": "4", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "Naomi's", + "excerpt": "replied, \\"May", "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 717, + "lineNumber": 820, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "1", + "V": "4", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Elimelek's", + "characterIndex": 55, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 729, + "lineNumber": 820, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "2", + "V": "4", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "Naomi,␣\\"Let", + "excerpt": "you!\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 741, + "lineNumber": 823, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1592,14 +1444,31 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "5", "bookID": "RUT", "branch": "master", - "excerpt": "Naomi, \\"Let", + "details": "line marker='\\\\w'", + "excerpt": "foreman,␣\\"Who", "extra": "ST", - "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 741, + "lineNumber": 834, + "location": " in en RUT book package from unfoldingWord master branch", + "message": "Unexpected \\" straight quote character", + "priority": 776, + "repoCode": "ST", + "repoName": "en_ust", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "RUT", + "branch": "master", + "excerpt": "foreman, \\"Who", + "extra": "ST", + "fieldName": "from \\\\w", + "filename": "08-RUT.usfm", + "lineNumber": 834, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1609,15 +1478,15 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "5", "bookID": "RUT", "branch": "master", - "characterIndex": 165, + "characterIndex": 82, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\zaln-s", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 741, + "lineNumber": 834, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1627,14 +1496,14 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "5", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "…ermission.\\"", + "excerpt": "to?\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 766, + "lineNumber": 840, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1644,14 +1513,14 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "6", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"Go", + "excerpt": "replied,␣\\"She", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 768, + "lineNumber": 843, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1661,14 +1530,14 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "6", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"Go", + "excerpt": "replied, \\"She", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 768, + "lineNumber": 843, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1678,15 +1547,15 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "6", "bookID": "RUT", "branch": "master", - "characterIndex": 64, + "characterIndex": 100, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 768, + "lineNumber": 843, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1696,31 +1565,14 @@ Object { }, Object { "C": "2", - "V": "2", + "V": "7", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "daughter.\\"", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 771, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "2", - "V": "3", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Elimelek's", + "excerpt": "me,␣'Please", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 802, + "lineNumber": 859, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected ' straight quote character", "priority": 775, @@ -1730,33 +1582,34 @@ Object { }, Object { "C": "2", - "V": "4", + "V": "7", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "saying,␣\\"May", + "excerpt": "me, 'Please", "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 814, + "lineNumber": 859, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "4", + "V": "7", "bookID": "RUT", "branch": "master", - "excerpt": "saying, \\"May", + "characterIndex": 50, + "excerpt": "…\\\\zaln-e\\\\*, '\\\\zaln-s …", "extra": "ST", - "fieldName": "from \\\\zaln-s", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 814, + "lineNumber": 859, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", + "message": "Unexpected ' character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", @@ -1764,32 +1617,31 @@ Object { }, Object { "C": "2", - "V": "4", + "V": "7", "bookID": "RUT", "branch": "master", - "characterIndex": 175, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "behind.'", "extra": "ST", - "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 814, + "lineNumber": 873, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "4", + "V": "7", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "you!\\"", + "excerpt": "shelter.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 818, + "lineNumber": 893, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1799,14 +1651,14 @@ Object { }, Object { "C": "2", - "V": "4", + "V": "8", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"May", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Ruth,␣\\"Young", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 820, + "lineNumber": 898, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1816,14 +1668,14 @@ Object { }, Object { "C": "2", - "V": "4", + "V": "8", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"May", + "excerpt": "Ruth, \\"Young", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 820, + "lineNumber": 898, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1833,15 +1685,15 @@ Object { }, Object { "C": "2", - "V": "4", + "V": "8", "bookID": "RUT", "branch": "master", - "characterIndex": 55, + "characterIndex": 158, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 820, + "lineNumber": 898, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1851,14 +1703,14 @@ Object { }, Object { "C": "2", - "V": "4", + "V": "9", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "you!\\"", + "details": "line marker='\\\\w'", + "excerpt": "filled.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 823, + "lineNumber": 972, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1868,14 +1720,14 @@ Object { }, Object { "C": "2", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "foreman,␣\\"Who", + "excerpt": "…xclaimed,␣\\"Why", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 834, + "lineNumber": 988, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1885,14 +1737,14 @@ Object { }, Object { "C": "2", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", - "excerpt": "foreman, \\"Who", + "excerpt": "exclaimed, \\"Why", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 834, + "lineNumber": 988, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1902,15 +1754,15 @@ Object { }, Object { "C": "2", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", - "characterIndex": 82, + "characterIndex": 57, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 834, + "lineNumber": 988, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1920,14 +1772,14 @@ Object { }, Object { "C": "2", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "to?\\"", + "excerpt": "foreigner!\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 840, + "lineNumber": 1011, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1937,14 +1789,14 @@ Object { }, Object { "C": "2", - "V": "6", + "V": "11", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"She", + "excerpt": "replied,␣\\"People", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 843, + "lineNumber": 1013, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -1954,14 +1806,14 @@ Object { }, Object { "C": "2", - "V": "6", + "V": "11", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"She", + "excerpt": "replied, \\"People", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 843, + "lineNumber": 1013, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1971,15 +1823,15 @@ Object { }, Object { "C": "2", - "V": "6", + "V": "11", "bookID": "RUT", "branch": "master", - "characterIndex": 100, + "characterIndex": 82, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 843, + "lineNumber": 1013, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -1989,51 +1841,50 @@ Object { }, Object { "C": "2", - "V": "7", + "V": "12", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "me,␣'Please", + "excerpt": "full.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 859, + "lineNumber": 1086, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "7", + "V": "13", "bookID": "RUT", "branch": "master", - "excerpt": "me, 'Please", + "details": "line marker='\\\\w'", + "excerpt": "replied,␣\\"Sir,", "extra": "ST", - "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 859, + "lineNumber": 1091, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "7", + "V": "13", "bookID": "RUT", "branch": "master", - "characterIndex": 50, - "excerpt": "…\\\\zaln-e\\\\*, '\\\\zaln-s …", + "excerpt": "replied, \\"Sir,", "extra": "ST", - "fieldName": "\\\\w", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 859, + "lineNumber": 1091, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", + "message": "Unexpected \\" character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", @@ -2041,31 +1892,32 @@ Object { }, Object { "C": "2", - "V": "7", + "V": "13", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "behind.'", + "characterIndex": 55, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 873, + "lineNumber": 1091, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "7", + "V": "13", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "shelter.\\"", + "excerpt": "girls!\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 893, + "lineNumber": 1122, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2075,14 +1927,14 @@ Object { }, Object { "C": "2", - "V": "8", + "V": "14", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Ruth,␣\\"Young", + "details": "line marker='\\\\w'", + "excerpt": "her,␣\\"Come", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 898, + "lineNumber": 1135, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2092,14 +1944,14 @@ Object { }, Object { "C": "2", - "V": "8", + "V": "14", "bookID": "RUT", "branch": "master", - "excerpt": "Ruth, \\"Young", + "excerpt": "her, \\"Come", "extra": "ST", - "fieldName": "from \\\\zaln-s", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 898, + "lineNumber": 1135, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2109,15 +1961,15 @@ Object { }, Object { "C": "2", - "V": "8", + "V": "14", "bookID": "RUT", "branch": "master", - "characterIndex": 158, + "characterIndex": 51, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\zaln-s", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 898, + "lineNumber": 1135, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2127,14 +1979,14 @@ Object { }, Object { "C": "2", - "V": "9", + "V": "14", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "filled.\\"", + "excerpt": "it.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 972, + "lineNumber": 1153, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2144,14 +1996,14 @@ Object { }, Object { "C": "2", - "V": "10", + "V": "15", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "…xclaimed,␣\\"Why", + "excerpt": "workers,␣\\"Even", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 988, + "lineNumber": 1193, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2161,14 +2013,14 @@ Object { }, Object { "C": "2", - "V": "10", + "V": "15", "bookID": "RUT", "branch": "master", - "excerpt": "exclaimed, \\"Why", + "excerpt": "workers, \\"Even", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 988, + "lineNumber": 1193, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2178,15 +2030,15 @@ Object { }, Object { "C": "2", - "V": "10", + "V": "15", "bookID": "RUT", "branch": "master", - "characterIndex": 57, + "characterIndex": 64, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 988, + "lineNumber": 1193, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2196,14 +2048,14 @@ Object { }, Object { "C": "2", - "V": "10", + "V": "16", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "foreigner!\\"", + "details": "line marker='\\\\zaln-s'", + "excerpt": "her.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1011, + "lineNumber": 1246, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2213,14 +2065,14 @@ Object { }, Object { "C": "2", - "V": "11", + "V": "19", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"People", + "details": "line marker='\\\\zaln-s'", + "excerpt": "her,␣\\"Where", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1013, + "lineNumber": 1320, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2230,14 +2082,14 @@ Object { }, Object { "C": "2", - "V": "11", + "V": "19", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"People", + "excerpt": "her, \\"Where", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1013, + "lineNumber": 1320, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2247,15 +2099,15 @@ Object { }, Object { "C": "2", - "V": "11", + "V": "19", "bookID": "RUT", "branch": "master", - "characterIndex": 82, + "characterIndex": 155, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1013, + "lineNumber": 1320, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2265,14 +2117,14 @@ Object { }, Object { "C": "2", - "V": "12", + "V": "19", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "full.\\"", + "excerpt": "you.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1086, + "lineNumber": 1347, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2282,14 +2134,14 @@ Object { }, Object { "C": "2", - "V": "13", + "V": "19", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"Sir,", + "excerpt": "said,␣\\"The", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1091, + "lineNumber": 1360, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2299,14 +2151,14 @@ Object { }, Object { "C": "2", - "V": "13", + "V": "19", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"Sir,", + "excerpt": "said, \\"The", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1091, + "lineNumber": 1360, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2316,15 +2168,15 @@ Object { }, Object { "C": "2", - "V": "13", + "V": "19", "bookID": "RUT", "branch": "master", - "characterIndex": 55, + "characterIndex": 52, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1091, + "lineNumber": 1360, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2334,14 +2186,14 @@ Object { }, Object { "C": "2", - "V": "13", + "V": "19", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "girls!\\"", + "excerpt": "Boaz.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1122, + "lineNumber": 1374, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2351,14 +2203,14 @@ Object { }, Object { "C": "2", - "V": "14", + "V": "20", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "her,␣\\"Come", + "excerpt": "…r-in-law,␣\\"May", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1135, + "lineNumber": 1379, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2368,14 +2220,14 @@ Object { }, Object { "C": "2", - "V": "14", + "V": "20", "bookID": "RUT", "branch": "master", - "excerpt": "her, \\"Come", + "excerpt": "…er-in-law, \\"May", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1135, + "lineNumber": 1379, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2385,15 +2237,15 @@ Object { }, Object { "C": "2", - "V": "14", + "V": "20", "bookID": "RUT", "branch": "master", - "characterIndex": 51, + "characterIndex": 145, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1135, + "lineNumber": 1379, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2403,14 +2255,14 @@ Object { }, Object { "C": "2", - "V": "14", + "V": "20", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "it.\\"", + "excerpt": "died.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1153, + "lineNumber": 1401, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2420,14 +2272,14 @@ Object { }, Object { "C": "2", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "workers,␣\\"Even", + "details": "line marker='\\\\zaln-s'", + "excerpt": "added,␣\\"That", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1193, + "lineNumber": 1404, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2437,14 +2289,14 @@ Object { }, Object { "C": "2", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "excerpt": "workers, \\"Even", + "excerpt": "added, \\"That", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1193, + "lineNumber": 1404, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2454,15 +2306,15 @@ Object { }, Object { "C": "2", - "V": "15", + "V": "20", "bookID": "RUT", "branch": "master", - "characterIndex": 64, + "characterIndex": 292, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1193, + "lineNumber": 1404, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2472,14 +2324,14 @@ Object { }, Object { "C": "2", - "V": "16", + "V": "20", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "her.\\"", + "details": "line marker='\\\\w'", + "excerpt": "family.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1246, + "lineNumber": 1425, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2489,14 +2341,14 @@ Object { }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "her,␣\\"Where", + "excerpt": "said,␣\\"He", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1320, + "lineNumber": 1435, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2506,14 +2358,14 @@ Object { }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", - "excerpt": "her, \\"Where", + "excerpt": "said, \\"He", "extra": "ST", "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1320, + "lineNumber": 1435, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2523,15 +2375,15 @@ Object { }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", - "characterIndex": 155, + "characterIndex": 173, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1320, + "lineNumber": 1435, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2541,50 +2393,51 @@ Object { }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "you.\\"", + "details": "line marker='\\\\zaln-s'", + "excerpt": "me,␣'Stay", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1347, + "lineNumber": 1438, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "said,␣\\"The", + "excerpt": "me, 'Stay", "extra": "ST", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1360, + "lineNumber": 1438, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", - "excerpt": "said, \\"The", + "characterIndex": 162, + "excerpt": "…\\\\zaln-e\\\\*, '\\\\zaln-s …", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1360, + "lineNumber": 1438, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", + "message": "Unexpected ' character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", @@ -2592,49 +2445,48 @@ Object { }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", - "characterIndex": 52, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "field.'\\"", "extra": "ST", - "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1360, + "lineNumber": 1453, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "19", + "V": "21", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "Boaz.\\"", + "excerpt": "field.'\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1374, + "lineNumber": 1453, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "20", + "V": "22", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "…r-in-law,␣\\"May", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Ruth,␣\\"My", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1379, + "lineNumber": 1460, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2644,14 +2496,14 @@ Object { }, Object { "C": "2", - "V": "20", + "V": "22", "bookID": "RUT", "branch": "master", - "excerpt": "…er-in-law, \\"May", + "excerpt": "Ruth, \\"My", "extra": "ST", - "fieldName": "from \\\\w", + "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1379, + "lineNumber": 1460, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2661,15 +2513,15 @@ Object { }, Object { "C": "2", - "V": "20", + "V": "22", "bookID": "RUT", "branch": "master", - "characterIndex": 145, + "characterIndex": 158, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\w", + "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1379, + "lineNumber": 1460, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2679,31 +2531,31 @@ Object { }, Object { "C": "2", - "V": "20", + "V": "22", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "died.\\"", + "excerpt": "else's", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1401, + "lineNumber": 1483, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { "C": "2", - "V": "20", + "V": "22", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "added,␣\\"That", + "excerpt": "you.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1404, + "lineNumber": 1488, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2713,170 +2565,169 @@ Object { }, Object { "C": "2", - "V": "20", + "V": "23", "bookID": "RUT", "branch": "master", - "excerpt": "added, \\"That", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Boaz's", "extra": "ST", - "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1404, + "lineNumber": 1497, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "20", + "C": "3", + "V": "1", "bookID": "RUT", "branch": "master", - "characterIndex": 292, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "Ruth,␣\\"My", "extra": "ST", - "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1404, + "lineNumber": 1537, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "20", + "C": "3", + "V": "1", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "family.\\"", + "excerpt": "Ruth, \\"My", "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1425, + "lineNumber": 1537, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "1", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "said,␣\\"He", + "characterIndex": 52, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1435, + "lineNumber": 1537, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "2", "bookID": "RUT", "branch": "master", - "excerpt": "said, \\"He", + "details": "line marker='\\\\zaln-s'", + "excerpt": "Boaz's", "extra": "ST", - "fieldName": "from \\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1435, + "lineNumber": 1560, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected ' straight quote character", + "priority": 775, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "4", "bookID": "RUT", "branch": "master", - "characterIndex": 173, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", + "details": "line marker='\\\\w'", + "excerpt": "do.\\"", "extra": "ST", - "fieldName": "\\\\zaln-s", "filename": "08-RUT.usfm", - "lineNumber": 1435, + "lineNumber": 1675, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "5", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "me,␣'Stay", + "details": "line marker='\\\\w'", + "excerpt": "replied,␣\\"I", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1438, + "lineNumber": 1678, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "5", "bookID": "RUT", "branch": "master", - "excerpt": "me, 'Stay", + "excerpt": "replied, \\"I", "extra": "ST", - "fieldName": "from \\\\zaln-s", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1438, + "lineNumber": 1678, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", + "message": "Unexpected \\" character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "5", "bookID": "RUT", "branch": "master", - "characterIndex": 162, - "excerpt": "…\\\\zaln-e\\\\*, '\\\\zaln-s …", + "characterIndex": 64, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "\\\\zaln-s", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1438, + "lineNumber": 1678, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' character after space", + "message": "Unexpected \\" character after space", "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "5", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "field.'\\"", + "excerpt": "do.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1453, + "lineNumber": 1688, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2885,49 +2736,50 @@ Object { "username": "unfoldingWord", }, Object { - "C": "2", - "V": "21", + "C": "3", + "V": "9", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "field.'\\"", + "excerpt": "her,␣\\"Who", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1453, + "lineNumber": 1787, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, + "message": "Unexpected \\" straight quote character", + "priority": 776, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "22", + "C": "3", + "V": "9", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Ruth,␣\\"My", + "excerpt": "her, \\"Who", "extra": "ST", + "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1460, + "lineNumber": 1787, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, + "message": "Unexpected \\" character after space", + "priority": 191, "repoCode": "ST", "repoName": "en_ust", "username": "unfoldingWord", }, Object { - "C": "2", - "V": "22", + "C": "3", + "V": "9", "bookID": "RUT", "branch": "master", - "excerpt": "Ruth, \\"My", + "characterIndex": 51, + "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", - "fieldName": "from \\\\zaln-s", + "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1460, + "lineNumber": 1787, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -2936,50 +2788,15 @@ Object { "username": "unfoldingWord", }, Object { - "C": "2", - "V": "22", - "bookID": "RUT", - "branch": "master", - "characterIndex": 158, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", - "extra": "ST", - "fieldName": "\\\\zaln-s", - "filename": "08-RUT.usfm", - "lineNumber": 1460, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "2", - "V": "22", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "else's", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 1483, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "2", - "V": "22", + "C": "3", + "V": "9", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "you.\\"", + "excerpt": "you?\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1488, + "lineNumber": 1789, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -2987,33 +2804,16 @@ Object { "repoName": "en_ust", "username": "unfoldingWord", }, - Object { - "C": "2", - "V": "23", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Boaz's", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 1497, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, Object { "C": "3", - "V": "1", + "V": "9", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "Ruth,␣\\"My", + "excerpt": "replied,␣\\"I", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1537, + "lineNumber": 1791, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3023,14 +2823,14 @@ Object { }, Object { "C": "3", - "V": "1", + "V": "9", "bookID": "RUT", "branch": "master", - "excerpt": "Ruth, \\"My", + "excerpt": "replied, \\"I", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1537, + "lineNumber": 1791, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3040,15 +2840,15 @@ Object { }, Object { "C": "3", - "V": "1", + "V": "9", "bookID": "RUT", "branch": "master", - "characterIndex": 52, + "characterIndex": 55, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1537, + "lineNumber": 1791, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3058,14 +2858,14 @@ Object { }, Object { "C": "3", - "V": "2", + "V": "9", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "Boaz's", + "details": "line marker='\\\\w'", + "excerpt": "husband's", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1560, + "lineNumber": 1805, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected ' straight quote character", "priority": 775, @@ -3075,14 +2875,14 @@ Object { }, Object { "C": "3", - "V": "4", + "V": "9", "bookID": "RUT", "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "do.\\"", + "details": "line marker='\\\\zaln-s'", + "excerpt": "me.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1675, + "lineNumber": 1813, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3092,14 +2892,14 @@ Object { }, Object { "C": "3", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"I", + "excerpt": "replied,␣\\"May", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1678, + "lineNumber": 1818, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3109,14 +2909,14 @@ Object { }, Object { "C": "3", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"I", + "excerpt": "replied, \\"May", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1678, + "lineNumber": 1818, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3126,15 +2926,15 @@ Object { }, Object { "C": "3", - "V": "5", + "V": "10", "bookID": "RUT", "branch": "master", - "characterIndex": 64, + "characterIndex": 55, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1678, + "lineNumber": 1818, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3144,14 +2944,31 @@ Object { }, Object { "C": "3", - "V": "5", + "V": "12", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "do.\\"", + "excerpt": "Naomi's", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1688, + "lineNumber": 1889, + "location": " in en RUT book package from unfoldingWord master branch", + "message": "Unexpected ' straight quote character", + "priority": 775, + "repoCode": "ST", + "repoName": "en_ust", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "RUT", + "branch": "master", + "details": "line marker='\\\\w'", + "excerpt": "morning.\\"", + "extra": "ST", + "filename": "08-RUT.usfm", + "lineNumber": 1988, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3161,14 +2978,14 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "14", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "her,␣\\"Who", + "excerpt": "added,␣\\"It", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1787, + "lineNumber": 1994, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3178,14 +2995,14 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "14", "bookID": "RUT", "branch": "master", - "excerpt": "her, \\"Who", + "excerpt": "added, \\"It", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1787, + "lineNumber": 1994, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3195,15 +3012,15 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "14", "bookID": "RUT", "branch": "master", - "characterIndex": 51, + "characterIndex": 53, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1787, + "lineNumber": 1994, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3213,14 +3030,14 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "14", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", - "excerpt": "you?\\"", + "excerpt": "here.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1789, + "lineNumber": 2006, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3230,14 +3047,14 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "15", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"I", + "excerpt": "her,␣\\"Bring", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1791, + "lineNumber": 2038, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3247,14 +3064,14 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "15", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"I", + "excerpt": "her, \\"Bring", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1791, + "lineNumber": 2038, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3264,15 +3081,15 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "15", "bookID": "RUT", "branch": "master", - "characterIndex": 55, + "characterIndex": 51, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1791, + "lineNumber": 2038, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3282,31 +3099,14 @@ Object { }, Object { "C": "3", - "V": "9", + "V": "15", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "husband's", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 1805, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "9", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "me.\\"", + "excerpt": "out.\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1813, + "lineNumber": 2046, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3316,14 +3116,14 @@ Object { }, Object { "C": "3", - "V": "10", + "V": "16", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "replied,␣\\"May", + "excerpt": "her,␣\\"Is", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1818, + "lineNumber": 2081, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3333,14 +3133,14 @@ Object { }, Object { "C": "3", - "V": "10", + "V": "16", "bookID": "RUT", "branch": "master", - "excerpt": "replied, \\"May", + "excerpt": "her, \\"Is", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1818, + "lineNumber": 2081, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3350,15 +3150,15 @@ Object { }, Object { "C": "3", - "V": "10", + "V": "16", "bookID": "RUT", "branch": "master", - "characterIndex": 55, + "characterIndex": 51, "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1818, + "lineNumber": 2081, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3368,31 +3168,14 @@ Object { }, Object { "C": "3", - "V": "12", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "Naomi's", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 1889, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected ' straight quote character", - "priority": 775, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "13", + "V": "16", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "morning.\\"", + "excerpt": "daughter?\\"", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1988, + "lineNumber": 2085, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3402,14 +3185,14 @@ Object { }, Object { "C": "3", - "V": "14", + "V": "17", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\w'", - "excerpt": "added,␣\\"It", + "excerpt": "Naomi,␣\\"He", "extra": "ST", "filename": "08-RUT.usfm", - "lineNumber": 1994, + "lineNumber": 2103, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" straight quote character", "priority": 776, @@ -3419,14 +3202,14 @@ Object { }, Object { "C": "3", - "V": "14", + "V": "17", "bookID": "RUT", "branch": "master", - "excerpt": "added, \\"It", + "excerpt": "Naomi, \\"He", "extra": "ST", "fieldName": "from \\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1994, + "lineNumber": 2103, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3436,7 +3219,7 @@ Object { }, Object { "C": "3", - "V": "14", + "V": "17", "bookID": "RUT", "branch": "master", "characterIndex": 53, @@ -3444,7 +3227,7 @@ Object { "extra": "ST", "fieldName": "\\\\w", "filename": "08-RUT.usfm", - "lineNumber": 1994, + "lineNumber": 2103, "location": " in en RUT book package from unfoldingWord master branch", "message": "Unexpected \\" character after space", "priority": 191, @@ -3454,214 +3237,7 @@ Object { }, Object { "C": "3", - "V": "14", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\zaln-s'", - "excerpt": "here.\\"", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 2006, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "15", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "her,␣\\"Bring", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 2038, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "15", - "bookID": "RUT", - "branch": "master", - "excerpt": "her, \\"Bring", - "extra": "ST", - "fieldName": "from \\\\w", - "filename": "08-RUT.usfm", - "lineNumber": 2038, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "15", - "bookID": "RUT", - "branch": "master", - "characterIndex": 51, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", - "extra": "ST", - "fieldName": "\\\\w", - "filename": "08-RUT.usfm", - "lineNumber": 2038, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "15", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "out.\\"", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 2046, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "16", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "her,␣\\"Is", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 2081, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "16", - "bookID": "RUT", - "branch": "master", - "excerpt": "her, \\"Is", - "extra": "ST", - "fieldName": "from \\\\w", - "filename": "08-RUT.usfm", - "lineNumber": 2081, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "16", - "bookID": "RUT", - "branch": "master", - "characterIndex": 51, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", - "extra": "ST", - "fieldName": "\\\\w", - "filename": "08-RUT.usfm", - "lineNumber": 2081, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "16", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "daughter?\\"", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 2085, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "17", - "bookID": "RUT", - "branch": "master", - "details": "line marker='\\\\w'", - "excerpt": "Naomi,␣\\"He", - "extra": "ST", - "filename": "08-RUT.usfm", - "lineNumber": 2103, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" straight quote character", - "priority": 776, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "17", - "bookID": "RUT", - "branch": "master", - "excerpt": "Naomi, \\"He", - "extra": "ST", - "fieldName": "from \\\\w", - "filename": "08-RUT.usfm", - "lineNumber": 2103, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "17", - "bookID": "RUT", - "branch": "master", - "characterIndex": 53, - "excerpt": "…\\\\zaln-e\\\\*, \\"\\\\zaln-s …", - "extra": "ST", - "fieldName": "\\\\w", - "filename": "08-RUT.usfm", - "lineNumber": 2103, - "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected \\" character after space", - "priority": 191, - "repoCode": "ST", - "repoName": "en_ust", - "username": "unfoldingWord", - }, - Object { - "C": "3", - "V": "17", + "V": "17", "bookID": "RUT", "branch": "master", "details": "line marker='\\\\zaln-s'", @@ -4832,13 +4408,32 @@ Object { "repoName": "en_ust", "username": "unfoldingWord", }, + Object { + "C": "1", + "V": "intro", + "bookID": "RUT", + "branch": "master", + "characterIndex": 4, + "excerpt": "Ruth 01 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_08-RUT.tsv", + "lineNumber": 3, + "location": " in en RUT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "irf4", + "username": "unfoldingWord", + }, Object { "C": "1", "V": "4", "bookID": "RUT", "branch": "master", "characterIndex": 20, - "details": "end part of quote = \\"וְ⁠שֵׁ֥ם הַ⁠שֵּׁנִ֖י\\" -- passage ►וַ⁠יִּשְׂא֣וּ לָ⁠הֶ֗ם נָשִׁים֙ מֹֽאֲבִיּ֔וֹת שֵׁ֤ם הָֽ⁠אַחַת֙ עָרְפָּ֔ה וְ⁠שֵׁ֥ם הַ⁠שֵּׁנִ֖ית ר֑וּת וַ⁠יֵּ֥שְׁבוּ שָׁ֖ם כְּ⁠עֶ֥שֶׂר שָׁנִֽים׃◄", + "details": "end part of quote = \\"וְ⁠שֵׁ֥ם הַ⁠שֵּׁנִ֖י\\" -- verse text ►וַ⁠יִּשְׂא֣וּ לָ⁠הֶ֗ם נָשִׁים֙ מֹֽאֲבִיּ֔וֹת שֵׁ֤ם הָֽ⁠אַחַת֙ עָרְפָּ֔ה וְ⁠שֵׁ֥ם הַ⁠שֵּׁנִ֖ית ר֑וּת וַ⁠יֵּ֥שְׁבוּ שָׁ֖ם כְּ⁠עֶ֥שֶׂר שָׁנִֽים׃◄", "excerpt": "…שֵׁ֥ם הַ⁠שֵּׁנִ֖י(ת=D1514/H5ea) occurrence=1", "extra": "TN", "fieldName": "OrigQuote", @@ -4907,6 +4502,25 @@ Object { "rowID": "w7ti", "username": "unfoldingWord", }, + Object { + "C": "2", + "V": "intro", + "bookID": "RUT", + "branch": "master", + "characterIndex": 4, + "excerpt": "Ruth 02 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_08-RUT.tsv", + "lineNumber": 68, + "location": " in en RUT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "ld2v", + "username": "unfoldingWord", + }, Object { "C": "2", "V": "9", @@ -4981,6 +4595,25 @@ Object { "rowID": "gnn5", "username": "unfoldingWord", }, + Object { + "C": "3", + "V": "intro", + "bookID": "RUT", + "branch": "master", + "characterIndex": 4, + "excerpt": "Ruth 03 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_08-RUT.tsv", + "lineNumber": 144, + "location": " in en RUT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "t4y5", + "username": "unfoldingWord", + }, Object { "C": "3", "V": "12", @@ -5005,15 +4638,15 @@ Object { "V": "intro", "bookID": "RUT", "branch": "master", - "characterIndex": 313, - "excerpt": "…t␣in␣him.␣", + "characterIndex": 4, + "excerpt": "Ruth 04 Genera…", "extra": "TN", "fieldName": "OccurrenceNote", "filename": "en_tn_08-RUT.tsv", "lineNumber": 205, "location": " in en RUT book package from unfoldingWord master branch", - "message": "Unexpected trailing space(s)", - "priority": 95, + "message": "Unexpected leading zero", + "priority": 92, "repoCode": "TN", "repoName": "en_tn", "rowID": "pz6m", @@ -5021,10 +4654,29 @@ Object { }, Object { "C": "4", - "V": "7", + "V": "intro", "bookID": "RUT", "branch": "master", - "details": "empty SR field", + "characterIndex": 313, + "excerpt": "…t␣in␣him.␣", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_08-RUT.tsv", + "lineNumber": 205, + "location": " in en RUT book package from unfoldingWord master branch", + "message": "Unexpected trailing space(s)", + "priority": 95, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "pz6m", + "username": "unfoldingWord", + }, + Object { + "C": "4", + "V": "7", + "bookID": "RUT", + "branch": "master", + "details": "empty SR field", "excerpt": "figs-idiom", "extra": "TN", "fieldName": "OccurrenceNote", @@ -5169,123 +4821,8270 @@ Object { }, Object { "C": "3", - "V": "9", - "bookID": "RUT", - "details": "left=0, right=1", - "extra": "TQ", - "filename": "rut/03/09.md", - "location": " in unfoldingWord (master)", - "message": "Mismatched “” characters", - "priority": 162, - "repoCode": "TQ", - "repoName": "en_tq", + "V": "9", + "bookID": "RUT", + "details": "left=0, right=1", + "extra": "TQ", + "filename": "rut/03/09.md", + "location": " in unfoldingWord (master)", + "message": "Mismatched “” characters", + "priority": 162, + "repoCode": "TQ", + "repoName": "en_tq", + "username": "unfoldingWord", + }, + Object { + "C": "4", + "V": "5", + "bookID": "RUT", + "characterIndex": 188, + "excerpt": "…r␣his␣inheritance.\\\\n\\\\n", + "extra": "TQ", + "filename": "rut/04/05.md", + "location": " in unfoldingWord (master)", + "message": "File ends with additional blank line(s)", + "priority": 138, + "repoCode": "TQ", + "repoName": "en_tq", + "username": "unfoldingWord", + }, + Object { + "C": "4", + "V": "12", + "bookID": "RUT", + "characterIndex": 147, + "excerpt": "…re␣a␣son␣to␣Judah.\\\\n\\\\n", + "extra": "TQ", + "filename": "rut/04/12.md", + "location": " in unfoldingWord (master)", + "message": "File ends with additional blank line(s)", + "priority": 138, + "repoCode": "TQ", + "repoName": "en_tq", + "username": "unfoldingWord", + }, + Object { + "C": "4", + "V": "15", + "bookID": "RUT", + "characterIndex": 179, + "excerpt": "…randson␣for␣Naomi.\\\\n\\\\n", + "extra": "TQ", + "filename": "rut/04/15.md", + "location": " in unfoldingWord (master)", + "message": "File ends with additional blank line(s)", + "priority": 138, + "repoCode": "TQ", + "repoName": "en_tq", + "username": "unfoldingWord", + }, + Object { + "C": "4", + "V": "17", + "bookID": "RUT", + "characterIndex": 157, + "excerpt": "…ndfather␣of␣David.\\\\n\\\\n", + "extra": "TQ", + "filename": "rut/04/17.md", + "location": " in unfoldingWord (master)", + "message": "File ends with additional blank line(s)", + "priority": 138, + "repoCode": "TQ", + "repoName": "en_tq", + "username": "unfoldingWord", + }, + Object { + "details": "username=unfoldingWord", + "extra": "SN", + "location": " in SN in en RUT book package from unfoldingWord master branch", + "message": "Repository doesn’t exist", + "priority": 997, + "repoCode": "SN", + "repoName": "en_sn", + "username": "unfoldingWord", + }, + Object { + "details": "username=unfoldingWord", + "extra": "SQ", + "location": " in SQ in en RUT book package from unfoldingWord master branch", + "message": "Repository doesn’t exist", + "priority": 997, + "repoCode": "SQ", + "repoName": "en_sq", + "username": "unfoldingWord", + }, + ], + "successList": Array [ + "Checked UHB file: 08-RUT.usfm", + "Checked LT file: 08-RUT.usfm", + "Checked ST file: 08-RUT.usfm", + "Checked TN file: en_tn_08-RUT.tsv", + "Checked 52 TQ files", + ], +} +`; + +exports[`checkBookPackage() - TIT should fail on missing repo 1`] = ` +Object { + "checkedFilenames": Array [ + "57-TIT.usfm", + "57-TIT.usfm", + "en_tn_57-TIT.tsv", + "tit/01/01.md", + "tit/01/02.md", + "tit/01/03.md", + "tit/01/04.md", + "tit/01/06.md", + "tit/01/07.md", + "tit/01/08.md", + "tit/01/09.md", + "tit/01/11.md", + "tit/01/13.md", + "tit/01/14.md", + "tit/01/15.md", + "tit/01/16.md", + "tit/02/02.md", + "tit/02/03.md", + "tit/02/04.md", + "tit/02/07.md", + "tit/02/08.md", + "tit/02/09.md", + "tit/02/10.md", + "tit/02/11.md", + "tit/02/12.md", + "tit/02/13.md", + "tit/02/14.md", + "tit/03/01.md", + "tit/03/03.md", + "tit/03/05.md", + "tit/03/07.md", + "tit/03/08.md", + "tit/03/09.md", + "tit/03/10.md", + "tit/03/14.md", + ], + "checkedRepoNames": Array [ + "el-x-koine_ugnt", + "en_ust", + "en_tn", + "en_tq", + ], + "noticeList": Array [ + Object { + "details": "username=unfoldingWord", + "extra": "TWL", + "location": " in TWL in en TIT book package from unfoldingWord master branch", + "message": "Repository doesn’t exist", + "priority": 997, + "repoCode": "TWL", + "repoName": "en_twl", + "username": "unfoldingWord", + }, + Object { + "bookID": "TIT", + "details": "username=unfoldingWord error=Simulated error - Could not find src/__tests__/fixtures/unfoldingWord/en_ult/57-TIT.usfm", + "extra": "LT", + "filename": "57-TIT.usfm", + "location": " in LT in en TIT book package from unfoldingWord master branch", + "message": "Unable to load", + "priority": 996, + "repoCode": "LT", + "repoName": "en_ult", + "username": "unfoldingWord", + }, + Object { + "C": "0", + "V": "1", + "bookID": "TIT", + "branch": "master", + "characterIndex": 33, + "excerpt": "…tr Thu Jul 02 2020 1…", + "extra": "ST", + "fieldName": "\\\\id", + "filename": "57-TIT.usfm", + "lineNumber": 1, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "ST", + "repoName": "en_ust", + "username": "unfoldingWord", + }, + Object { + "bookID": "TIT", + "branch": "master", + "characterIndex": 176298, + "excerpt": "…ces=\\"2\\"\\\\w*\\\\zaln-e\\\\*.", + "extra": "ST", + "filename": "57-TIT.usfm", + "location": " in en TIT book package from unfoldingWord master branch", + "message": "File ends without newline character", + "priority": 538, + "repoCode": "ST", + "repoName": "en_ust", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "intro", + "bookID": "TIT", + "branch": "master", + "characterIndex": 5, + "excerpt": "Titus 01 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 3, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "c7me", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "characterIndex": 304, + "excerpt": "…se. (See: \\\\[\\\\[rc://e…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 41, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected '\\\\[\\\\[' character combination", + "priority": 849, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "abcj", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "characterIndex": 359, + "excerpt": "…logic-goal\\\\]\\\\])", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 41, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected '\\\\]\\\\]' character combination", + "priority": 849, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "abcj", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "empty SR field", + "excerpt": "figs-metaphor", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 44, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Should have a SupportReference when OccurrenceNote has a TA link", + "priority": 789, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "w9kk", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "intro", + "bookID": "TIT", + "branch": "master", + "characterIndex": 5, + "excerpt": "Titus 02 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 71, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "h3il", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "SR='figs-activepassive'—found 2 TA links", + "excerpt": "[\\"figs-activepassive\\",\\"figs-metonymy\\"]", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 91, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Shouldn’t have multiple TA links in OccurrenceNote", + "priority": 786, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "t5v6", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "intro", + "bookID": "TIT", + "branch": "master", + "characterIndex": 5, + "excerpt": "Titus 03 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 133, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "zh6x", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "excerpt": "figs-inclusive", + "extra": "TN", + "fieldName": "SupportReference", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 189, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Link to TA should also be in OccurrenceNote", + "priority": 787, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "xy33", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "15", + "bookID": "TIT", + "branch": "master", + "excerpt": "figs-inclusive", + "extra": "TN", + "fieldName": "SupportReference", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 197, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Link to TA should also be in OccurrenceNote", + "priority": 787, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "xy35", + "username": "unfoldingWord", + }, + Object { + "details": "username=unfoldingWord", + "extra": "SN", + "location": " in SN in en TIT book package from unfoldingWord master branch", + "message": "Repository doesn’t exist", + "priority": 997, + "repoCode": "SN", + "repoName": "en_sn", + "username": "unfoldingWord", + }, + Object { + "details": "username=unfoldingWord", + "extra": "SQ", + "location": " in SQ in en TIT book package from unfoldingWord master branch", + "message": "Repository doesn’t exist", + "priority": 997, + "repoCode": "SQ", + "repoName": "en_sq", + "username": "unfoldingWord", + }, + ], + "successList": Array [ + "Checked UGNT file: 57-TIT.usfm", + "Checked ST file: 57-TIT.usfm", + "Checked TN file: en_tn_57-TIT.tsv", + "Checked 32 TQ files", + ], +} +`; + +exports[`checkBookPackage() - TIT should fail on unsupported language 1`] = ` +Object { + "checkedFilenames": Array [ + "57-TIT.usfm", + ], + "checkedRepoNames": Array [ + "el-x-koine_ugnt", + ], + "noticeList": Array [ + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/paul.md", + "excerpt": "rc://*/tw/dict/bible/names/paul", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 13, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/paul.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/names/paul.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/paul.md", + "excerpt": "rc://*/tw/dict/bible/names/paul", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 13, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/paul.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/servant.md", + "excerpt": "rc://*/tw/dict/bible/other/servant", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 14, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/servant.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/servant.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/servant.md", + "excerpt": "rc://*/tw/dict/bible/other/servant", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 14, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/servant.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 15, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 15, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/apostle.md", + "excerpt": "rc://*/tw/dict/bible/kt/apostle", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 16, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/apostle.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/apostle.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/apostle.md", + "excerpt": "rc://*/tw/dict/bible/kt/apostle", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 16, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/apostle.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 18, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/jesus.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 18, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 19, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/christ.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 19, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 21, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faith.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 21, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/elect.md", + "excerpt": "rc://*/tw/dict/bible/kt/elect", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 22, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/elect.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/elect.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/elect.md", + "excerpt": "rc://*/tw/dict/bible/kt/elect", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 22, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/elect.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 23, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 23, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/know.md", + "excerpt": "rc://*/tw/dict/bible/other/know", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 25, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/know.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/know.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/know.md", + "excerpt": "rc://*/tw/dict/bible/other/know", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 25, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/know.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 26, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/true.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 26, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/godly.md", + "excerpt": "rc://*/tw/dict/bible/kt/godly", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 29, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/godly.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/godly.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/godly.md", + "excerpt": "rc://*/tw/dict/bible/kt/godly", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 29, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/godly.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/hope.md", + "excerpt": "rc://*/tw/dict/bible/kt/hope", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 33, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/hope.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/hope.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/hope.md", + "excerpt": "rc://*/tw/dict/bible/kt/hope", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 33, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/hope.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 34, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/life.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 34, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/eternity.md", + "excerpt": "rc://*/tw/dict/bible/kt/eternity", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 35, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/eternity.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/eternity.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/eternity.md", + "excerpt": "rc://*/tw/dict/bible/kt/eternity", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 35, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/eternity.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/promise.md", + "excerpt": "rc://*/tw/dict/bible/kt/promise", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 37, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/promise.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/promise.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/promise.md", + "excerpt": "rc://*/tw/dict/bible/kt/promise", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 37, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/promise.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 40, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 40, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/time.md", + "excerpt": "rc://*/tw/dict/bible/other/time", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 42, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/time.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/time.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/time.md", + "excerpt": "rc://*/tw/dict/bible/other/time", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 42, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/time.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/reveal.md", + "excerpt": "rc://*/tw/dict/bible/kt/reveal", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 46, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/reveal.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/reveal.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/reveal.md", + "excerpt": "rc://*/tw/dict/bible/kt/reveal", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 46, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/reveal.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/time.md", + "excerpt": "rc://*/tw/dict/bible/other/time", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 48, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/time.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/time.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/time.md", + "excerpt": "rc://*/tw/dict/bible/other/time", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 48, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/time.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/wordofgod.md", + "excerpt": "rc://*/tw/dict/bible/kt/wordofgod", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 51, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/wordofgod.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/wordofgod.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/wordofgod.md", + "excerpt": "rc://*/tw/dict/bible/kt/wordofgod", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 51, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/wordofgod.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/preach.md", + "excerpt": "rc://*/tw/dict/bible/other/preach", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 54, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/preach.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/preach.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/preach.md", + "excerpt": "rc://*/tw/dict/bible/other/preach", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 54, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/preach.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/trust.md", + "excerpt": "rc://*/tw/dict/bible/kt/trust", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 56, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/trust.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/trust.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/trust.md", + "excerpt": "rc://*/tw/dict/bible/kt/trust", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 56, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/trust.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/command.md", + "excerpt": "rc://*/tw/dict/bible/kt/command", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 59, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/command.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/command.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/command.md", + "excerpt": "rc://*/tw/dict/bible/kt/command", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 59, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/command.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 61, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/savior.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 61, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 63, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 63, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/titus.md", + "excerpt": "rc://*/tw/dict/bible/names/titus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 66, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/titus.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/names/titus.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/titus.md", + "excerpt": "rc://*/tw/dict/bible/names/titus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 66, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/titus.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 67, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/true.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 67, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/son.md", + "excerpt": "rc://*/tw/dict/bible/kt/son", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 68, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/son.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/son.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/son.md", + "excerpt": "rc://*/tw/dict/bible/kt/son", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 68, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/son.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 71, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faith.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 71, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 72, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/grace.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 72, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/peace.md", + "excerpt": "rc://*/tw/dict/bible/other/peace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 74, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/peace.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/peace.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/peace.md", + "excerpt": "rc://*/tw/dict/bible/other/peace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 74, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/peace.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 80, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/christ.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 80, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 81, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/jesus.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 81, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 83, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/savior.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 83, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/crete.md", + "excerpt": "rc://*/tw/dict/bible/names/crete", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 93, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/crete.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/names/crete.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/crete.md", + "excerpt": "rc://*/tw/dict/bible/names/crete", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 93, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/crete.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/ordain.md", + "excerpt": "rc://*/tw/dict/bible/other/ordain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 99, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/ordain.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/ordain.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/ordain.md", + "excerpt": "rc://*/tw/dict/bible/other/ordain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 99, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/ordain.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/elder.md", + "excerpt": "rc://*/tw/dict/bible/other/elder", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 102, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/elder.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/elder.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/elder.md", + "excerpt": "rc://*/tw/dict/bible/other/elder", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 102, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/elder.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/blameless.md", + "excerpt": "rc://*/tw/dict/bible/kt/blameless", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 112, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/blameless.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/blameless.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/blameless.md", + "excerpt": "rc://*/tw/dict/bible/kt/blameless", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 112, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/blameless.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/children.md", + "excerpt": "rc://*/tw/dict/bible/kt/children", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 116, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/children.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/children.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/children.md", + "excerpt": "rc://*/tw/dict/bible/kt/children", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 116, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/children.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faithful.md", + "excerpt": "rc://*/tw/dict/bible/kt/faithful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 118, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faithful.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faithful.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faithful.md", + "excerpt": "rc://*/tw/dict/bible/kt/faithful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 118, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faithful.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/accuse.md", + "excerpt": "rc://*/tw/dict/bible/other/accuse", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 121, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/accuse.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/accuse.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/accuse.md", + "excerpt": "rc://*/tw/dict/bible/other/accuse", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 121, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/accuse.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebel.md", + "excerpt": "rc://*/tw/dict/bible/other/rebel", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 124, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebel.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/rebel.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebel.md", + "excerpt": "rc://*/tw/dict/bible/other/rebel", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 124, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebel.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/overseer.md", + "excerpt": "rc://*/tw/dict/bible/other/overseer", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 130, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/overseer.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/overseer.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/overseer.md", + "excerpt": "rc://*/tw/dict/bible/other/overseer", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 130, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/overseer.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/blameless.md", + "excerpt": "rc://*/tw/dict/bible/kt/blameless", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 131, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/blameless.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/blameless.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/blameless.md", + "excerpt": "rc://*/tw/dict/bible/kt/blameless", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 131, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/blameless.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/like.md", + "excerpt": "rc://*/tw/dict/bible/other/like", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 133, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/like.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/like.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/like.md", + "excerpt": "rc://*/tw/dict/bible/other/like", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 133, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/like.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 134, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 134, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/manager.md", + "excerpt": "rc://*/tw/dict/bible/other/manager", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 135, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/manager.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/manager.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/manager.md", + "excerpt": "rc://*/tw/dict/bible/other/manager", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 135, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/manager.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/wine.md", + "excerpt": "rc://*/tw/dict/bible/other/wine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 141, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/wine.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/wine.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/wine.md", + "excerpt": "rc://*/tw/dict/bible/other/wine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 141, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/wine.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 150, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 150, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/righteous.md", + "excerpt": "rc://*/tw/dict/bible/kt/righteous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 152, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/righteous.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/righteous.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/righteous.md", + "excerpt": "rc://*/tw/dict/bible/kt/righteous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 152, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/righteous.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/holy.md", + "excerpt": "rc://*/tw/dict/bible/kt/holy", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 153, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/holy.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/holy.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/holy.md", + "excerpt": "rc://*/tw/dict/bible/kt/holy", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 153, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/holy.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/selfcontrol.md", + "excerpt": "rc://*/tw/dict/bible/other/selfcontrol", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 154, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/selfcontrol.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/selfcontrol.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/selfcontrol.md", + "excerpt": "rc://*/tw/dict/bible/other/selfcontrol", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 154, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/selfcontrol.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/teach.md", + "excerpt": "rc://*/tw/dict/bible/other/teach", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 161, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/teach.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/teach.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/teach.md", + "excerpt": "rc://*/tw/dict/bible/other/teach", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 161, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/teach.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faithful.md", + "excerpt": "rc://*/tw/dict/bible/kt/faithful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 162, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faithful.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faithful.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faithful.md", + "excerpt": "rc://*/tw/dict/bible/kt/faithful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 162, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faithful.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/power.md", + "excerpt": "rc://*/tw/dict/bible/kt/power", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 165, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/power.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/power.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/power.md", + "excerpt": "rc://*/tw/dict/bible/kt/power", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 165, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/power.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/courage.md", + "excerpt": "rc://*/tw/dict/bible/other/courage", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 168, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/courage.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/courage.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/courage.md", + "excerpt": "rc://*/tw/dict/bible/other/courage", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 168, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/courage.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 171, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/doctrine.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 171, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebuke.md", + "excerpt": "rc://*/tw/dict/bible/other/rebuke", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 177, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebuke.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/rebuke.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebuke.md", + "excerpt": "rc://*/tw/dict/bible/other/rebuke", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 177, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebuke.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebel.md", + "excerpt": "rc://*/tw/dict/bible/other/rebel", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 185, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebel.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/rebel.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebel.md", + "excerpt": "rc://*/tw/dict/bible/other/rebel", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 185, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebel.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/vain.md", + "excerpt": "rc://*/tw/dict/bible/other/vain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 186, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/vain.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/vain.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/vain.md", + "excerpt": "rc://*/tw/dict/bible/other/vain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 186, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/vain.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/deceive.md", + "excerpt": "rc://*/tw/dict/bible/other/deceive", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 188, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/deceive.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/deceive.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/deceive.md", + "excerpt": "rc://*/tw/dict/bible/other/deceive", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 188, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/deceive.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/circumcise.md", + "excerpt": "rc://*/tw/dict/bible/kt/circumcise", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 193, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/circumcise.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/circumcise.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/circumcise.md", + "excerpt": "rc://*/tw/dict/bible/kt/circumcise", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 193, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/circumcise.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/household.md", + "excerpt": "rc://*/tw/dict/bible/other/household", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 201, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/household.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/household.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/household.md", + "excerpt": "rc://*/tw/dict/bible/other/household", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 201, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/household.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/teach.md", + "excerpt": "rc://*/tw/dict/bible/other/teach", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 203, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/teach.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/teach.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/teach.md", + "excerpt": "rc://*/tw/dict/bible/other/teach", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 203, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/teach.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/shame.md", + "excerpt": "rc://*/tw/dict/bible/other/shame", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 207, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/shame.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/shame.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/shame.md", + "excerpt": "rc://*/tw/dict/bible/other/shame", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 207, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/shame.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/profit.md", + "excerpt": "rc://*/tw/dict/bible/other/profit", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 208, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/profit.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/profit.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/profit.md", + "excerpt": "rc://*/tw/dict/bible/other/profit", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 208, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/profit.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/prophet.md", + "excerpt": "rc://*/tw/dict/bible/kt/prophet", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 218, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/prophet.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/prophet.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/prophet.md", + "excerpt": "rc://*/tw/dict/bible/kt/prophet", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 218, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/prophet.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/crete.md", + "excerpt": "rc://*/tw/dict/bible/names/crete", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 219, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/crete.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/names/crete.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/crete.md", + "excerpt": "rc://*/tw/dict/bible/names/crete", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 219, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/crete.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/evil.md", + "excerpt": "rc://*/tw/dict/bible/kt/evil", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 222, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/evil.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/evil.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/evil.md", + "excerpt": "rc://*/tw/dict/bible/kt/evil", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 222, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/evil.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/beast.md", + "excerpt": "rc://*/tw/dict/bible/other/beast", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 223, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/beast.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/beast.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/beast.md", + "excerpt": "rc://*/tw/dict/bible/other/beast", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 223, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/beast.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/testimony.md", + "excerpt": "rc://*/tw/dict/bible/kt/testimony", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 229, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/testimony.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/testimony.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/testimony.md", + "excerpt": "rc://*/tw/dict/bible/kt/testimony", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 229, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/testimony.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 232, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/true.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 232, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebuke.md", + "excerpt": "rc://*/tw/dict/bible/other/rebuke", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 236, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebuke.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/rebuke.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebuke.md", + "excerpt": "rc://*/tw/dict/bible/other/rebuke", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 236, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebuke.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 243, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faith.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 243, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jew.md", + "excerpt": "rc://*/tw/dict/bible/kt/jew", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 248, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jew.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/jew.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jew.md", + "excerpt": "rc://*/tw/dict/bible/kt/jew", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 248, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jew.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/command.md", + "excerpt": "rc://*/tw/dict/bible/kt/command", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 251, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/command.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/command.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/command.md", + "excerpt": "rc://*/tw/dict/bible/kt/command", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 251, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/command.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/turn.md", + "excerpt": "rc://*/tw/dict/bible/other/turn", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 253, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/turn.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/turn.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/turn.md", + "excerpt": "rc://*/tw/dict/bible/other/turn", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 253, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/turn.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 255, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/true.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/true.md", + "excerpt": "rc://*/tw/dict/bible/kt/true", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 255, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/true.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 259, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/purify.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 259, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 261, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/purify.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 261, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/corrupt.md", + "excerpt": "rc://*/tw/dict/bible/other/corrupt", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 264, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/corrupt.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/corrupt.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/corrupt.md", + "excerpt": "rc://*/tw/dict/bible/other/corrupt", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 264, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/corrupt.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/believe.md", + "excerpt": "rc://*/tw/dict/bible/kt/believe", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 266, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/believe.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/believe.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/believe.md", + "excerpt": "rc://*/tw/dict/bible/kt/believe", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 266, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/believe.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 268, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/purify.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 268, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/corrupt.md", + "excerpt": "rc://*/tw/dict/bible/other/corrupt", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 270, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/corrupt.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/corrupt.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/corrupt.md", + "excerpt": "rc://*/tw/dict/bible/other/corrupt", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 270, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/corrupt.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/mind.md", + "excerpt": "rc://*/tw/dict/bible/other/mind", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 274, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/mind.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/mind.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/mind.md", + "excerpt": "rc://*/tw/dict/bible/other/mind", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 274, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/mind.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/conscience.md", + "excerpt": "rc://*/tw/dict/bible/kt/conscience", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 277, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/conscience.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/conscience.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/conscience.md", + "excerpt": "rc://*/tw/dict/bible/kt/conscience", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 277, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/conscience.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 280, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 280, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/know.md", + "excerpt": "rc://*/tw/dict/bible/other/know", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 282, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/know.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/know.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/know.md", + "excerpt": "rc://*/tw/dict/bible/other/know", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 282, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/know.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 285, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 285, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/detestable.md", + "excerpt": "rc://*/tw/dict/bible/other/detestable", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 287, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/detestable.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/detestable.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/detestable.md", + "excerpt": "rc://*/tw/dict/bible/other/detestable", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 287, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/detestable.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/disobey.md", + "excerpt": "rc://*/tw/dict/bible/other/disobey", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 290, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/disobey.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/disobey.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/disobey.md", + "excerpt": "rc://*/tw/dict/bible/other/disobey", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 290, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/disobey.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 294, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 294, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 295, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "1", + "V": "16", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 295, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 308, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/doctrine.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 308, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/elder.md", + "excerpt": "rc://*/tw/dict/bible/other/elder", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 311, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/elder.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/elder.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/elder.md", + "excerpt": "rc://*/tw/dict/bible/other/elder", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 311, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/elder.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 318, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faith.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 318, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 320, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/love.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 320, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/perseverance.md", + "excerpt": "rc://*/tw/dict/bible/other/perseverance", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 322, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/perseverance.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/perseverance.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/perseverance.md", + "excerpt": "rc://*/tw/dict/bible/other/perseverance", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 322, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/perseverance.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/like.md", + "excerpt": "rc://*/tw/dict/bible/other/like", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 327, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/like.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/like.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/like.md", + "excerpt": "rc://*/tw/dict/bible/other/like", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 327, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/like.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/reverence.md", + "excerpt": "rc://*/tw/dict/bible/other/reverence", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 330, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/reverence.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/reverence.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/reverence.md", + "excerpt": "rc://*/tw/dict/bible/other/reverence", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 330, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/reverence.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/slander.md", + "excerpt": "rc://*/tw/dict/bible/other/slander", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 332, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/slander.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/slander.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/slander.md", + "excerpt": "rc://*/tw/dict/bible/other/slander", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 332, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/slander.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/wine.md", + "excerpt": "rc://*/tw/dict/bible/other/wine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 334, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/wine.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/wine.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/wine.md", + "excerpt": "rc://*/tw/dict/bible/other/wine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 334, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/wine.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/enslave.md", + "excerpt": "rc://*/tw/dict/bible/other/enslave", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 336, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/enslave.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/enslave.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/enslave.md", + "excerpt": "rc://*/tw/dict/bible/other/enslave", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 336, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/enslave.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 344, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/love.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 344, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 346, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/love.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 346, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/selfcontrol.md", + "excerpt": "rc://*/tw/dict/bible/other/selfcontrol", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 349, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/selfcontrol.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/selfcontrol.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/selfcontrol.md", + "excerpt": "rc://*/tw/dict/bible/other/selfcontrol", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 349, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/selfcontrol.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 350, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/purify.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 350, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 352, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 352, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/subject.md", + "excerpt": "rc://*/tw/dict/bible/other/subject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 353, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/subject.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/subject.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/subject.md", + "excerpt": "rc://*/tw/dict/bible/other/subject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 353, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/subject.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/slander.md", + "excerpt": "rc://*/tw/dict/bible/other/slander", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 364, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/slander.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/slander.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/slander.md", + "excerpt": "rc://*/tw/dict/bible/other/slander", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 364, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/slander.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/like.md", + "excerpt": "rc://*/tw/dict/bible/other/like", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 370, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/like.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/like.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/like.md", + "excerpt": "rc://*/tw/dict/bible/other/like", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 370, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/like.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/exhort.md", + "excerpt": "rc://*/tw/dict/bible/kt/exhort", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 371, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/exhort.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/exhort.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/exhort.md", + "excerpt": "rc://*/tw/dict/bible/kt/exhort", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 371, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/exhort.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/selfcontrol.md", + "excerpt": "rc://*/tw/dict/bible/other/selfcontrol", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 372, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/selfcontrol.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/selfcontrol.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/selfcontrol.md", + "excerpt": "rc://*/tw/dict/bible/other/selfcontrol", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 372, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/selfcontrol.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 380, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 380, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 381, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 381, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 384, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/doctrine.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 384, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/shame.md", + "excerpt": "rc://*/tw/dict/bible/other/shame", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 396, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/shame.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/shame.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/shame.md", + "excerpt": "rc://*/tw/dict/bible/other/shame", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 396, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/shame.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/evil.md", + "excerpt": "rc://*/tw/dict/bible/kt/evil", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 402, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/evil.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/evil.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/evil.md", + "excerpt": "rc://*/tw/dict/bible/kt/evil", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 402, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/evil.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/servant.md", + "excerpt": "rc://*/tw/dict/bible/other/servant", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 406, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/servant.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/servant.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/servant.md", + "excerpt": "rc://*/tw/dict/bible/other/servant", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 406, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/servant.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/lord.md", + "excerpt": "rc://*/tw/dict/bible/kt/lord", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 408, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/lord.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/lord.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/lord.md", + "excerpt": "rc://*/tw/dict/bible/kt/lord", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 408, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/lord.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/subject.md", + "excerpt": "rc://*/tw/dict/bible/other/subject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 409, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/subject.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/subject.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/subject.md", + "excerpt": "rc://*/tw/dict/bible/other/subject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 409, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/subject.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 422, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faith.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 422, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 424, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 424, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 427, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/doctrine.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/doctrine.md", + "excerpt": "rc://*/tw/dict/bible/other/doctrine", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 427, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/doctrine.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 430, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/savior.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 430, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 432, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 432, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 442, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/grace.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 442, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 444, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 444, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/save.md", + "excerpt": "rc://*/tw/dict/bible/kt/save", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 445, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/save.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/save.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/save.md", + "excerpt": "rc://*/tw/dict/bible/kt/save", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 445, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/save.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/discipline.md", + "excerpt": "rc://*/tw/dict/bible/kt/discipline", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 450, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/discipline.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/discipline.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/discipline.md", + "excerpt": "rc://*/tw/dict/bible/kt/discipline", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 450, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/discipline.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/godly.md", + "excerpt": "rc://*/tw/dict/bible/kt/godly", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 455, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/godly.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/godly.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/godly.md", + "excerpt": "rc://*/tw/dict/bible/kt/godly", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 455, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/godly.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/world.md", + "excerpt": "rc://*/tw/dict/bible/kt/world", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 458, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/world.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/world.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/world.md", + "excerpt": "rc://*/tw/dict/bible/kt/world", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 458, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/world.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/lust.md", + "excerpt": "rc://*/tw/dict/bible/other/lust", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 459, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/lust.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/lust.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/lust.md", + "excerpt": "rc://*/tw/dict/bible/other/lust", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 459, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/lust.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/righteous.md", + "excerpt": "rc://*/tw/dict/bible/kt/righteous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 462, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/righteous.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/righteous.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/righteous.md", + "excerpt": "rc://*/tw/dict/bible/kt/righteous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 462, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/righteous.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/godly.md", + "excerpt": "rc://*/tw/dict/bible/kt/godly", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 464, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/godly.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/godly.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/godly.md", + "excerpt": "rc://*/tw/dict/bible/kt/godly", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 464, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/godly.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 465, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/life.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 465, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/age.md", + "excerpt": "rc://*/tw/dict/bible/other/age", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 469, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/age.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/age.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/age.md", + "excerpt": "rc://*/tw/dict/bible/other/age", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 469, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/age.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/receive.md", + "excerpt": "rc://*/tw/dict/bible/other/receive", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 472, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/receive.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/receive.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/receive.md", + "excerpt": "rc://*/tw/dict/bible/other/receive", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 472, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/receive.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/bless.md", + "excerpt": "rc://*/tw/dict/bible/kt/bless", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 474, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/bless.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/bless.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/bless.md", + "excerpt": "rc://*/tw/dict/bible/kt/bless", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 474, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/bless.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/hope.md", + "excerpt": "rc://*/tw/dict/bible/kt/hope", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 475, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/hope.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/hope.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/hope.md", + "excerpt": "rc://*/tw/dict/bible/kt/hope", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 475, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/hope.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/glory.md", + "excerpt": "rc://*/tw/dict/bible/kt/glory", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 479, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/glory.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/glory.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/glory.md", + "excerpt": "rc://*/tw/dict/bible/kt/glory", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 479, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/glory.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 482, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 482, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 484, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/savior.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 484, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 486, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/jesus.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 486, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 487, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/christ.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 487, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/redeem.md", + "excerpt": "rc://*/tw/dict/bible/kt/redeem", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 496, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/redeem.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/redeem.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/redeem.md", + "excerpt": "rc://*/tw/dict/bible/kt/redeem", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 496, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/redeem.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/lawful.md", + "excerpt": "rc://*/tw/dict/bible/other/lawful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 500, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/lawful.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/lawful.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/lawful.md", + "excerpt": "rc://*/tw/dict/bible/other/lawful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 500, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/lawful.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 502, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/purify.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/purify.md", + "excerpt": "rc://*/tw/dict/bible/kt/purify", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 502, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/purify.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/zealous.md", + "excerpt": "rc://*/tw/dict/bible/kt/zealous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 506, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/zealous.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/zealous.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/zealous.md", + "excerpt": "rc://*/tw/dict/bible/kt/zealous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 506, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/zealous.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 507, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 507, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 508, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 508, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/exhort.md", + "excerpt": "rc://*/tw/dict/bible/kt/exhort", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 515, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/exhort.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/exhort.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/exhort.md", + "excerpt": "rc://*/tw/dict/bible/kt/exhort", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 515, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/exhort.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebuke.md", + "excerpt": "rc://*/tw/dict/bible/other/rebuke", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 517, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebuke.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/rebuke.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/rebuke.md", + "excerpt": "rc://*/tw/dict/bible/other/rebuke", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 517, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/rebuke.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/authority.md", + "excerpt": "rc://*/tw/dict/bible/kt/authority", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 520, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/authority.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/authority.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "2", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/authority.md", + "excerpt": "rc://*/tw/dict/bible/kt/authority", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 520, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/authority.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/ruler.md", + "excerpt": "rc://*/tw/dict/bible/other/ruler", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 530, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/ruler.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/ruler.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/ruler.md", + "excerpt": "rc://*/tw/dict/bible/other/ruler", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 530, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/ruler.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/authority.md", + "excerpt": "rc://*/tw/dict/bible/kt/authority", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 531, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/authority.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/authority.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/authority.md", + "excerpt": "rc://*/tw/dict/bible/kt/authority", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 531, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/authority.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/subject.md", + "excerpt": "rc://*/tw/dict/bible/other/subject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 532, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/subject.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/subject.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/subject.md", + "excerpt": "rc://*/tw/dict/bible/other/subject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 532, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/subject.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/obey.md", + "excerpt": "rc://*/tw/dict/bible/other/obey", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 533, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/obey.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/obey.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/obey.md", + "excerpt": "rc://*/tw/dict/bible/other/obey", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 533, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/obey.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 536, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 536, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 537, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "1", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 537, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/slander.md", + "excerpt": "rc://*/tw/dict/bible/other/slander", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 543, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/slander.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/slander.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/slander.md", + "excerpt": "rc://*/tw/dict/bible/other/slander", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 543, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/slander.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/peace.md", + "excerpt": "rc://*/tw/dict/bible/other/peace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 544, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/peace.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/peace.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/peace.md", + "excerpt": "rc://*/tw/dict/bible/other/peace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 544, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/peace.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/humble.md", + "excerpt": "rc://*/tw/dict/bible/kt/humble", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 549, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/humble.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/humble.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "2", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/humble.md", + "excerpt": "rc://*/tw/dict/bible/kt/humble", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 549, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/humble.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/foolish.md", + "excerpt": "rc://*/tw/dict/bible/kt/foolish", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 560, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/foolish.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/foolish.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/foolish.md", + "excerpt": "rc://*/tw/dict/bible/kt/foolish", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 560, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/foolish.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/disobey.md", + "excerpt": "rc://*/tw/dict/bible/other/disobey", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 561, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/disobey.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/disobey.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/disobey.md", + "excerpt": "rc://*/tw/dict/bible/other/disobey", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 561, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/disobey.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/astray.md", + "excerpt": "rc://*/tw/dict/bible/other/astray", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 562, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/astray.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/astray.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/astray.md", + "excerpt": "rc://*/tw/dict/bible/other/astray", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 562, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/astray.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/enslave.md", + "excerpt": "rc://*/tw/dict/bible/other/enslave", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 563, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/enslave.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/enslave.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/enslave.md", + "excerpt": "rc://*/tw/dict/bible/other/enslave", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 563, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/enslave.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/lust.md", + "excerpt": "rc://*/tw/dict/bible/other/lust", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 564, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/lust.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/lust.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/lust.md", + "excerpt": "rc://*/tw/dict/bible/other/lust", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 564, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/lust.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/evil.md", + "excerpt": "rc://*/tw/dict/bible/kt/evil", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 569, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/evil.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/evil.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/evil.md", + "excerpt": "rc://*/tw/dict/bible/kt/evil", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 569, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/evil.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/envy.md", + "excerpt": "rc://*/tw/dict/bible/other/envy", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 571, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/envy.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/envy.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/envy.md", + "excerpt": "rc://*/tw/dict/bible/other/envy", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 571, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/envy.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 572, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/life.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "3", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 572, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 584, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/love.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 584, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 587, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/savior.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 587, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 589, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "4", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 589, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 594, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 594, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/righteous.md", + "excerpt": "rc://*/tw/dict/bible/kt/righteous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 597, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/righteous.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/righteous.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/righteous.md", + "excerpt": "rc://*/tw/dict/bible/kt/righteous", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 597, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/righteous.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/mercy.md", + "excerpt": "rc://*/tw/dict/bible/kt/mercy", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 605, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/mercy.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/mercy.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/mercy.md", + "excerpt": "rc://*/tw/dict/bible/kt/mercy", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 605, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/mercy.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/save.md", + "excerpt": "rc://*/tw/dict/bible/kt/save", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 606, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/save.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/save.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/save.md", + "excerpt": "rc://*/tw/dict/bible/kt/save", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 606, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/save.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/clean.md", + "excerpt": "rc://*/tw/dict/bible/kt/clean", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 609, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/clean.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/clean.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/clean.md", + "excerpt": "rc://*/tw/dict/bible/kt/clean", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 609, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/clean.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/bornagain.md", + "excerpt": "rc://*/tw/dict/bible/kt/bornagain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 610, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/bornagain.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/bornagain.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "5", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/bornagain.md", + "excerpt": "rc://*/tw/dict/bible/kt/bornagain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 610, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/bornagain.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 624, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/jesus.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/jesus.md", + "excerpt": "rc://*/tw/dict/bible/kt/jesus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 624, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/jesus.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 625, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/christ.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/christ.md", + "excerpt": "rc://*/tw/dict/bible/kt/christ", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 625, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/christ.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 627, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/savior.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "6", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/savior.md", + "excerpt": "rc://*/tw/dict/bible/kt/savior", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 627, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/savior.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/justice.md", + "excerpt": "rc://*/tw/dict/bible/kt/justice", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 632, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/justice.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/justice.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/justice.md", + "excerpt": "rc://*/tw/dict/bible/kt/justice", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 632, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/justice.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 635, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/grace.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 635, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/heir.md", + "excerpt": "rc://*/tw/dict/bible/other/heir", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 636, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/heir.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/heir.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/heir.md", + "excerpt": "rc://*/tw/dict/bible/other/heir", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 636, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/heir.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/hope.md", + "excerpt": "rc://*/tw/dict/bible/kt/hope", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 639, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/hope.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/hope.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/hope.md", + "excerpt": "rc://*/tw/dict/bible/kt/hope", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 639, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/hope.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 640, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/life.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/life.md", + "excerpt": "rc://*/tw/dict/bible/kt/life", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 640, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/life.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/eternity.md", + "excerpt": "rc://*/tw/dict/bible/kt/eternity", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 641, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/eternity.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/eternity.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "7", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/eternity.md", + "excerpt": "rc://*/tw/dict/bible/kt/eternity", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 641, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/eternity.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faithful.md", + "excerpt": "rc://*/tw/dict/bible/kt/faithful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 645, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faithful.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faithful.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faithful.md", + "excerpt": "rc://*/tw/dict/bible/kt/faithful", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 645, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faithful.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 656, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 656, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 657, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 657, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/believe.md", + "excerpt": "rc://*/tw/dict/bible/kt/believe", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 660, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/believe.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/believe.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/believe.md", + "excerpt": "rc://*/tw/dict/bible/kt/believe", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 660, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/believe.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 661, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/god.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/god.md", + "excerpt": "rc://*/tw/dict/bible/kt/god", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 661, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/god.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 664, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 664, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/profit.md", + "excerpt": "rc://*/tw/dict/bible/other/profit", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 666, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/profit.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/profit.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "8", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/profit.md", + "excerpt": "rc://*/tw/dict/bible/other/profit", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 666, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/profit.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/foolish.md", + "excerpt": "rc://*/tw/dict/bible/kt/foolish", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 671, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/foolish.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/foolish.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/foolish.md", + "excerpt": "rc://*/tw/dict/bible/kt/foolish", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 671, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/foolish.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/strife.md", + "excerpt": "rc://*/tw/dict/bible/other/strife", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 677, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/strife.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/strife.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/strife.md", + "excerpt": "rc://*/tw/dict/bible/other/strife", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 677, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/strife.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/strife.md", + "excerpt": "rc://*/tw/dict/bible/other/strife", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 679, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/strife.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/strife.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/strife.md", + "excerpt": "rc://*/tw/dict/bible/other/strife", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 679, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/strife.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/lawofmoses.md", + "excerpt": "rc://*/tw/dict/bible/kt/lawofmoses", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 680, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/lawofmoses.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/lawofmoses.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/lawofmoses.md", + "excerpt": "rc://*/tw/dict/bible/kt/lawofmoses", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 680, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/lawofmoses.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/vain.md", + "excerpt": "rc://*/tw/dict/bible/other/vain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 686, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/vain.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/vain.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "9", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/vain.md", + "excerpt": "rc://*/tw/dict/bible/other/vain", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 686, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/vain.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/admonish.md", + "excerpt": "rc://*/tw/dict/bible/other/admonish", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 695, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/admonish.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/admonish.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/admonish.md", + "excerpt": "rc://*/tw/dict/bible/other/admonish", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 695, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/admonish.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/reject.md", + "excerpt": "rc://*/tw/dict/bible/other/reject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 696, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/reject.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/reject.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "10", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/reject.md", + "excerpt": "rc://*/tw/dict/bible/other/reject", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 696, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/reject.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/know.md", + "excerpt": "rc://*/tw/dict/bible/other/know", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 699, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/know.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/know.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/know.md", + "excerpt": "rc://*/tw/dict/bible/other/know", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 699, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/know.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/perverse.md", + "excerpt": "rc://*/tw/dict/bible/other/perverse", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 701, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/perverse.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/perverse.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/perverse.md", + "excerpt": "rc://*/tw/dict/bible/other/perverse", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 701, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/perverse.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/sin.md", + "excerpt": "rc://*/tw/dict/bible/kt/sin", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 705, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/sin.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/sin.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "11", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/sin.md", + "excerpt": "rc://*/tw/dict/bible/kt/sin", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 705, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/sin.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/send.md", + "excerpt": "rc://*/tw/dict/bible/other/send", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 712, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/send.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/send.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/send.md", + "excerpt": "rc://*/tw/dict/bible/other/send", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 712, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/send.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/tychicus.md", + "excerpt": "rc://*/tw/dict/bible/names/tychicus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 717, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/tychicus.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/names/tychicus.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "12", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/tychicus.md", + "excerpt": "rc://*/tw/dict/bible/names/tychicus", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 717, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/tychicus.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/law.md", + "excerpt": "rc://*/tw/dict/bible/other/law", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 732, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/law.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/law.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/law.md", + "excerpt": "rc://*/tw/dict/bible/other/law", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 732, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/law.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/apollos.md", + "excerpt": "rc://*/tw/dict/bible/names/apollos", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 734, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/apollos.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/names/apollos.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/names/apollos.md", + "excerpt": "rc://*/tw/dict/bible/names/apollos", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 734, + "location": " in zzz TIT book package from unfoldingWord master branch bible/names/apollos.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/send.md", + "excerpt": "rc://*/tw/dict/bible/other/send", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 736, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/send.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/send.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "13", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/send.md", + "excerpt": "rc://*/tw/dict/bible/other/send", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 736, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/send.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 748, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/good.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/good.md", + "excerpt": "rc://*/tw/dict/bible/kt/good", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 748, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/good.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 749, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/works.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/works.md", + "excerpt": "rc://*/tw/dict/bible/kt/works", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 749, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/works.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/fruit.md", + "excerpt": "rc://*/tw/dict/bible/other/fruit", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 758, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/fruit.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/other/fruit.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "5", - "bookID": "RUT", - "characterIndex": 188, - "excerpt": "…r␣his␣inheritance.\\\\n\\\\n", - "extra": "TQ", - "filename": "rut/04/05.md", - "location": " in unfoldingWord (master)", - "message": "File ends with additional blank line(s)", - "priority": 138, - "repoCode": "TQ", - "repoName": "en_tq", + "C": "3", + "V": "14", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/other/fruit.md", + "excerpt": "rc://*/tw/dict/bible/other/fruit", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 758, + "location": " in zzz TIT book package from unfoldingWord master branch bible/other/fruit.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "12", - "bookID": "RUT", - "characterIndex": 147, - "excerpt": "…re␣a␣son␣to␣Judah.\\\\n\\\\n", - "extra": "TQ", - "filename": "rut/04/12.md", - "location": " in unfoldingWord (master)", - "message": "File ends with additional blank line(s)", - "priority": 138, - "repoCode": "TQ", - "repoName": "en_tq", + "C": "3", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 770, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/love.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, Object { - "C": "4", + "C": "3", "V": "15", - "bookID": "RUT", - "characterIndex": 179, - "excerpt": "…randson␣for␣Naomi.\\\\n\\\\n", - "extra": "TQ", - "filename": "rut/04/15.md", - "location": " in unfoldingWord (master)", - "message": "File ends with additional blank line(s)", - "priority": 138, - "repoCode": "TQ", - "repoName": "en_tq", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/love.md", + "excerpt": "rc://*/tw/dict/bible/kt/love", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 770, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/love.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, Object { - "C": "4", - "V": "17", - "bookID": "RUT", - "characterIndex": 157, - "excerpt": "…ndfather␣of␣David.\\\\n\\\\n", - "extra": "TQ", - "filename": "rut/04/17.md", - "location": " in unfoldingWord (master)", - "message": "File ends with additional blank line(s)", - "priority": 138, - "repoCode": "TQ", - "repoName": "en_tq", + "C": "3", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 773, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/faith.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, Object { - "details": "username=unfoldingWord", - "extra": "SN", - "location": " in SN in en RUT book package from unfoldingWord master branch", - "message": "Repository doesn’t exist", - "priority": 997, - "repoCode": "SN", - "repoName": "en_sn", + "C": "3", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/faith.md", + "excerpt": "rc://*/tw/dict/bible/kt/faith", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 773, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/faith.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, Object { - "details": "username=unfoldingWord", - "extra": "SQ", - "location": " in SQ in en RUT book package from unfoldingWord master branch", - "message": "Repository doesn’t exist", - "priority": 997, - "repoCode": "SQ", - "repoName": "en_sq", + "C": "3", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 775, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md: Tests could not find src/__tests__/fixtures/unfoldingWord/zzz_tw/bible/kt/grace.md", + "message": "Error loading TW article", + "priority": 882, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", + "username": "unfoldingWord", + }, + Object { + "C": "3", + "V": "15", + "bookID": "TIT", + "branch": "master", + "details": "unfoldingWord zzz_tw master bible/kt/grace.md", + "excerpt": "rc://*/tw/dict/bible/kt/grace", + "extra": "UGNT", + "fieldName": "w", + "filename": "57-TIT.usfm", + "lineNumber": 775, + "location": " in zzz TIT book package from unfoldingWord master branch bible/kt/grace.md", + "message": "Unable to find/load TW article", + "priority": 883, + "repoCode": "UGNT", + "repoName": "el-x-koine_ugnt", "username": "unfoldingWord", }, - ], - "successList": Array [ - "Checked UHB file: 08-RUT.usfm", - "Checked LT file: 08-RUT.usfm", - "Checked ST file: 08-RUT.usfm", - "Checked TN file: en_tn_08-RUT.tsv", - "Checked 52 TQ files", - ], -} -`; - -exports[`checkBookPackage() - TIT should fail on missing repo 1`] = ` -Object { - "checkedFilenames": Array [ - "57-TIT.usfm", - ], - "checkedRepoNames": Array [ - "el-x-koine_ugnt", - ], - "noticeList": Array [ Object { "details": "username=unfoldingWord", "extra": "LT", "location": " in LT in zzz TIT book package from unfoldingWord master branch", - "message": "Repository doesn't exist", + "message": "Repository doesn’t exist", "priority": 997, "repoCode": "LT", "repoName": "zzz_glt", @@ -5295,7 +13094,7 @@ Object { "details": "username=unfoldingWord", "extra": "ST", "location": " in ST in zzz TIT book package from unfoldingWord master branch", - "message": "Repository doesn't exist", + "message": "Repository doesn’t exist", "priority": 997, "repoCode": "ST", "repoName": "zzz_gst", @@ -5305,7 +13104,7 @@ Object { "details": "username=unfoldingWord", "extra": "TN", "location": " in TN in zzz TIT book package from unfoldingWord master branch", - "message": "Repository doesn't exist", + "message": "Repository doesn’t exist", "priority": 997, "repoCode": "TN", "repoName": "zzz_tn", @@ -5315,7 +13114,7 @@ Object { "details": "username=unfoldingWord", "extra": "TQ", "location": " in unfoldingWord (master)", - "message": "Repository doesn't exist", + "message": "Repository doesn’t exist", "priority": 997, "repoCode": "TQ", "repoName": "zzz_tq", @@ -5328,61 +13127,6 @@ Object { } `; -exports[`checkBookPackage() - TIT should fail on unsupported language 1`] = ` -Object { - "checkedFilenames": Array [ - "57-TIT.usfm", - ], - "checkedRepoNames": Array [ - "el-x-koine_ugnt", - ], - "noticeList": Array [ - Object { - "bookID": "TIT", - "details": "username=unfoldingWord", - "extra": "LT", - "filename": "57-TIT.usfm", - "location": " in LT in zzz TIT book package from unfoldingWord master branch: Could not find src/__tests__/fixtures/unfoldingWord/zzz_glt/57-TIT.usfm", - "message": "Failed to load", - "priority": 996, - "repoName": "zzz_glt", - }, - Object { - "bookID": "TIT", - "details": "username=unfoldingWord", - "extra": "ST", - "filename": "57-TIT.usfm", - "location": " in ST in zzz TIT book package from unfoldingWord master branch: Could not find src/__tests__/fixtures/unfoldingWord/zzz_gst/57-TIT.usfm", - "message": "Failed to load", - "priority": 996, - "repoName": "zzz_gst", - }, - Object { - "bookID": "TIT", - "details": "username=unfoldingWord", - "extra": "TN", - "filename": "zzz_tn_57-TIT.tsv", - "location": " in TN in zzz TIT book package from unfoldingWord master branch: Could not find src/__tests__/fixtures/unfoldingWord/zzz_tn/zzz_tn_57-TIT.tsv", - "message": "Failed to load", - "priority": 996, - "repoName": "zzz_tn", - }, - Object { - "bookID": "TIT", - "details": "username=unfoldingWord", - "extra": "TQ", - "location": " in unfoldingWord (master)", - "message": "Failed to load", - "priority": 996, - "repoName": "zzz_tq", - }, - ], - "successList": Array [ - "Checked UGNT file: 57-TIT.usfm", - ], -} -`; - exports[`checkBookPackage() - TIT should pass 1`] = ` Object { "checkedFilenames": Array [ @@ -5441,6 +13185,24 @@ Object { "repoName": "en_twl", "username": "unfoldingWord", }, + Object { + "C": "0", + "V": "1", + "bookID": "TIT", + "branch": "master", + "characterIndex": 33, + "excerpt": "…tr Wed Sep 09 2020 2…", + "extra": "LT", + "fieldName": "\\\\id", + "filename": "57-TIT.usfm", + "lineNumber": 1, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "LT", + "repoName": "en_ult", + "username": "unfoldingWord", + }, Object { "C": "1", "V": "1", @@ -18213,6 +25975,24 @@ Object { "repoName": "en_ult", "username": "unfoldingWord", }, + Object { + "C": "0", + "V": "1", + "bookID": "TIT", + "branch": "master", + "characterIndex": 33, + "excerpt": "…tr Thu Jul 02 2020 1…", + "extra": "ST", + "fieldName": "\\\\id", + "filename": "57-TIT.usfm", + "lineNumber": 1, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "ST", + "repoName": "en_ust", + "username": "unfoldingWord", + }, Object { "bookID": "TIT", "branch": "master", @@ -18227,6 +26007,25 @@ Object { "repoName": "en_ust", "username": "unfoldingWord", }, + Object { + "C": "1", + "V": "intro", + "bookID": "TIT", + "branch": "master", + "characterIndex": 5, + "excerpt": "Titus 01 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 3, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "c7me", + "username": "unfoldingWord", + }, Object { "C": "1", "V": "9", @@ -18284,6 +26083,25 @@ Object { "rowID": "w9kk", "username": "unfoldingWord", }, + Object { + "C": "2", + "V": "intro", + "bookID": "TIT", + "branch": "master", + "characterIndex": 5, + "excerpt": "Titus 02 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 71, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "h3il", + "username": "unfoldingWord", + }, Object { "C": "2", "V": "5", @@ -18303,6 +26121,25 @@ Object { "rowID": "t5v6", "username": "unfoldingWord", }, + Object { + "C": "3", + "V": "intro", + "bookID": "TIT", + "branch": "master", + "characterIndex": 5, + "excerpt": "Titus 03 Genera…", + "extra": "TN", + "fieldName": "OccurrenceNote", + "filename": "en_tn_57-TIT.tsv", + "lineNumber": 133, + "location": " in en TIT book package from unfoldingWord master branch", + "message": "Unexpected leading zero", + "priority": 92, + "repoCode": "TN", + "repoName": "en_tn", + "rowID": "zh6x", + "username": "unfoldingWord", + }, Object { "C": "3", "V": "14", diff --git a/src/__tests__/__snapshots__/tn-tsv7-table-row-check.test.js.snap b/src/__tests__/__snapshots__/tn-tsv7-table-row-check.test.js.snap new file mode 100644 index 000000000..c1561e79c --- /dev/null +++ b/src/__tests__/__snapshots__/tn-tsv7-table-row-check.test.js.snap @@ -0,0 +1,1773 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`checkNotesTSV7DataRow() - Occurrence Note tests - should find empty note 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "n7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "n7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line", + "message": "Link to TA should also be in Note", + "priority": 787, + "rowID": "n7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "fieldName": "Note", + "location": " from test line", + "message": "Missing Note field", + "priority": 274, + "rowID": "n7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - Occurrence Note tests - should find white space 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "m7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "m7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line", + "message": "Link to TA should also be in Note", + "priority": 787, + "rowID": "m7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "fieldName": "Note", + "location": " from test line", + "message": "Field is only whitespace", + "priority": 373, + "rowID": "m7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - invalid Original Language 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "1", + "bookID": "GEN", + "fieldName": "Occurrence", + "location": " from test line", + "message": "Missing occurrence field when we have an original quote", + "priority": 750, + "rowID": "f2mg", + }, + Object { + "C": "1", + "V": "1", + "bookID": "GEN", + "fieldName": "Occurrence", + "location": " from test line", + "message": "Missing occurrence field", + "priority": 791, + "rowID": "f2mg", + }, + ], + "suggestion": "1:1 f2mg 0 1 In the beginning, God created the heavens and the earth “This is about how God made the heavens and the earth in the beginning.” This statement summarizes the rest of the chapter. Some languages translate it as “A very long time ago God created the heavens and the earth.” Translate it in a way that shows this actually happened and is not just a folk story.", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail to find OrigLang Quote 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "b7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "b7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "excerpt": "וְ⁠חֹ֖שֶךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "b7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "b7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with leading space 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "e7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "e7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 0, + "excerpt": "␣וְ⁠חֹ֖שֶׁךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unexpected leading space", + "priority": 109, + "rowID": "e7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 0, + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "excerpt": "(ּ=D1468/H5bc) וְ⁠חֹ֖שֶׁךְ occurrence=1", + "fieldName": "Quote", + "location": " from test line", + "message": "Seems original language quote might not start at the beginning of a word", + "priority": 909, + "rowID": "e7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "e7qw", + }, + ], + "suggestion": "1:2 e7qw figs-imperative וְ⁠חֹ֖שֶׁךְ 1 This is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with leading word joiner 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "g7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "g7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 0, + "excerpt": "‼וְ‼חֹ֖שֶׁךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unexpected leading word-joiner", + "priority": 770, + "rowID": "g7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "quote which starts with 'word joiner'", + "excerpt": "⁠וְ⁠חֹ֖שֶׁךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "g7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "g7qw", + }, + ], + "suggestion": "1:2 g7qw figs-imperative וְ⁠חֹ֖שֶׁךְ 1 This is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with leading zero width joiner 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "k7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "k7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 0, + "excerpt": "‼וְ⁠חֹ֖שֶׁךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unexpected leading zero-width joiner", + "priority": 771, + "rowID": "k7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "quote which starts with 'zero-width joiner'", + "excerpt": "‍וְ⁠חֹ֖שֶׁךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "k7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "k7qw", + }, + ], + "suggestion": "1:2 k7qw figs-imperative וְ⁠חֹ֖שֶׁךְ 1 This is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with leading zero width non-joiner 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "i7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "i7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "excerpt": "‌וְ⁠חֹ֖שֶׁךְ", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "i7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "i7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with trailing space 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "f7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "f7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 11, + "excerpt": "⁠חֹ֖שֶׁךְ␣", + "fieldName": "Quote", + "location": " from test line", + "message": "Unexpected trailing space(s)", + "priority": 95, + "rowID": "f7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "f7qw", + }, + ], + "suggestion": "1:2 f7qw figs-imperative וְ⁠חֹ֖שֶׁךְ 1 This is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with trailing word joiner 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "h7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "h7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 0, + "excerpt": "וְ‼חֹ֖שֶׁךְ‼", + "fieldName": "Quote", + "location": " from test line", + "message": "Unexpected trailing word-joiner", + "priority": 772, + "rowID": "h7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "quote which ends with 'word joiner'", + "excerpt": "וְ⁠חֹ֖שֶׁךְ⁠", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "h7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "h7qw", + }, + ], + "suggestion": "1:2 h7qw figs-imperative וְ⁠חֹ֖שֶׁךְ 1 This is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with trailing zero width joiner 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "l7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "l7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "characterIndex": 0, + "excerpt": "וְ⁠חֹ֖שֶׁךְ‼", + "fieldName": "Quote", + "location": " from test line", + "message": "Unexpected trailing zero-width joiner", + "priority": 773, + "rowID": "l7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "quote which ends with 'zero-width joiner'", + "excerpt": "וְ⁠חֹ֖שֶׁךְ‍", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "l7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "l7qw", + }, + ], + "suggestion": "1:2 l7qw figs-imperative וְ⁠חֹ֖שֶׁךְ 1 This is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])", +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with trailing zero width non-joiner 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "j7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "j7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "excerpt": "וְ⁠חֹ֖שֶׁךְ‌", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find original language quote in verse text", + "priority": 916, + "rowID": "j7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "j7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should fail with valid but high occurrence number 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "2", + "bookID": "MAT", + "details": "occurrence=2 but only 1 occurrence found, passage ►λέγοντες, ποῦ ἐστιν ὁ τεχθεὶς Βασιλεὺς τῶν Ἰουδαίων? εἴδομεν γὰρ αὐτοῦ τὸν ἀστέρα ἐν τῇ ἀνατολῇ καὶ ἤλθομεν προσκυνῆσαι αὐτῷ.◄", + "excerpt": "προσκυνῆσαροσκυνῆσαι", + "fieldName": "Quote", + "location": " from test line", + "message": "Unable to find duplicate original language quote in verse text", + "priority": 917, + "rowID": "v248", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - Original Quote tests - should find missing Original Quote 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "3", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "a7qw", + }, + Object { + "C": "1", + "V": "3", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "a7qw", + }, + Object { + "C": "1", + "V": "3", + "bookID": "GEN", + "fieldName": "Quote", + "location": " from test line", + "message": "Missing Quote field", + "priority": 919, + "rowID": "a7qw", + }, + Object { + "C": "1", + "V": "3", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "a7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - SupportReference tests - should find long SupportReference 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "not 5", + "excerpt": "r7q33", + "fieldName": "ID", + "location": " from test line", + "message": "Row ID should be exactly 4 characters", + "priority": 778, + "rowID": "r7q33", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "r7q33", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "r7q33", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "r7q33", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - SupportReference tests - should find missing SupportReference 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "fieldName": "Reference", + "location": " from test line", + "message": "Missing row ID field", + "priority": 931, + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - SupportReference tests - should find short SupportReference 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "not 3", + "excerpt": "q7q", + "fieldName": "ID", + "location": " from test line", + "message": "Row ID should be exactly 4 characters", + "priority": 778, + "rowID": "q7q", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "q7q", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "q7q", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "q7q", + }, + ], + "suggestion": undefined, +} +`; + +exports[`checkNotesTSV7DataRow() - TSV format tests - empty line should fail 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "Found 1 field", + "location": " from test line", + "message": "Found wrong number of TSV fields (expected 7)", + "priority": 984, + "rowID": undefined, + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - TSV format tests - should fail not TSV 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "Found 1 field", + "location": " from test line", + "message": "Found wrong number of TSV fields (expected 7)", + "priority": 984, + "rowID": undefined, + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - TSV format tests - should find wrong row count 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "Found 6 fields", + "location": " from test line", + "message": "Found wrong number of TSV fields (expected 7)", + "priority": 984, + "rowID": "w3r5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail broken link end 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "linked from TN SupportReference", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line figs-parallelism/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-parallelism/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=1, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [[ ]] link characters", + "priority": 845, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=2, right=1", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [] characters", + "priority": 563, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=1, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched () characters", + "priority": 563, + "rowID": "gnn5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail broken link start 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "linked from TN SupportReference", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line figs-parallelism/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-parallelism/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=0, right=1", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [[ ]] link characters", + "priority": 845, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=1, right=2", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [] characters", + "priority": 563, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=1, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched () characters", + "priority": 563, + "rowID": "gnn5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail double broken link end 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "linked from TN SupportReference", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line figs-parallelism/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-parallelism/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=1, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [[ ]] link characters", + "priority": 845, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=2, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [] characters", + "priority": 563, + "rowID": "gnn5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail double broken link start 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "linked from TN SupportReference", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line figs-parallelism/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-parallelism/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "left=0, right=2", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [] characters", + "priority": 563, + "rowID": "gnn5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail if SupportReference link differs from link in OccurrenceNote 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "6", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "urb3", + }, + Object { + "C": "1", + "V": "6", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "urb3", + }, + Object { + "C": "1", + "V": "6", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line", + "message": "Link to TA should also be in Note", + "priority": 787, + "rowID": "urb3", + }, + Object { + "C": "1", + "V": "6", + "bookID": "GEN", + "details": "need to carefully check \\"[[rc://*/ta/man/figs-parallelism]]\\"", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Unusual [[ ]] link(s)—not a recognized TA or TW link", + "priority": 649, + "rowID": "urb3", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid doublet link 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "linked from TN SupportReference", + "excerpt": "figs-parallelism", + "fieldName": "SupportReference", + "location": " from test line figs-parallelism/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-parallelism/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "need to carefully check \\"[Doublet](../figs-doublet/01.md)\\"", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Unusual [ ]( ) link(s)—not a recognized Bible or TA, TN, or TW link", + "priority": 648, + "rowID": "gnn5", + }, + Object { + "C": "2", + "V": "12", + "bookID": "RUT", + "details": "SR='figs-parallelism'", + "excerpt": "figs-parallelism", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "gnn5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid first link 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "excerpt": "figs-activepassive", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "zu6f", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-activepassive", + "fieldName": "SupportReference", + "location": " from test line figs-activepassive/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-activepassive/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "zu6f", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "unfoldingWord en_ta master translate/figs-activepassivez/01.md", + "excerpt": "[[rc://*/ta/man/translate/figs-activepassivez]]", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line translate/figs-activepassivez/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/figs-activepassivez/01.md", + "message": "Error loading TA article", + "priority": 885, + "rowID": "zu6f", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "SR='figs-activepassive'—found 2 TA links", + "excerpt": "[\\"figs-activepassivez\\",\\"figs-imperative\\"]", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "zu6f", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid link path 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "7", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "urb3", + }, + Object { + "C": "1", + "V": "7", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "urb3", + }, + Object { + "C": "1", + "V": "7", + "bookID": "GEN", + "details": "need to carefully check \\"[[rc://*/ta/woman/figs-imperative]]\\"", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Unusual [[ ]] link(s)—not a recognized TA or TW link", + "priority": 649, + "rowID": "urb3", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid second link 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "excerpt": "figs-activepassive", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "zu6f", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-activepassive", + "fieldName": "SupportReference", + "location": " from test line figs-activepassive/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-activepassive/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "zu6f", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "unfoldingWord en_ta master translate/figs-imperativez/01.md", + "excerpt": "[[rc://*/ta/man/translate/figs-imperativez]]", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line translate/figs-imperativez/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/figs-imperativez/01.md", + "message": "Error loading TA article", + "priority": 885, + "rowID": "zu6f", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "SR='figs-activepassive'—found 2 TA links", + "excerpt": "[\\"figs-activepassive\\",\\"figs-imperativez\\"]", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "zu6f", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid verse link 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "need to carefully check \\"[Genesis 1:7](../01/zzz.md)\\"", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Unusual [ ]( ) link(s)—not a recognized Bible or TA, TN, or TW link", + "priority": 648, + "rowID": "ha33", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid verse link end 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "left=1, middle=1, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [ ]( ) link characters", + "priority": 843, + "rowID": "ha33", + }, + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "left=1, right=0", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched () characters", + "priority": 563, + "rowID": "ha33", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - link tests - should fail invalid verse link start 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "9", + "bookID": "GEN", + "details": "left=0, right=1", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Mismatched [] characters", + "priority": 563, + "rowID": "ha33", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - should find invalid Book ID, chapter number, ID, SupportReference, quotes, OccurrenceNote 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GIN", + "location": " 'GIN' in first parameter: Error: expectedVersesPerChapterList() given invalid bookId: 'GIN'", + "message": "Invalid book identifier passed to checkNotesTSV7DataRow", + "priority": 979, + }, + Object { + "C": "1", + "V": "2", + "bookID": "GIN", + "details": "Found 8 fields", + "location": " from test line", + "message": "Found wrong number of TSV fields (expected 7)", + "priority": 984, + "rowID": "W-3r5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - should find invalid SupportReference and missing quotes 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "2", + "V": "3", + "bookID": "GEN", + "excerpt": "Laugh", + "fieldName": "SupportReference", + "location": " from test line", + "message": "Only 'Just-In-Time Training' TA articles allowed here", + "priority": 788, + "rowID": "w3r5", + }, + Object { + "C": "2", + "V": "3", + "bookID": "GEN", + "excerpt": "Laugh", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "w3r5", + }, + Object { + "C": "2", + "V": "3", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "Laugh", + "fieldName": "SupportReference", + "location": " from test line Laugh/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/Laugh/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "w3r5", + }, + Object { + "C": "2", + "V": "3", + "bookID": "GEN", + "excerpt": "Laugh", + "fieldName": "SupportReference", + "location": " from test line", + "message": "Link to TA should also be in Note", + "priority": 787, + "rowID": "w3r5", + }, + Object { + "C": "2", + "V": "3", + "bookID": "GEN", + "fieldName": "Quote", + "location": " from test line", + "message": "Missing Quote field", + "priority": 919, + "rowID": "w3r5", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - should find language code instead of asterisk 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "EXO", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "u7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "EXO", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "u7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "EXO", + "characterIndex": 90, + "details": "not 'en'", + "excerpt": "…e: [[rc://en/ta/man/…", + "fieldName": "Note", + "lineNumber": 1, + "location": " from test line", + "message": "Resource container link should have '*' language code", + "priority": 450, + "rowID": "u7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "EXO", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "u7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - should find mismatched bookId 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "t7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "t7qw", + }, + Object { + "C": "1", + "V": "2", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "t7qw", + }, + ], +} +`; + +exports[`checkNotesTSV7DataRow() - should find mismatched chapter verse 1`] = ` +Object { + "noticeList": Array [ + Object { + "C": "22", + "V": "33", + "bookID": "GEN", + "details": "expected '22'", + "excerpt": "2", + "fieldName": "Reference", + "location": " from test line", + "message": "Wrong chapter number", + "priority": 976, + "rowID": "s7qw", + }, + Object { + "C": "22", + "V": "33", + "bookID": "GEN", + "details": "expected '33'", + "excerpt": "3", + "fieldName": "Reference", + "location": " from test line", + "message": "Wrong verse number", + "priority": 975, + "rowID": "s7qw", + }, + Object { + "C": "22", + "V": "33", + "bookID": "GEN", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line undefined", + "message": "Badly formatted Resource Container link", + "priority": 879, + "rowID": "s7qw", + }, + Object { + "C": "22", + "V": "33", + "bookID": "GEN", + "details": "linked from TN SupportReference", + "excerpt": "figs-imperative", + "fieldName": "SupportReference", + "location": " from test line figs-imperative/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/figs-imperative/01.md", + "message": "Error loading TA article", + "priority": 888, + "rowID": "s7qw", + }, + Object { + "C": "22", + "V": "33", + "bookID": "GEN", + "details": "SR='figs-imperative'", + "excerpt": "figs-imperative", + "fieldName": "OccurrenceNote", + "location": " from test line", + "message": "Should have a SupportReference when Note has a TA link", + "priority": 789, + "rowID": "s7qw", + }, + ], +} +`; diff --git a/src/__tests__/__snapshots__/tn-table-row-check.test.js.snap b/src/__tests__/__snapshots__/tn-tsv9-table-row-check.test.js.snap similarity index 86% rename from src/__tests__/__snapshots__/tn-table-row-check.test.js.snap rename to src/__tests__/__snapshots__/tn-tsv9-table-row-check.test.js.snap index a379dde29..3c706f943 100644 --- a/src/__tests__/__snapshots__/tn-table-row-check.test.js.snap +++ b/src/__tests__/__snapshots__/tn-tsv9-table-row-check.test.js.snap @@ -10,7 +10,7 @@ Object { "details": "expected 'GEN'", "excerpt": "RUT", "fieldName": "Book", - "location": " that was supplied", + "location": " from test line", "message": "Wrong book identifier", "priority": 978, "rowID": "o7qw", @@ -23,7 +23,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "o7qw", @@ -40,7 +40,7 @@ Object { "V": "3", "bookID": "GEN", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Missing OrigQuote field", "priority": 919, "rowID": "w3r5", @@ -52,7 +52,7 @@ Object { "characterIndex": 11, "excerpt": "…ad ellipse...", "fieldName": "GLQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected doubled . characters", "priority": 177, "rowID": "w3r5", @@ -70,7 +70,7 @@ Object { "bookID": "GEN", "excerpt": "figs-imperative", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Link to TA should also be in OccurrenceNote", "priority": 787, "rowID": "n7qw", @@ -80,7 +80,7 @@ Object { "V": "2", "bookID": "GEN", "fieldName": "OccurrenceNote", - "location": " that was supplied", + "location": " from test line", "message": "Missing OccurrenceNote field", "priority": 274, "rowID": "n7qw", @@ -98,7 +98,7 @@ Object { "bookID": "GEN", "excerpt": "figs-imperative", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Link to TA should also be in OccurrenceNote", "priority": 787, "rowID": "m7qw", @@ -108,7 +108,7 @@ Object { "V": "2", "bookID": "GEN", "fieldName": "OccurrenceNote", - "location": " that was supplied", + "location": " from test line", "message": "Field is only whitespace", "priority": 373, "rowID": "m7qw", @@ -125,7 +125,7 @@ Object { "V": "1", "bookID": "GEN", "fieldName": "Occurrence", - "location": " that was supplied", + "location": " from test line", "message": "Missing occurrence field when we have an original quote", "priority": 750, "rowID": "f2mg", @@ -135,7 +135,7 @@ Object { "V": "1", "bookID": "GEN", "fieldName": "Occurrence", - "location": " that was supplied", + "location": " from test line", "message": "Missing occurrence field", "priority": 791, "rowID": "f2mg", @@ -152,10 +152,10 @@ Object { "C": "1", "V": "2", "bookID": "GEN", - "details": "passage ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", "excerpt": "וְ⁠חֹ֖שֶךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "b7qw", @@ -168,7 +168,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "b7qw", @@ -187,7 +187,7 @@ Object { "characterIndex": 0, "excerpt": "␣וְ⁠חֹ֖שֶׁךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected leading space", "priority": 109, "rowID": "e7qw", @@ -197,10 +197,10 @@ Object { "V": "2", "bookID": "GEN", "characterIndex": 0, - "details": "passage ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", "excerpt": "(ּ=D1468/H5bc) וְ⁠חֹ֖שֶׁךְ occurrence=1", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Seems original language quote might not start at the beginning of a word", "priority": 909, "rowID": "e7qw", @@ -213,7 +213,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "e7qw", @@ -233,7 +233,7 @@ Object { "characterIndex": 0, "excerpt": "‼וְ‼חֹ֖שֶׁךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected leading word-joiner", "priority": 770, "rowID": "g7qw", @@ -245,7 +245,7 @@ Object { "details": "quote which starts with 'word joiner'", "excerpt": "⁠וְ⁠חֹ֖שֶׁךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "g7qw", @@ -258,7 +258,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "g7qw", @@ -278,7 +278,7 @@ Object { "characterIndex": 0, "excerpt": "‼וְ⁠חֹ֖שֶׁךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected leading zero-width joiner", "priority": 771, "rowID": "k7qw", @@ -290,7 +290,7 @@ Object { "details": "quote which starts with 'zero-width joiner'", "excerpt": "‍וְ⁠חֹ֖שֶׁךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "k7qw", @@ -303,7 +303,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "k7qw", @@ -320,10 +320,10 @@ Object { "C": "1", "V": "2", "bookID": "GEN", - "details": "passage ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", "excerpt": "‌וְ⁠חֹ֖שֶׁךְ", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "i7qw", @@ -336,7 +336,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "i7qw", @@ -355,7 +355,7 @@ Object { "characterIndex": 11, "excerpt": "⁠חֹ֖שֶׁךְ␣", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected trailing space(s)", "priority": 95, "rowID": "f7qw", @@ -368,7 +368,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "f7qw", @@ -388,7 +388,7 @@ Object { "characterIndex": 0, "excerpt": "וְ‼חֹ֖שֶׁךְ‼", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected trailing word-joiner", "priority": 772, "rowID": "h7qw", @@ -400,7 +400,7 @@ Object { "details": "quote which ends with 'word joiner'", "excerpt": "וְ⁠חֹ֖שֶׁךְ⁠", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "h7qw", @@ -413,7 +413,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "h7qw", @@ -433,7 +433,7 @@ Object { "characterIndex": 0, "excerpt": "וְ⁠חֹ֖שֶׁךְ‼", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected trailing zero-width joiner", "priority": 773, "rowID": "l7qw", @@ -445,7 +445,7 @@ Object { "details": "quote which ends with 'zero-width joiner'", "excerpt": "וְ⁠חֹ֖שֶׁךְ‍", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "l7qw", @@ -458,7 +458,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "l7qw", @@ -475,10 +475,10 @@ Object { "C": "1", "V": "2", "bookID": "GEN", - "details": "passage ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", + "details": "verse text ►וְ⁠הָ⁠אָ֗רֶץ הָיְתָ֥ה תֹ֨הוּ֙ וָ⁠בֹ֔הוּ וְ⁠חֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְ⁠ר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַ⁠מָּֽיִם׃◄", "excerpt": "וְ⁠חֹ֖שֶׁךְ‌", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find original language quote in verse text", "priority": 916, "rowID": "j7qw", @@ -491,7 +491,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "j7qw", @@ -510,7 +510,7 @@ Object { "details": "occurrence=2 but only 1 occurrence found, passage ►λέγοντες, ποῦ ἐστιν ὁ τεχθεὶς Βασιλεὺς τῶν Ἰουδαίων? εἴδομεν γὰρ αὐτοῦ τὸν ἀστέρα ἐν τῇ ἀνατολῇ καὶ ἤλθομεν προσκυνῆσαι αὐτῷ.◄", "excerpt": "προσκυνῆσαροσκυνῆσαι", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unable to find duplicate original language quote in verse text", "priority": 917, "rowID": "v248", @@ -527,7 +527,7 @@ Object { "V": "3", "bookID": "GEN", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Missing OrigQuote field", "priority": 919, "rowID": "a7qw", @@ -540,7 +540,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "a7qw", @@ -559,7 +559,7 @@ Object { "details": "not 5", "excerpt": "r7q33", "fieldName": "ID", - "location": " that was supplied", + "location": " from test line", "message": "Row ID should be exactly 4 characters", "priority": 778, "rowID": "r7q33", @@ -572,7 +572,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "r7q33", @@ -589,7 +589,7 @@ Object { "V": "2", "bookID": "GEN", "fieldName": "Verse", - "location": " that was supplied", + "location": " from test line", "message": "Missing row ID field", "priority": 931, }, @@ -601,7 +601,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "", @@ -620,7 +620,7 @@ Object { "details": "not 3", "excerpt": "q7q", "fieldName": "ID", - "location": " that was supplied", + "location": " from test line", "message": "Row ID should be exactly 4 characters", "priority": 778, "rowID": "q7q", @@ -633,7 +633,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "q7q", @@ -651,7 +651,7 @@ Object { "V": "2", "bookID": "GEN", "details": "Found 1 field", - "location": " that was supplied", + "location": " from test line", "message": "Found wrong number of TSV fields (expected 9)", "priority": 984, "rowID": undefined, @@ -668,7 +668,7 @@ Object { "V": "2", "bookID": "GEN", "details": "Found 1 field", - "location": " that was supplied", + "location": " from test line", "message": "Found wrong number of TSV fields (expected 9)", "priority": 984, "rowID": undefined, @@ -685,7 +685,7 @@ Object { "V": "2", "bookID": "GEN", "details": "Found 8 fields", - "location": " that was supplied", + "location": " from test line", "message": "Found wrong number of TSV fields (expected 9)", "priority": 984, "rowID": "w3r5", @@ -704,7 +704,7 @@ Object { "details": "left=1, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [[ ]] link characters", "priority": 845, "rowID": "gnn5", @@ -716,7 +716,7 @@ Object { "details": "left=2, right=1", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [] characters", "priority": 563, "rowID": "gnn5", @@ -728,7 +728,7 @@ Object { "details": "left=1, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched () characters", "priority": 563, "rowID": "gnn5", @@ -747,7 +747,7 @@ Object { "details": "left=0, right=1", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [[ ]] link characters", "priority": 845, "rowID": "gnn5", @@ -759,7 +759,7 @@ Object { "details": "left=1, right=2", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [] characters", "priority": 563, "rowID": "gnn5", @@ -771,7 +771,7 @@ Object { "details": "left=1, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched () characters", "priority": 563, "rowID": "gnn5", @@ -790,7 +790,7 @@ Object { "details": "left=1, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [[ ]] link characters", "priority": 845, "rowID": "gnn5", @@ -802,7 +802,7 @@ Object { "details": "left=2, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [] characters", "priority": 563, "rowID": "gnn5", @@ -821,7 +821,7 @@ Object { "details": "left=0, right=2", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [] characters", "priority": 563, "rowID": "gnn5", @@ -839,7 +839,7 @@ Object { "bookID": "GEN", "excerpt": "figs-imperative", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Link to TA should also be in OccurrenceNote", "priority": 787, "rowID": "urb3", @@ -851,7 +851,7 @@ Object { "details": "need to carefully check \\"[[rc://*/ta/man/figs-parallelism]]\\"", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Unusual [[ ]] link(s)—not a recognized TA or TW link", "priority": 649, "rowID": "urb3", @@ -871,7 +871,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "gnn5", @@ -883,7 +883,7 @@ Object { "details": "need to carefully check \\"[Doublet](../figs-doublet/01.md)\\"", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Unusual [ ]( ) link(s)—not a recognized Bible or TA, TN, or TW link", "priority": 648, "rowID": "gnn5", @@ -903,7 +903,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "zu6f", @@ -916,7 +916,7 @@ Object { "excerpt": "[[rc://*/ta/man/translate/figs-activepassivez]]", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied translate/figs-activepassivez/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/figs-activepassivez/01.md", + "location": " from test line translate/figs-activepassivez/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/figs-activepassivez/01.md", "message": "Error loading TA article", "priority": 885, "rowID": "zu6f", @@ -929,7 +929,7 @@ Object { "excerpt": "…nd [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "zu6f", @@ -941,7 +941,7 @@ Object { "details": "SR='figs-activepassive'—found 2 TA links", "excerpt": "[\\"figs-activepassivez\\",\\"figs-imperative\\"]", "fieldName": "OccurrenceNote", - "location": " that was supplied", + "location": " from test line", "message": "Should have a SupportReference when OccurrenceNote has a TA link", "priority": 789, "rowID": "zu6f", @@ -960,7 +960,7 @@ Object { "details": "need to carefully check \\"[[rc://*/ta/woman/figs-imperative]]\\"", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Unusual [[ ]] link(s)—not a recognized TA or TW link", "priority": 649, "rowID": "urb3", @@ -980,7 +980,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "zu6f", @@ -993,7 +993,7 @@ Object { "excerpt": "…nd [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "zu6f", @@ -1006,7 +1006,7 @@ Object { "excerpt": "[[rc://*/ta/man/translate/figs-imperativez]]", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied translate/figs-imperativez/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/figs-imperativez/01.md", + "location": " from test line translate/figs-imperativez/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/figs-imperativez/01.md", "message": "Error loading TA article", "priority": 885, "rowID": "zu6f", @@ -1018,7 +1018,7 @@ Object { "details": "SR='figs-activepassive'—found 2 TA links", "excerpt": "[\\"figs-activepassive\\",\\"figs-imperativez\\"]", "fieldName": "OccurrenceNote", - "location": " that was supplied", + "location": " from test line", "message": "Shouldn’t have multiple TA links in OccurrenceNote", "priority": 786, "rowID": "zu6f", @@ -1037,7 +1037,7 @@ Object { "details": "need to carefully check \\"[Genesis 1:7](../01/zzz.md)\\"", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Unusual [ ]( ) link(s)—not a recognized Bible or TA, TN, or TW link", "priority": 648, "rowID": "ha33", @@ -1056,7 +1056,7 @@ Object { "details": "left=1, middle=1, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [ ]( ) link characters", "priority": 843, "rowID": "ha33", @@ -1068,7 +1068,7 @@ Object { "details": "left=1, right=0", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched () characters", "priority": 563, "rowID": "ha33", @@ -1087,7 +1087,7 @@ Object { "details": "left=0, right=1", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Mismatched [] characters", "priority": 563, "rowID": "ha33", @@ -1106,7 +1106,7 @@ Object { "details": "expected 'GEN'", "excerpt": "GIN", "fieldName": "Book", - "location": " that was supplied", + "location": " from test line", "message": "Wrong book identifier", "priority": 978, "rowID": "W-3r5", @@ -1118,7 +1118,7 @@ Object { "details": "expected '1'", "excerpt": "200", "fieldName": "Chapter", - "location": " that was supplied", + "location": " from test line", "message": "Wrong chapter number", "priority": 976, "rowID": "W-3r5", @@ -1129,7 +1129,7 @@ Object { "bookID": "GEN", "excerpt": "200", "fieldName": "Chapter", - "location": " that was supplied", + "location": " from test line", "message": "Invalid large chapter number", "priority": 823, "rowID": "W-3r5", @@ -1141,7 +1141,7 @@ Object { "details": "expected '2'", "excerpt": "9", "fieldName": "Verse", - "location": " that was supplied", + "location": " from test line", "message": "Wrong verse number", "priority": 975, "rowID": "W-3r5", @@ -1151,7 +1151,7 @@ Object { "V": "2", "bookID": "GEN", "fieldName": "Verse", - "location": " that was supplied", + "location": " from test line", "message": "Unable to check verse number", "priority": 812, "rowID": "W-3r5", @@ -1163,7 +1163,7 @@ Object { "details": "not 5", "excerpt": "W-3r5", "fieldName": "ID", - "location": " that was supplied", + "location": " from test line", "message": "Row ID should be exactly 4 characters", "priority": 778, "rowID": "W-3r5", @@ -1174,7 +1174,7 @@ Object { "bookID": "GEN", "excerpt": "Laugh", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Only 'Just-In-Time Training' TA articles allowed here", "priority": 788, "rowID": "W-3r5", @@ -1186,7 +1186,7 @@ Object { "details": "linked from TN SupportReference", "excerpt": "Laugh", "fieldName": "SupportReference", - "location": " that was supplied translate/Laugh/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/Laugh/01.md", + "location": " from test line translate/Laugh/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/Laugh/01.md", "message": "Error loading TA article", "priority": 888, "rowID": "W-3r5", @@ -1197,7 +1197,7 @@ Object { "bookID": "GEN", "excerpt": "Laugh", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Link to TA should also be in OccurrenceNote", "priority": 787, "rowID": "W-3r5", @@ -1207,7 +1207,7 @@ Object { "V": "2", "bookID": "GEN", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Missing OrigQuote field", "priority": 919, "rowID": "W-3r5", @@ -1218,7 +1218,7 @@ Object { "bookID": "GEN", "excerpt": "17", "fieldName": "Occurrence", - "location": " that was supplied", + "location": " from test line", "message": "Invalid occurrence field", "priority": 792, "rowID": "W-3r5", @@ -1230,7 +1230,7 @@ Object { "characterIndex": 11, "excerpt": "…ad ellipse...", "fieldName": "GLQuote", - "location": " that was supplied", + "location": " from test line", "message": "Unexpected doubled . characters", "priority": 177, "rowID": "W-3r5", @@ -1243,7 +1243,7 @@ Object { "excerpt": "Boo hoo,,", "fieldName": "OccurrenceNote", "lineNumber": 2, - "location": " that was supplied", + "location": " from test line", "message": "Unexpected doubled , characters", "priority": 177, "rowID": "W-3r5", @@ -1256,7 +1256,7 @@ Object { "excerpt": "…st my shoe !", "fieldName": "OccurrenceNote", "lineNumber": 3, - "location": " that was supplied", + "location": " from test line", "message": "Unexpected ! character after space", "priority": 191, "rowID": "W-3r5", @@ -1275,7 +1275,7 @@ Object { "bookID": "GEN", "excerpt": "Laugh", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Only 'Just-In-Time Training' TA articles allowed here", "priority": 788, "rowID": "w3r5", @@ -1287,7 +1287,7 @@ Object { "details": "linked from TN SupportReference", "excerpt": "Laugh", "fieldName": "SupportReference", - "location": " that was supplied translate/Laugh/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/Laugh/01.md", + "location": " from test line translate/Laugh/01.md: tn-table-row-check.test getFile(): Could not find src/__tests__/fixtures/unfoldingWord/en_ta/translate/Laugh/01.md", "message": "Error loading TA article", "priority": 888, "rowID": "w3r5", @@ -1298,7 +1298,7 @@ Object { "bookID": "GEN", "excerpt": "Laugh", "fieldName": "SupportReference", - "location": " that was supplied", + "location": " from test line", "message": "Link to TA should also be in OccurrenceNote", "priority": 787, "rowID": "w3r5", @@ -1308,7 +1308,7 @@ Object { "V": "3", "bookID": "GEN", "fieldName": "OrigQuote", - "location": " that was supplied", + "location": " from test line", "message": "Missing OrigQuote field", "priority": 919, "rowID": "w3r5", @@ -1329,7 +1329,7 @@ Object { "excerpt": "…e: [[rc://en/ta/man/…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "Resource container link should have '*' language code", "priority": 450, "rowID": "u7qw", @@ -1348,7 +1348,7 @@ Object { "details": "expected 'GEN'", "excerpt": "EXO", "fieldName": "Book", - "location": " that was supplied", + "location": " from test line", "message": "Wrong book identifier", "priority": 978, "rowID": "t7qw", @@ -1361,7 +1361,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "t7qw", @@ -1380,7 +1380,7 @@ Object { "details": "expected '22'", "excerpt": "2", "fieldName": "Chapter", - "location": " that was supplied", + "location": " from test line", "message": "Wrong chapter number", "priority": 976, "rowID": "s7qw", @@ -1392,7 +1392,7 @@ Object { "details": "expected '33'", "excerpt": "3", "fieldName": "Verse", - "location": " that was supplied", + "location": " from test line", "message": "Wrong verse number", "priority": 975, "rowID": "s7qw", @@ -1405,7 +1405,7 @@ Object { "excerpt": "…e: [[rc://*/ta/man/t…", "fieldName": "OccurrenceNote", "lineNumber": 1, - "location": " that was supplied", + "location": " from test line", "message": "tC cannot yet process '*' language code", "priority": 950, "rowID": "s7qw", diff --git a/src/__tests__/book-package-check.test.js b/src/__tests__/book-package-check.test.js index 57776af26..f71eaf153 100644 --- a/src/__tests__/book-package-check.test.js +++ b/src/__tests__/book-package-check.test.js @@ -43,11 +43,12 @@ describe('checkBookPackage() - ', () => { testFiles = {}; // reset test files }); - it.skip('TIT should fail on unsupported language', async() => { + it('TIT should fail on unsupported language', async() => { const username = 'unfoldingWord'; const languageCode = 'zzz'; const bookID = 'TIT'; const rawResults = await checkBookPackage(username, languageCode, bookID, () => {}, optionalCheckingOptions); + console.log(`TIT unsupported language BP test took ${rawResults.elapsedSeconds} seconds`); expect(rawResults.noticeList.length).toBeGreaterThan(0); const filteredResults = { successList: rawResults.successList, @@ -56,9 +57,9 @@ describe('checkBookPackage() - ', () => { checkedRepoNames: rawResults.checkedRepoNames, }; expect(filteredResults).toMatchSnapshot(); - }); + }, 6000); // Allow 6 seconds - it.skip('TIT should fail on missing repo', async() => { + it('TIT should fail on missing repo', async() => { const username = 'unfoldingWord'; const languageCode = 'en'; const bookID = 'TIT'; @@ -67,6 +68,7 @@ describe('checkBookPackage() - ', () => { }; const rawResults = await checkBookPackage(username, languageCode, bookID, () => {}, optionalCheckingOptions); + console.log(`TIT missing repo BP test took ${rawResults.elapsedSeconds} seconds`); expect(rawResults.noticeList.length).toBeGreaterThan(0); const filteredResults = { successList: rawResults.successList, @@ -75,13 +77,14 @@ describe('checkBookPackage() - ', () => { checkedRepoNames: rawResults.checkedRepoNames, }; expect(filteredResults).toMatchSnapshot(); - }); + }, 12000); // Allow 12 seconds it('TIT should pass', async() => { const username = 'unfoldingWord'; const languageCode = 'en'; const bookID = 'TIT'; const rawResults = await checkBookPackage(username, languageCode, bookID, () => {}, optionalCheckingOptions); + console.log(`TIT BP test took ${rawResults.elapsedSeconds} seconds`); expect(rawResults.noticeList.length).toBeGreaterThanOrEqual(0); const filteredResults = { successList: rawResults.successList, @@ -90,13 +93,14 @@ describe('checkBookPackage() - ', () => { checkedRepoNames: rawResults.checkedRepoNames, }; expect(filteredResults).toMatchSnapshot(); - }); + }, 15000); // Allow 15 seconds it('RUT should pass', async() => { const username = 'unfoldingWord'; const languageCode = 'en'; const bookID = 'RUT'; const rawResults = await checkBookPackage(username, languageCode, bookID, () => {}, optionalCheckingOptions); + console.log(`RUT BP test took ${rawResults.elapsedSeconds} seconds`); expect(rawResults.noticeList.length).toBeGreaterThanOrEqual(4); const filteredResults = { successList: rawResults.successList, @@ -105,7 +109,7 @@ describe('checkBookPackage() - ', () => { checkedRepoNames: rawResults.checkedRepoNames, }; expect(filteredResults).toMatchSnapshot(); - }); + }, 20000); // Allow 20 seconds }) @@ -139,4 +143,3 @@ const getAllFiles = function(dirPath, subPath, arrayOfFiles) { } return arrayOfFiles } - diff --git a/src/__tests__/tn-tsv7-table-row-check.test.js b/src/__tests__/tn-tsv7-table-row-check.test.js new file mode 100644 index 000000000..fd6b5418f --- /dev/null +++ b/src/__tests__/tn-tsv7-table-row-check.test.js @@ -0,0 +1,376 @@ +/* eslint-env jest */ + +import { checkNotesTSV7DataRow } from '../core/notes-tsv7-row-check'; +import Path from "path"; +import fs from 'fs-extra'; + +const optionalCheckingOptions = { + originalLanguageRepoUsername: 'unfoldingWord', + taRepoUsername: 'unfoldingWord', + disableLinkedTAArticlesCheckFlag: true, + disableLinkedTWArticlesCheckFlag: true, + getFile: params => { + const { username, repository, path } = params; + // console.log(`tn-table-row-check.test getFile(${username}, ${repository}, ${path})`) + const filePath = Path.join('./src/__tests__/fixtures', username, repository, path); + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath).toString(); + } + // eslint-disable-next-line no-throw-literal + throw `tn-table-row-check.test getFile(): Could not find ${filePath}`; + } +} + +describe('checkNotesTSV7DataRow() - ', () => { + const languageCode = 'en'; + const repoCode = 'TN2'; + + describe('link tests - ', () => { + it('should fail invalid doublet link', async () => { + const chosenLine = "2:12\tgnn5\t\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism]], [Doublet](../figs-doublet/01.md))"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail broken link start', async () => { + const chosenLine = "2:12\tgnn5\t\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [rc://*/ta/man/translate/figs-parallelism]]"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail broken link end', async () => { + const chosenLine = "2:12\tgnn5\t\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism]"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail double broken link start', async () => { + const chosenLine = "2:12\tgnn5\t\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: rc://*/ta/man/translate/figs-parallelism]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(3); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail double broken link end', async () => { + const chosenLine = "2:12\tgnn5\t\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism)"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail if SupportReference link differs from link in OccurrenceNote', async () => { + const chosenLine = "1:6\turb3\t\tfigs-imperative\t\t0\tThese are commands. By commanding that the expanse should exist and that it divide the waters, God made it exist and divide the waters. (See: [[rc://*/ta/man/figs-parallelism]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '6', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail invalid link path', async () => { + const chosenLine = "1:7\turb3\t\tfigs-imperative\t\t0\tThese are commands. By commanding that the expanse should exist and that it divide the waters, God made it exist and divide the waters. (See: [[rc://*/ta/woman/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '7', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(3); + expect(rawResults).toMatchSnapshot(); + }); + + it('should succeed with mixed link types', async () => { + const chosenLine = "1:8\tss9r\t\tfigs-merism\t\t0\tevening and morning\tThis refers to the whole day. The writer speaks of the whole day as if it were these two parts. In the Jewish culture, a day begins when the sun sets. See how you translated this in [Genesis 1:5](../01/05.md). (See: [[rc://*/ta/man/translate/figs-merism]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '8', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + }); + + it('should succeed with dual links', async () => { + const chosenLine = "1:9\tzu6f\t\tfigs-activepassive\t\t0\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://*/ta/man/translate/figs-activepassive]] and [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(3); + }); + + it('should fail invalid first link', async () => { + const chosenLine = "1:9\tzu6f\t\tfigs-activepassive\t\t0\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://*/ta/man/translate/figs-activepassivez]] and [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail invalid second link', async () => { + const chosenLine = "1:9\tzu6f\t\tfigs-activepassive\t\t0\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://*/ta/man/translate/figs-activepassive]] and [[rc://*/ta/man/translate/figs-imperativez]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should pass valid verse link', async () => { + const chosenLine = "1:19\tha33\t\t\t\t0\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md)."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '19', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(0); + }); + + it('should fail invalid verse link', async () => { + const chosenLine = "1:9\tha33\t\t\t\t0\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/zzz.md)."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail invalid verse link start', async () => { + const chosenLine = "1:9\tha33\t\t\t\t0\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in Genesis 1:7](../01/07.md)."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail invalid verse link end', async () => { + const chosenLine = "1:9\tha33\t\t\t\t0\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(2); + expect(rawResults).toMatchSnapshot(); + }); + + }); + + describe('Original Quote tests - ', () => { + it('invalid Original Language', async () => { + const chosenLine = "1:1\tf2mg\t\t\t0\t\tIn the beginning, God created the heavens and the earth “This is about how God made the heavens and the earth in the beginning.” This statement summarizes the rest of the chapter. Some languages translate it as “A very long time ago God created the heavens and the earth.” Translate it in a way that shows this actually happened and is not just a folk story."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '1', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(2); + expect(rawResults).toMatchSnapshot(); + }); + + it('should find missing Original Quote', async () => { + const chosenLine = "1:3\ta7qw\t\tfigs-imperative\t\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '3', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail to find OrigLang Quote', async () => { + const chosenLine = "1:2\tb7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail to find 2nd instance/occurrence', async () => { + const chosenLine = "1:2\tc7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t2\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + }); + + it('should fail with leading space', async () => { + const chosenLine = "1:2\te7qw\t\tfigs-imperative\t וְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with trailing space', async () => { + const chosenLine = "1:2\tf7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ \t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with leading word joiner', async () => { + const chosenLine = "1:2\tg7qw\t\tfigs-imperative\t\u2060וְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with trailing word joiner', async () => { + const chosenLine = "1:2\th7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\u2060\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with leading zero width non-joiner', async () => { + const chosenLine = "1:2\ti7qw\t\tfigs-imperative\t\u200cוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with trailing zero width non-joiner', async () => { + const chosenLine = "1:2\tj7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\u200c\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with leading zero width joiner', async () => { + const chosenLine = "1:2\tk7qw\t\tfigs-imperative\t\u200dוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with trailing zero width joiner', async () => { + const chosenLine = "1:2\tl7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\u200d\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail with valid but high occurrence number', async () => { + const chosenLine = "2:2\tv248\t\t\tπροσκυνῆσαι\t2\tPossible meanings are (1) they intended to worship the baby as divine, or (2) they wanted to honor him as a human king. If your language has a word that includes both meanings, you should consider using it here."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'MAT', '2', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + expect(rawResults).toMatchSnapshot(); + }); + + it('should pass with correct quote', async () => { + const chosenLine = "2:2\tv248\t\t\tπροσκυνῆσαι\t1\tPossible meanings are (1) they intended to worship the baby as divine, or (2) they wanted to honor him as a human king. If your language has a word that includes both meanings, you should consider using it here."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'MAT', '2', '2', 'from test line', optionalCheckingOptions); + // console.log(`Got raw results: ${JSON.stringify(rawResults)}`); + expect(rawResults.noticeList.length).toEqual(0); + }); + + }); + + describe('Occurrence Note tests - ', () => { + + it('should find white space', async () => { + const chosenLine = "1:2\tm7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\t "; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.some((entry) => entry.message.indexOf('whitespace') !== -1)); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should find empty note', async () => { + const chosenLine = "1:2\tn7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\t"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + }); + + describe('BookID tests - ', () => { + + it('should find invalid book ID', async () => { + const chosenLine = "1:2\tp7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + let error = false; + try { + await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GIN', '1', '2', 'from test line', optionalCheckingOptions); + error = false; + } catch (e) { + error = true; + } + expect(error).toBeTruthy(); + }); + + }); + + describe('TSV format tests - ', () => { + it('empty line should fail', async () => { + const chosenLine = ""; //lineG; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + expect(rawResults).toMatchSnapshot(); + }); + + it('header should succeed', async () => { + const chosenLine = "Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tNote"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(0); + }); + + it('header should fail', async () => { + const chosenLine = "Reference\tID\tTagg\tSupportReference\tBadQuote\tOccurrence\tNote"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(11); + }); + + it('should find wrong row count', async () => { + const chosenLine = "2:3\tw3r5\t\t1\t\t
Boo"; // only 6 fields + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + expect(rawResults).toMatchSnapshot(); + }); + + it('should fail not TSV', async () => { + const chosenLine = "Peace on Earth, good will to all men/people!"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); + expect(rawResults).toMatchSnapshot(); + }); + + }); + + describe('SupportReference tests - ', () => { + it('should find short SupportReference', async () => { + const chosenLine = "1:2\tq7q\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + rawResults.suggestion = undefined; // We need to get rid of random characters in suggestion + expect(rawResults).toMatchSnapshot(); + }); + + it('should find long SupportReference', async () => { + const chosenLine = "1:2\tr7q33\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should find missing SupportReference', async () => { + const chosenLine = "1:2\t\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + }); + + it('should find invalid SupportReference and missing quotes', async () => { + const chosenLine = "2:3\tw3r5\t\tLaugh\t\t1\tNote5"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '2', '3', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should handle front matter', async () => { + const chosenLine = "1:intro\tzb6f\t\t\t\t0\t# Genesis 01 General Notes

## Structure and formatting

This chapter presents the first account of God creating the world. There is a pattern to this account: “God said…God saw that it was good…This was evening and morning, the first day.” Translators should preserve this pattern in their versions.

## Special concepts in this chapter

### The universe

This account of creation is told within the framework of ancient Hebrew ideas about the universe: the earth was resting with water around it and below it. Over the earth was something like a vast dome, called “an expanse between the waters” (1:6), on top of which was more water. Translators should try to keep these original images in their work, even though readers in their project language might have a completely different idea of what the universe is like.

### Evening and morning

Genesis 1 presents the ancient Hebrew idea of a day: it begins with sunset, lasts through the night and continues through the daylight hours until the next sunset. This pattern should be preserved in translation, even if readers in the project language define “day” differently.

## Other possible translation difficulties in this chapter

### “In the beginning”

Some languages and cultures speak of the world as if it has always existed, as if it had no beginning. But “very long ago” is different from “in the beginning,” and you need to be sure that your translation communicates correctly.

### “God said, ‘Let there be’”

This expression occurs often in this chapter. It can be difficult to translate, because God is not shown as talking to a particular person. If God is talking to a thing, it is something not yet in existence. Translators should find the most natural way in the project language to signal the idea that God spoke things into existence; he created the world and the things in it by simply commanding that they should exist."; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', 'intro', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(3); + }); + + it('should find invalid Book ID, chapter number, ID, SupportReference, quotes, OccurrenceNote', async () => { + const chosenLine = "200:9\tW-3r5\t\tLaugh\t\t17\tBad ellipse...\t
Boo hoo,,
lost my shoe !"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GIN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(2); + expect(rawResults).toMatchSnapshot(); + }); + + it('should find mismatched chapter verse', async () => { + const chosenLine = "2:3\ts7qw\t\tfigs-imperative\t\t0\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '22', '33', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(5); + expect(rawResults).toMatchSnapshot(); + }); + + it('should find mismatched bookId', async () => { + const chosenLine = "1:2\tt7qw\t\tfigs-imperative\t\t0\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(3); + expect(rawResults).toMatchSnapshot(); + }); + + it('should find language code instead of asterisk', async () => { + const chosenLine = "1:2\tu7qw\t\tfigs-imperative\t\t0\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://en/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'EXO', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(4); + expect(rawResults).toMatchSnapshot(); + }); + + it('should be valid', async () => { + const chosenLine = "1:2\tv7qw\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; + const rawResults = await checkNotesTSV7DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(3); + }); + +}) diff --git a/src/__tests__/tn-table-row-check.test.js b/src/__tests__/tn-tsv9-table-row-check.test.js similarity index 80% rename from src/__tests__/tn-table-row-check.test.js rename to src/__tests__/tn-tsv9-table-row-check.test.js index 062c0c62c..bb1463ab6 100644 --- a/src/__tests__/tn-table-row-check.test.js +++ b/src/__tests__/tn-tsv9-table-row-check.test.js @@ -27,103 +27,103 @@ describe('checkTN_TSV9DataRow() - ', () => { describe('link tests - ', () => { it('should fail invalid doublet link', async () => { - const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh This is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism]], [Doublet](../figs-doublet/01.md))"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'that was supplied', optionalCheckingOptions); + const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism]], [Doublet](../figs-doublet/01.md))"; + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail broken link start', async () => { - const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh This is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [rc://*/ta/man/translate/figs-parallelism]]"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'that was supplied', optionalCheckingOptions); + const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [rc://*/ta/man/translate/figs-parallelism]]"; + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail broken link end', async () => { - const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh This is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism]"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'that was supplied', optionalCheckingOptions); + const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism]"; + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail double broken link start', async () => { - const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh This is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: rc://*/ta/man/translate/figs-parallelism]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'that was supplied', optionalCheckingOptions); + const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: rc://*/ta/man/translate/figs-parallelism]])"; + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should fail double broken link end', async () => { - const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh This is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism)"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'that was supplied', optionalCheckingOptions); + const chosenLine = "RUT\t2\t12\tgnn5\tfigs-parallelism\tשְׁלֵמָ֗ה\t1\tmay your full wages come from Yahweh\tThis is a poetic expression that is very similar to the previous sentence. Alternate translation: “May Yahweh fully give to you everything that you deserve” (See: [[rc://*/ta/man/translate/figs-parallelism)"; + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'RUT', '2', '12', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail if SupportReference link differs from link in OccurrenceNote', async () => { const chosenLine = "GEN\t1\t6\turb3\tfigs-imperative\t\t0\tLet there be an expanse…let it divide\tThese are commands. By commanding that the expanse should exist and that it divide the waters, God made it exist and divide the waters. (See: [[rc://*/ta/man/figs-parallelism]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '6', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '6', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail invalid link path', async () => { const chosenLine = "GEN\t1\t7\turb3\tfigs-imperative\t\t0\tLet there be an expanse…let it divide\tThese are commands. By commanding that the expanse should exist and that it divide the waters, God made it exist and divide the waters. (See: [[rc://*/ta/woman/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '7', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '7', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should succeed with mixed link types', async () => { const chosenLine = "GEN\t1\t8\tss9r\tfigs-merism\t\t0\tevening and morning\tThis refers to the whole day. The writer speaks of the whole day as if it were these two parts. In the Jewish culture, a day begins when the sun sets. See how you translated this in [Genesis 1:5](../01/05.md). (See: [[rc://*/ta/man/translate/figs-merism]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '8', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '8', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); }); it('should succeed with dual links', async () => { const chosenLine = "GEN\t1\t9\tzu6f\tfigs-activepassive\t\t0\tLet the waters…be gathered\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://*/ta/man/translate/figs-activepassive]] and [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); }); it('should fail invalid first link', async () => { const chosenLine = "GEN\t1\t9\tzu6f\tfigs-activepassive\t\t0\tLet the waters…be gathered\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://*/ta/man/translate/figs-activepassivez]] and [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(4); expect(rawResults).toMatchSnapshot(); }); it('should fail invalid second link', async () => { const chosenLine = "GEN\t1\t9\tzu6f\tfigs-activepassive\t\t0\tLet the waters…be gathered\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://*/ta/man/translate/figs-activepassive]] and [[rc://*/ta/man/translate/figs-imperativez]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(4); expect(rawResults).toMatchSnapshot(); }); it('should pass valid verse link', async () => { const chosenLine = "GEN\t1\t19\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md)."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '19', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '19', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(0); }); it('should fail invalid verse link', async () => { const chosenLine = "GEN\t1\t9\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/zzz.md)."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should fail invalid verse link start', async () => { const chosenLine = "GEN\t1\t9\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in Genesis 1:7](../01/07.md)."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should fail invalid verse link end', async () => { const chosenLine = "GEN\t1\t9\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '9', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); @@ -133,97 +133,97 @@ describe('checkTN_TSV9DataRow() - ', () => { describe('Original Quote tests - ', () => { it('invalid Original Language', async () => { const chosenLine = "GEN\t1\t1\tf2mg\t\t0\t\t\tIn the beginning, God created the heavens and the earth “This is about how God made the heavens and the earth in the beginning.” This statement summarizes the rest of the chapter. Some languages translate it as “A very long time ago God created the heavens and the earth.” Translate it in a way that shows this actually happened and is not just a folk story."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '1', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '1', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should find missing Original Quote', async () => { const chosenLine = "GEN\t1\t3\ta7qw\tfigs-imperative\t\t1\tLet there be light\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '3', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '3', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail to find OrigLang Quote', async () => { const chosenLine = "GEN\t1\t2\tb7qw\tfigs-imperative\tוְ⁠חֹ֖שֶךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail to find 2nd instance/occurrence', async () => { const chosenLine = "GEN\t1\t2\tc7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t2\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); }); it('should fail with leading space', async () => { const chosenLine = "GEN\t1\t2\te7qw\tfigs-imperative\t וְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail with trailing space', async () => { const chosenLine = "GEN\t1\t2\tf7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ \t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail with leading word joiner', async () => { const chosenLine = "GEN\t1\t2\tg7qw\tfigs-imperative\t\u2060וְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail with trailing word joiner', async () => { const chosenLine = "GEN\t1\t2\th7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\u2060\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail with leading zero width non-joiner', async () => { const chosenLine = "GEN\t1\t2\ti7qw\tfigs-imperative\t\u200cוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail with trailing zero width non-joiner', async () => { const chosenLine = "GEN\t1\t2\tj7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\u200c\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should fail with leading zero width joiner', async () => { const chosenLine = "GEN\t1\t2\tk7qw\tfigs-imperative\t\u200dוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail with trailing zero width joiner', async () => { const chosenLine = "GEN\t1\t2\tl7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\u200d\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should fail with valid but high occurrence number', async () => { const chosenLine = "MAT\t2\t2\tv248\t\tπροσκυνῆσαι\t2\tto worship\tPossible meanings are (1) they intended to worship the baby as divine, or (2) they wanted to honor him as a human king. If your language has a word that includes both meanings, you should consider using it here."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'MAT', '2', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'MAT', '2', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should pass with correct quote', async () => { const chosenLine = "MAT\t2\t2\tv248\t\tπροσκυνῆσαι\t1\tto worship\tPossible meanings are (1) they intended to worship the baby as divine, or (2) they wanted to honor him as a human king. If your language has a word that includes both meanings, you should consider using it here."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'MAT', '2', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'MAT', '2', '2', 'from test line', optionalCheckingOptions); // console.log(`Got raw results: ${JSON.stringify(rawResults)}`); expect(rawResults.noticeList.length).toEqual(0); }); @@ -234,14 +234,15 @@ describe('checkTN_TSV9DataRow() - ', () => { it('should find white space', async () => { const chosenLine = "GEN\t1\t2\tm7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\t "; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.some((entry) => entry.message.indexOf('whitespace') !== -1)); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should find empty note', async () => { const chosenLine = "GEN\t1\t2\tn7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\t"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); @@ -252,7 +253,7 @@ describe('checkTN_TSV9DataRow() - ', () => { it('should find bad ellipse', async () => { const chosenLine = "GEN\t2\t3\tw3r5\t\t\t1\tBad ellipse...\tNote8"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '2', '3', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '2', '3', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); @@ -263,16 +264,16 @@ describe('checkTN_TSV9DataRow() - ', () => { it('should find wrong book ID', async () => { const chosenLine = "RUT\t1\t2\to7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); - it.skip('should find invalid book ID', async () => { + it('should find invalid book ID', async () => { const chosenLine = "GIN\t1\t2\tp7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; let error = false; try { - await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GIN', '1', '2', 'that was supplied', optionalCheckingOptions); + await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GIN', '1', '2', 'from test line', optionalCheckingOptions); error = false; } catch (e) { error = true; @@ -285,27 +286,33 @@ describe('checkTN_TSV9DataRow() - ', () => { describe('TSV format tests - ', () => { it('empty line should fail', async () => { const chosenLine = ""; //lineG; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('header should succeed', async () => { const chosenLine = "Book\tChapter\tVerse\tID\tSupportReference\tOrigQuote\tOccurrence\tGLQuote\tOccurrenceNote"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(0); }); + it('header should fail', async () => { + const chosenLine = "Book\tChapter\tVerse\tID\tSupportReference\tOrigQuote\tOccurrence\tGLQuote\tOccurrenceNotes"; + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(11); + }); + it('should find wrong row count', async () => { const chosenLine = "EXO\t2\t3\tw3r5\t\t1\t\t
Boo"; // only 8 fields - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should fail not TSV', async () => { const chosenLine = "Peace on Earth, good will to all men/people!"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); @@ -315,7 +322,7 @@ describe('checkTN_TSV9DataRow() - ', () => { describe('SupportReference tests - ', () => { it('should find short SupportReference', async () => { const chosenLine = "GEN\t1\t2\tq7q\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); rawResults.suggestion = undefined; // We need to get rid of random characters in suggestion expect(rawResults).toMatchSnapshot(); @@ -323,14 +330,14 @@ describe('checkTN_TSV9DataRow() - ', () => { it('should find long SupportReference', async () => { const chosenLine = "GEN\t1\t2\tr7q33\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should find missing SupportReference', async () => { const chosenLine = "GEN\t1\t2\t\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); @@ -339,51 +346,49 @@ describe('checkTN_TSV9DataRow() - ', () => { it('should find invalid SupportReference and missing quotes', async () => { const chosenLine = "GEN\t2\t3\tw3r5\tLaugh\t\t1\t\tNote5"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '2', '3', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '2', '3', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(4); expect(rawResults).toMatchSnapshot(); }); - it('should skip front matter', async () => { + it('should handle front matter', async () => { const chosenLine = "GEN\t1\tintro\tzb6f\t\t\t0\t\t# Genesis 01 General Notes

## Structure and formatting

This chapter presents the first account of God creating the world. There is a pattern to this account: “God said…God saw that it was good…This was evening and morning, the first day.” Translators should preserve this pattern in their versions.

## Special concepts in this chapter

### The universe

This account of creation is told within the framework of ancient Hebrew ideas about the universe: the earth was resting with water around it and below it. Over the earth was something like a vast dome, called “an expanse between the waters” (1:6), on top of which was more water. Translators should try to keep these original images in their work, even though readers in their project language might have a completely different idea of what the universe is like.

### Evening and morning

Genesis 1 presents the ancient Hebrew idea of a day: it begins with sunset, lasts through the night and continues through the daylight hours until the next sunset. This pattern should be preserved in translation, even if readers in the project language define “day” differently.

## Other possible translation difficulties in this chapter

### “In the beginning”

Some languages and cultures speak of the world as if it has always existed, as if it had no beginning. But “very long ago” is different from “in the beginning,” and you need to be sure that your translation communicates correctly.

### “God said, ‘Let there be’”

This expression occurs often in this chapter. It can be difficult to translate, because God is not shown as talking to a particular person. If God is talking to a thing, it is something not yet in existence. Translators should find the most natural way in the project language to signal the idea that God spoke things into existence; he created the world and the things in it by simply commanding that they should exist."; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', 'intro', 'that was supplied', optionalCheckingOptions); - expect(rawResults.noticeList.length).toEqual(0); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', 'intro', 'from test line', optionalCheckingOptions); + expect(rawResults.noticeList.length).toEqual(1); }); it('should find invalid Book ID, chapter number, ID, SupportReference, quotes, OccurrenceNote', async () => { const chosenLine = "GIN\t200\t9\tW-3r5\tLaugh\t\t17\tBad ellipse...\t
Boo hoo,,
lost my shoe !"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(14); expect(rawResults).toMatchSnapshot(); }); it('should find mismatched chapter verse', async () => { const chosenLine = "GEN\t2\t3\ts7qw\tfigs-imperative\t\t0\tLet there be light\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '22', '33', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '22', '33', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(3); expect(rawResults).toMatchSnapshot(); }); it('should find mismatched bookId', async () => { const chosenLine = "EXO\t1\t2\tt7qw\tfigs-imperative\t\t0\tLet there be light\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(2); expect(rawResults).toMatchSnapshot(); }); it('should find language code instead of asterisk', async () => { const chosenLine = "EXO\t1\t2\tu7qw\tfigs-imperative\t\t0\tLet there be light\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://en/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'EXO', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'EXO', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); expect(rawResults).toMatchSnapshot(); }); it('should be valid', async () => { const chosenLine = "GEN\t1\t2\tv7qw\tfigs-imperative\tוְ⁠חֹ֖שֶׁךְ\t1\tDarkness\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://*/ta/man/translate/figs-imperative]])"; - const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'that was supplied', optionalCheckingOptions); + const rawResults = await checkTN_TSV9DataRow(languageCode, repoCode, chosenLine, 'GEN', '1', '2', 'from test line', optionalCheckingOptions); expect(rawResults.noticeList.length).toEqual(1); }); }) - - diff --git a/src/core/BCS-usfm-grammar-check.js b/src/core/BCS-usfm-grammar-check.js index 5679d461e..86ac89aaa 100644 --- a/src/core/BCS-usfm-grammar-check.js +++ b/src/core/BCS-usfm-grammar-check.js @@ -1,17 +1,30 @@ import grammar from 'usfm-grammar'; import * as books from '../core/books/books'; import { DEFAULT_EXCERPT_LENGTH } from './defaults' -import { userLog, debugLog, parameterAssert } from './utilities'; +// eslint-disable-next-line no-unused-vars +import { userLog, debugLog, functionLog, parameterAssert, ourParseInt } from './utilities'; -// const USFM_GRAMMAR_VALIDATOR_VERSION_STRING = '0.4.2'; +// const USFM_GRAMMAR_VALIDATOR_VERSION_STRING = '0.4.5'; +const LINE_COLUMN_NUMBERS_REGEX = new RegExp('Line (\\d{1,6}), col (\\d{1,4}):'); // e.g., "Line 1538, col 4: 1537 ..." -export function runBCSGrammarCheck(strictnessString, fileText, filename, givenLocation, checkingOptions) { + +/** + * + * @param {string} strictnessString -- 'strict' or 'relaxed' + * @param {string} bookID -- 3-character book ID + * @param {string} fileText -- the actual USFM text + * @param {string} filename -- for error messages + * @param {string} givenLocation -- for error messages + * @param {Object} checkingOptions -- optional options + * @returns {Object} including isValidUSFM flag + */ +export function runBCSGrammarCheck(strictnessString, bookID, fileText, filename, givenLocation, checkingOptions) { // Runs the BCS USFM Grammar checker // which can be quite time-consuming on large, complex USFM files - // debugLog(`Running ${strictnessString} BCS USFM grammar check${givenLocation} (can take quite a while for a large book)…`); - parameterAssert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); + // userLog(`Running ${strictnessString} BCS USFM grammar check${givenLocation} (can take quite a while for a large book)…`); + //parameterAssert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); let excerptLength; try { @@ -35,36 +48,51 @@ export function runBCSGrammarCheck(strictnessString, fileText, filename, givenLo // Returns a Boolean indicating whether the input USFM text satisfies the grammar or not. // This method is available in both default and relaxed modes. // const parserResult = ourUsfmParser.validate(); - // debugLog(`${new Date().getTime() / 1000} Running the USFMGrammar checker (may take several seconds)…`); - debugLog("Running the USFMGrammar checker (may take several seconds)…"); + // debugLog(`${new Date().getTime() / 1000} Running the BCS USFMGrammar checker (may take several seconds)…`); + // userLog(`Running the BCS USFMGrammar checker for ${bookID} (may take several seconds)…`); parserToJSONResultObject = ourUsfmParser.toJSON(); - // debugLog(`${new Date().getTime() / 1000} Got the USFMGrammar checker toJSON result: ${Object.keys(parserToJSONResultObject)}`); - // debugLog(`${new Date().getTime() / 1000} Got the USFMGrammar checker toJSON _messages: ${Object.keys(parserToJSONResultObject._messages)}`); - // debugLog(`${new Date().getTime() / 1000} Got the USFMGrammar checker: ${Object.keys(ourUsfmParser)}`); + // debugLog(`${new Date().getTime() / 1000} Got the BCS USFMGrammar checker toJSON result: ${Object.keys(parserToJSONResultObject)}`); + // debugLog(`${new Date().getTime() / 1000} Got the BCS USFMGrammar checker toJSON _messages: ${Object.keys(parserToJSONResultObject._messages)}`); + // debugLog(`${new Date().getTime() / 1000} Got the BCS USFMGrammar checker: ${Object.keys(ourUsfmParser)}`); parseWarnings = parserToJSONResultObject._warnings ? parserToJSONResultObject._warnings : ourUsfmParser.warnings; - // debugLog(`${new Date().getTime() / 1000} Got warnings from the USFMGrammar checker: (${parseWarnings.length}) ${parseWarnings}`); + // debugLog(`${new Date().getTime() / 1000} Got warnings from the BCS USFMGrammar checker: (${parseWarnings.length}) ${parseWarnings}`); } catch (parserError) { // This is how the Parser returns USFM errors, i.e., it stops after the first error - // debugLog(`${new Date().getTime() / 1000} Got an exception when using the USFMGrammar checker: ${parserError}`); + // debugLog(`${new Date().getTime() / 1000} Got an exception when using the BCS USFMGrammar checker: ${parserError}`); const ourErrorObject = { priority: 840, message: "USFMGrammar check failed", details: parserError, filename, location: givenLocation }; - // Say it's valid so we don't get an additional high-priority error - return { isValidUSFM: true, error: ourErrorObject, warnings: [] }; + try { // See if we can improve the result with line and column numbers + // NOTE: The following code is quite fragile + // as it depends on the precise format of the error message returned from USFMParser + const regexResultArray = LINE_COLUMN_NUMBERS_REGEX.exec(parserError); + const [totalLink, lineNumberString, columnNumberString] = regexResultArray; + ourErrorObject.lineNumber = ourParseInt(lineNumberString); + ourErrorObject.characterIndex = ourParseInt(columnNumberString) - 1; + const errorLineText = fileText.split('\n')[ourErrorObject.lineNumber - 1]; + ourErrorObject.excerpt = (ourErrorObject.characterIndex > excerptHalfLength ? '…' : '') + errorLineText.substring(ourErrorObject.characterIndex - excerptHalfLength, ourErrorObject.characterIndex + excerptHalfLengthPlus) + (ourErrorObject.characterIndex + excerptHalfLengthPlus < errorLineText.length ? '…' : ''); + // NOTE: Not 100% sure that it's more helpful to the user if we do this next line ??? + ourErrorObject.details = ourErrorObject.details.substring(totalLink.length); // Delete the line and column numbers that we found + } catch (secondError) { + debugLog(`USFMGrammar second error: ${secondError}`); + } + return { isValidUSFM: false, error: ourErrorObject, warnings: [] }; } let parserMessages; parserMessages = parserToJSONResultObject._messages; // Throw away the JSON (if any) // debugLog(` Finished BCS USFM grammar check with messages: ${JSON.stringify(parserResult)}\n and warnings: ${JSON.stringify(ourUsfmParser.warnings)}.`); + + // TODO: I think most of the following code is now obsolete and can be deleted let parseError; parseError = parserMessages._error; - // debugLog(` parseError: ${parseError}`); let ourErrorMessage, lineNumberString, characterIndex, excerpt; // NOTE: The following code is quite fragile // as it depends on the precise format of the error message returned from USFMParser let ourErrorObject = {}; if (parseError) { + debugLog("Oh! This USFMGrammer check code IS still needed!!!"); const contextRE = /(\d+?)\s\|\s(.+)/g; for (const errorLine of parseError.split('\n')) { // debugLog(`BCS errorLine=${errorLine}`); @@ -147,8 +175,8 @@ export function checkUSFMGrammar(bookID, strictnessString, filename, givenText, Returns a result object containing a successList and a noticeList */ - userLog(`checkUSFMGrammar(${givenText.length.toLocaleString()} chars, '${givenLocation}')…`); - parameterAssert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); + functionLog(`checkUSFMGrammar(${givenText.length.toLocaleString()} chars, '${givenLocation}')…`); + //parameterAssert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -171,16 +199,18 @@ export function checkUSFMGrammar(bookID, strictnessString, filename, givenText, */ function addNoticePartial(noticeObject) { // functionLog(`checkUSFMGrammar notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cUSFMgr addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cUSFMgr addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cUSFMgr addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cUSFMgr addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cUSFMgr addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cUSFMgr addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cUSFMgr addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cUSFMgr addNoticePartial: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cUSFMgr addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cUSFMgr addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cUSFMgr addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cUSFMgr addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cUSFMgr addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cUSFMgr addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "cUSFMgr addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cUSFMgr addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cUSFMgr addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cUSFMgr addNoticePartial: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cUSFMgr addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cUSFMgr addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); cugResult.noticeList.push({ ...noticeObject, bookID, filename }); } @@ -189,7 +219,7 @@ export function checkUSFMGrammar(bookID, strictnessString, filename, givenText, if (books.isExtraBookID(bookID)) // doesn’t work for these return cugResult; - const grammarCheckResult = runBCSGrammarCheck(strictnessString, givenText, filename, ourLocation, checkingOptions); + const grammarCheckResult = runBCSGrammarCheck(strictnessString, bookID, givenText, filename, ourLocation, checkingOptions); // debugLog(`grammarCheckResult=${JSON.stringify(grammarCheckResult)}`); if (!grammarCheckResult.isValidUSFM) diff --git a/src/core/BCS-usfm-grammar-check.md b/src/core/BCS-usfm-grammar-check.md index 76f843d6c..6c57a983f 100644 --- a/src/core/BCS-usfm-grammar-check.md +++ b/src/core/BCS-usfm-grammar-check.md @@ -7,11 +7,13 @@ Our packaged function returns a list of success messages and a list of (prioriti These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkUSFMGrammar } from './BCS-usfm-grammar-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderNumberedLines, RenderRawResults } from '../demos/RenderProcessedResults'; // USFM samples const textS = `\\id GEN Short test @@ -215,7 +217,7 @@ const strictness = 'strict'; const rawResults = checkUSFMGrammar(bookID, strictness, chosenTextName, chosenText, 'that was supplied'); <> -Check +Check ``` diff --git a/src/core/books/books.js b/src/core/books/books.js index 844b86edc..0ba0cc274 100644 --- a/src/core/books/books.js +++ b/src/core/books/books.js @@ -1,69 +1,70 @@ -export const BibleBookData = { "gen": {"id": "gen", "title": "Genesis", "usfm": "01-GEN", "testament": "old", "verseCount": 1533, "chapters": [31, 25, 24, 26, 32, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 18, 34, 24, 20, 67, 34, 35, 46, 22, 35, 43, 55, 32, 20, 31, 29, 43, 36, 30, 23, 23, 57, 38, 34, 34, 28, 34, 31, 22, 33, 26]}, -"exo": {"id": "exo", "title": "Exodus", "usfm": "02-EXO", "testament": "old", "verseCount": 1213, "chapters": [22, 25, 22, 31, 23, 30, 25, 32, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 26, 36, 31, 33, 18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 31, 43, 38]}, -"lev": {"id": "lev", "title": "Leviticus", "usfm": "03-LEV", "testament": "old", "verseCount": 859, "chapters": [17, 16, 17, 35, 19, 30, 38, 36, 24, 20, 47, 8, 59, 57, 33, 34, 16, 30, 37, 27, 24, 33, 44, 23, 55, 46, 34]}, -"num": {"id": "num", "title": "Numbers", "usfm": "04-NUM", "testament": "old", "verseCount": 1288, "chapters": [54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 35, 16, 33, 45, 41, 50, 13, 32, 22, 29, 35, 41, 30, 25, 18, 65, 23, 31, 40, 16, 54, 42, 56, 29, 34, 13]}, -"deu": {"id": "deu", "title": "Deuteronomy", "usfm": "05-DEU", "testament": "old", "verseCount": 959, "chapters": [46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 32, 18, 29, 23, 22, 20, 22, 21, 20, 23, 30, 25, 22, 19, 19, 26, 68, 29, 20, 30, 52, 29, 12]}, -"jos": {"id": "jos", "title": "Joshua", "usfm": "06-JOS", "testament": "old", "verseCount": 658, "chapters": [18, 24, 17, 24, 15, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51, 9, 45, 34, 16, 33]}, -"jdg": {"id": "jdg", "title": "Judges", "usfm": "07-JDG", "testament": "old", "verseCount": 618, "chapters": [36, 23, 31, 24, 31, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 48, 25]}, -"rut": {"id": "rut", "title": "Ruth", "usfm": "08-RUT", "testament": "old", "verseCount": 85, "chapters": [22, 23, 18, 22]}, -"1sa": {"id": "1sa", "title": "1 Samuel", "usfm": "09-1SA", "testament": "old", "verseCount": 810, "chapters": [28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 42, 15, 23, 29, 22, 44, 25, 12, 25, 11, 31, 13]}, -"2sa": {"id": "2sa", "title": "2 Samuel", "usfm": "10-2SA", "testament": "old", "verseCount": 695, "chapters": [27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 33, 43, 26, 22, 51, 39, 25]}, -"1ki": {"id": "1ki", "title": "1 Kings", "usfm": "11-1KI", "testament": "old", "verseCount": 816, "chapters": [53, 46, 28, 34, 18, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 43, 29, 53]}, -"2ki": {"id": "2ki", "title": "2 Kings", "usfm": "12-2KI", "testament": "old", "verseCount": 719, "chapters": [18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 21, 21, 25, 29, 38, 20, 41, 37, 37, 21, 26, 20, 37, 20, 30]}, -"1ch": {"id": "1ch", "title": "1 Chronicles", "usfm": "13-1CH", "testament": "old", "verseCount": 942, "chapters": [54, 55, 24, 43, 26, 81, 40, 40, 44, 14, 47, 40, 14, 17, 29, 43, 27, 17, 19, 8, 30, 19, 32, 31, 31, 32, 34, 21, 30]}, -"2ch": {"id": "2ch", "title": "2 Chronicles", "usfm": "14-2CH", "testament": "old", "verseCount": 822, "chapters": [17, 18, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 22, 15, 19, 14, 19, 34, 11, 37, 20, 12, 21, 27, 28, 23, 9, 27, 36, 27, 21, 33, 25, 33, 27, 23]}, -"ezr": {"id": "ezr", "title": "Ezra", "usfm": "15-EZR", "testament": "old", "verseCount": 280, "chapters": [11, 70, 13, 24, 17, 22, 28, 36, 15, 44]}, -"neh": {"id": "neh", "title": "Nehemiah", "usfm": "16-NEH", "testament": "old", "verseCount": 406, "chapters": [11, 20, 32, 23, 19, 19, 73, 18, 38, 39, 36, 47, 31]}, -"est": {"id": "est", "title": "Esther", "usfm": "17-EST", "testament": "old", "verseCount": 167, "chapters": [22, 23, 15, 17, 14, 14, 10, 17, 32, 3]}, -"job": {"id": "job", "title": "Job", "usfm": "18-JOB", "testament": "old", "verseCount": 1070, "chapters": [22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 22, 16, 21, 29, 29, 34, 30, 17, 25, 6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 30, 24, 34, 17]}, -"psa": {"id": "psa", "title": "Psalms", "usfm": "19-PSA", "testament": "old", "verseCount": 2461, "chapters": [6, 12, 8, 8, 12, 10, 17, 9, 20, 18, 7, 8, 6, 7, 5, 11, 15, 50, 14, 9, 13, 31, 6, 10, 22, 12, 14, 9, 11, 12, 24, 11, 22, 22, 28, 12, 40, 22, 13, 17, 13, 11, 5, 26, 17, 11, 9, 14, 20, 23, 19, 9, 6, 7, 23, 13, 11, 11, 17, 12, 8, 12, 11, 10, 13, 20, 7, 35, 36, 5, 24, 20, 28, 23, 10, 12, 20, 72, 13, 19, 16, 8, 18, 12, 13, 17, 7, 18, 52, 17, 16, 15, 5, 23, 11, 13, 12, 9, 9, 5, 8, 28, 22, 35, 45, 48, 43, 13, 31, 7, 10, 10, 9, 8, 18, 19, 2, 29, 176, 7, 8, 9, 4, 8, 5, 6, 5, 6, 8, 8, 3, 18, 3, 3, 21, 26, 9, 8, 24, 13, 10, 7, 12, 15, 21, 10, 20, 14, 9, 6]}, -"pro": {"id": "pro", "title": "Proverbs", "usfm": "20-PRO", "testament": "old", "verseCount": 915, "chapters": [33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 30, 31, 29, 35, 34, 28, 28, 27, 28, 27, 33, 31]}, -"ecc": {"id": "ecc", "title": "Ecclesiastes", "usfm": "21-ECC", "testament": "old", "verseCount": 222, "chapters": [18, 26, 22, 16, 20, 12, 29, 17, 18, 20, 10, 14]}, -"sng": {"id": "sng", "title": "Song of Songs", "usfm": "22-SNG", "testament": "old", "verseCount": 117, "chapters": [17, 17, 11, 16, 16, 13, 13, 14]}, -"isa": {"id": "isa", "title": "Isaiah", "usfm": "23-ISA", "testament": "old", "verseCount": 1292, "chapters": [31, 22, 26, 6, 30, 13, 25, 22, 21, 34, 16, 6, 22, 32, 9, 14, 14, 7, 25, 6, 17, 25, 18, 23, 12, 21, 13, 29, 24, 33, 9, 20, 24, 17, 10, 22, 38, 22, 8, 31, 29, 25, 28, 28, 25, 13, 15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 14, 21, 22, 11, 12, 19, 12, 25, 24]}, -"jer": {"id": "jer", "title": "Jeremiah", "usfm": "24-JER", "testament": "old", "verseCount": 1364, "chapters": [19, 37, 25, 31, 31, 30, 34, 22, 26, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 18, 14, 30, 40, 10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 21, 28, 18, 16, 18, 22, 13, 30, 5, 28, 7, 47, 39, 46, 64, 34]}, -"lam": {"id": "lam", "title": "Lamentations", "usfm": "25-LAM", "testament": "old", "verseCount": 154, "chapters": [22, 22, 66, 22, 22]}, -"ezk": {"id": "ezk", "title": "Ezekiel", "usfm": "26-EZK", "testament": "old", "verseCount": 1273, "chapters": [28, 10, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23, 8, 63, 24, 32, 14, 49, 32, 31, 49, 27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 23, 29, 49, 26, 20, 27, 31, 25, 24, 23, 35]}, -"dan": {"id": "dan", "title": "Daniel", "usfm": "27-DAN", "testament": "old", "verseCount": 357, "chapters": [21, 49, 30, 37, 31, 28, 28, 27, 27, 21, 45, 13]}, -"hos": {"id": "hos", "title": "Hosea", "usfm": "28-HOS", "testament": "old", "verseCount": 197, "chapters": [11, 23, 5, 19, 15, 11, 16, 14, 17, 15, 12, 14, 16, 9]}, -"jol": {"id": "jol", "title": "Joel", "usfm": "29-JOL", "testament": "old", "verseCount": 73, "chapters": [20, 32, 21]}, -"amo": {"id": "amo", "title": "Amos", "usfm": "30-AMO", "testament": "old", "verseCount": 146, "chapters": [15, 16, 15, 13, 27, 14, 17, 14, 15]}, -"oba": {"id": "oba", "title": "Obadiah", "usfm": "31-OBA", "testament": "old", "verseCount": 21, "chapters": [21]}, -"jon": {"id": "jon", "title": "Jonah", "usfm": "32-JON", "testament": "old", "verseCount": 48, "chapters": [17, 10, 10, 11]}, -"mic": {"id": "mic", "title": "Micah", "usfm": "33-MIC", "testament": "old", "verseCount": 105, "chapters": [16, 13, 12, 13, 15, 16, 20]}, -"nam": {"id": "nam", "title": "Nahum", "usfm": "34-NAM", "testament": "old", "verseCount": 47, "chapters": [15, 13, 19]}, -"hab": {"id": "hab", "title": "Habakkuk", "usfm": "35-HAB", "testament": "old", "verseCount": 56, "chapters": [17, 20, 19]}, -"zep": {"id": "zep", "title": "Zephaniah", "usfm": "36-ZEP", "testament": "old", "verseCount": 53, "chapters": [18, 15, 20]}, -"hag": {"id": "hag", "title": "Haggai", "usfm": "37-HAG", "testament": "old", "verseCount": 38, "chapters": [15, 23]}, -"zec": {"id": "zec", "title": "Zechariah", "usfm": "38-ZEC", "testament": "old", "verseCount": 211, "chapters": [21, 13, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14, 9, 21]}, -"mal": {"id": "mal", "title": "Malachi", "usfm": "39-MAL", "testament": "old", "verseCount": 55, "chapters": [14, 17, 18, 6]}, -"mat": {"id": "mat", "title": "Matthew", "usfm": "41-MAT", "testament": "new", "verseCount": 1071, "chapters": [25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 27, 35, 30, 34, 46, 46, 39, 51, 46, 75, 66, 20]}, -"mrk": {"id": "mrk", "title": "Mark", "usfm": "42-MRK", "testament": "new", "verseCount": 678, "chapters": [45, 28, 35, 41, 43, 56, 37, 38, 50, 52, 33, 44, 37, 72, 47, 20]}, -"luk": {"id": "luk", "title": "Luke", "usfm": "43-LUK", "testament": "new", "verseCount": 1151, "chapters": [80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 47, 38, 71, 56, 53]}, -"jhn": {"id": "jhn", "title": "John", "usfm": "44-JHN", "testament": "new", "verseCount": 879, "chapters": [51, 25, 36, 54, 47, 71, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 31, 25]}, -"act": {"id": "act", "title": "Acts", "usfm": "45-ACT", "testament": "new", "verseCount": 1007, "chapters": [26, 47, 26, 37, 42, 15, 60, 40, 43, 48, 30, 25, 52, 28, 41, 40, 34, 28, 41, 38, 40, 30, 35, 27, 27, 32, 44, 31]}, -"rom": {"id": "rom", "title": "Romans", "usfm": "46-ROM", "testament": "new", "verseCount": 433, "chapters": [32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27]}, -"1co": {"id": "1co", "title": "1 Corinthians", "usfm": "47-1CO", "testament": "new", "verseCount": 437, "chapters": [31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24]}, -"2co": {"id": "2co", "title": "2 Corinthians", "usfm": "48-2CO", "testament": "new", "verseCount": 257, "chapters": [24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 14]}, -"gal": {"id": "gal", "title": "Galatians", "usfm": "49-GAL", "testament": "new", "verseCount": 149, "chapters": [24, 21, 29, 31, 26, 18]}, -"eph": {"id": "eph", "title": "Ephesians", "usfm": "50-EPH", "testament": "new", "verseCount": 155, "chapters": [23, 22, 21, 32, 33, 24]}, -"php": {"id": "php", "title": "Philippians", "usfm": "51-PHP", "testament": "new", "verseCount": 104, "chapters": [30, 30, 21, 23]}, -"col": {"id": "col", "title": "Colossians", "usfm": "52-COL", "testament": "new", "verseCount": 95, "chapters": [29, 23, 25, 18]}, -"1th": {"id": "1th", "title": "1 Thessalonians", "usfm": "53-1TH", "testament": "new", "verseCount": 89, "chapters": [10, 20, 13, 18, 28]}, -"2th": {"id": "2th", "title": "2 Thessalonians", "usfm": "54-2TH", "testament": "new", "verseCount": 47, "chapters": [12, 17, 18]}, -"1ti": {"id": "1ti", "title": "1 Timothy", "usfm": "55-1TI", "testament": "new", "verseCount": 113, "chapters": [20, 15, 16, 16, 25, 21]}, -"2ti": {"id": "2ti", "title": "2 Timothy", "usfm": "56-2TI", "testament": "new", "verseCount": 83, "chapters": [18, 26, 17, 22]}, -"tit": {"id": "tit", "title": "Titus", "usfm": "57-TIT", "testament": "new", "verseCount": 46, "chapters": [16, 15, 15]}, -"phm": {"id": "phm", "title": "Philemon", "usfm": "58-PHM", "testament": "new", "verseCount": 25, "chapters": [25]}, -"heb": {"id": "heb", "title": "Hebrews", "usfm": "59-HEB", "testament": "new", "verseCount": 303, "chapters": [14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25]}, -"jas": {"id": "jas", "title": "James", "usfm": "60-JAS", "testament": "new", "verseCount": 108, "chapters": [27, 26, 18, 17, 20]}, -"1pe": {"id": "1pe", "title": "1 Peter", "usfm": "61-1PE", "testament": "new", "verseCount": 105, "chapters": [25, 25, 22, 19, 14]}, -"2pe": {"id": "2pe", "title": "2 Peter", "usfm": "62-2PE", "testament": "new", "verseCount": 61, "chapters": [21, 22, 18]}, -"1jn": {"id": "1jn", "title": "1 John", "usfm": "63-1JN", "testament": "new", "verseCount": 105, "chapters": [10, 29, 24, 21, 21]}, -"2jn": {"id": "2jn", "title": "2 John", "usfm": "64-2JN", "testament": "new", "verseCount": 13, "chapters": [13]}, -"3jn": {"id": "3jn", "title": "3 John", "usfm": "65-3JN", "testament": "new", "verseCount": 15, "chapters": [15]}, -"jud": {"id": "jud", "title": "Jude", "usfm": "66-JUD", "testament": "new", "verseCount": 25, "chapters": [25]}, -"rev": {"id": "rev", "title": "Revelation", "usfm": "67-REV", "testament": "new", "verseCount": 404, "chapters": [20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 17, 18, 20, 8, 21, 18, 24, 21, 15, 27, 21]} +export const BibleBookData = { + 'GEN': { 'title': 'Genesis', 'usfm': '01-GEN', 'testament': 'old', 'verseCount': 1533, 'verseList': [31, 25, 24, 26, 32, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 18, 34, 24, 20, 67, 34, 35, 46, 22, 35, 43, 55, 32, 20, 31, 29, 43, 36, 30, 23, 23, 57, 38, 34, 34, 28, 34, 31, 22, 33, 26] }, + 'EXO': { 'title': 'Exodus', 'usfm': '02-EXO', 'testament': 'old', 'verseCount': 1213, 'verseList': [22, 25, 22, 31, 23, 30, 25, 32, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 26, 36, 31, 33, 18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 31, 43, 38] }, + 'LEV': { 'title': 'Leviticus', 'usfm': '03-LEV', 'testament': 'old', 'verseCount': 859, 'verseList': [17, 16, 17, 35, 19, 30, 38, 36, 24, 20, 47, 8, 59, 57, 33, 34, 16, 30, 37, 27, 24, 33, 44, 23, 55, 46, 34] }, + 'NUM': { 'title': 'Numbers', 'usfm': '04-NUM', 'testament': 'old', 'verseCount': 1288, 'verseList': [54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 35, 16, 33, 45, 41, 50, 13, 32, 22, 29, 35, 41, 30, 25, 18, 65, 23, 31, 40, 16, 54, 42, 56, 29, 34, 13] }, + 'DEU': { 'title': 'Deuteronomy', 'usfm': '05-DEU', 'testament': 'old', 'verseCount': 959, 'verseList': [46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 32, 18, 29, 23, 22, 20, 22, 21, 20, 23, 30, 25, 22, 19, 19, 26, 68, 29, 20, 30, 52, 29, 12] }, + 'JOS': { 'title': 'Joshua', 'usfm': '06-JOS', 'testament': 'old', 'verseCount': 658, 'verseList': [18, 24, 17, 24, 15, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51, 9, 45, 34, 16, 33] }, + 'JDG': { 'title': 'Judges', 'usfm': '07-JDG', 'testament': 'old', 'verseCount': 618, 'verseList': [36, 23, 31, 24, 31, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 48, 25] }, + 'RUT': { 'title': 'Ruth', 'usfm': '08-RUT', 'testament': 'old', 'verseCount': 85, 'verseList': [22, 23, 18, 22] }, + '1SA': { 'title': '1 Samuel', 'usfm': '09-1SA', 'testament': 'old', 'verseCount': 810, 'verseList': [28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 42, 15, 23, 29, 22, 44, 25, 12, 25, 11, 31, 13] }, + '2SA': { 'title': '2 Samuel', 'usfm': '10-2SA', 'testament': 'old', 'verseCount': 695, 'verseList': [27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 33, 43, 26, 22, 51, 39, 25] }, + '1KI': { 'title': '1 Kings', 'usfm': '11-1KI', 'testament': 'old', 'verseCount': 816, 'verseList': [53, 46, 28, 34, 18, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 43, 29, 53] }, + '2KI': { 'title': '2 Kings', 'usfm': '12-2KI', 'testament': 'old', 'verseCount': 719, 'verseList': [18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 21, 21, 25, 29, 38, 20, 41, 37, 37, 21, 26, 20, 37, 20, 30] }, + '1CH': { 'title': '1 Chronicles', 'usfm': '13-1CH', 'testament': 'old', 'verseCount': 942, 'verseList': [54, 55, 24, 43, 26, 81, 40, 40, 44, 14, 47, 40, 14, 17, 29, 43, 27, 17, 19, 8, 30, 19, 32, 31, 31, 32, 34, 21, 30] }, + '2CH': { 'title': '2 Chronicles', 'usfm': '14-2CH', 'testament': 'old', 'verseCount': 822, 'verseList': [17, 18, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 22, 15, 19, 14, 19, 34, 11, 37, 20, 12, 21, 27, 28, 23, 9, 27, 36, 27, 21, 33, 25, 33, 27, 23] }, + 'EZR': { 'title': 'Ezra', 'usfm': '15-EZR', 'testament': 'old', 'verseCount': 280, 'verseList': [11, 70, 13, 24, 17, 22, 28, 36, 15, 44] }, + 'NEH': { 'title': 'Nehemiah', 'usfm': '16-NEH', 'testament': 'old', 'verseCount': 406, 'verseList': [11, 20, 32, 23, 19, 19, 73, 18, 38, 39, 36, 47, 31] }, + 'EST': { 'title': 'Esther', 'usfm': '17-EST', 'testament': 'old', 'verseCount': 167, 'verseList': [22, 23, 15, 17, 14, 14, 10, 17, 32, 3] }, + 'JOB': { 'title': 'Job', 'usfm': '18-JOB', 'testament': 'old', 'verseCount': 1070, 'verseList': [22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 22, 16, 21, 29, 29, 34, 30, 17, 25, 6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 30, 24, 34, 17] }, + 'PSA': { 'title': 'Psalms', 'usfm': '19-PSA', 'testament': 'old', 'verseCount': 2461, 'verseList': [6, 12, 8, 8, 12, 10, 17, 9, 20, 18, 7, 8, 6, 7, 5, 11, 15, 50, 14, 9, 13, 31, 6, 10, 22, 12, 14, 9, 11, 12, 24, 11, 22, 22, 28, 12, 40, 22, 13, 17, 13, 11, 5, 26, 17, 11, 9, 14, 20, 23, 19, 9, 6, 7, 23, 13, 11, 11, 17, 12, 8, 12, 11, 10, 13, 20, 7, 35, 36, 5, 24, 20, 28, 23, 10, 12, 20, 72, 13, 19, 16, 8, 18, 12, 13, 17, 7, 18, 52, 17, 16, 15, 5, 23, 11, 13, 12, 9, 9, 5, 8, 28, 22, 35, 45, 48, 43, 13, 31, 7, 10, 10, 9, 8, 18, 19, 2, 29, 176, 7, 8, 9, 4, 8, 5, 6, 5, 6, 8, 8, 3, 18, 3, 3, 21, 26, 9, 8, 24, 13, 10, 7, 12, 15, 21, 10, 20, 14, 9, 6] }, + 'PRO': { 'title': 'Proverbs', 'usfm': '20-PRO', 'testament': 'old', 'verseCount': 915, 'verseList': [33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 30, 31, 29, 35, 34, 28, 28, 27, 28, 27, 33, 31] }, + 'ECC': { 'title': 'Ecclesiastes', 'usfm': '21-ECC', 'testament': 'old', 'verseCount': 222, 'verseList': [18, 26, 22, 16, 20, 12, 29, 17, 18, 20, 10, 14] }, + 'SNG': { 'title': 'Song of Songs', 'usfm': '22-SNG', 'testament': 'old', 'verseCount': 117, 'verseList': [17, 17, 11, 16, 16, 13, 13, 14] }, + 'ISA': { 'title': 'Isaiah', 'usfm': '23-ISA', 'testament': 'old', 'verseCount': 1292, 'verseList': [31, 22, 26, 6, 30, 13, 25, 22, 21, 34, 16, 6, 22, 32, 9, 14, 14, 7, 25, 6, 17, 25, 18, 23, 12, 21, 13, 29, 24, 33, 9, 20, 24, 17, 10, 22, 38, 22, 8, 31, 29, 25, 28, 28, 25, 13, 15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 14, 21, 22, 11, 12, 19, 12, 25, 24] }, + 'JER': { 'title': 'Jeremiah', 'usfm': '24-JER', 'testament': 'old', 'verseCount': 1364, 'verseList': [19, 37, 25, 31, 31, 30, 34, 22, 26, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 18, 14, 30, 40, 10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 21, 28, 18, 16, 18, 22, 13, 30, 5, 28, 7, 47, 39, 46, 64, 34] }, + 'LAM': { 'title': 'Lamentations', 'usfm': '25-LAM', 'testament': 'old', 'verseCount': 154, 'verseList': [22, 22, 66, 22, 22] }, + 'EZK': { 'title': 'Ezekiel', 'usfm': '26-EZK', 'testament': 'old', 'verseCount': 1273, 'verseList': [28, 10, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23, 8, 63, 24, 32, 14, 49, 32, 31, 49, 27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 23, 29, 49, 26, 20, 27, 31, 25, 24, 23, 35] }, + 'DAN': { 'title': 'Daniel', 'usfm': '27-DAN', 'testament': 'old', 'verseCount': 357, 'verseList': [21, 49, 30, 37, 31, 28, 28, 27, 27, 21, 45, 13] }, + 'HOS': { 'title': 'Hosea', 'usfm': '28-HOS', 'testament': 'old', 'verseCount': 197, 'verseList': [11, 23, 5, 19, 15, 11, 16, 14, 17, 15, 12, 14, 16, 9] }, + 'JOL': { 'title': 'Joel', 'usfm': '29-JOL', 'testament': 'old', 'verseCount': 73, 'verseList': [20, 32, 21] }, + 'AMO': { 'title': 'Amos', 'usfm': '30-AMO', 'testament': 'old', 'verseCount': 146, 'verseList': [15, 16, 15, 13, 27, 14, 17, 14, 15] }, + 'OBA': { 'title': 'Obadiah', 'usfm': '31-OBA', 'testament': 'old', 'verseCount': 21, 'verseList': [21] }, + 'JON': { 'title': 'Jonah', 'usfm': '32-JON', 'testament': 'old', 'verseCount': 48, 'verseList': [17, 10, 10, 11] }, + 'MIC': { 'title': 'Micah', 'usfm': '33-MIC', 'testament': 'old', 'verseCount': 105, 'verseList': [16, 13, 12, 13, 15, 16, 20] }, + 'NAM': { 'title': 'Nahum', 'usfm': '34-NAM', 'testament': 'old', 'verseCount': 47, 'verseList': [15, 13, 19] }, + 'HAB': { 'title': 'Habakkuk', 'usfm': '35-HAB', 'testament': 'old', 'verseCount': 56, 'verseList': [17, 20, 19] }, + 'ZEP': { 'title': 'Zephaniah', 'usfm': '36-ZEP', 'testament': 'old', 'verseCount': 53, 'verseList': [18, 15, 20] }, + 'HAG': { 'title': 'Haggai', 'usfm': '37-HAG', 'testament': 'old', 'verseCount': 38, 'verseList': [15, 23] }, + 'ZEC': { 'title': 'Zechariah', 'usfm': '38-ZEC', 'testament': 'old', 'verseCount': 211, 'verseList': [21, 13, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14, 9, 21] }, + 'MAL': { 'title': 'Malachi', 'usfm': '39-MAL', 'testament': 'old', 'verseCount': 55, 'verseList': [14, 17, 18, 6] }, + 'MAT': { 'title': 'Matthew', 'usfm': '41-MAT', 'testament': 'new', 'verseCount': 1071, 'verseList': [25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 27, 35, 30, 34, 46, 46, 39, 51, 46, 75, 66, 20] }, + 'MRK': { 'title': 'Mark', 'usfm': '42-MRK', 'testament': 'new', 'verseCount': 678, 'verseList': [45, 28, 35, 41, 43, 56, 37, 38, 50, 52, 33, 44, 37, 72, 47, 20] }, + 'LUK': { 'title': 'Luke', 'usfm': '43-LUK', 'testament': 'new', 'verseCount': 1151, 'verseList': [80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 47, 38, 71, 56, 53] }, + 'JHN': { 'title': 'John', 'usfm': '44-JHN', 'testament': 'new', 'verseCount': 879, 'verseList': [51, 25, 36, 54, 47, 71, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 31, 25] }, + 'ACT': { 'title': 'Acts', 'usfm': '45-ACT', 'testament': 'new', 'verseCount': 1007, 'verseList': [26, 47, 26, 37, 42, 15, 60, 40, 43, 48, 30, 25, 52, 28, 41, 40, 34, 28, 41, 38, 40, 30, 35, 27, 27, 32, 44, 31] }, + 'ROM': { 'title': 'Romans', 'usfm': '46-ROM', 'testament': 'new', 'verseCount': 433, 'verseList': [32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27] }, + '1CO': { 'title': '1 Corinthians', 'usfm': '47-1CO', 'testament': 'new', 'verseCount': 437, 'verseList': [31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24] }, + '2CO': { 'title': '2 Corinthians', 'usfm': '48-2CO', 'testament': 'new', 'verseCount': 257, 'verseList': [24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 14] }, + 'GAL': { 'title': 'Galatians', 'usfm': '49-GAL', 'testament': 'new', 'verseCount': 149, 'verseList': [24, 21, 29, 31, 26, 18] }, + 'EPH': { 'title': 'Ephesians', 'usfm': '50-EPH', 'testament': 'new', 'verseCount': 155, 'verseList': [23, 22, 21, 32, 33, 24] }, + 'PHP': { 'title': 'Philippians', 'usfm': '51-PHP', 'testament': 'new', 'verseCount': 104, 'verseList': [30, 30, 21, 23] }, + 'COL': { 'title': 'Colossians', 'usfm': '52-COL', 'testament': 'new', 'verseCount': 95, 'verseList': [29, 23, 25, 18] }, + '1TH': { 'title': '1 Thessalonians', 'usfm': '53-1TH', 'testament': 'new', 'verseCount': 89, 'verseList': [10, 20, 13, 18, 28] }, + '2TH': { 'title': '2 Thessalonians', 'usfm': '54-2TH', 'testament': 'new', 'verseCount': 47, 'verseList': [12, 17, 18] }, + '1TI': { 'title': '1 Timothy', 'usfm': '55-1TI', 'testament': 'new', 'verseCount': 113, 'verseList': [20, 15, 16, 16, 25, 21] }, + '2TI': { 'title': '2 Timothy', 'usfm': '56-2TI', 'testament': 'new', 'verseCount': 83, 'verseList': [18, 26, 17, 22] }, + 'TIT': { 'title': 'Titus', 'usfm': '57-TIT', 'testament': 'new', 'verseCount': 46, 'verseList': [16, 15, 15] }, + 'PHM': { 'title': 'Philemon', 'usfm': '58-PHM', 'testament': 'new', 'verseCount': 25, 'verseList': [25] }, + 'HEB': { 'title': 'Hebrews', 'usfm': '59-HEB', 'testament': 'new', 'verseCount': 303, 'verseList': [14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25] }, + 'JAS': { 'title': 'James', 'usfm': '60-JAS', 'testament': 'new', 'verseCount': 108, 'verseList': [27, 26, 18, 17, 20] }, + '1PE': { 'title': '1 Peter', 'usfm': '61-1PE', 'testament': 'new', 'verseCount': 105, 'verseList': [25, 25, 22, 19, 14] }, + '2PE': { 'title': '2 Peter', 'usfm': '62-2PE', 'testament': 'new', 'verseCount': 61, 'verseList': [21, 22, 18] }, + '1JN': { 'title': '1 John', 'usfm': '63-1JN', 'testament': 'new', 'verseCount': 105, 'verseList': [10, 29, 24, 21, 21] }, + '2JN': { 'title': '2 John', 'usfm': '64-2JN', 'testament': 'new', 'verseCount': 13, 'verseList': [13] }, + '3JN': { 'title': '3 John', 'usfm': '65-3JN', 'testament': 'new', 'verseCount': 15, 'verseList': [15] }, + 'JUD': { 'title': 'Jude', 'usfm': '66-JUD', 'testament': 'new', 'verseCount': 25, 'verseList': [25] }, + 'REV': { 'title': 'Revelation', 'usfm': '67-REV', 'testament': 'new', 'verseCount': 404, 'verseList': [20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 17, 18, 20, 8, 21, 18, 24, 21, 15, 27, 21] } } const oftenMissingBCVList = [ @@ -80,7 +81,7 @@ const oftenMissingBCVList = [ ['MRK', 11, 26], ['MRK', 15, 28], ['MRK', 16, 9], ['MRK', 16, 10], ['MRK', 16, 11], ['MRK', 16, 12], ['MRK', 16, 13], ['MRK', 16, 14], - ['MRK', 16, 15], ['MRK', 16, 16], ['MRK', 16, 17], ['MRK', 16, 18], ['MRK', 16, 19], ['MRK', 16, 20], + ['MRK', 16, 15], ['MRK', 16, 16], ['MRK', 16, 17], ['MRK', 16, 18], ['MRK', 16, 19], ['MRK', 16, 20], // ['LUK', 4, 8b], // ['LUK', 9, 55], ['LUK', 9, 56], ['LUK', 17, 36], @@ -103,23 +104,12 @@ const oftenMissingBCVList = [ ]; -// import * as opt from './optimize' - -// export interface bookDataIF { -// "id"; -// "title"; -// "usfm"; -// "testament"; -// "verseCount": number; -// "chapters": number[]; -// } - -const extraBookList = ['FRT','BAK']; +const extraBookList = ['FRT', 'BAK']; export const isValidBookID = (bookId) => { - return bookId.toLowerCase() in BibleBookData || extraBookList.includes(bookId); + return bookId.toUpperCase() in BibleBookData || extraBookList.includes(bookId); } export const isOptionalValidBookID = (bookId) => { - return !bookId || bookId.toLowerCase() in BibleBookData || extraBookList.includes(bookId); + return !bookId || bookId.toUpperCase() in BibleBookData || extraBookList.includes(bookId); } export const isExtraBookID = (bookId) => { return extraBookList.includes(bookId); @@ -127,31 +117,35 @@ export const isExtraBookID = (bookId) => { export const usfmNumberName = (bookId) => { - try {return BibleBookData[bookId.toLowerCase()].usfm;} - catch(err) {throw new Error(`usfmNumberName() given invalid bookId: '${bookId}'`);} + try { return BibleBookData[bookId.toUpperCase()].usfm; } + catch (err) { throw new Error(`usfmNumberName() given invalid bookId: '${bookId}'`); } } -export const chaptersInBook = (bookId) => { - // parameterAssert(bookId.toLowerCase() !== 'obs', `chaptersInBook shouldn’t be passed '${bookId}'`); - let chapters; +export const expectedVersesPerChapterList = (bookId) => { + // //parameterAssert(bookId.toUpperCase() !== 'OBS', `expectedVersesPerChapterList shouldn’t be passed '${bookId}'`); + let verseList; try { - chapters = BibleBookData[bookId.toLowerCase()].chapters; + verseList = BibleBookData[bookId.toUpperCase()].verseList; } catch (err) { - throw new Error(`chaptersInBook() given invalid bookId: '${bookId}'`); + throw new Error(`expectedVersesPerChapterList() given invalid bookId: '${bookId}'`); } - if (chapters === undefined) { - throw new Error(`chaptersInBook(): Invalid bookId: '${bookId}'`); + if (verseList === undefined) { + throw new Error(`expectedVersesPerChapterList(): Invalid bookId: '${bookId}'`); } - return chapters; + return verseList; +}; + +export const chaptersInBook = (bookId) => { + return expectedVersesPerChapterList(bookId).length; }; export const isOneChapterBook = (bookId) => { - return chaptersInBook(bookId).length === 1; + return chaptersInBook(bookId) === 1; }; export const versesInChapter = (bookId, chapter) => { - // parameterAssert(bookId.toLowerCase() !== 'obs', `versesInChapter shouldn’t be passed '${bookId}'`); - const verses = chaptersInBook(bookId)[chapter - 1]; + // //parameterAssert(bookId.toUpperCase() !== 'OBS', `versesInChapter shouldn’t be passed '${bookId}'`); + const verses = expectedVersesPerChapterList(bookId)[chapter - 1]; if (verses === undefined) { throw new Error(`versesInChapter(${bookId}) given invalid chapter: ${chapter}`); } @@ -159,32 +153,33 @@ export const versesInChapter = (bookId, chapter) => { }; export const testament = (bookId) => { - const _testament = BibleBookData[bookId.toLowerCase()].testament; - return _testament; + try { return BibleBookData[bookId.toUpperCase()].testament; } + catch (err) { throw new Error(`testament() given invalid bookId: '${bookId}'`); } }; export function getEnglishBookName(bookId) { - return BibleBookData[bookId.toLowerCase()].title; + try { return BibleBookData[bookId.toUpperCase()].title; } + catch (err) { throw new Error(`getEnglishBookName() given invalid bookId: '${bookId}'`); } } export function isGoodEnglishBookName(givenBookName) { // debugLog(`isGoodEnglishBookName(${givenBookName})…`); const partialMatches = []; - const givenBookNameLower = givenBookName.toLowerCase(); + const givenBookNameLower = givenBookName.toUpperCase(); for (const bk in BibleBookData) { const thisBookName = BibleBookData[bk].title; // debugLog("thisBookName", thisBookName); - if (thisBookName===givenBookName) return true; - const thisBookNameLower = thisBookName.toLowerCase(); - if (thisBookNameLower===givenBookNameLower) return 1; + if (thisBookName === givenBookName) return true; + const thisBookNameLower = thisBookName.toUpperCase(); + if (thisBookNameLower === givenBookNameLower) return 1; if (thisBookNameLower.startsWith(givenBookNameLower)) partialMatches.push(thisBookName); } if (partialMatches.length === 1) return 2; // We got an unambiguous partial match, e.g., Gen for Genesis return false; } -export function isOftenMissing(bookID,C,V) { - function matchBCV(entry) { return entry[0]===bookID && entry[1]===C && entry[2]===V; } +export function isOftenMissing(bookID, C, V) { + function matchBCV(entry) { return entry[0] === bookID && entry[1] === C && entry[2] === V; } return oftenMissingBCVList.find(matchBCV) !== undefined; } diff --git a/src/core/defaults.js b/src/core/defaults.js index 7cdcfc928..dc29cfd08 100644 --- a/src/core/defaults.js +++ b/src/core/defaults.js @@ -4,6 +4,7 @@ export const REPO_CODES_LIST = [ 'UHB', 'UGNT', 'LT', 'ST', 'TA', 'TW', 'TWL', + // The ones with 2 suffix are the 2021 new TSV format repos 'TN', 'TN2', 'TQ', 'TQ2', 'SN', 'SQ', 'OBS', 'OBS-TWL', diff --git a/src/core/disabled-notices.js b/src/core/disabled-notices.js index bb5ae8720..d5b2223c1 100644 --- a/src/core/disabled-notices.js +++ b/src/core/disabled-notices.js @@ -1,4 +1,5 @@ -import { debugLog, userLog } from './utilities'; +// eslint-disable-next-line no-unused-vars +import { debugLog, userLog, functionLog } from './utilities'; /* This file handles the suppression of notices where we don’t want to disable or remove the actual check, but we just want to disable it for certain resources to handle special cases. @@ -10,7 +11,7 @@ import { debugLog, userLog } from './utilities'; */ -// const DISABLED_NOTICES_VERSION_STRING = '0.3.4'; +// const DISABLED_NOTICES_VERSION_STRING = '0.3.5'; const disabledNotices = [ @@ -19,6 +20,7 @@ const disabledNotices = [ { repoCode: 'TN', priority: 450, }, // TN "Resource container link should have '*' language code with (not 'en')" disabled as tC can’t handle it yet! { repoCode: 'TW', priority: 450, }, // TW "Resource container link should have '*' language code with (not 'en')" disabled as tC can’t handle it yet! + { extra: 'TW', priority: 450, }, // TW "Resource container link should have '*' language code with (not 'en')" disabled as tC can’t handle it yet! { repoCode: 'ST', message: "Bad punctuation nesting: } closing character doesn’t match", bookID: 'NEH', }, // 777 - complex { } nesting in direct speech { repoCode: 'ST', message: "Bad punctuation nesting: ” closing character doesn’t match", bookID: 'NEH', }, // 777 - complex { } nesting in direct speech @@ -72,7 +74,8 @@ const disabledNotices = [ */ export function isDisabledNotice(givenNotice) { // NOTE: The function will fail if repoCode is not set in the notices passed to this function - // debugLog(`isDisabledNotice(${JSON.stringify(givenNotice)})…`); + // NOTE: 'extra' is still valid at this point (not yet prepended to 'message') + // functionLog(`isDisabledNotice(${JSON.stringify(givenNotice)})…`); // if (givenNotice.repoCode === undefined) debugLog(`isDisabledNotice() cannot work without repoCode for ${JSON.stringify(givenNotice)}`); for (const disabledNotice of disabledNotices) { let matchedAllSpecifiedFields = true; diff --git a/src/core/field-link-check.js b/src/core/field-link-check.js index 314266668..3cc745c95 100644 --- a/src/core/field-link-check.js +++ b/src/core/field-link-check.js @@ -1,6 +1,8 @@ +// eslint-disable-next-line no-unused-vars import { REPO_CODES_LIST } from './defaults'; import { checkTextField } from './field-text-check' import { cachedGetFileUsingFullURL } from './getApi'; +// eslint-disable-next-line no-unused-vars import { userLog, parameterAssert } from './utilities'; @@ -18,16 +20,18 @@ export async function startLiveLinksCheck(linksList, existingNoticeList, callbac function addNoticePartial({ priority, message, characterIndex, excerpt, location }) { userLog(`sLLC Link Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(priority !== undefined, "sLLC addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof priority === 'number', `sLLC addNoticePartial: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); - parameterAssert(message !== undefined, "sLLC addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof message === 'string', `sLLC addNoticePartial: 'message' parameter should be a string not a '${typeof message}':${message}`); - // parameterAssert(characterIndex!==undefined, "sLLC addNoticePartial: 'characterIndex' parameter should be defined"); - if (characterIndex) parameterAssert(typeof characterIndex === 'number', `sLLC addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); - // parameterAssert(excerpt!==undefined, "sLLC addNoticePartial: 'excerpt' parameter should be defined"); - if (excerpt) parameterAssert(typeof excerpt === 'string', `sLLC addNoticePartial: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${excerpt}`); - // parameterAssert(location!==undefined, "sLLC addNoticePartial: 'location' parameter should be defined"); - // parameterAssert(typeof location==='string', `sLLC addNoticePartial: 'location' parameter should be a string not a '${typeof location}': ${location}`); + //parameterAssert(priority !== undefined, "sLLC addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof priority === 'number', `sLLC addNoticePartial: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); + //parameterAssert(message !== undefined, "sLLC addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof message === 'string', `sLLC addNoticePartial: 'message' parameter should be a string not a '${typeof message}':${message}`); + // //parameterAssert(characterIndex!==undefined, "sLLC addNoticePartial: 'characterIndex' parameter should be defined"); + if (characterIndex) { //parameterAssert(typeof characterIndex === 'number', `sLLC addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); + } + // //parameterAssert(excerpt!==undefined, "sLLC addNoticePartial: 'excerpt' parameter should be defined"); + if (excerpt) { //parameterAssert(typeof excerpt === 'string', `sLLC addNoticePartial: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${excerpt}`); + } + // //parameterAssert(location!==undefined, "sLLC addNoticePartial: 'location' parameter should be defined"); + // //parameterAssert(typeof location==='string', `sLLC addNoticePartial: 'location' parameter should be a string not a '${typeof location}': ${location}`); result.noticeList.push({ priority, message, characterIndex, excerpt, location }); } @@ -78,18 +82,18 @@ export function checkFieldLinks(languageCode, repoCode, fieldName, fieldText, li userLog(`checkFieldLinks('${languageCode}', '${repoCode}', '${fieldName}', '${fieldText}', ${JSON.stringify(linkOptions)}, '${optionalFieldLocation}', ${JSON.stringify(checkingOptions)})…`); // debugLog( "linkOptions", JSON.stringify(linkOptions)); // debugLog( "linkOptionsEC", linkOptions.expectedCount); - parameterAssert(languageCode !== undefined, "checkFieldLinks: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkFieldLinks: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(repoCode !== undefined, "checkFieldLinks: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkFieldLinks: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkFieldLinks: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(fieldName !== undefined, "checkFieldLinks: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkFieldLinks: 'fieldName' parameter should be a string not a '${typeof fieldName}': ${fieldName}`); - parameterAssert(fieldText !== undefined, "checkFieldLinks: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkFieldLinks: 'fieldText' parameter should be a string not a '${typeof fieldText}': ${fieldText}`); - parameterAssert(optionalFieldLocation !== undefined, "checkFieldLinks: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof optionalFieldLocation === 'string', `checkFieldLinks: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}': ${optionalFieldLocation}`); - parameterAssert(optionalFieldLocation.indexOf('true') === -1, `checkFieldLinks: 'optionalFieldLocation' parameter should not be '${optionalFieldLocation}'`); + //parameterAssert(languageCode !== undefined, "checkFieldLinks: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkFieldLinks: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(repoCode !== undefined, "checkFieldLinks: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkFieldLinks: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkFieldLinks: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(fieldName !== undefined, "checkFieldLinks: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkFieldLinks: 'fieldName' parameter should be a string not a '${typeof fieldName}': ${fieldName}`); + //parameterAssert(fieldText !== undefined, "checkFieldLinks: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkFieldLinks: 'fieldText' parameter should be a string not a '${typeof fieldText}': ${fieldText}`); + //parameterAssert(optionalFieldLocation !== undefined, "checkFieldLinks: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof optionalFieldLocation === 'string', `checkFieldLinks: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}': ${optionalFieldLocation}`); + //parameterAssert(optionalFieldLocation.indexOf('true') === -1, `checkFieldLinks: 'optionalFieldLocation' parameter should not be '${optionalFieldLocation}'`); let ourLocation = optionalFieldLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -98,16 +102,18 @@ export function checkFieldLinks(languageCode, repoCode, fieldName, fieldText, li function addNoticePartial({ priority, message, characterIndex, excerpt, location }) { userLog(`cFLs addNoticePartial: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(priority !== undefined, "cFLs addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof priority === 'number', `cFLs addNoticePartial: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); - parameterAssert(message !== undefined, "cFLs addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof message === 'string', `cFLs addNoticePartial: 'message' parameter should be a string not a '${typeof message}': ${message}`); - // parameterAssert(characterIndex!==undefined, "cFLs addNoticePartial: 'characterIndex' parameter should be defined"); - if (characterIndex) parameterAssert(typeof characterIndex === 'number', `cFLs addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); - // parameterAssert(excerpt!==undefined, "cFLs addNoticePartial: 'excerpt' parameter should be defined"); - if (excerpt) parameterAssert(typeof excerpt === 'string', `cFLs addNoticePartial: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${excerpt}`); - parameterAssert(location !== undefined, "cFLs addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof location === 'string', `cFLs addNoticePartial: 'location' parameter should be a string not a '${typeof location}': ${location}`); + //parameterAssert(priority !== undefined, "cFLs addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof priority === 'number', `cFLs addNoticePartial: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); + //parameterAssert(message !== undefined, "cFLs addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof message === 'string', `cFLs addNoticePartial: 'message' parameter should be a string not a '${typeof message}': ${message}`); + // //parameterAssert(characterIndex!==undefined, "cFLs addNoticePartial: 'characterIndex' parameter should be defined"); + if (characterIndex) { //parameterAssert(typeof characterIndex === 'number', `cFLs addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); + } + // //parameterAssert(excerpt!==undefined, "cFLs addNoticePartial: 'excerpt' parameter should be defined"); + if (excerpt) { //parameterAssert(typeof excerpt === 'string', `cFLs addNoticePartial: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${excerpt}`); + } + //parameterAssert(location !== undefined, "cFLs addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof location === 'string', `cFLs addNoticePartial: 'location' parameter should be a string not a '${typeof location}': ${location}`); result.noticeList.push({ priority, message, characterIndex, excerpt, location }); } diff --git a/src/core/field-link-check.md b/src/core/field-link-check.md index c141672a5..0267eac61 100644 --- a/src/core/field-link-check.md +++ b/src/core/field-link-check.md @@ -3,12 +3,14 @@ This function is for checking text fields that are links, or that contain links. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkFieldLinks } from './field-link-check'; import { processNoticesToErrorsWarnings } from '../demos/notice-processing-functions'; -import { RenderLines, RenderRawResults, RenderSuccessesErrorsWarnings } from '../demos/RenderProcessedResults'; +import { RenderRawResults, RenderSuccessesErrorsWarnings } from '../demos/RenderProcessedResults'; import { userLog } from './utilities'; // Empty, space, link, RC, good, and bad text samples diff --git a/src/core/field-text-check.js b/src/core/field-text-check.js index 7c126da8f..a49eeca08 100644 --- a/src/core/field-text-check.js +++ b/src/core/field-text-check.js @@ -1,9 +1,11 @@ +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' -import { OPEN_CLOSE_PUNCTUATION_PAIRS, BAD_CHARACTER_COMBINATIONS, isWhitespace, countOccurrences } from './text-handling-functions' +import { OPEN_CLOSE_PUNCTUATION_PAIRS, BAD_CHARACTER_COMBINATIONS, LEADING_ZERO_COMBINATIONS, isWhitespace, countOccurrences } from './text-handling-functions' +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; -// const FIELD_TEXT_VALIDATOR_VERSION_STRING = '0.3.5'; +// const FIELD_TEXT_VALIDATOR_VERSION_STRING = '0.3.6'; /** @@ -29,45 +31,48 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie // location: the detailed location string // (Returned in this way for more intelligent processing at a higher level) // functionLog(`checkTextField(${fieldName}, ${fieldText.length.toLocaleString()} chars, ${allowedLinks}, '${optionalFieldLocation}')…`); - parameterAssert(languageCode !== undefined, "checkTextField: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTextField: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(languageCode !== 'unfoldingWord', `checkTextField: 'languageCode' ${languageCode} parameter should be not be 'unfoldingWord'`); - parameterAssert(repoCode !== undefined, "checkTextField: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkTextField: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkTextField: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(fieldType !== undefined, "checkTextField: 'fieldType' parameter should be defined"); - parameterAssert(typeof fieldType === 'string', `checkTextField: 'fieldType' parameter should be a string not a '${typeof fieldType}': ${fieldType}`); - parameterAssert(fieldType !== '', `checkTextField: 'fieldType' ${fieldType} parameter should be not be an empty string`); - parameterAssert(fieldType === 'markdown' || fieldType === 'USFM' || fieldType === 'YAML' || fieldType === 'text' || fieldType === 'raw' || fieldType === 'link', `checkTextField: unrecognised 'fieldType' parameter: '${fieldType}'`); - parameterAssert(fieldName !== undefined, "checkTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}': ${fieldName}`); + //parameterAssert(languageCode !== undefined, "checkTextField: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTextField: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(languageCode !== 'unfoldingWord', `checkTextField: 'languageCode' ${languageCode} parameter should be not be 'unfoldingWord'`); + //parameterAssert(repoCode !== undefined, "checkTextField: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkTextField: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkTextField: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(fieldType !== undefined, "checkTextField: 'fieldType' parameter should be defined"); + //parameterAssert(typeof fieldType === 'string', `checkTextField: 'fieldType' parameter should be a string not a '${typeof fieldType}': ${fieldType}`); + //parameterAssert(fieldType !== '', `checkTextField: 'fieldType' ${fieldType} parameter should be not be an empty string`); + //parameterAssert(fieldType === 'markdown' || fieldType === 'USFM' || fieldType === 'YAML' || fieldType === 'text' || fieldType === 'raw' || fieldType === 'link', `checkTextField: unrecognised 'fieldType' parameter: '${fieldType}'`); + //parameterAssert(fieldName !== undefined, "checkTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}': ${fieldName}`); // if (fieldType !== 'markdown') - // parameterAssert(fieldName !== '', `checkTextField: ${fieldType} 'fieldName' parameter should be not be an empty string`); - parameterAssert(fieldText !== undefined, "checkTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}': ${fieldText}`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkTextField: allowedLinks parameter must be either true or false"); - if (!allowedLinks) parameterAssert(fieldText.indexOf('x-tw') < 0, `checkTextField should be allowedLinks for ${fieldType} ${fieldName} ${fieldText}`) - parameterAssert(optionalFieldLocation !== undefined, "checkTextField: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof optionalFieldLocation === 'string', `checkTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}': ${optionalFieldLocation}`); - parameterAssert(optionalFieldLocation.indexOf('true') === -1, `checkTextField: 'optionalFieldLocation' parameter should not be '${optionalFieldLocation}'`); - if (checkingOptions !== undefined) - parameterAssert(typeof checkingOptions === 'object', `checkTextField: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + // //parameterAssert(fieldName !== '', `checkTextField: ${fieldType} 'fieldName' parameter should be not be an empty string`); + //parameterAssert(fieldText !== undefined, "checkTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}': ${fieldText}`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkTextField: allowedLinks parameter must be either true or false"); + if (!allowedLinks) { //parameterAssert(fieldText.indexOf('x-tw') < 0, `checkTextField should be allowedLinks for ${fieldType} ${fieldName} ${fieldText}`); + } + //parameterAssert(optionalFieldLocation !== undefined, "checkTextField: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof optionalFieldLocation === 'string', `checkTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}': ${optionalFieldLocation}`); + //parameterAssert(optionalFieldLocation.indexOf('true') === -1, `checkTextField: 'optionalFieldLocation' parameter should not be '${optionalFieldLocation}'`); + if (checkingOptions !== undefined) { //parameterAssert(typeof checkingOptions === 'object', `checkTextField: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + } let result = { noticeList: [] }; function addNoticePartial(noticeObject) { // We add the fieldName here // debugLog(`dBTC Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "dBTCs addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `dBTCs addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "dBTCs addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `dBTCs addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "dBTCs addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `dBTCs addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "dBTCs addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `dBTCs addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "dBTCs addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `dBTCs addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "dBTCs addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `dBTCs addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "dBTCs addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `dBTCs addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "dBTCs addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `dBTCs addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "dBTCs addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `dBTCs addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "dBTCs addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `dBTCs addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // noticeObject.debugChain = noticeObject.debugChain ? `checkTextField(${fieldType}, ${fieldName}, ${allowedLinks}) ${noticeObject.debugChain}` : `checkTextField(${fieldType}, ${fieldName}, ${allowedLinks})`; if (fieldName.length) noticeObject.fieldName = fieldName; // Don’t add the field if it’s blank @@ -103,7 +108,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 895) && (characterIndex = fieldText.indexOf('\u200B')) >= 0) { const charCount = countOccurrences(fieldText, '\u200B'); - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/\u200B/g, '‼') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/\u200B/g, '‼') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 895, message: "Field contains zero-width space(s)", details: `${charCount} occurrence${charCount === 1 ? '' : 's'} found`, characterIndex, excerpt, location: ourLocation }); suggestion = suggestion.replace(/\u200B/g, ''); // Or should it be space ??? } @@ -117,20 +122,20 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 993) && (characterIndex = fieldText.indexOf('<<<<<<<')) >= 0) { const iy = characterIndex + excerptHalfLength; // Want excerpt to focus more on what follows - const excerpt = (iy > excerptHalfLength ? '…' : '') + fieldText.substring(iy - excerptHalfLength, iy + excerptHalfLengthPlus).replace(/ /g, '␣') + (iy + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (iy > excerptHalfLength ? '…' : '') + fieldText.substring(iy - excerptHalfLength, iy + excerptHalfLengthPlus).replace(/ /g, '␣') + (iy + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 993, message: "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation }); } else { if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 992) && (characterIndex = fieldText.indexOf('=======')) >= 0) { const iy = characterIndex + excerptHalfLength; // Want excerpt to focus more on what follows - const excerpt = (iy > excerptHalfLength ? '…' : '') + fieldText.substring(iy - excerptHalfLength, iy + excerptHalfLengthPlus).replace(/ /g, '␣') + (iy + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (iy > excerptHalfLength ? '…' : '') + fieldText.substring(iy - excerptHalfLength, iy + excerptHalfLengthPlus).replace(/ /g, '␣') + (iy + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 992, message: "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation }); } else { if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 991) && (characterIndex = fieldText.indexOf('>>>>>>>>')) >= 0) { const iy = characterIndex + excerptHalfLength; // Want excerpt to focus more on what follows - const excerpt = (iy > excerptHalfLength ? '…' : '') + fieldText.substring(iy - excerptHalfLength, iy + excerptHalfLengthPlus).replace(/ /g, '␣') + (iy + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (iy > excerptHalfLength ? '…' : '') + fieldText.substring(iy - excerptHalfLength, iy + excerptHalfLengthPlus).replace(/ /g, '␣') + (iy + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 991, message: "Unresolved GIT conflict", characterIndex, excerpt, location: ourLocation }); } } @@ -153,12 +158,12 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 64) && (characterIndex = fieldText.indexOf('
')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 64, message: "Unexpected leading space(s) after break", characterIndex, excerpt, location: ourLocation }); } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 63) && (characterIndex = fieldText.indexOf('\\n ')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 63, message: "Unexpected leading space(s) after line break", characterIndex, excerpt, location: ourLocation }); } @@ -199,12 +204,12 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 94) && (characterIndex = fieldText.indexOf(' = 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 94, message: "Unexpected trailing space(s) before break", characterIndex, excerpt, location: ourLocation }); } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 93) && (characterIndex = fieldText.indexOf(' \\n')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 93, message: "Unexpected trailing space(s) before line break", characterIndex, excerpt, location: ourLocation }); } @@ -222,7 +227,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 124) && (characterIndex = fieldText.indexOf(' ')) >= 0 && (fieldType !== 'markdown' || characterIndex !== fieldText.length - 2)) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); const doubleCount = countOccurrences(fieldText, ' '); let notice; if (doubleCount === 1) @@ -237,25 +242,25 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 583) && (characterIndex = fieldText.indexOf('\n')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 583, message: "Unexpected newLine character", characterIndex, excerpt, location: ourLocation }); suggestion = suggestion.replace(/\n/g, ' '); } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 582) && (characterIndex = fieldText.indexOf('\r')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 582, message: "Unexpected carriageReturn character", characterIndex, excerpt, location: ourLocation }); suggestion = suggestion.replace(/\r/g, ' '); } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 581) && (characterIndex = fieldText.indexOf('\xA0')) >= 0) { // non-break space - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/\xA0/g, '⍽') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/\xA0/g, '⍽') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 581, message: "Unexpected non-break space (uA0) character", characterIndex, excerpt, location: ourLocation }); suggestion = suggestion.replace(/\xA0/g, ' '); } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 580) && (characterIndex = fieldText.indexOf('\u202F')) >= 0) { // narrow non-break space - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/\u202F/g, '⍽') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/\u202F/g, '⍽') + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); const notice = { priority: 580, message: "Unexpected narrow non-break space (u202F) character", excerpt, location: ourLocation }; if ((fieldType !== 'raw' && fieldType !== 'text') || fieldName.substring(0, 6) !== 'from \\') notice.characterIndex = characterIndex; // characterIndex means nothing for processed USFM @@ -265,13 +270,13 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie if (fieldName === 'OrigQuote' || fieldName === 'Quote') { if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 179) && (characterIndex = fieldText.indexOf(' …')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 179, message: "Unexpected space before ellipse character", characterIndex, excerpt, location: ourLocation }); suggestion = suggestion.replace(/ …/g, '…'); } if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 178) && (characterIndex = fieldText.indexOf('… ')) >= 0) { - const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 178, message: "Unexpected space after ellipse character", characterIndex, excerpt, location: ourLocation }); suggestion = suggestion.replace(/… /g, '…'); } @@ -290,7 +295,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie doubledPunctuationCheckList += '-'; for (const punctChar of doubledPunctuationCheckList) { if ((characterIndex = fieldText.indexOf(punctChar + punctChar)) >= 0) { - let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); const notice = { priority: 177, message: `Unexpected doubled ${punctChar} characters`, excerpt, location: ourLocation }; if ((fieldType !== 'raw' && fieldType !== 'text') || fieldName.substring(0, 6) !== 'from \\') notice.characterIndex = characterIndex; // characterIndex means nothing for processed USFM @@ -309,7 +314,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie for (const punctChar of afterSpaceCheckList) { if ((!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 191) && (characterIndex = fieldText.indexOf(' ' + punctChar)) >= 0) { - let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); const notice = { priority: 191, message: `Unexpected ${punctChar} character after space`, excerpt, location: ourLocation }; if ((fieldType !== 'raw' && fieldType !== 'text') || fieldName.substring(0, 6) !== 'from \\') notice.characterIndex = characterIndex; // characterIndex means nothing for processed USFM @@ -320,7 +325,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie && (punctChar !== '!' || fieldType !== 'markdown') // image tag && fieldText[0] === punctChar) { characterIndex = 0; - let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 195, message: `Unexpected ${punctChar} character at start of line`, characterIndex, excerpt, location: ourLocation }); } } @@ -338,7 +343,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie if (fieldType !== 'YAML') beforeSpaceCheckList += '['; for (const punctChar of beforeSpaceCheckList) { if ((characterIndex = fieldText.indexOf(punctChar + ' ')) >= 0) { - let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); const notice = { priority: 192, message: `Unexpected space after ${punctChar} character`, excerpt, location: ourLocation }; if ((fieldType !== 'raw' && fieldType !== 'text') || fieldName.substring(0, 6) !== 'from \\') notice.characterIndex = characterIndex; // characterIndex means nothing for processed USFM @@ -356,7 +361,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie for (const punctChar of beforeEOLCheckList) { if (punctChar !== '—' && fieldText[fieldText.length - 1] === punctChar) { characterIndex = fieldText.length - 1; - let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : '') + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); const notice = { priority: 193, message: `Unexpected ${punctChar} character at end of line`, excerpt, location: ourLocation }; if ((fieldType !== 'raw' && fieldType !== 'text') || fieldName.substring(0, 6) !== 'from \\') notice.characterIndex = characterIndex; // characterIndex means nothing for processed USFM @@ -369,15 +374,25 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie // Check for bad combinations of characters for (const badCharCombination of BAD_CHARACTER_COMBINATIONS) if ((characterIndex = fieldText.indexOf(badCharCombination)) >= 0) { - let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); addNoticePartial({ priority: 849, message: `Unexpected '${badCharCombination}' character combination`, characterIndex, excerpt, location: ourLocation }); } + if (!checkingOptions?.cutoffPriorityLevel || checkingOptions?.cutoffPriorityLevel < 92) + // Check for leading zeroes in numbers + for (const badZeroCharCombination of LEADING_ZERO_COMBINATIONS) + if ((characterIndex = fieldText.indexOf(badZeroCharCombination)) >= 0 + // but not an error perhaps if followed by period, e.g., 0.32. + && (fieldText.substring(characterIndex + badZeroCharCombination.length, characterIndex + badZeroCharCombination.length + 1) !== '.')) { + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); + addNoticePartial({ priority: 92, message: `Unexpected leading zero`, characterIndex, excerpt, location: ourLocation }); + } + // // Check for problems created by tC Create or something // characterIndex = fieldText.indexOf('\\['); // if (characterIndex === -1) characterIndex = fieldText.indexOf('\\]'); // if (characterIndex !== -1) { - // let excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); + // const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''); // addNoticePartial({ priority: 849, message: "Unexpected \\[ or \\] characters", characterIndex, excerpt, location: ourLocation }); // } @@ -442,7 +457,7 @@ export function checkTextField(languageCode, repoCode, fieldType, fieldName, fie if (characterIndex === -1) characterIndex = fieldText.indexOf('.info'); if (characterIndex === -1) characterIndex = fieldText.indexOf('.bible'); if (characterIndex >= 0) { - let excerpt = `${characterIndex > excerptHalfLength ? '…' : ''}${fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus)}${characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''}` + const excerpt = `${characterIndex > excerptHalfLength ? '…' : ''}${fieldText.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus)}${characterIndex + excerptHalfLengthPlus < fieldText.length ? '…' : ''}` addNoticePartial({ priority: 765, message: "Unexpected link", characterIndex, excerpt, location: ourLocation }); } } diff --git a/src/core/field-text-check.md b/src/core/field-text-check.md index 626aae8e5..b9a4e9f40 100644 --- a/src/core/field-text-check.md +++ b/src/core/field-text-check.md @@ -7,11 +7,13 @@ This generic function returns a list/array of notices, that can then be post-pro This demonstration doesn’t display the raw notices, but rather displays the processed and formatted lists of errors and warnings. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkTextField } from './field-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, space, good, and bad, link, and RC text samples const textE = ""; diff --git a/src/core/file-text-check.js b/src/core/file-text-check.js index 78cea7784..f640adb3a 100644 --- a/src/core/file-text-check.js +++ b/src/core/file-text-check.js @@ -1,5 +1,7 @@ +// eslint-disable-next-line no-unused-vars import { REPO_CODES_LIST } from './defaults'; import { checkPlainText } from './plain-text-check'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; // const FILE_TEXT_VALIDATOR_VERSION_STRING = '0.3.1'; @@ -33,35 +35,37 @@ export function checkTextfileContents(languageCode, repoCode, fileType, filename // excerpt: a short excerpt of the string containing the error (or empty-string if irrelevant) // (Returned in this way for more intelligent processing at a higher level) // functionLog(`checkTextfileContents(${filename}, ${fileText.length.toLocaleString()} chars, '${optionalFileLocation}')…`); - parameterAssert(languageCode !== undefined, "checkTextfileContents: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTextfileContents: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(repoCode !== undefined, "checkTextfileContents: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkTextfileContents: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkTextfileContents: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(fileType !== undefined, "checkTextfileContents: 'fileType' parameter should be defined"); - parameterAssert(typeof fileType === 'string', `checkTextfileContents: 'fileType' parameter should be a string not a '${typeof fileType}': ${fileType}`); - parameterAssert(fileType !== '', `checkTextfileContents: 'fileType' ${fileType} parameter should be not be an empty string`); - parameterAssert(fileType === 'markdown' || fileType === 'USFM' || fileType === 'YAML' || fileType === 'text', `checkTextfileContents: unrecognised 'fileType' parameter: '${fileType}'`); - parameterAssert(filename !== undefined, "checkTextfileContents: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `checkTextfileContents: 'filename' parameter should be a string not a '${typeof filename}': ${filename}`); - parameterAssert(fileText !== undefined, "checkTextfileContents: 'fileText' parameter should be defined"); - parameterAssert(typeof fileText === 'string', `checkTextfileContents: 'fileText' parameter should be a string not a '${typeof fileText}': ${fileText}`); - parameterAssert(checkingOptions !== undefined, "checkTextfileContents: 'checkingOptions' parameter should be defined"); + //parameterAssert(languageCode !== undefined, "checkTextfileContents: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTextfileContents: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(repoCode !== undefined, "checkTextfileContents: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkTextfileContents: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkTextfileContents: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(fileType !== undefined, "checkTextfileContents: 'fileType' parameter should be defined"); + //parameterAssert(typeof fileType === 'string', `checkTextfileContents: 'fileType' parameter should be a string not a '${typeof fileType}': ${fileType}`); + //parameterAssert(fileType !== '', `checkTextfileContents: 'fileType' ${fileType} parameter should be not be an empty string`); + //parameterAssert(fileType === 'markdown' || fileType === 'USFM' || fileType === 'YAML' || fileType === 'text', `checkTextfileContents: unrecognised 'fileType' parameter: '${fileType}'`); + //parameterAssert(filename !== undefined, "checkTextfileContents: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `checkTextfileContents: 'filename' parameter should be a string not a '${typeof filename}': ${filename}`); + //parameterAssert(fileText !== undefined, "checkTextfileContents: 'fileText' parameter should be defined"); + //parameterAssert(typeof fileText === 'string', `checkTextfileContents: 'fileText' parameter should be a string not a '${typeof fileText}': ${fileText}`); + //parameterAssert(checkingOptions !== undefined, "checkTextfileContents: 'checkingOptions' parameter should be defined"); let result = { noticeList: [] }; function addNotice(noticeObject) { // debugLog(`dBTC Notice: (priority=${noticeObject.priority}) ${noticeObject.message}${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? ` ${noticeObject.excerpt}` : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "dBTCs addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `dBTCs addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "dBTCs addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `dBTCs addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "dBTCs addNotice: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `dBTCs addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "dBTCs addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `dBTCs addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "dBTCs addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `dBTCs addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "dBTCs addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `dBTCs addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "dBTCs addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `dBTCs addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "dBTCs addNotice: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `dBTCs addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "dBTCs addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `dBTCs addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "dBTCs addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `dBTCs addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkTextfileContents(${languageCode}, ${fileType}, ${filename}) ${noticeObject.debugChain}`; result.noticeList.push(noticeObject); } @@ -79,11 +83,11 @@ export function checkTextfileContents(languageCode, repoCode, fileType, filename // Updates the global list of notices // debugLog(`cPT ourCheckPlainText(${fieldName}, (${fieldText.length}), ${fieldLocation}, …)`); - // parameterAssert(textName !== undefined, "cPT ourCheckPlainText: 'textName' parameter should be defined"); - // parameterAssert(typeof textName === 'string', `cPT ourCheckPlainText: 'fieldName' parameter should be a string not a '${typeof textName}'`); - parameterAssert(plainText !== undefined, "cPT ourCheckPlainText: 'plainText' parameter should be defined"); - parameterAssert(typeof plainText === 'string', `cPT ourCheckPlainText: 'plainText' parameter should be a string not a '${typeof plainText}'`); - parameterAssert(checkingOptions !== undefined, "cPT ourCheckPlainText: 'checkingOptions' parameter should be defined"); + // //parameterAssert(textName !== undefined, "cPT ourCheckPlainText: 'textName' parameter should be defined"); + // //parameterAssert(typeof textName === 'string', `cPT ourCheckPlainText: 'fieldName' parameter should be a string not a '${typeof textName}'`); + //parameterAssert(plainText !== undefined, "cPT ourCheckPlainText: 'plainText' parameter should be defined"); + //parameterAssert(typeof plainText === 'string', `cPT ourCheckPlainText: 'plainText' parameter should be a string not a '${typeof plainText}'`); + //parameterAssert(checkingOptions !== undefined, "cPT ourCheckPlainText: 'checkingOptions' parameter should be defined"); const resultObject = checkPlainText(languageCode, repoCode, textType, textFilename, plainText, givenLocation, checkingOptions); @@ -140,7 +144,7 @@ export function checkTextfileContents(languageCode, repoCode, fileType, filename // if (ix === -1) ix = fileText.indexOf('.info'); // if (ix === -1) ix = fileText.indexOf('.bible'); // if (ix >= 0) { - // let excerpt = (ix>excerptHalfLength ? '…' : '') + fileText.substring(ix-excerptHalfLength, ix+excerptHalfLengthPlus) + (ix+excerptHalfLengthPlus < fileText.length ? '…' : '') + // const excerpt = (ix>excerptHalfLength ? '…' : '') + fileText.substring(ix-excerptHalfLength, ix+excerptHalfLengthPlus) + (ix+excerptHalfLengthPlus < fileText.length ? '…' : '') // addNotice({765, "Unexpected link", ix,excerpt, ourAtString}); // } // } diff --git a/src/core/file-text-check.md b/src/core/file-text-check.md index b4f884c52..0e74f4207 100644 --- a/src/core/file-text-check.md +++ b/src/core/file-text-check.md @@ -9,11 +9,13 @@ This generic function returns a list/array of notices, that can then be post-pro This demonstration doesn’t display the raw notices, but rather displays the processed and formatted lists of errors and warnings. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkTextfileContents } from './file-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, space, good, and bad samples const textE = ""; diff --git a/src/core/getApi.js b/src/core/getApi.js index 69d7797fa..81d280d76 100644 --- a/src/core/getApi.js +++ b/src/core/getApi.js @@ -6,15 +6,18 @@ import JSZip from 'jszip'; import * as books from './books'; import { clearCheckedArticleCache } from './notes-links-check'; // eslint-disable-next-line no-unused-vars -import { functionLog, debugLog, userLog, parameterAssert } from './utilities'; +import { functionLog, debugLog, userLog, parameterAssert, logicAssert } from './utilities'; -// const GETAPI_VERSION_STRING = '0.7.1'; +// const GETAPI_VERSION_STRING = '0.8.0'; const MAX_INDIVIDUAL_FILES_TO_DOWNLOAD = 5; // More than this and it downloads the zipfile for the entire repo -const baseURL = 'https://git.door43.org/'; -const apiPath = 'api/v1'; +const DOOR43_BASE_URL = 'https://git.door43.org/'; +const API_PATH = 'api/v1'; + +const OBS_PICTURE_ZIP_FILENAME = 'obs-images-360px.zip'; +const OBS_PICTURE_ZIP_URI = `https://cdn.door43.org/obs/jpg/${OBS_PICTURE_ZIP_FILENAME}`; // caches failed http file fetches so we don’t waste time with repeated attempts @@ -29,7 +32,7 @@ const zipStore = localforage.createInstance({ name: 'CV-zip-store', }); -// caches http file fetches done by cachedFetchFileFromServerBranch() +// caches http file fetches done by cachedFetchFileFromServerWithBranch() const cacheStore = localforage.createInstance({ driver: [localforage.INDEXEDDB], name: 'CV-web-cache', @@ -45,7 +48,7 @@ const unzipStore = localforage.createInstance({ // NOTE: Even if data expires in this AxiosCacheAdapter, the localforage caches don’t have the same / any expiry ages // (We expect the users of the demos to manually clear the caches when an update is required.) const Door43Api = setup({ - baseURL: baseURL, + baseURL: DOOR43_BASE_URL, cache: { store: cacheStore, maxAge: 1 * 60 * 60 * 1000, // 1 hour (unless they manually clear the cache) @@ -129,12 +132,23 @@ async function getUnZippedFile(path) { return contents; } +/** + * try to get previously unzipped picture file from cache + * @param {string} uri + * @return {Promise} resolves to file contents or null if not found + */ +async function getUnZippedPictureFile(uri) { + // functionLog(`getUnZippedPictureFile(${uri})`); + const contents = await unzipStore.getItem(uri); + return contents; +} + /** * searches for files in this order: * - cache of uncompressed files (unzipStore) * - cache of zipped repos (zipStore) - * - and finally calls cachedFetchFileFromServerBranch() which first checks in cacheStore to see if already fetched. * @param {string} username + * - and finally calls cachedFetchFileFromServerWithBranch() which first checks in cacheStore to see if already fetched. * @param {string} username * @param {string} repository * @param {string} path * @param {string} branch @@ -143,10 +157,10 @@ async function getUnZippedFile(path) { // This is the function that we call the most from the outside export async function cachedGetFile({ username, repository, path, branch }) { // functionLog(`cachedGetFile(${username}, ${repository}, ${path}, ${branch})…`); - parameterAssert(typeof username === 'string' && username.length, `cachedGetFile: username parameter should be a non-empty string not ${typeof username}: ${username}`); - parameterAssert(typeof repository === 'string' && repository.length, `cachedGetFile: repository parameter should be a non-empty string not ${typeof repository}: ${repository}`); - parameterAssert(typeof path === 'string' && path.length, `cachedGetFile: path parameter should be a non-empty string not ${typeof path}: ${path}`); - parameterAssert(typeof branch === 'string' && branch.length, `cachedGetFile: branch parameter should be a non-empty string not ${typeof branch}: ${branch}`); + //parameterAssert(typeof username === 'string' && username.length, `cachedGetFile: username parameter should be a non-empty string not ${typeof username}: ${username}`); + //parameterAssert(typeof repository === 'string' && repository.length, `cachedGetFile: repository parameter should be a non-empty string not ${typeof repository}: ${repository}`); + //parameterAssert(typeof path === 'string' && path.length, `cachedGetFile: path parameter should be a non-empty string not ${typeof path}: ${path}`); + //parameterAssert(typeof branch === 'string' && branch.length, `cachedGetFile: branch parameter should be a non-empty string not ${typeof branch}: ${branch}`); const filePath = Path.join(username, repository, path, branch); let contents = await getUnZippedFile(filePath); @@ -160,7 +174,7 @@ export async function cachedGetFile({ username, repository, path, branch }) { // if (filePath.indexOf('_tq/') < 0) // Don’t log for TQ2 files coz too many // userLog(` cachedGetFile got ${filePath} from zipfile`); if (!contents) { - contents = await cachedFetchFileFromServerBranch({ username, repository, path, branch }); + contents = await cachedFetchFileFromServerWithBranch({ username, repository, path, branch }); } if (contents) { @@ -237,11 +251,11 @@ export async function preloadReposIfNecessary(username, languageCode, bookIDList // NOTE: We preload TA and TW by default because we are likely to have many links to those repos // We preload TQ by default because it has thousands of files (17,337), so individual file fetches might be slow // even for one book which might have several hundred files. - functionLog(`preloadReposIfNecessary(${username}, ${languageCode}, ${bookIDList} (${typeof bookID}), ${branchOrRelease}, [${repoList}])…`); + // functionLog(`preloadReposIfNecessary(${username}, ${languageCode}, ${bookIDList} (${typeof bookID}), ${branchOrRelease}, [${repoList}])…`); let success = true; const repos_ = [...repoList]; - if (bookIDList.length === 1 && bookIDList[0] === 'OBS') { + if (bookIDList.includes('OBS')) { if (!repos_.includes('OBS')) repos_.unshift('OBS'); // push to beginning of list } @@ -250,13 +264,14 @@ export async function preloadReposIfNecessary(username, languageCode, bookIDList for (const bookID of bookIDList) { if (bookID !== 'OBS') { const whichTestament = books.testament(bookID); // returns 'old' or 'new' + logicAssert(whichTestament === 'old' || whichTestament === 'new', `preloadReposIfNecessary() couldn't find testament for '${bookID}'`); const origLangRepo = whichTestament === 'old' ? 'UHB' : 'UGNT'; if (!repos_.includes(origLangRepo)) repos_.unshift(origLangRepo); } } } - // debugLog(" Adjusted repo list", repos_.length, JSON.stringify(repos_)); + // debugLog(` Adjusted repo list: (${repos_.length}) ${JSON.stringify(repos_)}`); // // See if the required repos are there already // debugLog(`Check if need to preload ${repos_.length} repos: ${repos_}`) @@ -284,15 +299,18 @@ export async function preloadReposIfNecessary(username, languageCode, bookIDList // else userLog("All repos were cached already!"); for (const repoCode of repos_) { + // debugLog(`preloadReposIfNecessary: looking at repoCode '${repoCode}'…`); let adjustedLanguageCode = languageCode; if ((languageCode === 'hbo' && repoCode !== 'UHB') || (languageCode === 'el-x-koine' && repoCode !== 'UGNT')) adjustedLanguageCode = 'en'; // Assume English then let adjustedBranchOrRelease = branchOrRelease; let adjustedRepoCode = repoCode; - if (adjustedRepoCode.endsWith('2')) { + if (repoCode.endsWith('2')) { adjustedRepoCode = adjustedRepoCode.substring(0, adjustedRepoCode.length - 1); // Remove the '2' from the end adjustedBranchOrRelease = 'newFormat'; } + // else if (repoCode === 'OBS-TN' || repoCode === 'OBS-TQ' || repoCode === 'OBS-SN' || repoCode === 'OBS-SQ') + // adjustedBranchOrRelease = 'newFormat'; const repoName = formRepoName(adjustedLanguageCode, adjustedRepoCode); // debugLog(`preloadReposIfNecessary: preloading zip file for ${repoName}…`); const zipFetchSucceeded = await cachedGetRepositoryZipFile({ username, repository: repoName, branchOrRelease: adjustedBranchOrRelease }); @@ -300,6 +318,23 @@ export async function preloadReposIfNecessary(username, languageCode, bookIDList console.error(`preloadReposIfNecessary() misfetched zip file for ${repoCode} (${adjustedRepoCode}) repo with ${zipFetchSucceeded}`); success = false; } + if (repoCode === 'OBS') { + debugLog(`preloadReposIfNecessary: preloading OBS zipped pictures file from ${OBS_PICTURE_ZIP_URI}…`); + const zipBlob = await zipStore.getItem(OBS_PICTURE_ZIP_FILENAME); + // debugLog(` getZipFromStore(${uri} -- empty: ${!zipBlob}`); + if (!zipBlob) { + userLog(`downloadingOBSPicturesZipFile(${OBS_PICTURE_ZIP_URI})…`); + const response = await fetch(OBS_PICTURE_ZIP_URI); + if (response.status === 200 || response.status === 0) { + const zipArrayBuffer = await response.arrayBuffer(); // blob storage not supported on mobile + await zipStore.setItem(OBS_PICTURE_ZIP_FILENAME, zipArrayBuffer); + // debugLog(` downloadingOBSPicturesZipFile(${uri}) -- saved zip`); + } else { + console.error(`downloadingOBSPicturesZipFile(${OBS_PICTURE_ZIP_URI}) -- got response status: ${response.status}`); + success = false; + } + } + } } return success; } @@ -313,8 +348,8 @@ export async function preloadReposIfNecessary(username, languageCode, bookIDList * @param {string} branch * @return {Promise} resolves to file content */ -async function cachedFetchFileFromServerBranch({ username, repository, path, branch = 'master' }) { - // functionLog(`cachedFetchFileFromServerBranch(${username}, ${repository}, ${path}, ${branch})…`); +async function cachedFetchFileFromServerWithBranch({ username, repository, path, branch = 'master' }) { + // functionLog(`cachedFetchFileFromServerWithBranch(${username}, ${repository}, ${path}, ${branch})…`); // TODO: Check how slow this next call is -- can it be avoided or cached? // RJH removed this 2Oct2020 -- what’s the point -- it just slows things down -- // if it needs to be checked, should be checked before this point @@ -333,8 +368,8 @@ async function cachedFetchFileFromServerBranch({ username, repository, path, bra * @param {string} tag * @return {Promise} resolves to file content */ - export async function cachedFetchFileFromServerTag({ username, repository, path, tag }) { - // functionLog(`cachedFetchFileFromServerTag(${username}, ${repository}, ${path}, ${tag})…`); +export async function cachedFetchFileFromServerWithTag({ username, repository, path, tag }) { + // functionLog(`cachedFetchFileFromServerWithTag(${username}, ${repository}, ${path}, ${tag})…`); // TODO: Check how slow this next call is -- can it be avoided or cached? // RJH removed this 2Oct2020 -- what’s the point -- it just slows things down -- // if it needs to be checked, should be checked before this point @@ -353,7 +388,7 @@ async function cachedFetchFileFromServerBranch({ username, repository, path, bra * @param {string} branch * @return {Promise} resolves to file content */ - async function cachedFetchFileFromServerWorker(uri, username, repository, path, branchOrTag) { +async function cachedFetchFileFromServerWorker(uri, username, repository, path, branchOrTag) { // functionLog(`cachedFetchFileFromServerWorker(${uri}, ${username}, ${repository}, ${path}, ${branchOrTag})…`); // TODO: Check how slow this next call is -- can it be avoided or cached? // RJH removed this 2Oct2020 -- what’s the point -- it just slows things down -- @@ -398,7 +433,7 @@ async function cachedGetFileFromZipOrServer({ username, repository, path, branch let file; file = await getFileFromZip({ username, repository, path, branch }); if (!file) { - file = await cachedFetchFileFromServerBranch({ username, repository, path, branch }); + file = await cachedFetchFileFromServerWithBranch({ username, repository, path, branch }); } return file; } @@ -406,7 +441,7 @@ async function cachedGetFileFromZipOrServer({ username, repository, path, branch async function getUID({ username }) { // functionLog(`getUID(${username})…`); - const uri = Path.join(apiPath, 'users', username); + const uri = Path.join(API_PATH, 'users', username); // debugLog(`getUID uri=${uri}`); const user = await cachedGetFileUsingPartialURL({ uri }); // debugLog(`getUID user=${user}`); @@ -427,7 +462,7 @@ export async function repositoryExistsOnDoor43({ username, repository }) { // debugLog(`repositoryExistsOnDoor43 uid=${uid}`); // Default limit is 10 -- way too small const params = { q: repository, limit: 500, uid }; // Documentation says limit is 50, but larger numbers seem to work ok - const uri = Path.join(apiPath, 'repos', `search`); + const uri = Path.join(API_PATH, 'repos', `search`); // debugLog(`repositoryExistsOnDoor43 uri=${uri}`); let retrievedRepoList; try { @@ -460,7 +495,7 @@ export async function repositoryExistsOnDoor43({ username, repository }) { async function cachedGetFileUsingPartialURL({ uri, params }) { // functionLog(`cachedGetFileUsingPartialURL(${uri}, ${JSON.stringify(params)})…`); // debugLog(` get querying: ${baseURL+uri}`); - const response = await Door43Api.get(baseURL + uri, { params }); + const response = await Door43Api.get(DOOR43_BASE_URL + uri, { params }); if (response.request.fromCache !== true) userLog(` Door43Api downloaded Door43 ${uri}`); // debugLog(` cachedGetFileUsingPartialURL returning: ${JSON.stringify(response.data)}`); return response.data; @@ -468,6 +503,44 @@ async function cachedGetFileUsingPartialURL({ uri, params }) { export async function cachedGetFileUsingFullURL({ uri, params }) { // functionLog(`cachedGetFileUsingFullURL(${uri}, ${params})…`); + if (uri.startsWith('https://cdn.door43.org/obs/jpg/360px/obs')) { + // userLog("cachedGetFileUsingFullURL() is checking if the OBS picture is in a downloaded zip file…"); + let pictureContents = await getUnZippedPictureFile(uri); + if (pictureContents) { + // debugLog(`cachedGetFileUsingFullURL got ${uri} from unzipped cache`); + return pictureContents; + } + const zipBlob = await zipStore.getItem(OBS_PICTURE_ZIP_FILENAME); + // debugLog(` getZipFromStore(${OBS_PICTURE_ZIP_FILENAME} -- empty: ${!zipBlob}`); + try { + if (zipBlob) { + // debugLog(` Got zipBlob for ${OBS_PICTURE_ZIP_FILENAME}`); + const zip = await JSZip.loadAsync(zipBlob); + // zip.forEach(function (relativePath) { + // debugLog(`relPath=${relativePath}`); // Displays 'relPath=360px/obs-en-17-09.jpg' + // }) + const zipPath = uri.substring(31); // Drop https://cdn.door43.org/obs/jpg/ to get 360px/obs-en-01-05.jpg + // debugLog(` zipPath=${zipPath}`); + pictureContents = await zip.file(zipPath).async('string'); + // debugLog(` Got zipBlob ${pictureContents.length} bytes`); + } + // else userLog(" No zipBlob"); + } catch (error) { + if (error.message.indexOf(' is null') < 0) + console.error(`cachedGetFileUsingPartialURL for ${uri} got: ${error.message}`); + pictureContents = null; + } + // if (contents) + // if (filePath.indexOf('_tq/') < 0) // Don’t log for TQ2 files coz too many + // userLog(` cachedGetFile got ${filePath} from zipfile`); + if (pictureContents) { + // save unzipped file in cache to speed later retrieval + await unzipStore.setItem(uri, pictureContents); + // userLog(`cachedGetFileUsingFullURL saved ${uri} to cache for next time`); + return pictureContents; + } + // else console.error(`cachedGetFileUsingFullURL(${uri}) -- failed to get file from zip`); + } const response = await Door43Api.get(uri, { params }); if (response.request.fromCache !== true) userLog(` Door43Api downloaded ${uri}`); // debugLog(` cachedGetFileUsingFullURL returning: ${response.data}`); @@ -644,7 +717,7 @@ async function getFileFromZip({ username, repository, path, branchOrRelease }) { function zipUri({ username, repository, branchOrRelease = 'master' }) { // functionLog(`zipUri(${username}, ${repository}, ${branchOrRelease})…`); const zipPath = Path.join(username, repository, 'archive', `${branchOrRelease}.zip`); - const zipUri = baseURL + zipPath; + const zipUri = DOOR43_BASE_URL + zipPath; return zipUri; }; diff --git a/src/core/manifest-text-check.js b/src/core/manifest-text-check.js index 827b8de87..5217e1013 100644 --- a/src/core/manifest-text-check.js +++ b/src/core/manifest-text-check.js @@ -1,14 +1,15 @@ +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { checkYAMLText } from './yaml-text-check'; import { cachedGetFile, getFileListFromZip } from './getApi'; -import { BibleBookData } from './books/books' +import { BibleBookData, testament } from './books/books' import Ajv from 'ajv'; import { removeDisabledNotices } from './disabled-notices'; // eslint-disable-next-line no-unused-vars -import { debugLog, functionLog, parameterAssert } from './utilities'; +import { debugLog, functionLog, parameterAssert, logicAssert } from './utilities'; -const MANIFEST_VALIDATOR_VERSION_STRING = '0.4.4'; +const MANIFEST_VALIDATOR_VERSION_STRING = '0.4.6'; // Pasted in 2020-10-02 from https://raw.githubusercontent.com/unfoldingWord/dcs/master/options/schema/rc.schema.json // Updated 2021-02-19 @@ -561,14 +562,14 @@ const validate = ajv.compile(MANIFEST_SCHEMA); /** * - * @param {string} languageCode - * @param {string} repoCode - * @param {string} username - * @param {string} repoName - * @param {string} repoBranch - * @param {string} manifestText - * @param {string} givenLocation - * @param {Object} checkingOptions + * @param {string} languageCode -- language of main thing being checked -- normally the same as the first part of the repoName, e.g., 'en', but may differ for original language repos + * @param {string} repoCode -- e.g., 'UHB', 'LT', 'TN', 'SQ2' + * @param {string} username -- or orgname -- owner of DCS repo + * @param {string} repoName -- e.g., 'en_tn' + * @param {string} repoBranch -- e.g., 'master' + * @param {string} manifestText -- contents of manifest.yaml + * @param {string} givenLocation -- optional description of location of manifest + * @param {Object} checkingOptions -- optional option key:value pairs */ export async function checkManifestText(languageCode, repoCode, username, repoName, repoBranch, manifestText, givenLocation, checkingOptions) { /* This function is optimised for checking the entire file, i.e., all lines. @@ -577,26 +578,27 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa Returns a result object containing a successList and a noticeList */ - // functionLog(`checkManifestText(${username}, ${repoCode}, ${repoName}, ${repoBranch}, ${manifestText.length} chars, ${givenLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkManifestText: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkManifestText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(repoCode !== undefined, "checkManifestText: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkManifestText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkManifestText: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(username !== undefined, "checkManifestText: 'username' parameter should be defined"); - parameterAssert(typeof username === 'string', `checkManifestText: 'username' parameter should be a string not a '${typeof username}': ${username}`); - parameterAssert(repoName !== undefined, "checkManifestText: 'repoName' parameter should be defined"); - parameterAssert(typeof repoName === 'string', `checkManifestText: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); - parameterAssert(repoBranch !== undefined, "checkManifestText: 'repoBranch' parameter should be defined"); - parameterAssert(typeof repoBranch === 'string', `checkManifestText: 'repoBranch' parameter should be a string not a '${typeof repoBranch}': ${repoBranch}`); - parameterAssert(manifestText !== undefined, "checkManifestText: 'manifestText' parameter should be defined"); - parameterAssert(typeof manifestText === 'string', `checkManifestText: 'manifestText' parameter should be a string not a '${typeof manifestText}': ${manifestText}`); - parameterAssert(givenLocation !== undefined, "checkManifestText: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkManifestText: 'optionalFieldLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); - parameterAssert(givenLocation.indexOf('true') === -1, `checkManifestText: 'optionalFieldLocation' parameter should not be '${givenLocation}'`); - parameterAssert(checkingOptions !== undefined, "checkManifestText: 'checkingOptions' parameter should be defined"); - if (checkingOptions !== undefined) - parameterAssert(typeof checkingOptions === 'object', `checkManifestText: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + // functionLog(`checkManifestText(${languageCode}, ${repoCode}, ${username}, ${repoName}, ${repoBranch}, ${manifestText.length} chars, ${givenLocation}, ${JSON.stringify(checkingOptions)})…`); + //parameterAssert(languageCode !== undefined, "checkManifestText: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkManifestText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(repoCode !== undefined, "checkManifestText: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkManifestText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkManifestText: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(username !== undefined, "checkManifestText: 'username' parameter should be defined"); + //parameterAssert(typeof username === 'string', `checkManifestText: 'username' parameter should be a string not a '${typeof username}': ${username}`); + //parameterAssert(repoName !== undefined, "checkManifestText: 'repoName' parameter should be defined"); + //parameterAssert(typeof repoName === 'string', `checkManifestText: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); + if (repoCode !== 'UHB' && repoCode !== 'UGNT') { parameterAssert(repoName.startsWith(languageCode), `checkManifestText: 'repoName' parameter '${repoName}' should start with language code: '${languageCode}_'`); } + //parameterAssert(repoBranch !== undefined, "checkManifestText: 'repoBranch' parameter should be defined"); + //parameterAssert(typeof repoBranch === 'string', `checkManifestText: 'repoBranch' parameter should be a string not a '${typeof repoBranch}': ${repoBranch}`); + //parameterAssert(manifestText !== undefined, "checkManifestText: 'manifestText' parameter should be defined"); + //parameterAssert(typeof manifestText === 'string', `checkManifestText: 'manifestText' parameter should be a string not a '${typeof manifestText}': ${manifestText}`); + //parameterAssert(givenLocation !== undefined, "checkManifestText: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkManifestText: 'optionalFieldLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); + //parameterAssert(givenLocation.indexOf('true') === -1, `checkManifestText: 'optionalFieldLocation' parameter should not be '${givenLocation}'`); + //parameterAssert(checkingOptions !== undefined, "checkManifestText: 'checkingOptions' parameter should be defined"); + if (checkingOptions !== undefined) { //parameterAssert(typeof checkingOptions === 'object', `checkManifestText: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + } let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -623,16 +625,18 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa } function addNotice(noticeObject) { // functionLog(`checkManifestText Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cManT addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cManT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cManT addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cManT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cManT addNotice: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cManT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cManT addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cManT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cManT addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cManT addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cManT addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cManT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cManT addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cManT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "cManT addNotice: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cManT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cManT addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cManT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cManT addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cManT addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (repoName) noticeObject.repoName = repoName; if (noticeObject.debugChain) noticeObject.debugChain = `checkManifestText ${noticeObject.debugChain}`; @@ -647,11 +651,11 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa // Updates the global list of notices // debugLog(`cManT ourYAMLTextChecks(${textName}, (${fieldText.length}), ${allowedLinks}, ${fieldLocation}, …)`); - parameterAssert(textName !== undefined, "cManT ourYAMLTextChecks: 'textName' parameter should be defined"); - parameterAssert(typeof textName === 'string', `cManT ourYAMLTextChecks: 'textName' parameter should be a string not a '${typeof textName}'`); - parameterAssert(manifestText !== undefined, "cManT ourYAMLTextChecks: 'manifestText' parameter should be defined"); - parameterAssert(typeof manifestText === 'string', `cManT ourYAMLTextChecks: 'manifestText' parameter should be a string not a '${typeof manifestText}'`); - // parameterAssert( allowedLinks===true || allowedLinks===false, "cManT ourYAMLTextChecks: allowedLinks parameter must be either true or false"); + //parameterAssert(textName !== undefined, "cManT ourYAMLTextChecks: 'textName' parameter should be defined"); + //parameterAssert(typeof textName === 'string', `cManT ourYAMLTextChecks: 'textName' parameter should be a string not a '${typeof textName}'`); + //parameterAssert(manifestText !== undefined, "cManT ourYAMLTextChecks: 'manifestText' parameter should be defined"); + //parameterAssert(typeof manifestText === 'string', `cManT ourYAMLTextChecks: 'manifestText' parameter should be a string not a '${typeof manifestText}'`); + // //parameterAssert( allowedLinks===true || allowedLinks===false, "cManT ourYAMLTextChecks: allowedLinks parameter must be either true or false"); const cYtResultObject = checkYAMLText('en', repoCode, textName, manifestText, givenLocation, checkingOptions); @@ -681,6 +685,18 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa // const DublinCoreData = formData.dublin_core // debugLog("checkManifestText DublinCoreData", JSON.stringify(DublinCoreData)); + + try { + const languageIdentifier = formData['dublin_core']['language']['identifier']; + if ((repoCode === 'UHB' && languageIdentifier !== 'hbo') + || (repoCode === 'UGNT' && languageIdentifier !== 'el-x-koine') + || (repoCode !== 'UHB' && repoCode !== 'UGNT' && languageIdentifier !== languageCode)) // for most repos + addNotice({ priority: 933, message: "Manifest' language' 'identifier' doesn't match", details: `expected '${languageCode}' but manifest has '${languageIdentifier}'`, location: ourLocation }); + } catch (e) { + debugLog(`checkManifestText got error ${e.message} while loading 'language' 'identifier'`); + addNotice({ priority: 934, message: "'language' key or 'idenfier' subkey is missing", location: ourLocation }); + } + // TODO: We could add a lot more checking here // for (const mainKey in formData) { // userLog("mainKey", typeof mainKey, mainKey); @@ -714,14 +730,23 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa // Check that the project files in the manifest actually exist const getFile_ = (checkingOptions && checkingOptions?.getFile) ? checkingOptions?.getFile : cachedGetFile; + let haveOTbooks = false, haveNTbooks = false; const ourProjectPathList = []; // Make a list for the next check for (const projectEntry of formData['projects']) { // debugLog(`Manifest project: ${JSON.stringify(projectEntry)}`); const projectKeys = Object.keys(projectEntry); // Expect title, versification, identifier, sort, path, categories // debugLog("Project keys", JSON.stringify(projectKeys)); for (const keyName of ['identifier', 'path', 'sort']) + // TODO: What about 'title', 'versification', 'categories' -- are they not compulsory if (projectKeys.indexOf(keyName) === -1) addNotice({ priority: 939, message: "Key is missing for project", details: keyName, excerpt: JSON.stringify(projectEntry), location: ourLocation }); + let whichTestament; + try { + whichTestament = testament(projectEntry['identifier']); // returns 'old' or 'new' for valid Bible books + } catch { } + if (whichTestament === 'old') haveOTbooks = true; + else if (whichTestament === 'new') haveNTbooks = true; + const projectFilepath = projectEntry['path']; ourProjectPathList.push(projectFilepath); @@ -732,7 +757,7 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa if (!checkingOptions || checkingOptions?.disableAllLinkFetchingFlag !== true) { // Try fetching the file maybe let isBookFolder = false; for (const thisBookID of Object.keys(BibleBookData)) - if (projectFilepath === `./${thisBookID}`) { isBookFolder = true; break; } + if (projectFilepath === `./${thisBookID.toLowerCase()}`) { isBookFolder = true; break; } if (!isBookFolder) { let projectFileContent; try { @@ -766,6 +791,27 @@ export async function checkManifestText(languageCode, repoCode, username, repoNa addNotice({ priority: 832, message: `Seems project file is missing from the manifest`, excerpt: repoFilepath, location: ourLocation }); } } + + if (repoCode === 'TWL' || repoCode === 'TN' || repoCode === 'TN2') { + // Check that the necessary relation fields are present + const relationList = []; // Make a list for the next check + let haveUHB = false, haveUGNT = false; + try { + for (const relation of formData['dublin_core']['relation']) { + // debugLog(`${repoCode} manifest relation: ${relation}`); + relationList.push(relation); + if (relation.startsWith('hbo/uhb')) haveUHB = true; + if (relation.startsWith('el-x-koine/ugnt')) haveUGNT = true; + } + } catch (e) { + debugLog(`checkManifestText got error ${e.message} while loading 'relation' fields`); + addNotice({ priority: 930, message: "'relation' key is missing", location: ourLocation }); + } + if (haveOTbooks && !haveUHB) + addNotice({ priority: 817, message: `UHB 'relation' is missing`, details: JSON.stringify(relationList), location: ourLocation }); + if (haveNTbooks && !haveUGNT) + addNotice({ priority: 816, message: `UGNT 'relation' is missing`, details: JSON.stringify(relationList), location: ourLocation }); + } } if (!checkingOptions?.suppressNoticeDisablingFlag) { diff --git a/src/core/manifest-text-check.md b/src/core/manifest-text-check.md index 6157b0657..84c9706bc 100644 --- a/src/core/manifest-text-check.md +++ b/src/core/manifest-text-check.md @@ -1,18 +1,20 @@ ## Manifest Text Check Sandbox -This function checks the given manifest.yaml for typical formatting errors. See https://resource-container.readthedocs.io/en/latest/manifest.html for the manifest specification. +This function checks the given manifest.yaml for typical formatting errors. See [[https://resource-container.readthedocs.io/en/latest/manifest.html]] for the manifest specification. It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other details to help locate the error as available.) These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkManifestText } from './manifest-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderNumberedLines, RenderRawResults } from '../demos/RenderProcessedResults'; // Manifest empty, good and bad text samples const textE = ''; @@ -228,7 +230,7 @@ function OurCheckManifestText(props) { const [results, setResults] = useState(null); - // We need the following construction because checkTN_TSV9DataRow is an ASYNC function + // We need the following construction because checkManifestText is an ASYNC function useEffect(() => { // Use an IIFE (Immediately Invoked Function Expression) // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 @@ -236,13 +238,13 @@ function OurCheckManifestText(props) { // Display our "waiting" message setResults(

Checking {chosenTextName}…

); const checkingOptions = {}; - const rawResults = await checkManifestText('en', 'LT', 'unfoldingWord', 'en_ult', 'master', chosenText, 'in manifest data that was supplied', checkingOptions); + const rawResults = await checkManifestText(languageCode, 'LT', 'unfoldingWord', 'en_ult', 'master', chosenText, givenLocation, checkingOptions); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done manifest text checks"]; setResults(
Check {chosenTextName}: "{chosenText.substr(0,256)}…"

- Manifest contents: + Manifest contents:
); diff --git a/src/core/markdown-file-contents-check.js b/src/core/markdown-file-contents-check.js index cb233452f..73d022a83 100644 --- a/src/core/markdown-file-contents-check.js +++ b/src/core/markdown-file-contents-check.js @@ -23,19 +23,19 @@ export async function checkMarkdownFileContents(languageCode, repoCode, markdown Returns a result object containing a successList and a noticeList */ // functionLog(`checkMarkdownFileContents(lC=${languageCode}, rC=${repoCode}, fn=${markdownFilename}, ${markdownText.length}, ${givenLocation})…`); - parameterAssert(languageCode !== undefined, "checkMarkdownFileContents: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkMarkdownFileContents: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - if (markdownFilename !== 'LICENSE.md' && markdownFilename !== 'README.md') - parameterAssert(repoCode === 'TW' || repoCode === 'TA' || repoCode === 'TQ' || repoCode === 'OBS' || repoCode === 'OBS-TQ', `checkMarkdownFileContents: 'repoCode' parameter should be 'TW', 'TA', 'TQ', 'OBS', or 'OBS-TQ' not '${repoCode}'`); - parameterAssert(markdownFilename !== undefined, "checkMarkdownFileContents: 'markdownFilename' parameter should be defined"); - parameterAssert(typeof markdownFilename === 'string', `checkMarkdownFileContents: 'markdownFilename' parameter should be a string not a '${typeof markdownFilename}': ${markdownFilename}`); - parameterAssert(markdownText !== undefined, "checkMarkdownFileContents: 'markdownText' parameter should be defined"); - parameterAssert(typeof markdownText === 'string', `checkMarkdownFileContents: 'markdownText' parameter should be a string not a '${typeof markdownText}': ${markdownText}`); - parameterAssert(givenLocation !== undefined, "checkMarkdownFileContents: 'givenLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkMarkdownFileContents: 'givenLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); - parameterAssert(givenLocation.indexOf('true') === -1, `checkMarkdownFileContents: 'givenLocation' parameter should not be '${givenLocation}'`); - if (checkingOptions !== undefined) - parameterAssert(typeof checkingOptions === 'object', `checkMarkdownFileContents: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + //parameterAssert(languageCode !== undefined, "checkMarkdownFileContents: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkMarkdownFileContents: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + if (markdownFilename !== 'LICENSE.md' && markdownFilename !== 'README.md') { //parameterAssert(repoCode === 'TW' || repoCode === 'TA' || repoCode === 'TQ' || repoCode === 'OBS' || repoCode === 'OBS-TQ', `checkMarkdownFileContents: 'repoCode' parameter should be 'TW', 'TA', 'TQ', 'OBS', or 'OBS-TQ' not '${repoCode}'`); + } + //parameterAssert(markdownFilename !== undefined, "checkMarkdownFileContents: 'markdownFilename' parameter should be defined"); + //parameterAssert(typeof markdownFilename === 'string', `checkMarkdownFileContents: 'markdownFilename' parameter should be a string not a '${typeof markdownFilename}': ${markdownFilename}`); + //parameterAssert(markdownText !== undefined, "checkMarkdownFileContents: 'markdownText' parameter should be defined"); + //parameterAssert(typeof markdownText === 'string', `checkMarkdownFileContents: 'markdownText' parameter should be a string not a '${typeof markdownText}': ${markdownText}`); + //parameterAssert(givenLocation !== undefined, "checkMarkdownFileContents: 'givenLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkMarkdownFileContents: 'givenLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); + //parameterAssert(givenLocation.indexOf('true') === -1, `checkMarkdownFileContents: 'givenLocation' parameter should not be '${givenLocation}'`); + if (checkingOptions !== undefined) { //parameterAssert(typeof checkingOptions === 'object', `checkMarkdownFileContents: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + } let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -62,16 +62,18 @@ export async function checkMarkdownFileContents(languageCode, repoCode, markdown } function addNoticePartial(noticeObject) { // functionLog(`checkMarkdownFileContents addNoticePartial: (priority=${noticeObject.priority}) ${noticeObject.message}${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? " " + noticeObject.excerpt : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cMdT addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cMdT addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cMdT addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cMdT addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cMdT addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cMdT addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cMdT addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cMdT addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cMdT addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cMdT addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cMdT addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cMdT addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cMdT addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cMdT addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "cMdT addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cMdT addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cMdT addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cMdT addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cMdT addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cMdT addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkMarkdownFileContents ${noticeObject.debugChain}`; // Prepend our name result.noticeList.push({ ...noticeObject, filename: markdownFilename }); @@ -92,10 +94,10 @@ export async function checkMarkdownFileContents(languageCode, repoCode, markdown // Updates the global list of notices // debugLog(`cMdT ourCheckMarkdownText(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${optionalFieldLocation}, …)`); - parameterAssert(markdownText !== undefined, "cMdFC ourCheckMarkdownText: 'markdownText' parameter should be defined"); - parameterAssert(typeof markdownText === 'string', `cMdFC ourCheckMarkdownText: 'markdownText' parameter should be a string not a '${typeof markdownText}'`); - parameterAssert(optionalFieldLocation !== undefined, "cMdFC ourCheckMarkdownText: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof optionalFieldLocation === 'string', `cMdFC ourCheckMarkdownText: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); + //parameterAssert(markdownText !== undefined, "cMdFC ourCheckMarkdownText: 'markdownText' parameter should be defined"); + //parameterAssert(typeof markdownText === 'string', `cMdFC ourCheckMarkdownText: 'markdownText' parameter should be a string not a '${typeof markdownText}'`); + //parameterAssert(optionalFieldLocation !== undefined, "cMdFC ourCheckMarkdownText: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof optionalFieldLocation === 'string', `cMdFC ourCheckMarkdownText: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); const cmtResultObject = await checkMarkdownText(languageCode, repoCode, markdownFilename, markdownText, optionalFieldLocation, checkingOptions); // debugLog(`cmtResultObject=${JSON.stringify(cmtResultObject)}`); @@ -121,9 +123,9 @@ export async function checkMarkdownFileContents(languageCode, repoCode, markdown // Updates the global list of notices // debugLog(`cMdFC ourFileTextCheck(${markdownText}, (${markdownText.length}), ${optionalFieldLocation}, ${JSON.stringify(checkingOptions)})`); - parameterAssert(markdownText !== undefined, "cMdFC ourFileTextCheck: 'markdownText' parameter should be defined"); - parameterAssert(typeof markdownText === 'string', `cMdFC ourFileTextCheck: 'markdownText' parameter should be a string not a '${typeof markdownText}'`); - parameterAssert(checkingOptions !== undefined, "cMdFC ourFileTextCheck: 'checkingOptions' parameter should be defined"); + //parameterAssert(markdownText !== undefined, "cMdFC ourFileTextCheck: 'markdownText' parameter should be defined"); + //parameterAssert(typeof markdownText === 'string', `cMdFC ourFileTextCheck: 'markdownText' parameter should be a string not a '${typeof markdownText}'`); + //parameterAssert(checkingOptions !== undefined, "cMdFC ourFileTextCheck: 'checkingOptions' parameter should be defined"); const ctfcResultObject = checkTextfileContents(languageCode, repoCode, 'markdown', markdownFilename, markdownText, optionalFieldLocation, checkingOptions); // debugLog(`ctfcResultObject=${JSON.stringify(ctfcResultObject)}`); diff --git a/src/core/markdown-text-check.js b/src/core/markdown-text-check.js index f6b5f8057..77dfc870f 100644 --- a/src/core/markdown-text-check.js +++ b/src/core/markdown-text-check.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { checkTextField } from './field-text-check'; import { checkNotesLinksToOutside } from './notes-links-check'; @@ -7,7 +8,7 @@ import { removeDisabledNotices } from './disabled-notices'; import { parameterAssert, dataAssert, debugLog } from './utilities'; -const MARKDOWN_TEXT_VALIDATOR_VERSION_STRING = '0.7.1'; +const MARKDOWN_TEXT_VALIDATOR_VERSION_STRING = '0.7.3'; /** @@ -27,22 +28,24 @@ export async function checkMarkdownText(languageCode, repoCode, textOrFileName, Returns a result object containing a successList and a noticeList */ // functionLog(`checkMarkdownText(${languageCode}, ${repoCode}, ${textOrFileName}, ${markdownText.length}, ${givenLocation}, …)…`); - parameterAssert(languageCode !== undefined, "checkMarkdownText: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkMarkdownText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(languageCode !== 'unfoldingWord', `checkMarkdownText: 'languageCode' ${languageCode} parameter should be not be 'unfoldingWord'`); - parameterAssert(repoCode !== undefined, "checkMarkdownText: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkMarkdownText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkMarkdownText: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(textOrFileName !== undefined, "checkMarkdownText: 'textOrFileName' parameter should be defined"); - parameterAssert(typeof textOrFileName === 'string', `checkMarkdownText: 'textOrFileName' parameter should be a string not a '${typeof textOrFileName}': ${textOrFileName}`); - parameterAssert(markdownText !== undefined, "checkMarkdownText: 'markdownText' parameter should be defined"); - parameterAssert(typeof markdownText === 'string', `checkMarkdownText: 'markdownText' parameter should be a string not a '${typeof markdownText}': ${markdownText}`); - parameterAssert(givenLocation !== undefined, "checkMarkdownText: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkMarkdownText: 'optionalFieldLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); - parameterAssert(givenLocation.indexOf('true') === -1, `checkMarkdownText: 'optionalFieldLocation' parameter should not be '${givenLocation}'`); - parameterAssert(checkingOptions !== undefined, "checkMarkdownText: 'checkingOptions' parameter should be defined"); - if (checkingOptions !== undefined) - parameterAssert(typeof checkingOptions === 'object', `checkMarkdownText: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + //parameterAssert(languageCode !== undefined, "checkMarkdownText: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkMarkdownText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(languageCode !== 'unfoldingWord', `checkMarkdownText: 'languageCode' ${languageCode} parameter should be not be 'unfoldingWord'`); + //parameterAssert(repoCode !== undefined, "checkMarkdownText: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkMarkdownText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkMarkdownText: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(textOrFileName !== undefined, "checkMarkdownText: 'textOrFileName' parameter should be defined"); + //parameterAssert(typeof textOrFileName === 'string', `checkMarkdownText: 'textOrFileName' parameter should be a string not a '${typeof textOrFileName}': ${textOrFileName}`); + //parameterAssert(textOrFileName !== `${languageCode}_${repoCode.toLowerCase()}`, `checkMarkdownText: 'textOrFileName' parameter should not be the repoName: '${textOrFileName}'`); + if (textOrFileName === `${languageCode}_${repoCode.toLowerCase()}`) { console.trace('checkMarkdownText()'); } + //parameterAssert(markdownText !== undefined, "checkMarkdownText: 'markdownText' parameter should be defined"); + //parameterAssert(typeof markdownText === 'string', `checkMarkdownText: 'markdownText' parameter should be a string not a '${typeof markdownText}': ${markdownText}`); + //parameterAssert(givenLocation !== undefined, "checkMarkdownText: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkMarkdownText: 'optionalFieldLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); + //parameterAssert(givenLocation.indexOf('true') === -1, `checkMarkdownText: 'optionalFieldLocation' parameter should not be '${givenLocation}'`); + //parameterAssert(checkingOptions !== undefined, "checkMarkdownText: 'checkingOptions' parameter should be defined"); + if (checkingOptions !== undefined) { //parameterAssert(typeof checkingOptions === 'object', `checkMarkdownText: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + } let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -69,16 +72,18 @@ export async function checkMarkdownText(languageCode, repoCode, textOrFileName, } function addNotice(noticeObject) { // functionLog(`checkMarkdownText addNotice: (priority=${noticeObject.priority}) ${noticeObject.message}${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? " " + excerpt : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cMdT addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cMdT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cMdT addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cMdT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cMdT addNotice: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cMdT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cMdT addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cMdT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cMdT addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cMdT addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cMdT addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cMdT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cMdT addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cMdT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "cMdT addNotice: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cMdT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cMdT addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cMdT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cMdT addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cMdT addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // noticeObject.debugChain = noticeObject.debugChain ? `checkMarkdownText(${languageCode}, ${textOrFileName}) ${noticeObject.debugChain}` : `checkMarkdownText(${languageCode}, ${textOrFileName})`; result.noticeList.push(noticeObject); // Used to have filename: textName, but that isn’t always a filename !!! @@ -100,15 +105,15 @@ export async function checkMarkdownText(languageCode, repoCode, textOrFileName, // Updates the global list of notices // functionLog(`cMdT ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${optionalFieldLocation}, …)`); - parameterAssert(fieldName !== undefined, "cMdT ourCheckTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `cMdT ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(lineNumber !== undefined, "cMdT ourCheckTextField: 'lineNumber' parameter should be defined"); - parameterAssert(typeof lineNumber === 'number', `cMdT ourCheckTextField: 'lineNumber' parameter should be a number not a '${typeof lineNumber}'`); - parameterAssert(fieldText !== undefined, "cMdT ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `cMdT ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "cMdT ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(optionalFieldLocation !== undefined, "cMdT ourCheckTextField: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof optionalFieldLocation === 'string', `cMdT ourCheckTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); + //parameterAssert(fieldName !== undefined, "cMdT ourCheckTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `cMdT ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(lineNumber !== undefined, "cMdT ourCheckTextField: 'lineNumber' parameter should be defined"); + //parameterAssert(typeof lineNumber === 'number', `cMdT ourCheckTextField: 'lineNumber' parameter should be a number not a '${typeof lineNumber}'`); + //parameterAssert(fieldText !== undefined, "cMdT ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `cMdT ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "cMdT ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(optionalFieldLocation !== undefined, "cMdT ourCheckTextField: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof optionalFieldLocation === 'string', `cMdT ourCheckTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); const dbtcResultObject = checkTextField(languageCode, repoCode, 'markdown', fieldName, fieldText, allowedLinks, optionalFieldLocation, checkingOptions); @@ -127,14 +132,19 @@ export async function checkMarkdownText(languageCode, repoCode, textOrFileName, // Updates the global list of notices // functionLog(`checkUSFMText ourCheckNotesLinksToOutside(${lineNumber}, ${C}:${V}, ${marker}, (${twLinkText.length}) '${twLinkText}', ${location}, ${JSON.stringify(checkingOptions)})`); - parameterAssert(lineNumber !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'lineNumber' parameter should be defined"); - parameterAssert(typeof lineNumber === 'number', `checkUSFMText ourCheckNotesLinksToOutside: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); - parameterAssert(lineText !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'lineText' parameter should be defined"); - parameterAssert(typeof lineText === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'lineText' parameter should be a string not a '${typeof lineText}': ${lineText}`); - parameterAssert(location !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'location' parameter should be defined"); - parameterAssert(typeof location === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'location' parameter should be a string not a '${typeof location}': ${location}`); - - const coTNlResultObject = await checkNotesLinksToOutside(languageCode, repoCode, '', '', '', textOrFileName, lineText, location, { ...checkingOptions, defaultLanguageCode: languageCode }); + //parameterAssert(lineNumber !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'lineNumber' parameter should be defined"); + //parameterAssert(typeof lineNumber === 'number', `checkUSFMText ourCheckNotesLinksToOutside: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); + //parameterAssert(lineText !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'lineText' parameter should be defined"); + //parameterAssert(typeof lineText === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'lineText' parameter should be a string not a '${typeof lineText}': ${lineText}`); + //parameterAssert(location !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'location' parameter should be defined"); + //parameterAssert(typeof location === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'location' parameter should be a string not a '${typeof location}': ${location}`); + + // Empty fields on the next line are bookID, C, V (as we don't have that information here) + let adjustedTextOrFileName = textOrFileName; + if (textOrFileName === 'README.md' || textOrFileName === 'LICENSE.md') adjustedTextOrFileName = textOrFileName.substring(0, textOrFileName.length - 3); + let adjustedLanguageCode = languageCode; // This is the language code of the resource with the link + if (languageCode === 'hbo' || languageCode === 'el-x-koine') adjustedLanguageCode = 'en' // This is a guess (and won't be needed for TWs when we switch to TWLs) + const coTNlResultObject = await checkNotesLinksToOutside(languageCode, repoCode, '', '', '', adjustedTextOrFileName, lineText, location, { ...checkingOptions, defaultLanguageCode: adjustedLanguageCode }); // debugLog(`coTNlResultObject=${JSON.stringify(coTNlResultObject)}`); // Choose only ONE of the following diff --git a/src/core/markdown-text-check.md b/src/core/markdown-text-check.md index d5f4d8069..99c2aa5b9 100644 --- a/src/core/markdown-text-check.md +++ b/src/core/markdown-text-check.md @@ -7,13 +7,15 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import Markdown from 'react-markdown' import { checkMarkdownText } from './markdown-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Markdown text samples const textSG = `# Short Good Markdown Test @@ -53,7 +55,7 @@ function OurCheckMarkdownText(props) { const [results, setResults] = useState(null); - // We need the following construction because checkTN_TSV9DataRow is an ASYNC function + // We need the following construction because checkMarkdownText is an ASYNC function useEffect(() => { // Use an IIFE (Immediately Invoked Function Expression) // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 diff --git a/src/core/notes-links-check.js b/src/core/notes-links-check.js index 0d0abb54c..d6bded0be 100644 --- a/src/core/notes-links-check.js +++ b/src/core/notes-links-check.js @@ -1,6 +1,7 @@ import localforage from 'localforage'; import Path from 'path'; import * as books from '../core/books/books'; +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { countOccurrences } from './text-handling-functions' import { cachedGetFile, cachedGetFileUsingFullURL, checkMarkdownText } from '../core'; @@ -8,7 +9,7 @@ import { cachedGetFile, cachedGetFileUsingFullURL, checkMarkdownText } from '../ import { userLog, debugLog, functionLog, parameterAssert, logicAssert, dataAssert, ourParseInt } from './utilities'; -// const NOTES_LINKS_VALIDATOR_VERSION_STRING = '0.7.22'; +// const NOTES_LINKS_VALIDATOR_VERSION_STRING = '0.7.29'; // const DEFAULT_LANGUAGE_CODE = 'en'; const DEFAULT_BRANCH = 'master'; @@ -23,7 +24,7 @@ const TA_RELATIVE2_DISPLAY_LINK_REGEX = new RegExp('\\[([^\\]]+?)\\]\\(\\.{2}/\\ const TW_DOUBLE_BRACKETED_LINK_REGEX = new RegExp('\\[\\[rc://([^ /]+?)/tw/dict/bible/([^ /]+?)/([^ /\\]]+?)\\]\\]', 'g'); // Enclosed in [[ ]] const TWL_RAW_LINK_REGEX = new RegExp('rc://([^ /]+?)/tw/dict/bible/([^ /]+?)/(.+)', 'g'); // Just a raw link -const TW_INTERNAL_REGEX = new RegExp('\\[([-,A-Za-z ()]+?)\\]\\(\\.{2}/([a-z]{2,5})/([-A-Za-z\\d]{2,20})\\.md\\)', 'g');// [Asher](../names/asher.md) +const TW_INTERNAL_REGEX = new RegExp('\\[([-,\\w ()]+?)\\]\\(\\.{2}/([a-z]{2,5})/([-A-Za-z\\d]{2,20})\\.md\\)', 'g');// [Asher](../names/asher.md) // NOTE: Bible link format is archaic, presumably from pre-USFM days! // TODO: Do we need to normalise Bible links, i.e., make sure that the link itself @@ -52,11 +53,13 @@ const TITLED_IMAGE_REGEX = new RegExp('!\\[([^\\]]*?)\\]\\(([^ \\)]+?) "([^"\\)] // Caches the path names of files which have been already checked // Used for storing paths to TA and TW articles that have already been checked +// so that we don't needless check them again each time they're linked to const checkedArticleStore = localforage.createInstance({ driver: [localforage.INDEXEDDB], name: 'CV-checked-path-store', }); +// Sadly we have to clear this for each run, otherwise we wouldn't get any warnings that were from these checks export async function clearCheckedArticleCache() { userLog("clearCheckedArticleCache()…"); await checkedArticleStore.clear(); @@ -92,7 +95,7 @@ async function alreadyChecked({ username, repository, path, branch }) { /** * * @param {string} languageCode, e.g., 'en' - * @param {string} repoCode, e.g., 'TN', 'SN', 'TN2', or even 'TWL' + * @param {string} repoCode, e.g., 'TN', 'SN', 'TN2', or even 'UHB', 'UGNT', or 'TWL' for the initial repo for the file being checked * @param {string} bookID * @param {string} givenC * @param {string} givenV @@ -131,27 +134,31 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // if (fieldText.indexOf('brother') !== -1) // functionLog(`checkNotesLinksToOutside('${languageCode}', '${repoCode}', ${bookID} ${givenC}:${givenV} '${fieldName}', (${fieldText.length})'${fieldText}', ${givenLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkNotesLinksToOutside: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkNotesLinksToOutside: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode !== undefined, "checkNotesLinksToOutside: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkNotesLinksToOutside: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkNotesLinksToOutside: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(bookID !== undefined, "checkNotesLinksToOutside: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkNotesLinksToOutside: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(typeof givenC === 'string', `checkNotesLinksToOutside: 'givenC' parameter should be a string not a '${typeof givenC}'`); - parameterAssert(typeof givenV === 'string', `checkNotesLinksToOutside: 'givenV' parameter should be a string not a '${typeof givenV}'`); + //parameterAssert(languageCode !== undefined, "checkNotesLinksToOutside: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkNotesLinksToOutside: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + // //parameterAssert(languageCode !== 'hbo' && languageCode !== 'el-x-koine', `checkNotesLinksToOutside: 'languageCode' parameter should not be an original language code: '${languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkNotesLinksToOutside: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkNotesLinksToOutside: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkNotesLinksToOutside: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(bookID !== undefined, "checkNotesLinksToOutside: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkNotesLinksToOutside: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(typeof givenC === 'string', `checkNotesLinksToOutside: 'givenC' parameter should be a string not a '${typeof givenC}'`); + //parameterAssert(typeof givenV === 'string', `checkNotesLinksToOutside: 'givenV' parameter should be a string not a '${typeof givenV}'`); // if (fieldName !== 'MDFile') { - // parameterAssert(bookID.length === 3, `checkNotesLinksToOutside: 'bookID' parameter should be three characters long not ${bookID.length}`); - // parameterAssert(bookID.toUpperCase() === bookID, `checkNotesLinksToOutside: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - // parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkNotesLinksToOutside: '${bookID}' is not a valid USFM book identifier`); + // //parameterAssert(bookID.length === 3, `checkNotesLinksToOutside: 'bookID' parameter should be three characters long not ${bookID.length}`); + // //parameterAssert(bookID.toUpperCase() === bookID, `checkNotesLinksToOutside: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + // //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkNotesLinksToOutside: '${bookID}' is not a valid USFM book identifier`); // } - parameterAssert(fieldName !== undefined, "checkNotesLinksToOutside: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkNotesLinksToOutside: 'fieldText' parameter should be a string not a '${typeof fieldName}'`); - // parameterAssert(fieldName === 'OccurrenceNote' || fieldName === 'Note' || fieldName === 'TWLink', `checkNotesLinksToOutside: 'fieldName' parameter should be 'OccurrenceNote' or 'Note' or 'TWLink' not '${fieldName}'`); - parameterAssert(fieldText !== undefined, "checkNotesLinksToOutside: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkNotesLinksToOutside: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(givenLocation !== undefined, "checkNotesLinksToOutside: 'fieldText' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkNotesLinksToOutside: 'fieldText' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(fieldName !== undefined, "checkNotesLinksToOutside: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkNotesLinksToOutside: 'fieldText' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldName !== `${languageCode}_${repoCode.toLowerCase()}`, `checkNotesLinksToOutside: 'fieldText' parameter should not be the repoName: '${fieldName}'`); + // if (fieldName === `${languageCode}_${repoCode.toLowerCase()}`) { console.trace('checkNotesLinksToOutside()'); } + if (!fieldName.startsWith('TA ') && !fieldName.startsWith('TW ') && fieldName.indexOf('/') === -1) { //parameterAssert(fieldName === 'OccurrenceNote' || fieldName === 'Note' || fieldName === 'TWLink' || fieldName === 'Response' || fieldName === 'README' || fieldName === 'LICENSE', `checkNotesLinksToOutside: 'fieldName' parameter should be 'OccurrenceNote', 'Note', 'TWLink', 'Response', 'README' or 'LICENSE' not '${fieldName}'`); + } + //parameterAssert(fieldText !== undefined, "checkNotesLinksToOutside: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkNotesLinksToOutside: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(givenLocation !== undefined, "checkNotesLinksToOutside: 'fieldText' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkNotesLinksToOutside: 'fieldText' parameter should be a string not a '${typeof givenLocation}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -164,18 +171,20 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g * @param {Object} noticeObject expected to contain priority, message, characterIndex, exerpt, location */ function addNoticePartial(noticeObject) { - // functionLog(`checkNotesLinksToOutside Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cTNlnk addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cTNlnk addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cTNlnk addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cTNlnk addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cTNlnk addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cTNlnk addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cTNlnk addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cTNlnk addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cTNlnk addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cTNlnk addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); - // noticeObject.debugChain = noticeObject.debugChain ? `checkNotesLinksToOutside ${noticeObject.debugChain}` : `checkNotesLinksToOutside(${fieldName})`; + // functionLog(`checkNotesLinksToOutside Notice: (priority = ${ priority }) ${ message } ${ characterIndex > 0 ? ` (at character ${characterIndex})` : "" } ${ excerpt ? ` ${excerpt}` : "" } ${ location } `); + //parameterAssert(noticeObject.priority !== undefined, "cTNlnk addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cTNlnk addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority} `); + //parameterAssert(noticeObject.message !== undefined, "cTNlnk addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cTNlnk addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message} `); + // //parameterAssert(characterIndex !== undefined, "cTNlnk addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cTNlnk addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex} `); + } + // //parameterAssert(excerpt !== undefined, "cTNlnk addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cTNlnk addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt} `); + } + //parameterAssert(noticeObject.location !== undefined, "cTNlnk addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cTNlnk addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location} `); + // noticeObject.debugChain = noticeObject.debugChain ? `checkNotesLinksToOutside ${ noticeObject.debugChain } ` : `checkNotesLinksToOutside(${ fieldName })`; ctarResult.noticeList.push({ ...noticeObject, bookID, fieldName }); } @@ -185,17 +194,19 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let excerptLength = checkingOptions?.excerptLength; if (typeof excerptLength !== 'number' || isNaN(excerptLength)) { excerptLength = DEFAULT_EXCERPT_LENGTH; - // debugLog(`Using default excerptLength=${excerptLength}`); - } // else debugLog(`Using supplied excerptLength=${excerptLength}`, `cf. default=${DEFAULT_EXCERPT_LENGTH}`); + // debugLog(`Using default excerptLength = ${ excerptLength } `); + } // else debugLog(`Using supplied excerptLength = ${ excerptLength } `, `cf.default = ${ DEFAULT_EXCERPT_LENGTH } `); const excerptHalfLength = Math.floor(excerptLength / 2); // rounded down const excerptHalfLengthPlus = Math.floor((excerptLength + 1) / 2); // rounded up - // debugLog(`Using excerptHalfLength=${excerptHalfLength}`, `excerptHalfLengthPlus=${excerptHalfLengthPlus}`); + // debugLog(`Using excerptHalfLength = ${ excerptHalfLength } `, `excerptHalfLengthPlus = ${ excerptHalfLengthPlus } `); const getFile_ = (checkingOptions && checkingOptions?.getFile) ? checkingOptions?.getFile : cachedGetFile; let defaultLanguageCode = checkingOptions?.defaultLanguageCode; // if (!defaultLanguageCode) defaultLanguageCode = DEFAULT_LANGUAGE_CODE; - if (!defaultLanguageCode) defaultLanguageCode = languageCode; - // debugLog("checkNotesLinksToOutside defaultLanguageCode", defaultLanguageCode); + let adjustedLanguageCode = languageCode; // This is the language code of the resource with the link + if (languageCode === 'hbo' || languageCode === 'el-x-koine') adjustedLanguageCode = 'en' // This is a guess (and won't be needed for TWs when we switch to TWLs) + if (!defaultLanguageCode) defaultLanguageCode = adjustedLanguageCode; + // debugLog(`checkNotesLinksToOutside defaultLanguageCode=${defaultLanguageCode}`); let taRepoUsername = checkingOptions?.taRepoUsername; if (!taRepoUsername) taRepoUsername = defaultLanguageCode === 'en' ? 'unfoldingWord' : 'Door43-Catalog'; @@ -205,6 +216,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g if (!twRepoUsername) twRepoUsername = defaultLanguageCode === 'en' ? 'unfoldingWord' : 'Door43-Catalog'; let twRepoBranch = checkingOptions?.twRepoBranch; if (!twRepoBranch) twRepoBranch = DEFAULT_BRANCH; + // debugLog(`checkNotesLinksToOutside ended up with taRepoUsername=${taRepoUsername} taRepoBranch=${taRepoBranch} twRepoUsername=${twRepoUsername} twRepoBranch=${twRepoBranch}`); // Convert our given C:V strings to integers let givenVfirstPart = ''; @@ -217,15 +229,28 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g try { givenCint = (givenC === 'front') ? 0 : ourParseInt(givenC); givenVint = (givenV === 'intro') ? 0 : ourParseInt(givenVfirstPart); - if (givenVfirstPart !== givenV && givenV !== 'intro') debugLog(`From '${givenC}':'${givenV}' got '${givenC}':'${givenVfirstPart}' then integers ${givenCint}:${givenVint}`); + if (givenVfirstPart !== givenV && givenV !== 'intro') debugLog(`From '${givenC}': '${givenV}' got '${givenC}': '${givenVfirstPart}' then integers ${givenCint}: ${givenVint} `); } catch (cvError) { - console.error(`TN Link Check couldn’t parse given chapter and verse numbers for ${bookID} ${givenC}:${givenV} ${fieldName}' via ${givenC}:${givenVfirstPart} got ${givenCint}:${givenVint} with ${cvError}`); + console.error(`TN Link Check couldn’t parse given chapter and verse numbers for ${bookID} ${givenC}: ${givenV} ${fieldName} ' via ${givenC}:${givenVfirstPart} got ${givenCint}:${givenVint} with ${cvError}`); + } + } + + if (fieldName === 'x-tw' || fieldName === 'TWLink' || fieldName === 'SupportReference') { + // The link should be the entire field (not just a string inside the field), so check for leading/trailing spaces + const trimStartFieldText = fieldText.trimStart(), trimEndFieldText = fieldText.trimEnd(); + if (trimStartFieldText !== fieldText) { + const excerpt = fieldText.substring(0, excerptLength).replace(/ /g, '␣') + (fieldText.length > excerptLength ? '…' : ''); + addNoticePartial({ priority: 784, message: "Unexpected leading whitespace in link field", excerpt, characterIndex: 0, location: ourLocation }); + } + else if (trimEndFieldText !== fieldText) { + const excerpt = (fieldText.length > excerptLength ? '…' : '') + fieldText.substring(fieldText.length - 10).replace(/ /g, '␣'); + addNoticePartial({ priority: 785, message: "Unexpected trailing whitespace in link field", excerpt, characterIndex: fieldText.length - 1, location: ourLocation }); } } let regexResultArray; - // Check for image links + // Check for image links (including OBS pictures) while ((regexResultArray = SIMPLE_IMAGE_REGEX.exec(fieldText))) { // debugLog(`Got markdown image in line ${lineNumber}:`, JSON.stringify(regexResultArray)); const [totalLink, altText, fetchLink] = regexResultArray; @@ -284,14 +309,14 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = TW_INTERNAL_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside TW_INTERNAL_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); twLinkCount1 += 1; - parameterAssert(regexResultArray.length === 4, `TW_INTERNAL_REGEX expected 4 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 4, `TW_INTERNAL_REGEX expected 4 fields (not ${regexResultArray.length})`); // eslint-disable-next-line no-unused-vars let [totalLink, _displayName, category, article] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - const twRepoName = `${languageCode}_tw`; + const twRepoName = `${defaultLanguageCode}_tw`; // debugLog(`Got twRepoName=${twRepoName}`); - const filepath = `bible/${category}/${article}.md`; + const filepath = `bible/${category}/${article.trim()}.md`; // debugLog(`Got tW filepath=${filepath}`); if (!checkingOptions?.disableAllLinkFetchingFlag) { @@ -302,7 +327,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g twFileContent = await getFile_(twPathParameters); // if (regexResultArray[3] === 'brother') debugLog(`Fetched fileContent for ${JSON.stringify(twPathParameters)}: ${typeof twFileContent} ${twFileContent.length}`); } catch (trcGCerror) { - console.error(`checkNotesLinksToOutside(${bookID}, ${fieldName}, …) failed to load TW`, twRepoUsername, twRepoName, filepath, twRepoBranch, trcGCerror.message); + console.error(`checkNotesLinksToOutside(${bookID}, ${fieldName}, …) failed to load TW ${twRepoUsername} ${twRepoName}, ${filepath}, ${twRepoBranch}: ${trcGCerror.message}`); addNoticePartial({ priority: 882, message: `Error loading TW article`, details: `${twRepoUsername} ${twRepoName} ${twRepoBranch} ${filepath}`, excerpt: totalLink, location: `${ourLocation} ${filepath}: ${trcGCerror}` }); } if (!twFileContent) @@ -315,28 +340,28 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // // functionLog(`checkNotesLinksToOutside got ${checkingOptions?.disableLinkedTWArticlesCheckFlag} so checking TW article: ${filepath}`); // if (await alreadyChecked(twPathParameters) !== true) { // // functionLog(`checkNotesLinksToOutside needs to check TW article: ${filepath}`); - // const checkTWFileResult = await checkMarkdownText(languageCode, repoCode, `TW ${regexResultArray[3]}.md`, twFileContent, ourLocation, checkingOptions); + // const checkTWFileResult = await checkMarkdownText(languageCode, repoCode, `TW ${regexResultArray[3].trim()}.md`, twFileContent, ourLocation, checkingOptions); // for (const noticeObject of checkTWFileResult.noticeList) // ctarResult.noticeList.push({ ...noticeObject, username: twRepoUsername, repoCode: 'TW', repoName: twRepoName, filename: filepath, location: ` linked to${ourLocation}`, extra: 'TW' }); // ctarResult.checkedFileCount += 1; - // ctarResult.checkedFilenames.push(`${regexResultArray[3]}.md`); + // ctarResult.checkedFilenames.push(`${regexResultArray[3].trim()}.md`); // ctarResult.checkedFilesizes = twFileContent.length; // ctarResult.checkedFilenameExtensions = ['md']; // ctarResult.checkedRepoNames.push(twRepoName); // markAsChecked(twPathParameters); // don’t bother waiting for the result // } // } - // else debugLog("disableLinkedTWArticlesCheckFlag is set to TRUE!"); + // else debugLog("checkNotesLinksToOutside: disableLinkedTWArticlesCheckFlag is set to TRUE!"); } } - else debugLog("disableAllLinkFetchingFlag is set to TRUE!"); + // else debugLog("checkNotesLinksToOutside: disableAllLinkFetchingFlag is set to TRUE!"); } // Check for TA links like [How to Translate Names](rc://en/ta/man/translate/translate-names) while ((regexResultArray = TA_FULL_DISPLAY_LINK_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside TA_FULL_DISPLAY_LINK_REGEX resultArray=${JSON.stringify(regexResultArray)}`); taLinkCount1 += 1; - parameterAssert(regexResultArray.length === 5, `TA_FULL_DISPLAY_LINK_REGEX expected 5 fields (not ${regexResultArray.length})`) + //parameterAssert(regexResultArray.length === 5, `TA_FULL_DISPLAY_LINK_REGEX expected 5 fields (not ${regexResultArray.length})`) // eslint-disable-next-line no-unused-vars let [totalLink, _displayName, foundLanguageCode, part, article] = regexResultArray; processedLinkList.push(totalLink); // Save the full link @@ -378,11 +403,12 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // functionLog(`checkNotesLinksToOutside got ${checkingOptions?.disableLinkedTAArticlesCheckFlag} so checking TA article: ${filepath}`); if (await alreadyChecked(taPathParameters) !== true) { // functionLog(`checkNotesLinksToOutside needs to check TA article: ${filepath}`); - const checkTAFileResult = await checkMarkdownText(foundLanguageCode, repoCode, `TA ${regexResultArray[3]}.md`, taFileContent, ourLocation, checkingOptions); + const checkTAFileResult = await checkMarkdownText(foundLanguageCode, repoCode, `TA ${regexResultArray[3].trim()}.md`, taFileContent, ourLocation, checkingOptions); for (const noticeObject of checkTAFileResult.noticeList) + // Why don't we use addNoticePartial() here? (It adds bookID and fieldName.) Maybe it would be misleading??? ctarResult.noticeList.push({ ...noticeObject, username: taRepoUsername, repoCode: 'TA', repoName: taRepoName, filename: filepath, location: ` linked to${ourLocation}`, extra: 'TA' }); ctarResult.checkedFileCount += 1; - ctarResult.checkedFilenames.push(`${regexResultArray[3]}.md`); + ctarResult.checkedFilenames.push(`${regexResultArray[3].trim()}.md`); ctarResult.checkedFilesizes = taFileContent.length; ctarResult.checkedFilenameExtensions = ['md']; ctarResult.checkedRepoNames.push(taRepoName); @@ -398,12 +424,12 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = TA_RELATIVE1_DISPLAY_LINK_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside TA_RELATIVE1_DISPLAY_LINK_REGEX resultArray=${JSON.stringify(regexResultArray)}`); taLinkCount1 += 1; - parameterAssert(regexResultArray.length === 3, `TA_RELATIVE1_DISPLAY_LINK_REGEX expected 3 fields (not ${regexResultArray.length})`) + //parameterAssert(regexResultArray.length === 3, `TA_RELATIVE1_DISPLAY_LINK_REGEX expected 3 fields (not ${regexResultArray.length})`) // eslint-disable-next-line no-unused-vars let [totalLink, _displayName, article] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - const taRepoName = `${languageCode}_ta`; + const taRepoName = `${defaultLanguageCode}_ta`; // debugLog(`Got taRepoName=${taRepoName}`); let TAsection = 'translate'; if (fieldName.startsWith('checking/')) TAsection = 'checking'; @@ -435,11 +461,11 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // // functionLog(`checkNotesLinksToOutside got ${checkingOptions?.disableLinkedTAArticlesCheckFlag} so checking TA article: ${filepath}`); // if (await alreadyChecked(taPathParameters) !== true) { // // functionLog(`checkNotesLinksToOutside needs to check TA article: ${filepath}`); - // const checkTAFileResult = await checkMarkdownText(languageCode, repoCode, `TA ${regexResultArray[3]}.md`, taFileContent, ourLocation, checkingOptions); + // const checkTAFileResult = await checkMarkdownText(languageCode, repoCode, `TA ${regexResultArray[3].trim()}.md`, taFileContent, ourLocation, checkingOptions); // for (const noticeObject of checkTAFileResult.noticeList) // ctarResult.noticeList.push({ ...noticeObject, username: taRepoUsername, repoCode: 'TA', repoName: taRepoName, filename: filepath, location: ` linked to${ourLocation}`, extra: 'TA' }); // ctarResult.checkedFileCount += 1; - // ctarResult.checkedFilenames.push(`${regexResultArray[3]}.md`); + // ctarResult.checkedFilenames.push(`${regexResultArray[3].trim()}.md`); // ctarResult.checkedFilesizes = taFileContent.length; // ctarResult.checkedFilenameExtensions = ['md']; // ctarResult.checkedRepoNames.push(taRepoName); @@ -453,12 +479,12 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = TA_RELATIVE2_DISPLAY_LINK_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside TA_RELATIVE2_DISPLAY_LINK_REGEX resultArray=${JSON.stringify(regexResultArray)}`); taLinkCount1 += 1; - parameterAssert(regexResultArray.length === 4, `TA_RELATIVE2_DISPLAY_LINK_REGEX expected 4 fields (not ${regexResultArray.length})`) + //parameterAssert(regexResultArray.length === 4, `TA_RELATIVE2_DISPLAY_LINK_REGEX expected 4 fields (not ${regexResultArray.length})`) // eslint-disable-next-line no-unused-vars let [totalLink, _displayName, TAsection, article] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - const taRepoName = `${languageCode}_ta`; + const taRepoName = `${defaultLanguageCode}_ta`; // debugLog(`Got taRepoName=${taRepoName}`); const filepath = `${TAsection}/${article}/01.md`; // Other files are title.md, sub-title.md // debugLog(`Got tA filepath=${filepath}`); @@ -485,11 +511,11 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // // functionLog(`checkNotesLinksToOutside got ${checkingOptions?.disableLinkedTAArticlesCheckFlag} so checking TA article: ${filepath}`); // if (await alreadyChecked(taPathParameters) !== true) { // // functionLog(`checkNotesLinksToOutside needs to check TA article: ${filepath}`); - // const checkTAFileResult = await checkMarkdownText(languageCode, repoCode, `TA ${regexResultArray[3]}.md`, taFileContent, ourLocation, checkingOptions); + // const checkTAFileResult = await checkMarkdownText(languageCode, repoCode, `TA ${regexResultArray[3].trim()}.md`, taFileContent, ourLocation, checkingOptions); // for (const noticeObject of checkTAFileResult.noticeList) // ctarResult.noticeList.push({ ...noticeObject, username: taRepoUsername, repoCode: 'TA', repoName: taRepoName, filename: filepath, location: ` linked to${ourLocation}`, extra: 'TA' }); // ctarResult.checkedFileCount += 1; - // ctarResult.checkedFilenames.push(`${regexResultArray[3]}.md`); + // ctarResult.checkedFilenames.push(`${regexResultArray[3].trim()}.md`); // ctarResult.checkedFilesizes = taFileContent.length; // ctarResult.checkedFilenameExtensions = ['md']; // ctarResult.checkedRepoNames.push(taRepoName); @@ -506,7 +532,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = TA_DOUBLE_BRACKETED_LINK_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside TA_DOUBLE_BRACKETED_LINK_REGEX resultArray=${JSON.stringify(regexResultArray)}`); taLinkCount2 += 1; - parameterAssert(regexResultArray.length === 4, `TA_DOUBLE_BRACKETED_LINK_REGEX expected 4 fields (not ${regexResultArray.length})`) + //parameterAssert(regexResultArray.length === 4, `TA_DOUBLE_BRACKETED_LINK_REGEX expected 4 fields (not ${regexResultArray.length})`) let [totalLink, foundLanguageCode, part, article] = regexResultArray; processedLinkList.push(totalLink); // Save the full link @@ -547,11 +573,12 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // functionLog(`checkNotesLinksToOutside got ${checkingOptions?.disableLinkedTAArticlesCheckFlag} so checking TA article: ${filepath}`); if (await alreadyChecked(taPathParameters) !== true) { // functionLog(`checkNotesLinksToOutside needs to check TA article: ${filepath}`); - const checkTAFileResult = await checkMarkdownText(foundLanguageCode, repoCode, `TA ${regexResultArray[3]}.md`, taFileContent, ourLocation, checkingOptions); + const checkTAFileResult = await checkMarkdownText(foundLanguageCode, repoCode, `TA ${regexResultArray[3].trim()}.md`, taFileContent, ourLocation, checkingOptions); for (const noticeObject of checkTAFileResult.noticeList) + // Why don't we use addNoticePartial() here? (It adds bookID and fieldName.) Maybe it would be misleading??? ctarResult.noticeList.push({ ...noticeObject, username: taRepoUsername, repoCode: 'TA', repoName: taRepoName, filename: filepath, location: ` linked to${ourLocation}`, extra: 'TA' }); ctarResult.checkedFileCount += 1; - ctarResult.checkedFilenames.push(`${regexResultArray[3]}.md`); + ctarResult.checkedFilenames.push(`${regexResultArray[3].trim()}.md`); ctarResult.checkedFilesizes = taFileContent.length; ctarResult.checkedFilenameExtensions = ['md']; ctarResult.checkedRepoNames.push(taRepoName); @@ -569,14 +596,14 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = ourTWRegex.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside ${languageCode} ${repoCode} ${fieldName} ${givenC}:${givenV} found TW resultArray=${JSON.stringify(regexResultArray)}`); twLinkCount2 += 1; - parameterAssert(regexResultArray.length === 4, `TW_REGEX expected 4 fields (not ${regexResultArray.length})`) + //parameterAssert(regexResultArray.length === 4, `TW_REGEX expected 4 fields (not ${regexResultArray.length})`) let [totalLink, foundLanguageCode, category, article] = regexResultArray; processedLinkList.push(totalLink); // Save the full link if (!foundLanguageCode || foundLanguageCode === '*') foundLanguageCode = defaultLanguageCode; const twRepoName = `${foundLanguageCode}_tw`; // debugLog(`Got twRepoName=${twRepoName}`); - const filepath = `bible/${category}/${article}.md`; + const filepath = `bible/${category}/${article.trim()}.md`; // debugLog(`Got tW filepath=${filepath}`); if (!checkingOptions?.disableAllLinkFetchingFlag) { @@ -587,7 +614,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g twFileContent = await getFile_(twPathParameters); // if (article === 'brother') debugLog(`Fetched fileContent for ${JSON.stringify(twPathParameters)}: ${typeof twFileContent} ${twFileContent.length}`); } catch (trcGCerror) { - console.error(`checkNotesLinksToOutside(${bookID}, ${fieldName}, …) failed to load TW`, twRepoUsername, twRepoName, filepath, twRepoBranch, trcGCerror.message); + console.error(`checkNotesLinksToOutside(${bookID}, ${fieldName}, …) failed to load TW ${twRepoUsername} ${twRepoName}, ${filepath}, ${twRepoBranch}: ${trcGCerror.message}`); addNoticePartial({ priority: 882, message: `Error loading TW article`, details: `${twRepoUsername} ${twRepoName} ${twRepoBranch} ${filepath}`, excerpt: totalLink, location: `${ourLocation} ${filepath}: ${trcGCerror}` }); } if (!twFileContent) @@ -599,21 +626,22 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g // functionLog(`checkNotesLinksToOutside got ${checkingOptions?.disableLinkedTWArticlesCheckFlag} so checking TW article: ${filepath}`); if (await alreadyChecked(twPathParameters) !== true) { // functionLog(`checkNotesLinksToOutside needs to check TW article: ${filepath}`); - const checkTWFileResult = await checkMarkdownText(foundLanguageCode, repoCode, `TW ${regexResultArray[3]}.md`, twFileContent, ourLocation, checkingOptions); + const checkTWFileResult = await checkMarkdownText(foundLanguageCode, repoCode, `TW ${regexResultArray[3].trim()}.md`, twFileContent, ourLocation, checkingOptions); for (const noticeObject of checkTWFileResult.noticeList) + // Why don't we use addNoticePartial() here? (It adds bookID and fieldName.) Maybe it would be misleading??? ctarResult.noticeList.push({ ...noticeObject, username: twRepoUsername, repoCode: 'TW', repoName: twRepoName, filename: filepath, location: ` linked to${ourLocation}`, extra: 'TW' }); ctarResult.checkedFileCount += 1; - ctarResult.checkedFilenames.push(`${regexResultArray[3]}.md`); + ctarResult.checkedFilenames.push(`${regexResultArray[3].trim()}.md`); ctarResult.checkedFilesizes = twFileContent.length; ctarResult.checkedFilenameExtensions = ['md']; ctarResult.checkedRepoNames.push(twRepoName); markAsChecked(twPathParameters); // don’t bother waiting for the result } } - else debugLog("disableLinkedTWArticlesCheckFlag is set to TRUE!"); + // else debugLog("checkNotesLinksToOutside: disableLinkedTWArticlesCheckFlag is set to TRUE!"); } } - else debugLog("disableAllLinkFetchingFlag is set to TRUE!"); + // else debugLog("checkNotesLinksToOutside: disableAllLinkFetchingFlag is set to TRUE!"); } // debugLog("checkNotesLinksToOutside: Search for Bible links") @@ -621,7 +649,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BIBLE_FULL_HELP_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BIBLE_FULL_HELP_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); otherBookBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 9, `BIBLE_FULL_HELP_REGEX expected 9 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 9, `BIBLE_FULL_HELP_REGEX expected 9 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1, Lg, B2, C2, V2] = regexResultArray; // debugLog(`Lg='${Lg}' B2='${B2}' C2='${C2}' V2='${V2}'`); processedLinkList.push(totalLink); // Save the full link @@ -629,14 +657,16 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g if (Lg !== '*' && Lg !== languageCode) addNoticePartial({ priority: 669, message: "Unexpected language code in link", details: `resource language code is '${languageCode}'`, excerpt: Lg, location: ourLocation }); - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}' in '${totalLink}'`); + if (optionalN1) { //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}' in '${totalLink}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in TN RC link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1 === 'Song of Solomon' ? 'Unexpected' : 'Unknown'} Bible book name in TN RC link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -667,13 +697,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BIBLE_FULL_HELP_REGEX linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside1 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible help link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -687,18 +717,20 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BIBLE_REGEX_THIS_CHAPTER_RELATIVE.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BIBLE_REGEX_THIS_CHAPTER_RELATIVE regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); thisChapterBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 6, `BIBLE_REGEX_THIS_CHAPTER_RELATIVE expected 6 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 6, `BIBLE_REGEX_THIS_CHAPTER_RELATIVE expected 6 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1 === 'Song of Solomon' ? 'Unexpected' : 'Unknown'} Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -706,7 +738,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g const linkVerseInt = ourParseInt(V2); if (C1 === undefined) { - if (!books.isOneChapterBook(linkBookCode)) { + if (linkBookCode.length === 0 || !books.isOneChapterBook(linkBookCode)) { // debugLog(` checkNotesLinksToOutside C1 missing in BIBLE_REGEX_THIS_CHAPTER_RELATIVE regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); addNoticePartial({ priority: 555, message: "Possible missing chapter number in markdown Bible link", excerpt: totalLink, location: ourLocation }); } @@ -730,13 +762,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BIBLE_REGEX_THIS_CHAPTER_RELATIVE linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside2 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), givenCint); + numVersesThisChapter = books.versesInChapter(linkBookCode, givenCint); } catch (tlcNVerror) { } if (!givenCint || givenCint < 1 || givenCint > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${givenCint} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -749,7 +781,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = THIS_VERSE_TO_THIS_CHAPTER_BIBLE_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside THIS_VERSE_TO_THIS_CHAPTER_BIBLE_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); thisVerseBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 4, `THIS_VERSE_TO_THIS_CHAPTER_BIBLE_REGEX expected 4 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 4, `THIS_VERSE_TO_THIS_CHAPTER_BIBLE_REGEX expected 4 fields (not ${regexResultArray.length})`); let [totalLink, V1, C2, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link @@ -770,13 +802,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `THIS_VERSE_TO_THIS_CHAPTER_BIBLE_REGEX linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside3 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -789,7 +821,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = THIS_VERSE_RANGE_TO_THIS_CHAPTER_BIBLE_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside THIS_VERSE_RANGE_TO_THIS_CHAPTER_BIBLE_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); thisVerseBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 5, `THIS_VERSE_RANGE_TO_THIS_CHAPTER_BIBLE_REGEX expected 5 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 5, `THIS_VERSE_RANGE_TO_THIS_CHAPTER_BIBLE_REGEX expected 5 fields (not ${regexResultArray.length})`); let [totalLink, V1a, V1b, C2, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link @@ -814,13 +846,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `THIS_VERSE_RANGE_TO_THIS_CHAPTER_BIBLE_REGEX linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside4 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -833,18 +865,20 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BIBLE_REGEX_THIS_BOOK_RELATIVE.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BIBLE_REGEX_THIS_BOOK_RELATIVE regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); thisBookBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 7, `BIBLE_REGEX_THIS_BOOK_RELATIVE expected 7 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 7, `BIBLE_REGEX_THIS_BOOK_RELATIVE expected 7 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1, C2, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in relative Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown'} Bible book name in relative Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -868,13 +902,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BIBLE_REGEX_THIS_BOOK_RELATIVE linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside5 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -887,18 +921,20 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BCV_V_TO_THIS_BOOK_BIBLE_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BCV_V_TO_THIS_BOOK_BIBLE_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); thisBookBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 9, `BCV_V_TO_THIS_BOOK_BIBLE_REGEX expected 9 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 9, `BCV_V_TO_THIS_BOOK_BIBLE_REGEX expected 9 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1a, V1b, B2, C2, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown'} Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -929,13 +965,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BCV_V_TO_THIS_BOOK_BIBLE_REGEX linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside6 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -948,18 +984,21 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BCV_V_TO_THIS_CHAPTER_BIBLE_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BCV_V_TO_THIS_CHAPTER_BIBLE_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); thisChapterBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 7, `BCV_V_TO_THIS_CHAPTER_BIBLE_REGEX expected 7 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 7, `BCV_V_TO_THIS_CHAPTER_BIBLE_REGEX expected 7 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1a, V1b, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { + //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown'} Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -984,10 +1023,10 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BCV_V_TO_THIS_CHAPTER_BIBLE_REGEX linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); // try { - // numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + // numChaptersThisBook = books.chaptersInBook(linkBookCode); // } catch (tlcNCerror) { } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), givenC); + numVersesThisChapter = books.versesInChapter(linkBookCode, givenC); } catch (tlcNVerror) { } if (!linkVerseInt || linkVerseInt < 0 || linkVerseInt > numVersesThisChapter) addNoticePartial({ priority: 653, message: "Bad verse number in markdown Bible link", details: `${linkBookCode} ${givenC}:${linkVerseInt} vs ${numVersesThisChapter} verses`, excerpt: totalLink, location: ourLocation }); @@ -998,18 +1037,21 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BIBLE_REGEX_OTHER_BOOK_ABSOLUTE.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BIBLE_REGEX_OTHER_BOOK_ABSOLUTE regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); otherBookBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 8, `BIBLE_REGEX_OTHER_BOOK_ABSOLUTE expected 8 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 8, `BIBLE_REGEX_OTHER_BOOK_ABSOLUTE expected 8 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1, B2, C2, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { + //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown'} Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -1034,13 +1076,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BIBLE_REGEX_OTHER_BOOK_ABSOLUTE linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside8 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -1053,18 +1095,21 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = BIBLE_REGEX_OTHER_BOOK_RELATIVE.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside BIBLE_REGEX_OTHER_BOOK_RELATIVE regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); otherBookBibleLinkCount1 += 1; - parameterAssert(regexResultArray.length === 8, `BIBLE_REGEX_OTHER_BOOK_RELATIVE expected 8 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 8, `BIBLE_REGEX_OTHER_BOOK_RELATIVE expected 8 fields (not ${regexResultArray.length})`); let [totalLink, optionalN1, optionalB1, C1, V1, B2, C2, V2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { + //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name const checkResult = books.isGoodEnglishBookName(optionalB1); // debugLog(optionalB1, "isGoodEnglishBookName checkResult", checkResult); if (checkResult === undefined || checkResult === false) - addNoticePartial({ priority: 143, message: "Unknown Bible book name in Bible link", details: totalLink, excerpt: optionalB1, location: ourLocation }); + // NOTE: Our English bookname table has 'Song of Songs' + addNoticePartial({ priority: optionalB1 === 'Song of Solomon' ? 43 : 143, message: `${optionalB1==='Song of Solomon'?'Unexpected' : 'Unknown'} Bible book name in Bible link`, details: totalLink, excerpt: optionalB1, location: ourLocation }); } } @@ -1089,13 +1134,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `BIBLE_REGEX_OTHER_BOOK_RELATIVE linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside9 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 655, message: "Bad chapter number in markdown Bible link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -1108,12 +1153,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = TN_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside TN_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); TNLinkCount1 += 1; - parameterAssert(regexResultArray.length === 9, `TN_REGEX expected 9 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 9, `TN_REGEX expected 9 fields (not ${regexResultArray.length})`); // eslint-disable-next-line no-unused-vars let [totalLink, optionalN1, optionalB1, C1, V1, B2, C2, V2, _noteID2] = regexResultArray; processedLinkList.push(totalLink); // Save the full link - if (optionalN1) parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + if (optionalN1) { //parameterAssert(optionalB1, `Should have book name as well as number '${optionalN1}'`); + } if (optionalB1) { optionalB1 = `${optionalN1}${optionalB1}`.trim(); // e.g., 1 Timothy if (defaultLanguageCode === 'en') { // should be able to check the book name @@ -1145,13 +1191,13 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g let numChaptersThisBook, numVersesThisChapter; logicAssert(linkBookCode.toLowerCase() !== 'obs', `TN_REGEX linkBookCode shouldn’t be '${linkBookCode}' in notes-links-check`); try { - numChaptersThisBook = books.chaptersInBook(linkBookCode.toLowerCase()).length; + numChaptersThisBook = books.chaptersInBook(linkBookCode); } catch (tlcNCerror) { debugLog(`checkNotesLinksToOutside10 with linkBookCode '${linkBookCode}' got error: ${tlcNCerror}`); numChaptersThisBook = 0; - } + } try { - numVersesThisChapter = books.versesInChapter(linkBookCode.toLowerCase(), linkChapterInt); + numVersesThisChapter = books.versesInChapter(linkBookCode, linkChapterInt); } catch (tlcNVerror) { } if (!linkChapterInt || linkChapterInt < 1 || linkChapterInt > numChaptersThisBook) addNoticePartial({ priority: 656, message: "Bad chapter number in markdown TN link", details: `${linkBookCode} ${linkChapterInt} vs ${numChaptersThisBook} chapters`, excerpt: totalLink, location: ourLocation }); @@ -1167,7 +1213,7 @@ export async function checkNotesLinksToOutside(languageCode, repoCode, bookID, g while ((regexResultArray = SIMPLE_DISPLAY_LINK_REGEX.exec(fieldText))) { // debugLog(` checkNotesLinksToOutside SIMPLE_DISPLAY_LINK_REGEX regexResultArray(${regexResultArray.length})=${JSON.stringify(regexResultArray)}`); generalLinkCount1 += 1; - parameterAssert(regexResultArray.length === 3, `SIMPLE_DISPLAY_LINK_REGEX expected 3 fields (not ${regexResultArray.length})`); + //parameterAssert(regexResultArray.length === 3, `SIMPLE_DISPLAY_LINK_REGEX expected 3 fields (not ${regexResultArray.length})`); // eslint-disable-next-line no-unused-vars let [totalLink, displayText, uri] = regexResultArray; processedLinkList.push(totalLink); // Save the full link diff --git a/src/core/notes-tsv7-row-check.js b/src/core/notes-tsv7-row-check.js index 8d10da385..f04cc6a1b 100644 --- a/src/core/notes-tsv7-row-check.js +++ b/src/core/notes-tsv7-row-check.js @@ -1,15 +1,17 @@ -import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' -import { isWhitespace, countOccurrences } from './text-handling-functions' +// eslint-disable-next-line no-unused-vars +import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults'; +import { isWhitespace, countOccurrences } from './text-handling-functions'; import * as books from './books/books'; import { checkTextField } from './field-text-check'; import { checkMarkdownText } from './markdown-text-check'; import { checkSupportReferenceInTA } from './ta-reference-check'; // import { checkNotesLinksToOutside } from './notes-links-check'; import { checkOriginalLanguageQuoteAndOccurrence } from './orig-quote-check'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; -// const NOTES_TABLE_ROW_VALIDATOR_VERSION_STRING = '0.6.13'; +// const NOTES_TABLE_ROW_VALIDATOR_VERSION_STRING = '0.6.14'; const NUM_EXPECTED_NOTES_TSV_FIELDS = 7; // so expects 6 tabs per line const EXPECTED_NOTES_HEADING_LINE = 'Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tNote'; @@ -50,25 +52,30 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID Returns an object containing the noticeList. */ // functionLog(`checkNotesTSV7DataRow(${languageCode}, ${repoCode}, ${line}, ${bookID}, ${givenRowLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkNotesTSV7DataRow: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkNotesTSV7DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode !== undefined, "checkNotesTSV7DataRow: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkNotesTSV7DataRow: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkNotesTSV7DataRow: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(line !== undefined, "checkNotesTSV7DataRow: 'line' parameter should be defined"); - parameterAssert(typeof line === 'string', `checkNotesTSV7DataRow: 'line' parameter should be a string not a '${typeof line}'`); - parameterAssert(bookID !== undefined, "checkNotesTSV7DataRow: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkNotesTSV7DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkNotesTSV7DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkNotesTSV7DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkNotesTSV7DataRow: '${bookID}' is not a valid USFM book identifier`); - // parameterAssert(givenC !== undefined, "checkNotesTSV7DataRow: 'givenC' parameter should be defined"); - if (givenC) parameterAssert(typeof givenC === 'string', `checkNotesTSV7DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); - // parameterAssert(givenV !== undefined, "checkNotesTSV7DataRow: 'givenV' parameter should be defined"); - if (givenV) parameterAssert(typeof givenV === 'string', `checkNotesTSV7DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); - parameterAssert(givenRowLocation !== undefined, "checkNotesTSV7DataRow: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenRowLocation === 'string', `checkNotesTSV7DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); - parameterAssert(givenRowLocation.indexOf('true') === -1, "checkNotesTSV7DataRow: 'givenRowLocation' parameter should not be 'true'"); + //parameterAssert(languageCode !== undefined, "checkNotesTSV7DataRow: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkNotesTSV7DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkNotesTSV7DataRow: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkNotesTSV7DataRow: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + // parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkNotesTSV7DataRow: 'repoCode' parameter should not be '${repoCode}'`); + parameterAssert(repoCode==='TN2' || repoCode==='SN', `checkNotesTSV7DataRow: 'repoCode' parameter should be 'TN2' or 'SN', not '${repoCode}'`); + //parameterAssert(line !== undefined, "checkNotesTSV7DataRow: 'line' parameter should be defined"); + //parameterAssert(typeof line === 'string', `checkNotesTSV7DataRow: 'line' parameter should be a string not a '${typeof line}'`); + //parameterAssert(bookID !== undefined, "checkNotesTSV7DataRow: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkNotesTSV7DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkNotesTSV7DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkNotesTSV7DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkNotesTSV7DataRow: '${bookID}' is not a valid USFM book identifier`); + // //parameterAssert(givenC !== undefined, "checkNotesTSV7DataRow: 'givenC' parameter should be defined"); + if (givenC) { + //parameterAssert(typeof givenC === 'string', `checkNotesTSV7DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); + } + // //parameterAssert(givenV !== undefined, "checkNotesTSV7DataRow: 'givenV' parameter should be defined"); + if (givenV) { + //parameterAssert(typeof givenV === 'string', `checkNotesTSV7DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); + } + //parameterAssert(givenRowLocation !== undefined, "checkNotesTSV7DataRow: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenRowLocation === 'string', `checkNotesTSV7DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); + //parameterAssert(givenRowLocation.indexOf('true') === -1, "checkNotesTSV7DataRow: 'givenRowLocation' parameter should not be 'true'"); let ourRowLocation = givenRowLocation; if (ourRowLocation && ourRowLocation[0] !== ' ') ourRowLocation = ` ${ourRowLocation}`; @@ -90,18 +97,20 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID * @param {string} location - description of where the issue is located */ // functionLog(`checkNotesTSV7DataRow addNoticePartial(priority=${noticeObject.priority}) ${noticeObject.message}, ${noticeObject.characterIndex}, ${noticeObject.excerpt}, ${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `checkNotesTSV7DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `checkNotesTSV7DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(lineNumber !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'lineNumber' parameter should be defined"); - // parameterAssert(typeof lineNumber === 'number', `checkNotesTSV7DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); - // parameterAssert(characterIndex !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `checkNotesTSV7DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `checkNotesTSV7DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `checkNotesTSV7DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `checkNotesTSV7DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `checkNotesTSV7DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(lineNumber !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'lineNumber' parameter should be defined"); + // //parameterAssert(typeof lineNumber === 'number', `checkNotesTSV7DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); + // //parameterAssert(characterIndex !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `checkNotesTSV7DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `checkNotesTSV7DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "checkNotesTSV7DataRow addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `checkNotesTSV7DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // Also uses the given bookID,C,V, parameters from the main function call // noticeObject.debugChain = noticeObject.debugChain ? `checkNotesTSV7DataRow ${noticeObject.debugChain}` : `checkNotesTSV7DataRow(${repoCode})`; @@ -127,17 +136,17 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // We don’t currently use the allowedLinks parameter // functionLog(`checkNotesTSV7DataRow ourMarkdownTextChecks(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be a string not a '${typeof rowID}'`); - // parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be defined"); - // parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldName === 'Note', `checkNotesTSV7DataRow ourMarkdownTextChecks: Only run this check on Notes not '${fieldName}'`); - parameterAssert(fieldText !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkNotesTSV7DataRow ourMarkdownTextChecks: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be a string not a '${typeof rowID}'`); + // //parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be defined"); + // //parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldName === 'Note', `checkNotesTSV7DataRow ourMarkdownTextChecks: Only run this check on Notes not '${fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkNotesTSV7DataRow ourMarkdownTextChecks: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const omtcResultObject = await checkMarkdownText(languageCode, repoCode, fieldName, fieldText, rowLocation, checkingOptions); @@ -147,7 +156,7 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of omtcResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); // NOTE: Ellipses in Note have the normal meaning // not like the specialised meaning in the Quote snippet fields if (noticeEntry.priority !== 178 && noticeEntry.priority !== 179 // unexpected space after ellipse, ellipse after space @@ -176,16 +185,16 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // Updates the global list of notices // functionLog(`checkNotesTSV7DataRow ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkNotesTSV7DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkNotesTSV7DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkNotesTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkNotesTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const fieldType = fieldName === 'Note' ? 'markdown' : 'raw'; const octfResultObject = checkTextField(languageCode, repoCode, fieldType, fieldName, fieldText, allowedLinks, rowLocation, checkingOptions); @@ -196,7 +205,7 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of octfResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } return octfResultObject.suggestion; // There may or may not be one! @@ -209,13 +218,13 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // Updates the global list of notices // functionLog(`checkNotesTSV7DataRow ourCheckSupportReferenceInTA(${fieldName}, (${taLinkText.length}) '${taLinkText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(taLinkText !== undefined, "checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be defined"); - parameterAssert(typeof taLinkText === 'string', `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(taLinkText !== undefined, "checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be defined"); + //parameterAssert(typeof taLinkText === 'string', `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourCheckSupportReferenceInTA: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const coqResultObject = await checkSupportReferenceInTA(fieldName, taLinkText, rowLocation, { ...checkingOptions, taRepoLanguageCode: languageCode, expectFullLink: true }); @@ -225,7 +234,7 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckSupportReferenceInTA notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckSupportReferenceInTA notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } } @@ -240,15 +249,15 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // Updates the global list of notices // functionLog(`checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence(${fieldName}, (${fieldText.length}) '${fieldText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(occurrence !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be defined"); - parameterAssert(typeof occurrence === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(occurrence !== undefined, "checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be defined"); + //parameterAssert(typeof occurrence === 'string', `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkNotesTSV7DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const coqResultObject = await checkOriginalLanguageQuoteAndOccurrence(languageCode, repoCode, fieldName, fieldText, occurrence, bookID, givenC, givenV, rowLocation, checkingOptions); @@ -258,63 +267,13 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuoteAndOccurrence notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuoteAndOccurrence notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } } // end of ourCheckTNOriginalLanguageQuoteAndOccurrence function - /* - async function ourCheckNotesLinksToOutside(rowID, fieldName, taLinkText, rowLocation, checkingOptions) { - // Checks that the TA/TW/Bible reference can be found - - // Updates the global list of notices - - // functionLog(`checkNotesTSV7DataRow ourCheckNotesLinksToOutside(${rowID}, ${fieldName}, (${taLinkText.length}) '${taLinkText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldName === 'Note', `checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be 'Note' not '${fieldName}'`); - parameterAssert(taLinkText !== undefined, "checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'taLinkText' parameter should be defined"); - parameterAssert(typeof taLinkText === 'string', `checkNotesTSV7DataRow ourCheckNotesLinksToOutside: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); - - const coqResultObject = await checkNotesLinksToOutside(languageCode, repoCode, bookID, givenC, givenV, fieldName, taLinkText, rowLocation, { ...checkingOptions, defaultLanguageCode: languageCode }); - // debugLog("coqResultObject", JSON.stringify(coqResultObject)); - - // Choose only ONE of the following - // This is the fast way of append the results from this field - // result.noticeList = result.noticeList.concat(coqResultObject.noticeList); - // If we need to put everything through addNoticePartial, e.g., for debugging or filtering - // process results line by line - for (const coqNoticeEntry of coqResultObject.noticeList) { - if (coqNoticeEntry.extra) // it must be an indirect check on a TA or TW article from a TN2 check - drResult.noticeList.push(coqNoticeEntry); // Just copy the complete notice as is - else // For our direct checks, we add the repoCode as an extra value - addNoticePartial({ ...coqNoticeEntry, rowID, fieldName }); - } - // The following is needed coz we might be checking the linked TA and/or TW articles - if (coqResultObject.checkedFileCount && coqResultObject.checkedFileCount > 0) - if (typeof drResult.checkedFileCount === 'number') drResult.checkedFileCount += coqResultObject.checkedFileCount; - else drResult.checkedFileCount = coqResultObject.checkedFileCount; - if (coqResultObject.checkedFilesizes && coqResultObject.checkedFilesizes > 0) - if (typeof drResult.checkedFilesizes === 'number') drResult.checkedFilesizes += coqResultObject.checkedFilesizes; - else drResult.checkedFilesizes = coqResultObject.checkedFilesizes; - if (coqResultObject.checkedRepoNames && coqResultObject.checkedRepoNames.length > 0) - for (const checkedRepoName of coqResultObject.checkedRepoNames) - try { if (drResult.checkedRepoNames.indexOf(checkedRepoName) < 0) drResult.checkedRepoNames.push(checkedRepoName); } - catch { drResult.checkedRepoNames = [checkedRepoName]; } - if (coqResultObject.checkedFilenameExtensions && coqResultObject.checkedFilenameExtensions.length > 0) - for (const checkedFilenameExtension of coqResultObject.checkedFilenameExtensions) - try { if (drResult.checkedFilenameExtensions.indexOf(checkedFilenameExtension) < 0) drResult.checkedFilenameExtensions.push(checkedFilenameExtension); } - catch { drResult.checkedFilenameExtensions = [checkedFilenameExtension]; } - // if (drResult.checkedFilenameExtensions) userLog("drResult", JSON.stringify(drResult)); - } - // end of ourCheckNotesLinksToOutside function - */ - - // Main code for checkNotesTSV7DataRow function if (line === EXPECTED_NOTES_HEADING_LINE) // Assume it must be ok return drResult; // We can’t detect if it’s in the wrong place @@ -338,9 +297,9 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID if (bookID === 'OBS') numChaptersThisBook = 50; // There's 50 Open Bible Stories else { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkNotesTSV7DataRow"); + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkNotesTSV7DataRow"); try { - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch (tlcNCerror) { addNoticePartial({ priority: 979, message: "Invalid book identifier passed to checkNotesTSV7DataRow", location: ` '${bookID}' in first parameter: ${tlcNCerror}` }); } @@ -394,7 +353,7 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID else addNoticePartial({ priority: 820, message: "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:${V}${ourRowLocation}` }); - if (V.length) { + if (V?.length) { // can be undefined if no colon at split above if (V !== givenV) addNoticePartial({ priority: 975, message: "Wrong verse number", details: `expected '${givenV}'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation }); if (bookID === 'OBS' || V === 'intro') { } @@ -493,8 +452,7 @@ export async function checkNotesTSV7DataRow(languageCode, repoCode, line, bookID // if (V !== 'intro') // addNoticePartial({priority:500, message:"Invalid zero occurrence field", rowID, location:rowLocation); } - else if (occurrence === '-1') // TODO check the special conditions when this can occur??? - ; + else if (occurrence === '-1') { } // TODO check the special conditions when this can occur??? else if ('12345678'.indexOf(occurrence) < 0) { // it’s not one of these integers addNoticePartial({ priority: 792, message: `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation }); OSuggestion = '1'; diff --git a/src/core/notes-tsv7-row-check.md b/src/core/notes-tsv7-row-check.md index 72493a63a..7442e899b 100644 --- a/src/core/notes-tsv7-row-check.md +++ b/src/core/notes-tsv7-row-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkNotesTSV7DataRow } from './notes-tsv7-row-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, Header, Nonsense, Good, Bad, Very bad, and Actual line samples const lineE = ""; diff --git a/src/core/notes-tsv7-table-check.js b/src/core/notes-tsv7-table-check.js index 3cac42cd1..306303ab9 100644 --- a/src/core/notes-tsv7-table-check.js +++ b/src/core/notes-tsv7-table-check.js @@ -2,6 +2,7 @@ import * as books from './books/books'; import { DEFAULT_EXCERPT_LENGTH } from './defaults' import { checkNotesTSV7DataRow } from './notes-tsv7-row-check'; import { removeDisabledNotices } from './disabled-notices'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -31,16 +32,16 @@ export async function checkNotesTSV7Table(languageCode, repoCode, bookID, filena Returns a result object containing a successList and a noticeList */ // functionLog(`checkNotesTSV7Table(${languageCode}, ${repoCode}, ${bookID}, ${tableText.length}, ${givenLocation},${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkNotesTSV7Table: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkNotesTSV7Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode.endsWith('TN') || repoCode.endsWith('TN2') || repoCode.endsWith('SN'), `checkNotesTSV7Table: repoCode expected to end with 'TN', 'TN2', or 'SN' not '${repoCode}'`); - parameterAssert(bookID !== undefined, "checkNotesTSV7Table: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkNotesTSV7Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkNotesTSV7Table: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkNotesTSV7Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkNotesTSV7Table: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(givenLocation !== undefined, "checkNotesTSV7Table: 'givenLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkNotesTSV7Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(languageCode !== undefined, "checkNotesTSV7Table: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkNotesTSV7Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode.endsWith('TN') || repoCode.endsWith('TN2') || repoCode.endsWith('SN'), `checkNotesTSV7Table: repoCode expected to end with 'TN', 'TN2', or 'SN' not '${repoCode}'`); + //parameterAssert(bookID !== undefined, "checkNotesTSV7Table: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkNotesTSV7Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkNotesTSV7Table: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkNotesTSV7Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkNotesTSV7Table: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(givenLocation !== undefined, "checkNotesTSV7Table: 'givenLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkNotesTSV7Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -53,20 +54,24 @@ export async function checkNotesTSV7Table(languageCode, repoCode, bookID, filena } function addNoticePartial(noticeObject) { // functionLog(`checkNotesTSV7Table notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "ATSV addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "ATSV addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(C !== undefined, "ATSV addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); - // parameterAssert(V !== undefined, "ATSV addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); - // parameterAssert(characterIndex !== undefined, "ATSV addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "ATSV addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "ATSV addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "ATSV addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "ATSV addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(C !== undefined, "ATSV addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); + } + // //parameterAssert(V !== undefined, "ATSV addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); + } + // //parameterAssert(characterIndex !== undefined, "ATSV addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "ATSV addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "ATSV addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkNotesTSV7Table ${noticeObject.debugChain}`; carResult.noticeList.push({ ...noticeObject, bookID, filename, repoCode }); @@ -92,9 +97,9 @@ export async function checkNotesTSV7Table(languageCode, repoCode, bookID, filena if (bookID === 'OBS') numChaptersThisBook = 50; // There's 50 Open Bible Stories else { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkNotesTSV7Table"); + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkNotesTSV7Table"); try { - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch { if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. diff --git a/src/core/notes-tsv7-table-check.md b/src/core/notes-tsv7-table-check.md index 55f431ad2..a39b2decd 100644 --- a/src/core/notes-tsv7-table-check.md +++ b/src/core/notes-tsv7-table-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkNotesTSV7Table } from './notes-tsv7-table-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Text samples const textA = `Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tNote diff --git a/src/core/orig-quote-check.js b/src/core/orig-quote-check.js index bda74557b..799b47d39 100644 --- a/src/core/orig-quote-check.js +++ b/src/core/orig-quote-check.js @@ -1,11 +1,12 @@ import * as books from '../core/books/books'; +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { cachedGetFile } from '../core/getApi'; // eslint-disable-next-line no-unused-vars import { functionLog, debugLog, parameterAssert, logicAssert, dataAssert, ourParseInt } from './utilities'; -// const QUOTE_VALIDATOR_VERSION_STRING = '0.9.2'; +// const QUOTE_VALIDATOR_VERSION_STRING = '0.9.6'; /** @@ -36,29 +37,29 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo // checkingOptions?.originalLanguageRepoBranch (or tag) // functionLog(`checkOriginalLanguageQuoteAndOccurrence v${QUOTE_VALIDATOR_VERSION_STRING} ${languageCode}, ${repoCode}, ${fieldName}, (${fieldText.length}) '${fieldText}', ${occurrenceString}, ${bookID} ${C}:${V} ${givenLocation}, …)…`); - parameterAssert(languageCode !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkOriginalLanguageQuoteAndOccurrence: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(fieldName !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(fieldText.length >= 1, `checkOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should have text not ${fieldText.length} characters`); - parameterAssert(occurrenceString !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'occurrenceString' parameter should be defined"); - parameterAssert(typeof occurrenceString === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'occurrenceString' parameter should be a string not a '${typeof occurrenceString}'`); - parameterAssert(bookID !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkOriginalLanguageQuoteAndOccurrence: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(C !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'C' parameter should be defined"); - parameterAssert(typeof C === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'C' parameter should be a string not a '${typeof C}'`); - parameterAssert(V !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'V' parameter should be defined"); - parameterAssert(typeof V === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'V' parameter should be a string not a '${typeof V}'`); - parameterAssert(givenLocation !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'givenLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(languageCode !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkOriginalLanguageQuoteAndOccurrence: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(fieldName !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(fieldText.length >= 1, `checkOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should have text not ${fieldText.length} characters`); + //parameterAssert(occurrenceString !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'occurrenceString' parameter should be defined"); + //parameterAssert(typeof occurrenceString === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'occurrenceString' parameter should be a string not a '${typeof occurrenceString}'`); + //parameterAssert(bookID !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkOriginalLanguageQuoteAndOccurrence: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkOriginalLanguageQuoteAndOccurrence: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(C !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'C' parameter should be defined"); + //parameterAssert(typeof C === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'C' parameter should be a string not a '${typeof C}'`); + //parameterAssert(V !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'V' parameter should be defined"); + //parameterAssert(typeof V === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'V' parameter should be a string not a '${typeof V}'`); + //parameterAssert(givenLocation !== undefined, "checkOriginalLanguageQuoteAndOccurrence: 'givenLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkOriginalLanguageQuoteAndOccurrence: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); const discontiguousDivider = (repoCode === 'TN') ? '…' : ' & '; // debugLog(`Got discontiguousDivider='${discontiguousDivider}' for ${repoCode}`); @@ -70,16 +71,18 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo function addNotice(noticeObject) { // functionLog(`checkOriginalLanguageQuoteAndOccurrence Notice: (priority=${noticeObject.priority}) ${noticeObject.message}${characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? ` ${noticeObject.excerpt}` : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cOLQ addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cOLQ addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cOLQ addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cOLQ addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cOLQ addNotice: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cOLQ addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cOLQ addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cOLQ addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt} for ${noticeObject.priority}`); - parameterAssert(noticeObject.location !== undefined, "cOLQ addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cOLQ addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cOLQ addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cOLQ addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cOLQ addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cOLQ addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "cOLQ addNotice: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cOLQ addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cOLQ addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cOLQ addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt} for ${noticeObject.priority}`); + } + //parameterAssert(noticeObject.location !== undefined, "cOLQ addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cOLQ addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); colqResult.noticeList.push(noticeObject); } @@ -137,7 +140,14 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo // debugLog(`Got OBS ${V}:${C} '${verseText}'`); } else { // not OBS, so a USFM Bible book const bookNumberAndName = books.usfmNumberName(bookID); - const whichTestament = books.testament(bookID); // returns 'old' or 'new' + let whichTestament; + try { + whichTestament = books.testament(bookID); // returns 'old' or 'new' + } catch (bNNerror) { + if (books.isValidBookID(bookID)) // must be in FRT, BAK, etc. + whichTestament = 'other'; + } + logicAssert(whichTestament === 'old' || whichTestament === 'new', `getOriginalPassage() couldn't find testament for '${bookID}'`); const originalLanguageRepoLanguageCode = whichTestament === 'old' ? 'hbo' : 'el-x-koine'; const originalLanguageRepoCode = whichTestament === 'old' ? 'UHB' : 'UGNT'; const originalLanguageRepoName = `${originalLanguageRepoLanguageCode}_${originalLanguageRepoCode.toLowerCase()}`; @@ -216,11 +226,11 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo // Final clean-up (shouldn’t be necessary, but just in case) verseText = verseText.replace(/ {2}/g, ' '); - parameterAssert(verseText.indexOf('\\w') === -1, `getOriginalPassage: Should be no \\w in ${bookID} ${C}:${V} '${verseText}'`); - parameterAssert(verseText.indexOf('\\k') === -1, `getOriginalPassage: Should be no \\k in ${bookID} ${C}:${V} '${verseText}'`); - parameterAssert(verseText.indexOf('x-') === -1, `getOriginalPassage: Should be no x- in ${bookID} ${C}:${V} '${verseText}'`); - parameterAssert(verseText.indexOf('\\f') === -1, `getOriginalPassage: Should be no \\f in ${bookID} ${C}:${V} '${verseText}'`); - parameterAssert(verseText.indexOf('\\x') === -1, `getOriginalPassage: Should be no \\x in ${bookID} ${C}:${V} '${verseText}'`); + //parameterAssert(verseText.indexOf('\\w') === -1, `getOriginalPassage: Should be no \\w in ${bookID} ${C}:${V} '${verseText}'`); + //parameterAssert(verseText.indexOf('\\k') === -1, `getOriginalPassage: Should be no \\k in ${bookID} ${C}:${V} '${verseText}'`); + //parameterAssert(verseText.indexOf('x-') === -1, `getOriginalPassage: Should be no x- in ${bookID} ${C}:${V} '${verseText}'`); + //parameterAssert(verseText.indexOf('\\f') === -1, `getOriginalPassage: Should be no \\f in ${bookID} ${C}:${V} '${verseText}'`); + //parameterAssert(verseText.indexOf('\\x') === -1, `getOriginalPassage: Should be no \\x in ${bookID} ${C}:${V} '${verseText}'`); } // debugLog(` getOriginalPassage(${bookID} ${C}:${V}) is returning '${verseText}'`); @@ -241,26 +251,26 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo */ function checkFoundQuoteSegment(foundQuoteSegment, partDescription, occurrenceString, partialVerseText, fullVerseText, location) { // if (partDescription) functionLog(`checkFoundQuoteSegment(${foundQuoteSegment}, ${partDescription}, ${verseText}, ${location}) ${C}:${V}…`); - parameterAssert(foundQuoteSegment !== undefined, "checkFoundQuoteSegment: 'foundQuoteSegment' parameter should be defined"); - parameterAssert(typeof foundQuoteSegment === 'string', `checkFoundQuoteSegment: 'foundQuoteSegment' parameter should be a string not a '${typeof foundQuoteSegment}'`); - parameterAssert(partDescription !== undefined, "checkFoundQuoteSegment: 'partDescription' parameter should be defined"); - parameterAssert(typeof partDescription === 'string', `checkFoundQuoteSegment: 'partDescription' parameter should be a string not a '${typeof partDescription}'`); - parameterAssert(occurrenceString !== undefined, "checkFoundQuoteSegment: 'occurrenceString' parameter should be defined"); - parameterAssert(typeof occurrenceString === 'string', `checkFoundQuoteSegment: 'occurrenceString' parameter should be a string not a '${typeof occurrenceString}'`); - parameterAssert(partialVerseText !== undefined, "checkFoundQuoteSegment: 'partialVerseText' parameter should be defined"); - parameterAssert(typeof partialVerseText === 'string', `checkFoundQuoteSegment: 'partialVerseText' parameter should be a string not a '${typeof partialVerseText}'`); - parameterAssert(fullVerseText !== undefined, "checkFoundQuoteSegment: 'fullVerseText' parameter should be defined"); - parameterAssert(typeof fullVerseText === 'string', `checkFoundQuoteSegment: 'fullVerseText' parameter should be a string not a '${typeof fullVerseText}'`); - parameterAssert(fullVerseText.length >= partialVerseText.length, `checkFoundQuoteSegment: 'partialVerseText' should not be longer`); - parameterAssert(location !== undefined, "checkFoundQuoteSegment: 'location' parameter should be defined"); - parameterAssert(typeof location === 'string', `checkFoundQuoteSegment: 'location' parameter should be a string not a '${typeof location}'`); - - let details = `passage ►${fullVerseText}◄`; + //parameterAssert(foundQuoteSegment !== undefined, "checkFoundQuoteSegment: 'foundQuoteSegment' parameter should be defined"); + //parameterAssert(typeof foundQuoteSegment === 'string', `checkFoundQuoteSegment: 'foundQuoteSegment' parameter should be a string not a '${typeof foundQuoteSegment}'`); + //parameterAssert(partDescription !== undefined, "checkFoundQuoteSegment: 'partDescription' parameter should be defined"); + //parameterAssert(typeof partDescription === 'string', `checkFoundQuoteSegment: 'partDescription' parameter should be a string not a '${typeof partDescription}'`); + //parameterAssert(occurrenceString !== undefined, "checkFoundQuoteSegment: 'occurrenceString' parameter should be defined"); + //parameterAssert(typeof occurrenceString === 'string', `checkFoundQuoteSegment: 'occurrenceString' parameter should be a string not a '${typeof occurrenceString}'`); + //parameterAssert(partialVerseText !== undefined, "checkFoundQuoteSegment: 'partialVerseText' parameter should be defined"); + //parameterAssert(typeof partialVerseText === 'string', `checkFoundQuoteSegment: 'partialVerseText' parameter should be a string not a '${typeof partialVerseText}'`); + //parameterAssert(fullVerseText !== undefined, "checkFoundQuoteSegment: 'fullVerseText' parameter should be defined"); + //parameterAssert(typeof fullVerseText === 'string', `checkFoundQuoteSegment: 'fullVerseText' parameter should be a string not a '${typeof fullVerseText}'`); + //parameterAssert(fullVerseText.length >= partialVerseText.length, `checkFoundQuoteSegment: 'partialVerseText' should not be longer`); + //parameterAssert(location !== undefined, "checkFoundQuoteSegment: 'location' parameter should be defined"); + //parameterAssert(typeof location === 'string', `checkFoundQuoteSegment: 'location' parameter should be a string not a '${typeof location}'`); + + let details = `verse text ►${fullVerseText}◄`; if (partDescription.length) details = `${partDescription} part of quote = "${foundQuoteSegment}" -- ${details}`; let remainingVerseBits = partialVerseText.split(foundQuoteSegment); // NOTE: can split (badly) on short strings (like δὲ or εἰ) mid-word if (remainingVerseBits.length > 2) // Join the extra bits back up - remainingVerseBits = [remainingVerseBits[0], remainingVerseBits.slice(1).join(discontiguousDivider)]; + remainingVerseBits = [remainingVerseBits[0], remainingVerseBits.slice(1).join(discontiguousDivider)]; logicAssert(remainingVerseBits.length === 2, `remaining bits are ${remainingVerseBits.length}`); // Note: There's some Hebrew (RTL) characters at the beginning of the following regex @@ -271,33 +281,37 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo // const precedingRegex = new RegExp('[ ־*[("\'“‘]', 'g'); // NOTE: This algorithm has to handle a single word inside another prior word, e.g., searching for δὲ in οὐδὲν δὲ συνκεκαλυμμένον ἐστὶν if (foundQuoteSegment.slice(0) !== ' ' && remainingVerseBits[0] - && precedingChar && ' ־*[("\'“‘—'.indexOf(precedingChar) === -1 // handle punctuation expected before words - && (foundQuoteSegment.indexOf(' ') !== -1 || partialVerseText.indexOf(` ${foundQuoteSegment}`) === -1) // it's multiword, or there's not another word that fits + && precedingChar && ' ־*[("\'“‘—'.indexOf(precedingChar) === -1 // handle punctuation expected before words + && (foundQuoteSegment.indexOf(' ') !== -1 || partialVerseText.indexOf(` ${foundQuoteSegment}`) === -1) // it's multiword, or there's not another word that fits ) { let precederDescription; if (precedingChar === '\u2060') precederDescription = 'WordJoiner'; else if (precedingChar === '\u200D') precederDescription = 'ZeroWidth-WordJoiner'; else precederDescription = `${precedingChar}=D${precedingChar.charCodeAt(0)}/H${precedingChar.charCodeAt(0).toString(16)}`; // debugLog(`Seems ${bookID} ${C}:${V} '${foundQuoteSegment}' might not start at the beginning of a word—it’s preceded by '${precederDescription}' in '${partialVerseText}' of '${fullVerseText}'`); - const excerpt = `(${precederDescription})${foundQuoteSegment.substring(0, excerptLength - 3)}${(foundQuoteSegment.length > excerptLength - 3 ? '…' : '')}${occurrenceString.length? ` occurrence=${occurrenceString}`:''}`; + const excerpt = `(${precederDescription})${foundQuoteSegment.substring(0, excerptLength - 3)}${(foundQuoteSegment.length > excerptLength - 3 ? '…' : '')}${occurrenceString.length ? ` occurrence=${occurrenceString}` : ''}`; // We greatly lower the priority if we're less sure that it's a genuine error - addNotice({ priority: foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(` ${foundQuoteSegment}`) === -1?909: 389, message: "Seems original language quote might not start at the beginning of a word", details, characterIndex: 0, excerpt, location }); + addNotice({ priority: foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(` ${foundQuoteSegment}`) === -1 ? 909 : 389, message: "Seems original language quote might not start at the beginning of a word", details, characterIndex: 0, excerpt, location }); } const followingChar = remainingVerseBits[1][0]; // debugLog(`Next char after ${C}:${V} '${foundQuoteSegment}' is '${followingChar}'`); // Note: There's some Hebrew (RTL) characters at the beginning of the following string used in regex - const allowedWordEndChars = ' ׃־.,:;?!–—)'; - const followingRegex = new RegExp(`${foundQuoteSegment}[${allowedWordEndChars}]`, 'g'); + const allowedWordEndChars = ' ׃־.,:;?!–—)…'; // Ellipsis occurs in UGNT, e.g., Rom 3:15, Rev 2:26, 18:7 + // We make up the RegEx on the fly but we need to escape special chars in foundQuoteSegment + // debugLog(`checkFoundQuoteSegment ${bookID} ${C}:${V} regex will be '${foundQuoteSegment}[${allowedWordEndChars}]'`); + const escapedFoundQuoteSegment = foundQuoteSegment.replace(/\(/g, '\\(').replace(/\)/g, '\\)'); // Segments may have any one or more of these (not necessarily matched) + // if (escapedFoundQuoteSegment !== foundQuoteSegment ) debugLog(`checkFoundQuoteSegment ${bookID} ${C}:${V} from '${foundQuoteSegment}' regex will be '${escapedFoundQuoteSegment}[${allowedWordEndChars}]'`); + const followingRegex = new RegExp(`${escapedFoundQuoteSegment}[${allowedWordEndChars}]`, 'g'); if (foundQuoteSegment.slice(-1) !== ' ' && remainingVerseBits[1] - && followingChar && allowedWordEndChars.indexOf(followingChar) === -1 // handle punctuation expected after words - && (foundQuoteSegment.indexOf(' ') !== -1 || partialVerseText.search(followingRegex) === -1) // it's multiword, or there's not another word that fits - ) { + && followingChar && allowedWordEndChars.indexOf(followingChar) === -1 // handle punctuation expected after words + && (foundQuoteSegment.indexOf(' ') !== -1 || partialVerseText.search(followingRegex) === -1) // it's multiword, or there's not another word that fits + ) { // No problems if quote is followed by expected terminator-type punctuation // const badCharString = `'${followingChar}'=D${followingChar.charCodeAt(0)}/H${followingChar.charCodeAt(0).toString(16)}`; // debugLog(`Seems ${bookID} ${C}:${V} '${foundQuoteSegment}' might not finish at the end of a word—it’s followed by ${badCharString} in '${partialVerseText}' of '${fullVerseText}'`); - const excerpt = `${(foundQuoteSegment.length > excerptLength - 3 ? '…' : '')}${foundQuoteSegment.substring(foundQuoteSegment.length - excerptLength + 3, foundQuoteSegment.length)}(${followingChar}=D${remainingVerseBits[1].charCodeAt(0)}/H${remainingVerseBits[1].charCodeAt(0).toString(16)})${occurrenceString.length? ` occurrence=${occurrenceString}`:''}`; + const excerpt = `${(foundQuoteSegment.length > excerptLength - 3 ? '…' : '')}${foundQuoteSegment.substring(foundQuoteSegment.length - excerptLength + 3, foundQuoteSegment.length)}(${followingChar}=D${remainingVerseBits[1].charCodeAt(0)}/H${remainingVerseBits[1].charCodeAt(0).toString(16)})${occurrenceString.length ? ` occurrence=${occurrenceString}` : ''}`; // We greatly lower the priority if we're less sure that it's a genuine error - addNotice({ priority: foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(followingRegex) === -1? 908: 388, message: "Seems original language quote might not finish at the end of a word", details, characterIndex: foundQuoteSegment.length, excerpt, location }); + addNotice({ priority: foundQuoteSegment.indexOf(' ') !== -1 || fullVerseText.search(followingRegex) === -1 ? 908 : 388, message: "Seems original language quote might not finish at the end of a word", details, characterIndex: foundQuoteSegment.length, excerpt, location }); } } // end of checkFoundQuoteSegment function @@ -313,14 +327,14 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo */ function checkNotFoundQuoteSegment(notFoundQuoteSegment, partDescription, occurrenceString, fullVerseText, location) { if (partDescription) functionLog(`checkNotFoundQuoteSegment(${notFoundQuoteSegment}, ${partDescription}, ${fullVerseText}, ${location}) ${C}:${V}…`); - parameterAssert(notFoundQuoteSegment !== undefined, "checkNotFoundQuoteSegment: 'notFoundQuoteSegment' parameter should be defined"); - parameterAssert(typeof notFoundQuoteSegment === 'string', `checkNotFoundQuoteSegment: 'notFoundQuoteSegment' parameter should be a string not a '${typeof notFoundQuoteSegment}'`); - parameterAssert(partDescription !== undefined, "checkNotFoundQuoteSegment: 'partDescription' parameter should be defined"); - parameterAssert(typeof partDescription === 'string', `checkNotFoundQuoteSegment: 'partDescription' parameter should be a string not a '${typeof partDescription}'`); - parameterAssert(fullVerseText !== undefined, "checkNotFoundQuoteSegment: 'fullVerseText' parameter should be defined"); - parameterAssert(typeof fullVerseText === 'string', `checkNotFoundQuoteSegment: 'fullVerseText' parameter should be a string not a '${typeof fullVerseText}'`); - parameterAssert(location !== undefined, "checkNotFoundQuoteSegment: 'location' parameter should be defined"); - parameterAssert(typeof location === 'string', `checkNotFoundQuoteSegment: 'location' parameter should be a string not a '${typeof location}'`); + //parameterAssert(notFoundQuoteSegment !== undefined, "checkNotFoundQuoteSegment: 'notFoundQuoteSegment' parameter should be defined"); + //parameterAssert(typeof notFoundQuoteSegment === 'string', `checkNotFoundQuoteSegment: 'notFoundQuoteSegment' parameter should be a string not a '${typeof notFoundQuoteSegment}'`); + //parameterAssert(partDescription !== undefined, "checkNotFoundQuoteSegment: 'partDescription' parameter should be defined"); + //parameterAssert(typeof partDescription === 'string', `checkNotFoundQuoteSegment: 'partDescription' parameter should be a string not a '${typeof partDescription}'`); + //parameterAssert(fullVerseText !== undefined, "checkNotFoundQuoteSegment: 'fullVerseText' parameter should be defined"); + //parameterAssert(typeof fullVerseText === 'string', `checkNotFoundQuoteSegment: 'fullVerseText' parameter should be a string not a '${typeof fullVerseText}'`); + //parameterAssert(location !== undefined, "checkNotFoundQuoteSegment: 'location' parameter should be defined"); + //parameterAssert(typeof location === 'string', `checkNotFoundQuoteSegment: 'location' parameter should be a string not a '${typeof location}'`); let excerpt = partDescription ? `${partDescription ? '(' + partDescription + ' quote portion)' : ''} '${notFoundQuoteSegment}'` : ''; @@ -354,7 +368,7 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo addNotice({ priority: 916, message: "Unable to find original language quote in verse text", details: "quote which ends with 'zero-width joiner'" + (noBreakSpaceText ? ' ' + noBreakSpaceText : ''), excerpt, location: ourLocation }); } else { if (!excerpt) excerpt = notFoundQuoteSegment.length <= excerptLength ? notFoundQuoteSegment : (notFoundQuoteSegment.substring(0, excerptHalfLength) + (notFoundQuoteSegment.length > 2 * excerptHalfLength ? '…' : '') + notFoundQuoteSegment.substring(notFoundQuoteSegment.length - excerptHalfLength, notFoundQuoteSegment.length)); - addNotice({ priority: 916, message: "Unable to find original language quote in verse text", details: noBreakSpaceText ? noBreakSpaceText : `passage ►${fullVerseText}◄`, excerpt, location: ourLocation }); + addNotice({ priority: 916, message: "Unable to find original language quote in verse text", details: noBreakSpaceText ? noBreakSpaceText : `verse text ►${fullVerseText}◄`, excerpt, location: ourLocation }); } } // end of checkNotFoundQuoteSegment function @@ -380,9 +394,9 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo catch { dataAssert(false, `NOTE: We got occurrence=${occurrence} from ${C}:${V} '${occurrenceString}'`); } // errors in this field are noted elsewhere // if fieldText.lstrip() !== fieldText: - // addNotice({priority:0, message:`Unexpected whitespace at start of {TNid} '{fieldText}'") + // addNotice({priority:0, message:`Unexpected whitespace at start of ${TNid} '${fieldText}'") // if fieldText.rstrip() !== fieldText: - // addNotice({priority:0, message:`Unexpected whitespace at end of {TNid} '{fieldText}'") + // addNotice({priority:0, message:`Unexpected whitespace at end of ${TNid} '${fieldText}'") // fieldText = fieldText.strip() # so we don’t get consequential errors let characterIndex; @@ -436,7 +450,7 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo // Now check if the quote can be found in the verse text if (quoteBits) { // it had an ellipsis - // parameterAssert(occurrence === 1, `Oh -- can get '${fieldText}' with occurrence=${occurrence} in ${bookID} ${C}:${V}`); + // //parameterAssert(occurrence === 1, `Oh -- can get '${fieldText}' with occurrence=${occurrence} in ${bookID} ${C}:${V}`); if (occurrence !== 1) { addNotice({ priority: 50, message: "Is this quote/occurrence correct???", details: `Occurrence=${occurrence}`, excerpt: fieldText, location: ourLocation }); } @@ -457,16 +471,16 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo if (verseText.indexOf(quoteBits[bitIndex]) >= 0) { logicAssert(bitIndex > 0, "This shouldn't happen for bitIndex of zero!"); // debugLog(`914, Unable to find '${fieldText}' ${numQuoteBits === 1 ? '' : `'${quoteBits[bitIndex]}' `}${partDescription ? '(' + partDescription + ') ' : ''}in '${verseText}'`); - addNotice({ priority: 914, message: "Unable to find original language quote portion in the right place in the verse text", details: `passage ►${verseText}◄`, excerpt, location: ourLocation }); + addNotice({ priority: 914, message: "Unable to find original language quote portion in the right place in the verse text", details: `verse text ►${verseText}◄`, excerpt, location: ourLocation }); } else { // debugLog(`915, Unable to find '${fieldText}' ${numQuoteBits === 1 ? '' : `'${quoteBits[bitIndex]}' `}${partDescription ? '(' + partDescription + ') ' : ''}in '${verseText}'`); checkNotFoundQuoteSegment(fieldText, partDescription, occurrenceString, verseText, ourLocation); - // addNotice({ priority: 915, message: "Unable to find original language quote portion in verse text", details: `passage ►${verseText}◄`, excerpt, location: ourLocation }); + // addNotice({ priority: 915, message: "Unable to find original language quote portion in verse text", details: `verse text ►${verseText}◄`, excerpt, location: ourLocation }); } } else { // We found this bit // debugLog(`Found ${C}:${V} origQuote portion ${bitIndex} '${quoteBits[bitIndex]}' at ${quoteIndex} (num text chars = ${verseText.length})`); const verseTextBits = verseText.split(quoteBits[bitIndex]); // NOTE: can split (badly) on short strings (like δὲ or εἰ) mid-word - checkFoundQuoteSegment(quoteBits[bitIndex], partDescription, occurrenceString, `${verseTextBits[occurrence-1]}${quoteBits[bitIndex]}${verseTextBits[occurrence]}`, verseText, ourLocation); + checkFoundQuoteSegment(quoteBits[bitIndex], partDescription, occurrenceString, `${verseTextBits[occurrence - 1]}${quoteBits[bitIndex]}${verseTextBits[occurrence]}`, verseText, ourLocation); } } } else // < 2 @@ -482,7 +496,7 @@ export async function checkOriginalLanguageQuoteAndOccurrence(languageCode, repo const excerpt = fieldText.substring(0, excerptHalfLength) + (fieldText.length > 2 * excerptHalfLength ? '…' : '') + fieldText.substring(fieldText.length - excerptHalfLength, fieldText.length); addNotice({ priority: 917, message: "Unable to find duplicate original language quote in verse text", details: `occurrence=${occurrenceString} but ${actualOccurrencesText} occurrence${actualNumOccurrences === 1 ? '' : 's'} found, passage ►${verseText}◄`, excerpt, location: ourLocation }); } else { - checkFoundQuoteSegment(fieldText, '', occurrenceString, `${verseTextBits[occurrence-1]}${fieldText}${verseTextBits[occurrence]}`, verseText, ourLocation); + checkFoundQuoteSegment(fieldText, '', occurrenceString, `${verseTextBits[occurrence - 1]}${fieldText}${verseTextBits[occurrence]}`, verseText, ourLocation); } } else { // We only need to check for one occurrence // TODO: The error in the next line has been notified elsewhere, but should we try to handle it more intelligently here ??? diff --git a/src/core/plain-text-check.js b/src/core/plain-text-check.js index d0b57eb77..38788b1e6 100644 --- a/src/core/plain-text-check.js +++ b/src/core/plain-text-check.js @@ -1,7 +1,9 @@ +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { OPEN_CLOSE_PUNCTUATION_PAIRS, PAIRED_PUNCTUATION_OPENERS, PAIRED_PUNCTUATION_CLOSERS, isWhitespace, countOccurrences } from './text-handling-functions' import { checkTextField } from './field-text-check'; import { removeDisabledNotices } from './disabled-notices'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -26,20 +28,20 @@ export function checkPlainText(languageCode, repoCode, textType, textName, plain Returns a result object containing a successList and a noticeList */ // functionLog(`checkPlainText(${textName}, (${plainText.length} chars), ${givenLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkPlainText: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkPlainText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(languageCode !== 'markdown' && languageCode !== 'USFM' && languageCode !== 'YAML' && languageCode !== 'text' && languageCode !== 'raw' && languageCode !== 'unfoldingWord', `checkPlainText: 'languageCode' ${languageCode} parameter should be not be '${languageCode}'`); - parameterAssert(repoCode !== undefined, "checkPlainText: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkPlainText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkPlainText: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(textType !== undefined, "checkPlainText: 'textType' parameter should be defined"); - parameterAssert(typeof textType === 'string', `checkPlainText: 'textType' parameter should be a string not a '${typeof textType}': ${textType}`); - parameterAssert(textType === 'markdown' || textType === 'USFM' || textType === 'YAML' || textType === 'text' || textType === 'raw', `checkPlainText: unrecognised 'textType' parameter: '${textType}'`); - parameterAssert(textName !== undefined, "checkPlainText: 'textName' parameter should be defined"); - parameterAssert(typeof textName === 'string', `checkPlainText: 'textName' parameter should be a string not a '${typeof textName}': ${textName}`); - parameterAssert(plainText !== undefined, "checkPlainText: 'plainText' parameter should be defined"); - parameterAssert(typeof plainText === 'string', `checkPlainText: 'plainText' parameter should be a string not a '${typeof plainText}': ${plainText}`); - parameterAssert(checkingOptions !== undefined, "checkPlainText: 'checkingOptions' parameter should be defined"); + //parameterAssert(languageCode !== undefined, "checkPlainText: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkPlainText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(languageCode !== 'markdown' && languageCode !== 'USFM' && languageCode !== 'YAML' && languageCode !== 'text' && languageCode !== 'raw' && languageCode !== 'unfoldingWord', `checkPlainText: 'languageCode' ${languageCode} parameter should be not be '${languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkPlainText: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkPlainText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkPlainText: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(textType !== undefined, "checkPlainText: 'textType' parameter should be defined"); + //parameterAssert(typeof textType === 'string', `checkPlainText: 'textType' parameter should be a string not a '${typeof textType}': ${textType}`); + //parameterAssert(textType === 'markdown' || textType === 'USFM' || textType === 'YAML' || textType === 'text' || textType === 'raw', `checkPlainText: unrecognised 'textType' parameter: '${textType}'`); + //parameterAssert(textName !== undefined, "checkPlainText: 'textName' parameter should be defined"); + //parameterAssert(typeof textName === 'string', `checkPlainText: 'textName' parameter should be a string not a '${typeof textName}': ${textName}`); + //parameterAssert(plainText !== undefined, "checkPlainText: 'plainText' parameter should be defined"); + //parameterAssert(typeof plainText === 'string', `checkPlainText: 'plainText' parameter should be a string not a '${typeof plainText}': ${plainText}`); + //parameterAssert(checkingOptions !== undefined, "checkPlainText: 'checkingOptions' parameter should be defined"); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -67,15 +69,17 @@ export function checkPlainText(languageCode, repoCode, textType, textName, plain function addNotice(noticeObject) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // functionLog(`checkPlainText notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cPT addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cPT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cPT addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cPT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cPT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt!==undefined, "cPT addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cPT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cPT addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cPT addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cPT addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cPT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cPT addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cPT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cPT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt!==undefined, "cPT addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cPT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cPT addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cPT addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // noticeObject.debugChain = noticeObject.debugChain ? `checkPlainText(${textType}, ${textName}) ${noticeObject.debugChain}` : `checkPlainText(${textType}, ${textName})`; cptResult.noticeList.push(noticeObject); @@ -96,13 +100,13 @@ export function checkPlainText(languageCode, repoCode, textType, textName, plain // Updates the global list of notices // debugLog(`cPT ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${fieldLocation}, …)`); - parameterAssert(lineNumber !== undefined, "cPT ourCheckTextField: 'lineNumber' parameter should be defined"); - parameterAssert(typeof lineNumber === 'number', `cPT ourCheckTextField: 'fieldName' parameter should be a number not a '${typeof lineNumber}'`); - parameterAssert(fieldText !== undefined, "cPT ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `cPT ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "cPT ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(optionalFieldLocation !== undefined, "cPT ourCheckTextField: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof optionalFieldLocation === 'string', `cPT ourCheckTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); + //parameterAssert(lineNumber !== undefined, "cPT ourCheckTextField: 'lineNumber' parameter should be defined"); + //parameterAssert(typeof lineNumber === 'number', `cPT ourCheckTextField: 'fieldName' parameter should be a number not a '${typeof lineNumber}'`); + //parameterAssert(fieldText !== undefined, "cPT ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `cPT ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "cPT ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(optionalFieldLocation !== undefined, "cPT ourCheckTextField: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof optionalFieldLocation === 'string', `cPT ourCheckTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); const resultObject = checkTextField(languageCode, repoCode, textType, '', fieldText, allowedLinks, optionalFieldLocation, checkingOptions); diff --git a/src/core/plain-text-check.md b/src/core/plain-text-check.md index 27d843b1c..cc657275f 100644 --- a/src/core/plain-text-check.md +++ b/src/core/plain-text-check.md @@ -7,11 +7,13 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkPlainText } from './plain-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderNumberedLines, RenderRawResults } from '../demos/RenderProcessedResults'; // Plain text samples const textSG = `Short Good Plain Test @@ -48,7 +50,7 @@ if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done plain text checks"]; <> -Source (normalized): +Source (normalized): ``` diff --git a/src/core/questions-tsv7-row-check.js b/src/core/questions-tsv7-row-check.js index fff07d34f..a1f2ffb3e 100644 --- a/src/core/questions-tsv7-row-check.js +++ b/src/core/questions-tsv7-row-check.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { isWhitespace, countOccurrences } from './text-handling-functions' import * as books from './books/books'; @@ -8,7 +9,7 @@ import { checkOriginalLanguageQuoteAndOccurrence } from './orig-quote-check'; import { debugLog, parameterAssert } from './utilities'; -// const QUESTIONS_TABLE_ROW_VALIDATOR_VERSION_STRING = '0.2.5'; +// const QUESTIONS_TABLE_ROW_VALIDATOR_VERSION_STRING = '0.2.6'; const NUM_EXPECTED_QUESTIONS_TSV_FIELDS = 7; // so expects 6 tabs per line const EXPECTED_QUESTIONS_HEADING_LINE = 'Reference\tID\tTags\tQuote\tOccurrence\tQuestion\tResponse'; @@ -48,25 +49,29 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo Returns an object containing the noticeList. */ // functionLog(`checkQuestionsTSV7DataRow(${languageCode}, ${repoCode}, ${line}, ${bookID}, ${givenRowLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkQuestionsTSV7DataRow: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkQuestionsTSV7DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode !== undefined, "checkQuestionsTSV7DataRow: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkQuestionsTSV7DataRow: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkQuestionsTSV7DataRow: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(line !== undefined, "checkQuestionsTSV7DataRow: 'line' parameter should be defined"); - parameterAssert(typeof line === 'string', `checkQuestionsTSV7DataRow: 'line' parameter should be a string not a '${typeof line}'`); - parameterAssert(bookID !== undefined, "checkQuestionsTSV7DataRow: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkQuestionsTSV7DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkQuestionsTSV7DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkQuestionsTSV7DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkQuestionsTSV7DataRow: '${bookID}' is not a valid USFM book identifier`); - // parameterAssert(givenC !== undefined, "checkQuestionsTSV7DataRow: 'givenC' parameter should be defined"); - if (givenC) parameterAssert(typeof givenC === 'string', `checkQuestionsTSV7DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); - // parameterAssert(givenV !== undefined, "checkQuestionsTSV7DataRow: 'givenV' parameter should be defined"); - if (givenV) parameterAssert(typeof givenV === 'string', `checkQuestionsTSV7DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); - parameterAssert(givenRowLocation !== undefined, "checkQuestionsTSV7DataRow: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenRowLocation === 'string', `checkQuestionsTSV7DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); - parameterAssert(givenRowLocation.indexOf('true') === -1, "checkQuestionsTSV7DataRow: 'givenRowLocation' parameter should not be 'true'"); + //parameterAssert(languageCode !== undefined, "checkQuestionsTSV7DataRow: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkQuestionsTSV7DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkQuestionsTSV7DataRow: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkQuestionsTSV7DataRow: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkQuestionsTSV7DataRow: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(line !== undefined, "checkQuestionsTSV7DataRow: 'line' parameter should be defined"); + //parameterAssert(typeof line === 'string', `checkQuestionsTSV7DataRow: 'line' parameter should be a string not a '${typeof line}'`); + //parameterAssert(bookID !== undefined, "checkQuestionsTSV7DataRow: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkQuestionsTSV7DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkQuestionsTSV7DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkQuestionsTSV7DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkQuestionsTSV7DataRow: '${bookID}' is not a valid USFM book identifier`); + // //parameterAssert(givenC !== undefined, "checkQuestionsTSV7DataRow: 'givenC' parameter should be defined"); + if (givenC) { + //parameterAssert(typeof givenC === 'string', `checkQuestionsTSV7DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); + } + // //parameterAssert(givenV !== undefined, "checkQuestionsTSV7DataRow: 'givenV' parameter should be defined"); + if (givenV) { + //parameterAssert(typeof givenV === 'string', `checkQuestionsTSV7DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); + } + //parameterAssert(givenRowLocation !== undefined, "checkQuestionsTSV7DataRow: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenRowLocation === 'string', `checkQuestionsTSV7DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); + //parameterAssert(givenRowLocation.indexOf('true') === -1, "checkQuestionsTSV7DataRow: 'givenRowLocation' parameter should not be 'true'"); let ourRowLocation = givenRowLocation; if (ourRowLocation && ourRowLocation[0] !== ' ') ourRowLocation = ` ${ourRowLocation}`; @@ -88,18 +93,20 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo * @param {string} location - description of where the issue is located */ // functionLog(`checkQuestionsTSV7DataRow addNoticePartial(priority=${noticeObject.priority}) ${noticeObject.message}, ${noticeObject.characterIndex}, ${noticeObject.excerpt}, ${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `checkQuestionsTSV7DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `checkQuestionsTSV7DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(lineNumber !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'lineNumber' parameter should be defined"); - // parameterAssert(typeof lineNumber === 'number', `checkQuestionsTSV7DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); - // parameterAssert(characterIndex !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `checkQuestionsTSV7DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `checkQuestionsTSV7DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `checkQuestionsTSV7DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `checkQuestionsTSV7DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `checkQuestionsTSV7DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(lineNumber !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'lineNumber' parameter should be defined"); + // //parameterAssert(typeof lineNumber === 'number', `checkQuestionsTSV7DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); + // //parameterAssert(characterIndex !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `checkQuestionsTSV7DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `checkQuestionsTSV7DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "checkQuestionsTSV7DataRow addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `checkQuestionsTSV7DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // Also uses the given bookID,C,V, parameters from the main function call // noticeObject.debugChain = noticeObject.debugChain ? `checkQuestionsTSV7DataRow ${noticeObject.debugChain}` : `checkQuestionsTSV7DataRow(${repoCode})`; @@ -125,17 +132,17 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // We don’t currently use the allowedLinks parameter // functionLog(`checkQuestionsTSV7DataRow ourMarkdownTextChecks(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be a string not a '${typeof rowID}'`); - // parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be defined"); - // parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldName === 'Question' || fieldName === 'Response', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: Only run this check on Questions and Responses not '${fieldName}'`); - parameterAssert(fieldText !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowID' parameter should be a string not a '${typeof rowID}'`); + // //parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be defined"); + // //parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldName === 'Question' || fieldName === 'Response', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: Only run this check on Questions and Responses not '${fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkQuestionsTSV7DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const omtcResultObject = await checkMarkdownText(languageCode, repoCode, fieldName, fieldText, rowLocation, checkingOptions); @@ -145,7 +152,7 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of omtcResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); // NOTE: Ellipses in Question and Answer have the normal meaning // not like the specialised meaning in the Quote snippet fields if (noticeEntry.priority !== 178 && noticeEntry.priority !== 179 // unexpected space after ellipse, ellipse after space @@ -174,16 +181,16 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // Updates the global list of notices // functionLog(`checkQuestionsTSV7DataRow ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkQuestionsTSV7DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkQuestionsTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkQuestionsTSV7DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkQuestionsTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkQuestionsTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkQuestionsTSV7DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const fieldType = fieldName === 'Question' ? 'markdown' : 'raw'; const octfResultObject = checkTextField(languageCode, repoCode, fieldType, fieldName, fieldText, allowedLinks, rowLocation, checkingOptions); @@ -194,7 +201,7 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of octfResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } return octfResultObject.suggestion; // There may or may not be one! @@ -210,15 +217,15 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // Updates the global list of notices // functionLog(`checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote(${fieldName}, (${fieldText.length}) '${fieldText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(occurrence !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'occurrence' parameter should be defined"); - parameterAssert(typeof occurrence === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(occurrence !== undefined, "checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'occurrence' parameter should be defined"); + //parameterAssert(typeof occurrence === 'string', `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkQuestionsTSV7DataRow ourCheckQOriginalLanguageQuote: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const coqResultObject = await checkOriginalLanguageQuoteAndOccurrence(languageCode, repoCode, fieldName, fieldText, occurrence, bookID, givenC, givenV, rowLocation, checkingOptions); @@ -228,61 +235,13 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckQOriginalLanguageQuote notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckQOriginalLanguageQuote notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } } // end of ourCheckQOriginalLanguageQuote function - // async function ourCheckNotesLinksToOutside(rowID, fieldName, taLinkText, rowLocation, checkingOptions) { - // // Checks that the TA/TW/Bible reference can be found - - // // Updates the global list of notices - - // // functionLog(`checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside(${rowID}, ${fieldName}, (${taLinkText.length}) '${taLinkText}', ${rowLocation}, …)`); - // parameterAssert(rowID !== undefined, "checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be defined"); - // parameterAssert(typeof rowID === 'string', `checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be a string not a '${typeof rowID}'`); - // parameterAssert(fieldName !== undefined, "checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be defined"); - // parameterAssert(typeof fieldName === 'string', `checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - // parameterAssert(fieldName === 'Question', `checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be 'Question' not '${fieldName}'`); - // parameterAssert(taLinkText !== undefined, "checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'taLinkText' parameter should be defined"); - // parameterAssert(typeof taLinkText === 'string', `checkQuestionsTSV7DataRow ourCheckNotesLinksToOutside: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); - - // const coqResultObject = await checkNotesLinksToOutside(languageCode, repoCode, bookID, givenC, givenV, fieldName, taLinkText, rowLocation, { ...checkingOptions, defaultLanguageCode: languageCode }); - // // debugLog("coqResultObject", JSON.stringify(coqResultObject)); - - // // Choose only ONE of the following - // // This is the fast way of append the results from this field - // // result.noticeList = result.noticeList.concat(coqResultObject.noticeList); - // // If we need to put everything through addNoticePartial, e.g., for debugging or filtering - // // process results line by line - // for (const coqNoticeEntry of coqResultObject.noticeList) { - // if (coqNoticeEntry.extra) // it must be an indirect check on a TA or TW article from a TN2 check - // drResult.noticeList.push(coqNoticeEntry); // Just copy the complete notice as is - // else // For our direct checks, we add the repoCode as an extra value - // addNoticePartial({ ...coqNoticeEntry, rowID, fieldName }); - // } - // // The following is needed coz we might be checking the linked TA and/or TW articles - // if (coqResultObject.checkedFileCount && coqResultObject.checkedFileCount > 0) - // if (typeof drResult.checkedFileCount === 'number') drResult.checkedFileCount += coqResultObject.checkedFileCount; - // else drResult.checkedFileCount = coqResultObject.checkedFileCount; - // if (coqResultObject.checkedFilesizes && coqResultObject.checkedFilesizes > 0) - // if (typeof drResult.checkedFilesizes === 'number') drResult.checkedFilesizes += coqResultObject.checkedFilesizes; - // else drResult.checkedFilesizes = coqResultObject.checkedFilesizes; - // if (coqResultObject.checkedRepoNames && coqResultObject.checkedRepoNames.length > 0) - // for (const checkedRepoName of coqResultObject.checkedRepoNames) - // try { if (drResult.checkedRepoNames.indexOf(checkedRepoName) < 0) drResult.checkedRepoNames.push(checkedRepoName); } - // catch { drResult.checkedRepoNames = [checkedRepoName]; } - // if (coqResultObject.checkedFilenameExtensions && coqResultObject.checkedFilenameExtensions.length > 0) - // for (const checkedFilenameExtension of coqResultObject.checkedFilenameExtensions) - // try { if (drResult.checkedFilenameExtensions.indexOf(checkedFilenameExtension) < 0) drResult.checkedFilenameExtensions.push(checkedFilenameExtension); } - // catch { drResult.checkedFilenameExtensions = [checkedFilenameExtension]; } - // // if (drResult.checkedFilenameExtensions) userLog("drResult", JSON.stringify(drResult)); - // } - // // end of ourCheckNotesLinksToOutside function - - // Main code for checkQuestionsTSV7DataRow function if (line === EXPECTED_QUESTIONS_HEADING_LINE) // Assume it must be ok return drResult; // We can’t detect if it’s in the wrong place @@ -306,9 +265,9 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo if (bookID === 'OBS') numChaptersThisBook = 50; // There's 50 Open Bible Stories else { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in question-row-check"); + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in question-row-check"); try { - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch (tlcNCerror) { addNoticePartial({ priority: 979, message: "Invalid book identifier passed to checkQuestionsTSV7DataRow", location: ` '${bookID}' in first parameter: ${tlcNCerror}` }); } @@ -365,7 +324,7 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo else addNoticePartial({ priority: 820, message: "Missing chapter number", rowID, fieldName: 'Reference', excerpt: `?:${V}`, location: ourRowLocation }); - if (V?.length) { + if (V?.length) { // can be undefined if no colon at split above if (V.indexOf('-') === -1) { // Not a verse bridge if (V !== givenV) addNoticePartial({ priority: 975, message: "Wrong verse number", details: `expected '${givenV}'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation }); @@ -394,7 +353,7 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo addNoticePartial({ priority: 975, message: "Wrong verse number", details: `expected '${givenV}' to be inside range`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation }); else if (intV1 >= intV2) addNoticePartial({ priority: 808, message: "Bad verse range", details: "Second digits should be greater", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation }); - else if (intV1 === 0 && bookID !== 'PSA') // Psalms have \d as verse zero + else if (intV1 === 0 && bookID !== 'PSA') // Psalms have \d as verse zero addNoticePartial({ priority: 814, message: "Invalid zero verse number", rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation }); else { if (haveGoodChapterNumber) { @@ -460,8 +419,7 @@ export async function checkQuestionsTSV7DataRow(languageCode, repoCode, line, bo // if (V !== 'intro') // addNoticePartial({priority:500, message:"Invalid zero occurrence field", rowID, location:rowLocation); } - else if (occurrence === '-1') // TODO check the special conditions when this can occur??? - ; + else if (occurrence === '-1') { }// TODO check the special conditions when this can occur??? else if ('12345678'.indexOf(occurrence) < 0) { // it’s not one of these integers addNoticePartial({ priority: 792, message: `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation }); OSuggestion = '1'; diff --git a/src/core/questions-tsv7-row-check.md b/src/core/questions-tsv7-row-check.md index 04c5e60b8..75488e07b 100644 --- a/src/core/questions-tsv7-row-check.md +++ b/src/core/questions-tsv7-row-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkQuestionsTSV7DataRow } from './questions-tsv7-row-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, Header, Nonsense, Good, Bad, Very bad, and Actual line samples const lineE = ""; diff --git a/src/core/questions-tsv7-table-check.js b/src/core/questions-tsv7-table-check.js index c62ec1670..48f155bad 100644 --- a/src/core/questions-tsv7-table-check.js +++ b/src/core/questions-tsv7-table-check.js @@ -2,6 +2,7 @@ import * as books from './books/books'; import { DEFAULT_EXCERPT_LENGTH } from './defaults' import { checkQuestionsTSV7DataRow } from './questions-tsv7-row-check'; import { removeDisabledNotices } from './disabled-notices'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -31,16 +32,16 @@ export async function checkQuestionsTSV7Table(languageCode, repoCode, bookID, fi Returns a result object containing a successList and a noticeList */ // functionLog(`checkQuestionsTSV7Table(${languageCode}, ${repoCode}, ${bookID}, ${filename}, ${tableText.length}, ${givenLocation},${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkQuestionsTSV7Table: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkQuestionsTSV7Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode.endsWith('TQ') || repoCode.endsWith('TQ2') || repoCode.endsWith('SQ'), `checkQuestionsTSV7Table: repoCode expected to end with 'TQ', 'TQ2', or 'SQ' not '${repoCode}'`); - parameterAssert(bookID !== undefined, "checkQuestionsTSV7Table: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkQuestionsTSV7Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkQuestionsTSV7Table: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkQuestionsTSV7Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkQuestionsTSV7Table: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(givenLocation !== undefined, "checkQuestionsTSV7Table: 'givenLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkQuestionsTSV7Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(languageCode !== undefined, "checkQuestionsTSV7Table: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkQuestionsTSV7Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode.endsWith('TQ') || repoCode.endsWith('TQ2') || repoCode.endsWith('SQ'), `checkQuestionsTSV7Table: repoCode expected to end with 'TQ', 'TQ2', or 'SQ' not '${repoCode}'`); + //parameterAssert(bookID !== undefined, "checkQuestionsTSV7Table: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkQuestionsTSV7Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkQuestionsTSV7Table: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkQuestionsTSV7Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkQuestionsTSV7Table: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(givenLocation !== undefined, "checkQuestionsTSV7Table: 'givenLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkQuestionsTSV7Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -53,20 +54,24 @@ export async function checkQuestionsTSV7Table(languageCode, repoCode, bookID, fi } function addNoticePartial(noticeObject) { // functionLog(`checkQuestionsTSV7Table notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "ATSV addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "ATSV addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(C !== undefined, "ATSV addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); - // parameterAssert(V !== undefined, "ATSV addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); - // parameterAssert(characterIndex !== undefined, "ATSV addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "ATSV addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "ATSV addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "ATSV addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "ATSV addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(C !== undefined, "ATSV addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); + } + // //parameterAssert(V !== undefined, "ATSV addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); + } + // //parameterAssert(characterIndex !== undefined, "ATSV addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "ATSV addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "ATSV addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkQuestionsTSV7Table ${noticeObject.debugChain}`; carResult.noticeList.push({ ...noticeObject, bookID, filename, repoCode }); @@ -92,9 +97,9 @@ export async function checkQuestionsTSV7Table(languageCode, repoCode, bookID, fi if (bookID === 'OBS') numChaptersThisBook = 50; // There's 50 Open Bible Stories else { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkQuestionsTSV7Table"); + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkQuestionsTSV7Table"); try { - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch { if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. diff --git a/src/core/questions-tsv7-table-check.md b/src/core/questions-tsv7-table-check.md index 85566d3b8..d3a058de1 100644 --- a/src/core/questions-tsv7-table-check.md +++ b/src/core/questions-tsv7-table-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkQuestionsTSV7Table } from './questions-tsv7-table-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Text samples const textA = `Reference\tID\tTags\tQuote\tOccurrence\tQuestion\tResponse diff --git a/src/core/ta-reference-check.js b/src/core/ta-reference-check.js index 8ab046cc2..264814693 100644 --- a/src/core/ta-reference-check.js +++ b/src/core/ta-reference-check.js @@ -1,6 +1,6 @@ import { cachedGetFile } from '../core/getApi'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; -// import { consoleLogObject } from '../core/utilities'; // const TA_REFERENCE_VALIDATOR_VERSION_STRING = '0.3.2'; @@ -19,16 +19,16 @@ export async function checkSupportReferenceInTA(fieldName, fieldText, givenLocat // checkingOptions?.expectFullLink (bool) // functionLog(`checkSupportReferenceInTA v${TA_REFERENCE_VALIDATOR_VERSION_STRING} (${fieldName}, (${fieldText.length}) '${fieldText}', ${givenLocation}, …)`); - parameterAssert(fieldName !== undefined, "checkSupportReferenceInTA: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkSupportReferenceInTA: 'fieldText' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkSupportReferenceInTA: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkSupportReferenceInTA: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(givenLocation !== undefined, "checkSupportReferenceInTA: 'fieldText' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkSupportReferenceInTA: 'fieldText' parameter should be a string not a '${typeof givenLocation}'`); - parameterAssert(fieldName === 'SupportReference', `Unexpected checkSupportReferenceInTA fieldName='${fieldName}'`); // so far - parameterAssert(givenLocation.indexOf(fieldName) < 0, `checkSupportReferenceInTA: 'givenLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(fieldName !== undefined, "checkSupportReferenceInTA: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkSupportReferenceInTA: 'fieldText' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkSupportReferenceInTA: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkSupportReferenceInTA: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(givenLocation !== undefined, "checkSupportReferenceInTA: 'fieldText' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkSupportReferenceInTA: 'fieldText' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(fieldName === 'SupportReference', `Unexpected checkSupportReferenceInTA fieldName='${fieldName}'`); // so far + //parameterAssert(givenLocation.indexOf(fieldName) < 0, `checkSupportReferenceInTA: 'givenLocation' parameter should be not contain fieldName=${fieldName}`); - parameterAssert(fieldName === 'SupportReference'); + //parameterAssert(fieldName === 'SupportReference'); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -37,16 +37,18 @@ export async function checkSupportReferenceInTA(fieldName, fieldText, givenLocat function addNoticePartial(noticeObject) { // functionLog(`checkSupportReferenceInTA Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cTAref addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cTAref addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cTAref addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cTAref addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex !== undefined, "cTAref addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cTAref addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cTAref addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cTAref addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cTAref addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cTAref addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cTAref addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cTAref addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cTAref addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cTAref addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex !== undefined, "cTAref addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cTAref addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cTAref addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cTAref addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cTAref addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cTAref addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); ctarResult.noticeList.push({ ...noticeObject, fieldName }); } diff --git a/src/core/text-handling-functions.js b/src/core/text-handling-functions.js index a5c69e96a..b50bbce8e 100644 --- a/src/core/text-handling-functions.js +++ b/src/core/text-handling-functions.js @@ -16,6 +16,9 @@ export const BAD_CHARACTER_COMBINATIONS = [ '\\[\\[', '\\]\\]', // These were introduced by a tC Create bug (NOTE: \[ or \] is quite legal) '] (http', '] (.', // Bad markdown links (with a space between the parts) ]; +export const LEADING_ZERO_COMBINATIONS = [ + ' 0', ':0', '
0', '“0', '‘0', +]; export function isWhitespace(myString) { // includes zero-width space @@ -60,4 +63,4 @@ export function ourDeleteAll(givenString, findString) { while (resultString.indexOf(findString) >= 0) resultString = resultString.replace(findString, ''); return resultString; -} \ No newline at end of file +} diff --git a/src/core/tn-tsv9-row-check.js b/src/core/tn-tsv9-row-check.js index 83a70f20f..489467c49 100644 --- a/src/core/tn-tsv9-row-check.js +++ b/src/core/tn-tsv9-row-check.js @@ -1,11 +1,12 @@ -import { DEFAULT_EXCERPT_LENGTH } from './defaults' -import { isWhitespace, countOccurrences } from './text-handling-functions' +import { DEFAULT_EXCERPT_LENGTH } from './defaults'; +import { isWhitespace, countOccurrences } from './text-handling-functions'; import * as books from './books/books'; import { checkTextField } from './field-text-check'; import { checkMarkdownText } from './markdown-text-check'; import { checkSupportReferenceInTA } from './ta-reference-check'; // import { checkNotesLinksToOutside } from './notes-links-check'; import { checkOriginalLanguageQuoteAndOccurrence } from './orig-quote-check'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -43,22 +44,24 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, Returns an object containing the noticeList. */ // functionLog(`checkTN_TSV9DataRow(${languageCode}, ${repoCode}, ${line}, ${bookID}, ${givenRowLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkTN_TSV9DataRow: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTN_TSV9DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode === 'TN', `checkTN_TSV9DataRow: repoCode expected 'TN' not '${repoCode}'`); - parameterAssert(line !== undefined, "checkTN_TSV9DataRow: 'line' parameter should be defined"); - parameterAssert(typeof line === 'string', `checkTN_TSV9DataRow: 'line' parameter should be a string not a '${typeof line}'`); - parameterAssert(bookID !== undefined, "checkTN_TSV9DataRow: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkTN_TSV9DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkTN_TSV9DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkTN_TSV9DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(books.isValidBookID(bookID), `checkTN_TSV9DataRow: '${bookID}' is not a valid USFM book identifier`); - // parameterAssert(givenC !== undefined, "checkTN_TSV9DataRow: 'givenC' parameter should be defined"); - if (givenC) parameterAssert(typeof givenC === 'string', `checkTN_TSV9DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); - // parameterAssert(givenV !== undefined, "checkTN_TSV9DataRow: 'givenV' parameter should be defined"); - if (givenV) parameterAssert(typeof givenV === 'string', `checkTN_TSV9DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); - parameterAssert(givenRowLocation !== undefined, "checkTN_TSV9DataRow: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenRowLocation === 'string', `checkTN_TSV9DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); + //parameterAssert(languageCode !== undefined, "checkTN_TSV9DataRow: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTN_TSV9DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode === 'TN', `checkTN_TSV9DataRow: repoCode expected 'TN' not '${repoCode}'`); + //parameterAssert(line !== undefined, "checkTN_TSV9DataRow: 'line' parameter should be defined"); + //parameterAssert(typeof line === 'string', `checkTN_TSV9DataRow: 'line' parameter should be a string not a '${typeof line}'`); + //parameterAssert(bookID !== undefined, "checkTN_TSV9DataRow: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkTN_TSV9DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkTN_TSV9DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkTN_TSV9DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(books.isValidBookID(bookID), `checkTN_TSV9DataRow: '${bookID}' is not a valid USFM book identifier`); + // //parameterAssert(givenC !== undefined, "checkTN_TSV9DataRow: 'givenC' parameter should be defined"); + if (givenC) { //parameterAssert(typeof givenC === 'string', `checkTN_TSV9DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); + } + // //parameterAssert(givenV !== undefined, "checkTN_TSV9DataRow: 'givenV' parameter should be defined"); + if (givenV) { //parameterAssert(typeof givenV === 'string', `checkTN_TSV9DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); + } + //parameterAssert(givenRowLocation !== undefined, "checkTN_TSV9DataRow: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenRowLocation === 'string', `checkTN_TSV9DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); let ourRowLocation = givenRowLocation; if (ourRowLocation && ourRowLocation[0] !== ' ') ourRowLocation = ` ${ourRowLocation}`; @@ -80,18 +83,20 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, */ function addNoticePartial(noticeObject) { // functionLog(`checkTN_TSV9DataRow addNoticePartial(priority=${noticeObject.priority}) ${noticeObject.message}, ${noticeObject.characterIndex}, ${noticeObject.excerpt}, ${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `checkTN_TSV9DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `checkTN_TSV9DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(lineNumber !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'lineNumber' parameter should be defined"); - // parameterAssert(typeof lineNumber === 'number', `checkTN_TSV9DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); - // parameterAssert(characterIndex !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `checkTN_TSV9DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `checkTN_TSV9DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `checkTN_TSV9DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `checkTN_TSV9DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `checkTN_TSV9DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(lineNumber !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'lineNumber' parameter should be defined"); + // //parameterAssert(typeof lineNumber === 'number', `checkTN_TSV9DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); + // //parameterAssert(characterIndex !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `checkTN_TSV9DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `checkTN_TSV9DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "checkTN_TSV9DataRow addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `checkTN_TSV9DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // noticeObject.debugChain = noticeObject.debugChain ? `checkTN_TSV9DataRow ${noticeObject.debugChain}` : 'checkTN_TSV9DataRow'; // Also uses the given bookID,C,V, parameters from the main function call drResult.noticeList.push({ ...noticeObject, bookID, C: givenC, V: givenV }); @@ -116,17 +121,17 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // We don’t currently use the allowedLinks parameter // functionLog(`checkTN_TSV9DataRow ourMarkdownTextChecks(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowID' parameter should be a string not a '${typeof rowID}'`); - // parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldName' parameter should be defined"); - // parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldName === 'OccurrenceNote', `checkTN_TSV9DataRow ourMarkdownTextChecks: Only run this check on OccurrenceNotes not '${fieldName}'`); - parameterAssert(fieldText !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkTN_TSV9DataRow ourMarkdownTextChecks: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowID' parameter should be a string not a '${typeof rowID}'`); + // //parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldName' parameter should be defined"); + // //parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldName === 'OccurrenceNote', `checkTN_TSV9DataRow ourMarkdownTextChecks: Only run this check on OccurrenceNotes not '${fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkTN_TSV9DataRow ourMarkdownTextChecks: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourMarkdownTextChecks: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const omtcResultObject = await checkMarkdownText(languageCode, repoCode, fieldName, fieldText, rowLocation, checkingOptions); @@ -136,7 +141,7 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of omtcResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); // NOTE: Ellipses in OccurrenceNote have the normal meaning // not like the specialised meaning in the snippet fields Quote and GLQuote if (noticeEntry.priority !== 178 && noticeEntry.priority !== 179 // unexpected space after ellipse, ellipse after space @@ -165,16 +170,16 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // Updates the global list of notices // functionLog(`checkTN_TSV9DataRow ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkTN_TSV9DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkTN_TSV9DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkTN_TSV9DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkTN_TSV9DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const fieldType = fieldName === 'OccurrenceNote' ? 'markdown' : 'raw'; const octfResultObject = checkTextField(languageCode, repoCode, fieldType, fieldName, fieldText, allowedLinks, rowLocation, checkingOptions); @@ -185,7 +190,7 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of octfResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } return octfResultObject.suggestion; // There may or may not be one! @@ -206,13 +211,13 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // Updates the global list of notices // functionLog(`checkTN_TSV9DataRow ourCheckSupportReferenceInTA(${fieldName}, (${taLinkText.length}) '${taLinkText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(taLinkText !== undefined, "checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be defined"); - parameterAssert(typeof taLinkText === 'string', `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(taLinkText !== undefined, "checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be defined"); + //parameterAssert(typeof taLinkText === 'string', `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourCheckSupportReferenceInTA: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const coqResultObject = await checkSupportReferenceInTA(fieldName, taLinkText, rowLocation, { ...checkingOptions, taRepoLanguageCode: languageCode }); @@ -222,7 +227,7 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckSupportReferenceInTA notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckSupportReferenceInTA notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } } @@ -246,15 +251,15 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // Updates the global list of notices // functionLog(`checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence(${fieldName}, (${fieldText.length}) '${fieldText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(occurrence !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be defined"); - parameterAssert(typeof occurrence === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(occurrence !== undefined, "checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be defined"); + //parameterAssert(typeof occurrence === 'string', `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTN_TSV9DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const coqResultObject = await checkOriginalLanguageQuoteAndOccurrence(languageCode, repoCode, fieldName, fieldText, occurrence, bookID, givenC, givenV, rowLocation, checkingOptions); @@ -264,7 +269,7 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuoteAndOccurrence notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuoteAndOccurrence notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } } @@ -292,8 +297,8 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, const lowercaseBookID = bookID.toLowerCase(); let numChaptersThisBook; try { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in tn_table-row-check"); - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in tn_table-row-check"); + numChaptersThisBook = books.chaptersInBook(bookID); } catch (tlcNCerror) { addNoticePartial({ priority: 979, message: "Invalid book identifier passed to checkTN_TSV9DataRow", location: ` '${bookID}' in first parameter: ${tlcNCerror}` }); } @@ -432,8 +437,7 @@ export async function checkTN_TSV9DataRow(languageCode, repoCode, line, bookID, // if (V !== 'intro') // addNoticePartial({priority:500, message:"Invalid zero occurrence field", rowID, location:rowLocation); } - else if (occurrence === '-1') // TODO check the special conditions when this can occur??? - ; + else if (occurrence === '-1') { } // TODO check the special conditions when this can occur??? else if ('12345678'.indexOf(occurrence) < 0) { // it’s not one of these integers addNoticePartial({ priority: 792, message: `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation }); OSuggestion = '1'; diff --git a/src/core/tn-tsv9-row-check.md b/src/core/tn-tsv9-row-check.md index 8663bc11c..4fffe89e4 100644 --- a/src/core/tn-tsv9-row-check.md +++ b/src/core/tn-tsv9-row-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkTN_TSV9DataRow } from './tn-tsv9-row-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, Header, Nonsense, Good, Bad, Very bad, and Actual line samples const lineE = ""; diff --git a/src/core/tn-tsv9-table-check.js b/src/core/tn-tsv9-table-check.js index 9f9e65cb9..30de28f3d 100644 --- a/src/core/tn-tsv9-table-check.js +++ b/src/core/tn-tsv9-table-check.js @@ -2,6 +2,7 @@ import * as books from './books/books'; import { DEFAULT_EXCERPT_LENGTH } from './defaults' import { checkTN_TSV9DataRow } from './tn-tsv9-row-check'; import { removeDisabledNotices } from './disabled-notices'; +// eslint-disable-next-line no-unused-vars import { debugLog, parameterAssert } from './utilities'; @@ -32,17 +33,17 @@ export async function checkTN_TSV9Table(languageCode, repoCode, bookID, filename Returns a result object containing a successList and a noticeList */ // functionLog(`checkTN_TSV9Table(${languageCode}, ${bookID}, ${filename}, ${tableText.length}, ${givenLocation},${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkTN_TSV9Table: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTN_TSV9Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode === 'TN', `checkTN_TSV9Table: repoCode expected 'TN' not '${repoCode}'`); - parameterAssert(bookID !== undefined, "checkTN_TSV9Table: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkTN_TSV9Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkTN_TSV9Table: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkTN_TSV9Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(books.isValidBookID(bookID), `checkTN_TSV9Table: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(givenLocation !== undefined, "checkTN_TSV9Table: 'givenLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkTN_TSV9Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); - parameterAssert(checkingOptions !== undefined, "checkTN_TSV9Table: 'checkingOptions' parameter should be defined"); + //parameterAssert(languageCode !== undefined, "checkTN_TSV9Table: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTN_TSV9Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode === 'TN', `checkTN_TSV9Table: repoCode expected 'TN' not '${repoCode}'`); + //parameterAssert(bookID !== undefined, "checkTN_TSV9Table: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkTN_TSV9Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkTN_TSV9Table: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkTN_TSV9Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(books.isValidBookID(bookID), `checkTN_TSV9Table: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(givenLocation !== undefined, "checkTN_TSV9Table: 'givenLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkTN_TSV9Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(checkingOptions !== undefined, "checkTN_TSV9Table: 'checkingOptions' parameter should be defined"); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -63,20 +64,24 @@ export async function checkTN_TSV9Table(languageCode, repoCode, bookID, filename */ function addNoticePartial(noticeObject) { // functionLog(`checkTN_TSV9Table notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "TSV addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "TSV addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(C !== undefined, "TSV addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); - // parameterAssert(V !== undefined, "TSV addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); - // parameterAssert(characterIndex !== undefined, "TSV addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "TSV addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "TSV addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "TSV addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "TSV addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(C !== undefined, "TSV addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); + } + // //parameterAssert(V !== undefined, "TSV addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); + } + // //parameterAssert(characterIndex !== undefined, "TSV addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "TSV addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "TSV addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkTN_TSV9Table ${noticeObject.debugChain}`; // NOTE: We only add the repoCode here because this function is called directly by tC Create // and notice disabling currently depends on knowing the repoCode @@ -102,8 +107,8 @@ export async function checkTN_TSV9Table(languageCode, repoCode, bookID, filename let lowercaseBookID = bookID.toLowerCase(); let numChaptersThisBook = 0; try { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in tn_table-text-check"); - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in tn_table-text-check"); + numChaptersThisBook = books.chaptersInBook(bookID); } catch { if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. diff --git a/src/core/tn-tsv9-table-check.md b/src/core/tn-tsv9-table-check.md index 32b7584ee..e73d3d9d0 100644 --- a/src/core/tn-tsv9-table-check.md +++ b/src/core/tn-tsv9-table-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkTN_TSV9Table } from './tn-tsv9-table-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Text samples const textA = `Book\tChapter\tVerse\tID\tSupportReference\tQuote\tOccurrence\tGLQuote\tOccurrenceNote diff --git a/src/core/twl-tsv6-row-check.js b/src/core/twl-tsv6-row-check.js index ad2bc186e..6c7144f9e 100644 --- a/src/core/twl-tsv6-row-check.js +++ b/src/core/twl-tsv6-row-check.js @@ -1,15 +1,16 @@ -import { DEFAULT_EXCERPT_LENGTH } from './defaults' -import { isWhitespace, countOccurrences } from './text-handling-functions' +import { DEFAULT_EXCERPT_LENGTH } from './defaults'; +import { isWhitespace, countOccurrences } from './text-handling-functions'; import * as books from './books/books'; import { checkTextField } from './field-text-check'; // import { checkMarkdownText } from './markdown-text-check'; // import { checkSupportReferenceInTA } from './ta-reference-check'; import { checkNotesLinksToOutside } from './notes-links-check'; import { checkOriginalLanguageQuoteAndOccurrence } from './orig-quote-check'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; -// const TWL_TABLE_ROW_VALIDATOR_VERSION_STRING = '0.1.6'; +// const TWL_TABLE_ROW_VALIDATOR_VERSION_STRING = '0.1.8'; const NUM_EXPECTED_TWL_TSV_FIELDS = 6; // so expects 5 tabs per line const EXPECTED_TWL_HEADING_LINE = 'Reference\tID\tTags\tOrigWords\tOccurrence\tTWLink'; @@ -47,23 +48,25 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, Returns an object containing the noticeList. */ // functionLog(`checkTWL_TSV6DataRow(${languageCode}, ${repoCode}, ${line}, ${bookID}, ${givenRowLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkTWL_TSV6DataRow: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTWL_TSV6DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode === 'TWL' || repoCode === 'OBS-TWL', `checkTWL_TSV6DataRow: repoCode expected 'TWL' or 'OBS-TWL' not '${repoCode}'`); - parameterAssert(line !== undefined, "checkTWL_TSV6DataRow: 'line' parameter should be defined"); - parameterAssert(typeof line === 'string', `checkTWL_TSV6DataRow: 'line' parameter should be a string not a '${typeof line}'`); - parameterAssert(bookID !== undefined, "checkTWL_TSV6DataRow: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkTWL_TSV6DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkTWL_TSV6DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkTWL_TSV6DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkTWL_TSV6DataRow: '${bookID}' is not a valid USFM book identifier`); - // parameterAssert(givenC !== undefined, "checkTWL_TSV6DataRow: 'givenC' parameter should be defined"); - if (givenC) parameterAssert(typeof givenC === 'string', `checkTWL_TSV6DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); - // parameterAssert(givenV !== undefined, "checkTWL_TSV6DataRow: 'givenV' parameter should be defined"); - if (givenV) parameterAssert(typeof givenV === 'string', `checkTWL_TSV6DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); - parameterAssert(givenRowLocation !== undefined, "checkTWL_TSV6DataRow: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenRowLocation === 'string', `checkTWL_TSV6DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); - parameterAssert(givenRowLocation.indexOf('true') === -1, "checkTWL_TSV6DataRow: 'givenRowLocation' parameter should not be 'true'"); + //parameterAssert(languageCode !== undefined, "checkTWL_TSV6DataRow: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTWL_TSV6DataRow: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode === 'TWL' || repoCode === 'OBS-TWL', `checkTWL_TSV6DataRow: repoCode expected 'TWL' or 'OBS-TWL' not '${repoCode}'`); + //parameterAssert(line !== undefined, "checkTWL_TSV6DataRow: 'line' parameter should be defined"); + //parameterAssert(typeof line === 'string', `checkTWL_TSV6DataRow: 'line' parameter should be a string not a '${typeof line}'`); + //parameterAssert(bookID !== undefined, "checkTWL_TSV6DataRow: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkTWL_TSV6DataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkTWL_TSV6DataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkTWL_TSV6DataRow: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkTWL_TSV6DataRow: '${bookID}' is not a valid USFM book identifier`); + // //parameterAssert(givenC !== undefined, "checkTWL_TSV6DataRow: 'givenC' parameter should be defined"); + if (givenC) { //parameterAssert(typeof givenC === 'string', `checkTWL_TSV6DataRow: 'givenC' parameter should be a string not a '${typeof givenC}'`); + } + // //parameterAssert(givenV !== undefined, "checkTWL_TSV6DataRow: 'givenV' parameter should be defined"); + if (givenV) { //parameterAssert(typeof givenV === 'string', `checkTWL_TSV6DataRow: 'givenV' parameter should be a string not a '${typeof givenV}'`); + } + //parameterAssert(givenRowLocation !== undefined, "checkTWL_TSV6DataRow: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenRowLocation === 'string', `checkTWL_TSV6DataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); + //parameterAssert(givenRowLocation.indexOf('true') === -1, "checkTWL_TSV6DataRow: 'givenRowLocation' parameter should not be 'true'"); let ourRowLocation = givenRowLocation; if (ourRowLocation && ourRowLocation[0] !== ' ') ourRowLocation = ` ${ourRowLocation}`; @@ -85,18 +88,20 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, * @param {string} location - description of where the issue is located */ // functionLog(`checkTWL_TSV6DataRow addNoticePartial(priority=${noticeObject.priority}) ${noticeObject.message}, ${noticeObject.characterIndex}, ${noticeObject.excerpt}, ${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `checkTWL_TSV6DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `checkTWL_TSV6DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(lineNumber !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'lineNumber' parameter should be defined"); - // parameterAssert(typeof lineNumber === 'number', `checkTWL_TSV6DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); - // parameterAssert(characterIndex !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `checkTWL_TSV6DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `checkTWL_TSV6DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `checkTWL_TSV6DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `checkTWL_TSV6DataRow addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `checkTWL_TSV6DataRow addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(lineNumber !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'lineNumber' parameter should be defined"); + // //parameterAssert(typeof lineNumber === 'number', `checkTWL_TSV6DataRow addNoticePartial: 'lineNumber' parameter should be a number not a '${typeof lineNumber}': ${lineNumber}`); + // //parameterAssert(characterIndex !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `checkTWL_TSV6DataRow addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `checkTWL_TSV6DataRow addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "checkTWL_TSV6DataRow addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `checkTWL_TSV6DataRow addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // Also uses the given bookID,C,V, parameters from the main function call // noticeObject.debugChain = noticeObject.debugChain ? `checkTWL_TSV6DataRow ${noticeObject.debugChain}` : `checkTWL_TSV6DataRow(${repoCode})`; @@ -120,16 +125,16 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, // Updates the global list of notices // functionLog(`checkTWL_TSV6DataRow ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "checkTWL_TSV6DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(rowLocation !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); - parameterAssert(typeof rowLocation === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTWL_TSV6DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "checkTWL_TSV6DataRow ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(rowLocation !== undefined, "checkTWL_TSV6DataRow ourCheckTextField: 'rowLocation' parameter should be defined"); + //parameterAssert(typeof rowLocation === 'string', `checkTWL_TSV6DataRow ourCheckTextField: 'rowLocation' parameter should be a string not a '${typeof rowLocation}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTWL_TSV6DataRow ourCheckTextField: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const fieldType = 'raw'; const octfResultObject = checkTextField(languageCode, repoCode, fieldType, fieldName, fieldText, allowedLinks, rowLocation, checkingOptions); @@ -140,7 +145,7 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of octfResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTextField notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } return octfResultObject.suggestion; // There may or may not be one! @@ -156,15 +161,15 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, // Updates the global list of notices // functionLog(`checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence(${fieldName}, (${fieldText.length}) '${fieldText}', ${rowLocation}, …)`); - parameterAssert(rowID !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldText !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(occurrence !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be defined"); - parameterAssert(typeof occurrence === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); - parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); + //parameterAssert(rowID !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldText !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(occurrence !== undefined, "checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be defined"); + //parameterAssert(typeof occurrence === 'string', `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'occurrence' parameter should be a string not a '${typeof occurrence}'`); + //parameterAssert(rowLocation.indexOf(fieldName) < 0, `checkTWL_TSV6DataRow ourCheckTNOriginalLanguageQuoteAndOccurrence: 'rowLocation' parameter should be not contain fieldName=${fieldName}`); const colqResultObject = await checkOriginalLanguageQuoteAndOccurrence(languageCode, repoCode, fieldName, fieldText, occurrence, bookID, givenC, givenV, rowLocation, checkingOptions); @@ -174,7 +179,7 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of colqResultObject.noticeList) { - // parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuoteAndOccurrence notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuoteAndOccurrence notice length=${Object.keys(noticeEntry).length}`); addNoticePartial({ ...noticeEntry, rowID, fieldName }); } } @@ -187,13 +192,15 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, // Updates the global list of notices // functionLog(`checkTWL_TSV6DataRow ourCheckNotesLinksToOutside(${rowID}, ${fieldName}, (${twLinkText.length}) '${twLinkText}', ${rowLocation}, ${JSON.stringify(checkingOptions)})`); - parameterAssert(rowID !== undefined, "checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be defined"); - parameterAssert(typeof rowID === 'string', `checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be a string not a '${typeof rowID}'`); - parameterAssert(fieldName === 'TWLink', `checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be 'TWLink' not '${fieldName}'`); - parameterAssert(twLinkText !== undefined, "checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'twLinkText' parameter should be defined"); - parameterAssert(typeof twLinkText === 'string', `checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'twLinkText' parameter should be a string not a '${typeof twLinkText}'`); - - const coTNlResultObject = await checkNotesLinksToOutside(languageCode, repoCode, bookID, givenC, givenV, fieldName, twLinkText, rowLocation, { ...checkingOptions, defaultLanguageCode: languageCode }); + //parameterAssert(rowID !== undefined, "checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be defined"); + //parameterAssert(typeof rowID === 'string', `checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'rowID' parameter should be a string not a '${typeof rowID}'`); + //parameterAssert(fieldName === 'TWLink', `checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'fieldName' parameter should be 'TWLink' not '${fieldName}'`); + //parameterAssert(twLinkText !== undefined, "checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'twLinkText' parameter should be defined"); + //parameterAssert(typeof twLinkText === 'string', `checkTWL_TSV6DataRow ourCheckNotesLinksToOutside: 'twLinkText' parameter should be a string not a '${typeof twLinkText}'`); + + let adjustedLanguageCode = languageCode; // This is the language code of the resource with the link + if (languageCode === 'hbo' || languageCode === 'el-x-koine') adjustedLanguageCode = 'en' // This is a guess (and won't be needed for TWs when we switch to TWLs) + const coTNlResultObject = await checkNotesLinksToOutside(languageCode, repoCode, bookID, givenC, givenV, fieldName, twLinkText, rowLocation, { ...checkingOptions, defaultLanguageCode: adjustedLanguageCode }); // debugLog(`coTNlResultObject=${JSON.stringify(coTNlResultObject)}`); // Choose only ONE of the following @@ -250,9 +257,9 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, if (bookID === 'OBS') numChaptersThisBook = 50; // There's 50 Open Bible Stories else { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkTWL_TSV6DataRow"); + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkTWL_TSV6DataRow"); try { - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch (tlcNCerror) { addNoticePartial({ priority: 979, message: "Invalid book identifier passed to checkTWL_TSV6DataRow", location: ` '${bookID}' in first parameter: ${tlcNCerror}` }); } @@ -306,7 +313,7 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, else addNoticePartial({ priority: 820, message: "Missing chapter number", rowID, fieldName: 'Reference', location: ` ?:${V}${ourRowLocation}` }); - if (V.length) { + if (V?.length) { // can be undefined if no colon at split above if (V !== givenV) addNoticePartial({ priority: 975, message: "Wrong verse number", details: `expected '${givenV}'`, rowID, fieldName: 'Reference', excerpt: V, location: ourRowLocation }); if (bookID === 'OBS' || V === 'intro') { } @@ -376,8 +383,7 @@ export async function checkTWL_TSV6DataRow(languageCode, repoCode, line, bookID, // if (V !== 'intro') // addNoticePartial({priority:500, message:"Invalid zero occurrence field", rowID, location:rowLocation); } - else if (occurrence === '-1') // TODO check the special conditions when this can occur??? - ; + else if (occurrence === '-1') { }// TODO check the special conditions when this can occur??? else if ('12345678'.indexOf(occurrence) < 0) { // it’s not one of these integers addNoticePartial({ priority: 792, message: `Invalid occurrence field`, fieldName: 'Occurrence', rowID, excerpt: occurrence, location: ourRowLocation }); OSuggestion = '1'; diff --git a/src/core/twl-tsv6-row-check.md b/src/core/twl-tsv6-row-check.md index 58a8a705c..6a23b644d 100644 --- a/src/core/twl-tsv6-row-check.md +++ b/src/core/twl-tsv6-row-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkTWL_TSV6DataRow } from './twl-tsv6-row-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, Header, Nonsense, Good, Bad, Very bad, and Actual line samples const lineE = ""; diff --git a/src/core/twl-tsv6-table-check.js b/src/core/twl-tsv6-table-check.js index 17a6a748d..0798e2de5 100644 --- a/src/core/twl-tsv6-table-check.js +++ b/src/core/twl-tsv6-table-check.js @@ -2,6 +2,7 @@ import * as books from './books/books'; import { DEFAULT_EXCERPT_LENGTH } from './defaults' import { checkTWL_TSV6DataRow } from './twl-tsv6-row-check'; import { removeDisabledNotices } from './disabled-notices'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -31,16 +32,16 @@ export async function checkTWL_TSV6Table(languageCode, repoCode, bookID, filenam Returns a result object containing a successList and a noticeList */ // functionLog(`checkTWL_TSV6Table(${languageCode}, ${repoCode}, ${bookID}, ${tableText.length}, ${givenLocation},${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkTWL_TSV6Table: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTWL_TSV6Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode === 'TWL' || repoCode === 'OBS-TWL', `checkTWL_TSV6Table: repoCode expected 'TWL' or 'OBS-TWL' not '${repoCode}'`); - parameterAssert(bookID !== undefined, "checkTWL_TSV6Table: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkTWL_TSV6Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkTWL_TSV6Table: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkTWL_TSV6Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkTWL_TSV6Table: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(givenLocation !== undefined, "checkTWL_TSV6Table: 'givenLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkTWL_TSV6Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(languageCode !== undefined, "checkTWL_TSV6Table: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTWL_TSV6Table: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode === 'TWL' || repoCode === 'OBS-TWL', `checkTWL_TSV6Table: repoCode expected 'TWL' or 'OBS-TWL' not '${repoCode}'`); + //parameterAssert(bookID !== undefined, "checkTWL_TSV6Table: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkTWL_TSV6Table: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkTWL_TSV6Table: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkTWL_TSV6Table: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkTWL_TSV6Table: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(givenLocation !== undefined, "checkTWL_TSV6Table: 'givenLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkTWL_TSV6Table: 'givenLocation' parameter should be a string not a '${typeof givenLocation}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -53,20 +54,24 @@ export async function checkTWL_TSV6Table(languageCode, repoCode, bookID, filenam } function addNoticePartial(noticeObject) { // functionLog(`checkTWL_TSV6Table notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "ATSV addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "ATSV addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(C !== undefined, "ATSV addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); - // parameterAssert(V !== undefined, "ATSV addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); - // parameterAssert(characterIndex !== undefined, "ATSV addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "ATSV addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "ATSV addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "ATSV addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `TSV addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "ATSV addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `TSV addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(C !== undefined, "ATSV addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `TSV addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); + } + // //parameterAssert(V !== undefined, "ATSV addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `TSV addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); + } + // //parameterAssert(characterIndex !== undefined, "ATSV addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `TSV addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "ATSV addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `TSV addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "ATSV addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `TSV addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkTWL_TSV6Table ${noticeObject.debugChain}`; carResult.noticeList.push({ ...noticeObject, bookID, filename, repoCode }); @@ -92,9 +97,9 @@ export async function checkTWL_TSV6Table(languageCode, repoCode, bookID, filenam if (bookID === 'OBS') numChaptersThisBook = 50; // There's 50 Open Bible Stories else { - parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkTWL_TSV6Table"); + //parameterAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in checkTWL_TSV6Table"); try { - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch { if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. diff --git a/src/core/twl-tsv6-table-check.md b/src/core/twl-tsv6-table-check.md index 20aecb718..0b183b723 100644 --- a/src/core/twl-tsv6-table-check.md +++ b/src/core/twl-tsv6-table-check.md @@ -7,12 +7,14 @@ It returns a list of success messages and a list of notice components. (There is These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import React, { useState, useEffect } from 'react'; import { checkTWL_TSV6Table } from './twl-tsv6-table-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // Text samples const textA = `Reference\tID\tTags\tOrigWords\tOccurrence\tTWLink diff --git a/src/core/usfm-js-check.js b/src/core/usfm-js-check.js index b3c0c3bf8..f665cb079 100644 --- a/src/core/usfm-js-check.js +++ b/src/core/usfm-js-check.js @@ -1,5 +1,7 @@ import { toJSON } from 'usfm-js'; +// eslint-disable-next-line no-unused-vars import * as books from '../core/books/books'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -31,17 +33,17 @@ export function checkUSFMToJSON(bookID, filename, givenText, givenLocation, chec Returns a result object containing a successList and a noticeList */ // functionLog(`checkUSFMToJSON(${givenText.length.toLocaleString()} chars, '${givenLocation}')…`); - parameterAssert(bookID !== undefined, "checkUSFMToJSON: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkUSFMToJSON: 'bookID' parameter should be a string not a '${typeof bookID}': ${bookID}`); - parameterAssert(bookID.length === 3, `checkUSFMToJSON: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkUSFMToJSON: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(books.isValidBookID(bookID), `checkUSFMToJSON: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(filename !== undefined, "checkUSFMToJSON: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `checkUSFMToJSON: 'filename' parameter should be a string not a '${typeof filename}': ${filename}`); - parameterAssert(givenText !== undefined, "checkUSFMToJSON: 'givenText' parameter should be defined"); - parameterAssert(typeof givenText === 'string', `checkUSFMToJSON: 'givenText' parameter should be a string not a '${typeof givenText}': ${givenText}`); - parameterAssert(givenLocation !== undefined, "checkUSFMToJSON: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkUSFMToJSON: 'givenRowLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(bookID !== undefined, "checkUSFMToJSON: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkUSFMToJSON: 'bookID' parameter should be a string not a '${typeof bookID}': ${bookID}`); + //parameterAssert(bookID.length === 3, `checkUSFMToJSON: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkUSFMToJSON: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(books.isValidBookID(bookID), `checkUSFMToJSON: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(filename !== undefined, "checkUSFMToJSON: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `checkUSFMToJSON: 'filename' parameter should be a string not a '${typeof filename}': ${filename}`); + //parameterAssert(givenText !== undefined, "checkUSFMToJSON: 'givenText' parameter should be defined"); + //parameterAssert(typeof givenText === 'string', `checkUSFMToJSON: 'givenText' parameter should be a string not a '${typeof givenText}': ${givenText}`); + //parameterAssert(givenLocation !== undefined, "checkUSFMToJSON: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkUSFMToJSON: 'givenRowLocation' parameter should be a string not a '${typeof givenLocation}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -64,16 +66,18 @@ export function checkUSFMToJSON(bookID, filename, givenText, givenLocation, chec * @param {string} location - description of where the issue is located */ // functionLog(`checkUSFMToJSON notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(priority !== undefined, "cUSFMjs addNotice6to7: 'priority' parameter should be defined"); - parameterAssert(typeof priority === 'number', `cUSFMjs addNotice6to7: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); - parameterAssert(message !== undefined, "cUSFMjs addNotice6to7: 'message' parameter should be defined"); - parameterAssert(typeof message === 'string', `cUSFMjs addNotice6to7: 'message' parameter should be a string not a '${typeof message}': ${message}`); - // parameterAssert(characterIndex !== undefined, "cUSFMjs addNotice6to7: 'characterIndex' parameter should be defined"); - if (characterIndex) parameterAssert(typeof characterIndex === 'number', `cUSFMjs addNotice6to7: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); - // parameterAssert(excerpt !== undefined, "cUSFMjs addNotice6to7: 'excerpt' parameter should be defined"); - if (excerpt) parameterAssert(typeof excerpt === 'string', `cUSFMjs addNotice6to7: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${excerpt}`); - parameterAssert(location !== undefined, "cUSFMjs addNotice6to7: 'location' parameter should be defined"); - parameterAssert(typeof location === 'string', `cUSFMjs addNotice6to7: 'location' parameter should be a string not a '${typeof location}': ${location}`); + //parameterAssert(priority !== undefined, "cUSFMjs addNotice6to7: 'priority' parameter should be defined"); + //parameterAssert(typeof priority === 'number', `cUSFMjs addNotice6to7: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); + //parameterAssert(message !== undefined, "cUSFMjs addNotice6to7: 'message' parameter should be defined"); + //parameterAssert(typeof message === 'string', `cUSFMjs addNotice6to7: 'message' parameter should be a string not a '${typeof message}': ${message}`); + // //parameterAssert(characterIndex !== undefined, "cUSFMjs addNotice6to7: 'characterIndex' parameter should be defined"); + if (characterIndex) { //parameterAssert(typeof characterIndex === 'number', `cUSFMjs addNotice6to7: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cUSFMjs addNotice6to7: 'excerpt' parameter should be defined"); + if (excerpt) { //parameterAssert(typeof excerpt === 'string', `cUSFMjs addNotice6to7: 'excerpt' parameter should be a string not a '${typeof excerpt}': ${excerpt}`); + } + //parameterAssert(location !== undefined, "cUSFMjs addNotice6to7: 'location' parameter should be defined"); + //parameterAssert(typeof location === 'string', `cUSFMjs addNotice6to7: 'location' parameter should be a string not a '${typeof location}': ${location}`); result.noticeList.push({ priority, message, bookID, lineNumber, characterIndex, excerpt, location }); } diff --git a/src/core/usfm-js-check.md b/src/core/usfm-js-check.md index e1cd93ad5..7829bcaf2 100644 --- a/src/core/usfm-js-check.md +++ b/src/core/usfm-js-check.md @@ -9,11 +9,13 @@ Our packaged function returns a list of success messages and a list of (prioriti These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkUSFMToJSON } from './usfm-js-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderNumberedLines, RenderRawResults } from '../demos/RenderProcessedResults'; // USFM samples const textS = `\\id GEN Short test @@ -187,7 +189,7 @@ const chosenText = textH; const rawResults = checkUSFMToJSON('GEN', chosenTextName, chosenText, 'that was supplied'); <> -Check +Check ``` diff --git a/src/core/usfm-text-check.js b/src/core/usfm-text-check.js index 275278eb2..beabe3246 100644 --- a/src/core/usfm-text-check.js +++ b/src/core/usfm-text-check.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { isWhitespace, countOccurrences, ourDeleteAll } from './text-handling-functions' import * as books from '../core/books/books'; @@ -6,18 +7,19 @@ import { checkTextfileContents } from './file-text-check'; import { runUsfmJsCheck } from './usfm-js-check'; import { runBCSGrammarCheck } from './BCS-usfm-grammar-check'; import { checkNotesLinksToOutside } from './notes-links-check'; -import { userLog, parameterAssert, logicAssert, dataAssert, ourParseInt } from './utilities'; +// eslint-disable-next-line no-unused-vars +import { userLog, functionLog, debugLog, parameterAssert, logicAssert, dataAssert, ourParseInt } from './utilities'; import { removeDisabledNotices } from './disabled-notices'; -// const USFM_VALIDATOR_VERSION_STRING = '0.8.8'; +// const USFM_VALIDATOR_VERSION_STRING = '0.8.15'; -const VALID_LINE_START_CHARACTERS = `([“‘`; // '{' gets added for STs +const VALID_LINE_START_CHARACTERS = `([“‘—`; // Last one is em-dash — '{' gets added later for STs // See http://ubsicap.github.io/usfm/master/index.html -const COMPULSORY_MARKERS = ['id', 'ide']; -const EXPECTED_MARKERS = ['usfm', 'mt1']; +// const COMPULSORY_MARKERS = ['id', 'ide']; // These are specifically checked for by the code near the start of mainUSFMCheck() +const EXPECTED_MARKERS = ['usfm', 'mt1']; // The check also allows for removal of the final '1' const EXPECTED_BIBLE_BOOK_MARKERS = ['h', 'toc1', 'toc2', 'toc3']; const EXPECTED_PERIPHERAL_BOOK_MARKERS = ['periph']; @@ -52,7 +54,7 @@ const PARAGRAPH_MARKERS = ['p', 'po', 'pm', 'ph', 'ph1', 'ph2', 'ph3', 'ph4', 'tr']; -const NOTE_MARKERS = ['f', 'x']; +const MAIN_NOTE_MARKERS = ['f', 'x']; const SPECIAL_MARKERS = ['w', 'zaln-s', 'k-s', 'qt-s', 'qt1-s', 'qt2-s', 'lit']; @@ -60,15 +62,15 @@ const MILESTONE_MARKERS = ['ts\\*', 'ts-s', 'ts-e', 'k-e\\*']; // Is this a good const MARKERS_WITHOUT_CONTENT = ['b', 'nb', 'ib', 'ie'].concat(MILESTONE_MARKERS); const ALLOWED_LINE_START_MARKERS = [].concat(INTRO_LINE_START_MARKERS).concat(HEADING_TYPE_MARKERS) .concat(CV_MARKERS).concat(PARAGRAPH_MARKERS) - .concat(NOTE_MARKERS).concat(SPECIAL_MARKERS).concat(MARKERS_WITHOUT_CONTENT) - .concat(MILESTONE_MARKERS); + .concat(MAIN_NOTE_MARKERS).concat(SPECIAL_MARKERS).concat(MARKERS_WITHOUT_CONTENT) + .concat(MILESTONE_MARKERS).concat(['qs']); const DEPRECATED_MARKERS = [ 'h1', 'h2', 'h3', 'h4', 'pr', 'ph', 'ph1', 'ph2', 'ph3', 'ph4', 'addpn', 'pro', 'fdc', 'xdc']; const MARKERS_WITH_COMPULSORY_CONTENT = [].concat(INTRO_LINE_START_MARKERS).concat(HEADING_TYPE_MARKERS) - .concat(CV_MARKERS).concat(NOTE_MARKERS).concat(SPECIAL_MARKERS); + .concat(CV_MARKERS).concat(MAIN_NOTE_MARKERS).concat(SPECIAL_MARKERS); const FOOTNOTE_INTERNAL_MARKERS = ['fr', 'fq', 'fqa', 'fk', 'fl', 'fw', 'fp', 'fv', 'ft', 'fdc', 'fm', 'xt']; const XREF_INTERNAL_MARKERS = ['xo', 'xk', 'xq', 'xt', 'xta', 'xop', 'xot', 'xnt', 'xdc', 'rq']; const SIMPLE_CHARACTER_MARKERS = ['add', 'bk', 'dc', 'k', 'nd', 'ord', 'pn', 'png', 'addpn', @@ -85,7 +87,7 @@ const CANONICAL_TEXT_MARKERS = ['d'].concat(PARAGRAPH_MARKERS).concat(CHARACTER_ // eslint-disable-next-line no-unused-vars const ANY_TEXT_MARKERS = [].concat(INTRO_LINE_START_MARKERS).concat(HEADING_TYPE_MARKERS) .concat(PARAGRAPH_MARKERS).concat(CHARACTER_MARKERS) - .concat(NOTE_MARKERS).concat(SPECIAL_MARKERS); + .concat(MAIN_NOTE_MARKERS).concat(SPECIAL_MARKERS); const MATCHED_CHARACTER_FORMATTING_PAIRS = [ ['\\add ', '\\add*'], ['\\addpn ', '\\addpn*'], ['\\bd ', '\\bd*'], ['\\bdit ', '\\bdit*'], @@ -112,7 +114,7 @@ const MATCHED_CHARACTER_FORMATTING_PAIRS = [ ['\\sls ', '\\sls*'], ['\\sup ', '\\sup*'], ['\\tl ', '\\tl*'], - ['\\w ', '\\w*'], + ['\\w ', '\\w*'], // Note that we also have \+w and \+w* in our files ['\\wa ', '\\wa*'], ['\\wg ', '\\wg*'], ['\\wh ', '\\wh*'], ['\\wj ', '\\wj*'], @@ -121,11 +123,13 @@ const MATCHED_CHARACTER_FORMATTING_PAIRS = [ ['\\f ', '\\f*'], ['\\x ', '\\x*'], ]; -const W_REGEX = new RegExp('\\\\w ([^\\\\]+?)\\\\w\\*', 'g'); +const W_REGEX = new RegExp('\\\\\\+?w ([^\\\\]+?)\\\\\\+?w\\*', 'g'); // \w ...\w* or \+w ...\+w* const ZALNS_REGEX = new RegExp('\\\\zaln-s (.+?)\\\\\\*', 'g'); const KS_REGEX = new RegExp('\\\\k-s (.+?)\\\\\\*', 'g'); const ATTRIBUTE_REGEX = new RegExp('[ |]([^ |]+?)="([^"]*?)"', 'g'); +const HEBREW_CANTILLATION_REGEX = new RegExp('[֑֖֛֢֣֤֥֦֧֪֚֭֮֒֓֔֕֗֘֙֜֝֞֟֠֡֨֩֫֬֯]', 'g'); // There's 31 accent marks in there +const BAD_HEBREW_VOWEL_DAGESH_REGEX = new RegExp('[\\u05b4\\u05b5\\u05b6\\u05b7\\u05b8\\u05b9\\u05ba\\05bb]\\u05bc', 'g'); /** @@ -138,7 +142,7 @@ const ATTRIBUTE_REGEX = new RegExp('[ |]([^ |]+?)="([^"]*?)"', 'g'); * @param {string} givenLocation * @param {Object} checkingOptions */ -export function checkUSFMText(languageCode, repoCode, bookID, filename, givenText, givenLocation, checkingOptions) { +export async function checkUSFMText(languageCode, repoCode, bookID, filename, givenText, givenLocation, checkingOptions) { /* This function is optimised for checking the entire file, i.e., all lines. bookID is a three-character UPPERCASE USFM book identifier. @@ -148,21 +152,24 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex Returns a result object containing a successList and a noticeList */ // functionLog(`checkUSFMText(${languageCode}, ${repoCode}, ${bookID}, ${filename}, ${givenText.length.toLocaleString()} chars, '${givenLocation}', ${JSON.stringify(checkingOptions)})…`); - parameterAssert(languageCode !== undefined, "checkUSFMText: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkUSFMText: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); - parameterAssert(repoCode !== undefined, "checkUSFMText: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkUSFMText: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkUSFMText: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(bookID !== undefined, "checkUSFMText: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkUSFMText: 'bookID' parameter should be a string not a '${typeof bookID}'`); - parameterAssert(bookID.length === 3, `checkUSFMText: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkUSFMText: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkUSFMText: '${bookID}' is not a valid USFM book identifier`); - parameterAssert(filename !== undefined, "checkUSFMText: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `checkUSFMText: 'filename' parameter should be a string not a '${typeof filename}'`); - parameterAssert(givenLocation !== undefined, "checkUSFMText: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkUSFMText: 'givenRowLocation' parameter should be a string not a '${typeof givenLocation}'`); - parameterAssert(checkingOptions !== undefined, "checkUSFMText: 'checkingOptions' parameter should be defined"); + // const match = HEBREW_CANTILLATION_REGEX.exec('\\f + \\ft Q \\+w הִנֵּ֤ה|lemma="הִנֵּ֤ה" strong="H2009" x-morph="He,Tm"\\+w*\\f*'); + // console.log(`Got test cantillation match: ${typeof match} ${match.length} '${JSON.stringify(match)}'`); + + //parameterAssert(languageCode !== undefined, "checkUSFMText: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkUSFMText: 'languageCode' parameter should be a string not a '${typeof languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkUSFMText: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkUSFMText: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkUSFMText: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(bookID !== undefined, "checkUSFMText: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkUSFMText: 'bookID' parameter should be a string not a '${typeof bookID}'`); + //parameterAssert(bookID.length === 3, `checkUSFMText: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkUSFMText: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkUSFMText: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(filename !== undefined, "checkUSFMText: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `checkUSFMText: 'filename' parameter should be a string not a '${typeof filename}'`); + //parameterAssert(givenLocation !== undefined, "checkUSFMText: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkUSFMText: 'givenRowLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(checkingOptions !== undefined, "checkUSFMText: 'checkingOptions' parameter should be defined"); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -195,25 +202,30 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex function addNoticePartial(noticeObject) { // debugLog("checkUSFMText addNoticePartial:", JSON.stringify(noticeObject)); // functionLog(`checkUSFMText addNoticePartial: (priority=${noticeObject.priority}) ${noticeObject.C}:${noticeObject.V} ${noticeObject.message}${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? ` ${noticeObject.excerpt}` : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cUSFM addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cUSFM addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cUSFM addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cUSFM addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(C !== undefined, "cUSFM addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `cUSFM addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); - // parameterAssert(V !== undefined, "cUSFM addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `cUSFM addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); - // parameterAssert(characterIndex !== undefined, "cUSFM addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex !== undefined) parameterAssert(typeof noticeObject.characterIndex === 'number', `cUSFM addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cUSFM addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cUSFM addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cUSFM addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cUSFM addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cUSFM addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cUSFM addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cUSFM addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cUSFM addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(C !== undefined, "cUSFM addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `cUSFM addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); + } + // //parameterAssert(V !== undefined, "cUSFM addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `cUSFM addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); + } + // //parameterAssert(characterIndex !== undefined, "cUSFM addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex !== undefined) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cUSFM addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt !== undefined, "cUSFM addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cUSFM addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cUSFM addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cUSFM addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); // Doublecheck -- we don’t want "Mismatched {}" per line, only per file + // eslint-disable-next-line no-unused-vars const noticeObjectString = JSON.stringify(noticeObject); - parameterAssert(noticeObject.message.indexOf("Mismatched {}") === -1 || noticeObject.lineNumber === undefined, `checkUSFMText addNoticePartial: got bad notice: ${noticeObjectString}`); - parameterAssert(noticeObjectString.indexOf('NONE') === -1 && noticeObjectString.indexOf('SPECIAL') === -1, `checkUSFMText addNoticePartial: 'NONE' & 'SPECIAL' shouldn't make it thru to end user: ${noticeObjectString}`) + //parameterAssert(noticeObject.message.indexOf("Mismatched {}") === -1 || noticeObject.lineNumber === undefined, `checkUSFMText addNoticePartial: got bad notice: ${noticeObjectString}`); + //parameterAssert(noticeObjectString.indexOf('NONE') === -1 && noticeObjectString.indexOf('SPECIAL') === -1, `checkUSFMText addNoticePartial: 'NONE' & 'SPECIAL' shouldn't make it thru to end user: ${noticeObjectString}`) if (noticeObject.debugChain) noticeObject.debugChain = `checkUSFMText ${noticeObject.debugChain}`; result.noticeList.push({ ...noticeObject, bookID, filename }); } @@ -222,9 +234,9 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex function ourRunBCSGrammarCheck(filename, fileText, fileLocation) { // Runs the BCS USFM Grammar checker // which can be quite time-consuming on large, complex USFM files - // debugLog("Running our BCS USFM grammar check (can take quite a while for a large book)…"); + // functionLog("Running our BCS USFM grammar check (can take quite a while for a large book)…"); - const grammarCheckResult = runBCSGrammarCheck('strict', fileText, filename, fileLocation, checkingOptions); + const grammarCheckResult = runBCSGrammarCheck('strict', bookID, fileText, filename, fileLocation, checkingOptions); // NOTE: We haven’t figured out how to get ERRORS out of this parser yet // debugLog(` Finished our BCS USFM grammar check with ${grammarCheckResult.isValidUSFM} and ${grammarCheckResult.warnings.length} warnings.`); addSuccessMessage(`Checked USFM Grammar (strict mode) ${grammarCheckResult.isValidUSFM ? "without errors" : " (but the USFM DIDN’T validate)"}`); @@ -253,7 +265,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex addNoticePartial({ priority: 102, message: `USFMGrammar: ${warningString}`, location: fileLocation }); if (!grammarCheckResult.isValidUSFM) { - const relaxedGrammarCheckResult = runBCSGrammarCheck('relaxed', fileText, filename, fileLocation); + const relaxedGrammarCheckResult = runBCSGrammarCheck('relaxed', bookID, fileText, filename, fileLocation); addSuccessMessage(`Checked USFM Grammar (relaxed mode) ${relaxedGrammarCheckResult.isValidUSFM ? "without errors" : " (but the USFM DIDN’T validate)"}`); if (!relaxedGrammarCheckResult.isValidUSFM) addNoticePartial({ priority: 644, message: "USFM3 Grammar Check (relaxed mode) doesn’t pass either", location: fileLocation }); @@ -279,9 +291,9 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex Note that this code below does NOT check for chapters and verses being in the correct order. That’s done elsewhere. */ - // debugLog("Running CVCheck() using USFM-JS (can take quite a while for a large book)…"); - let chapterNumberString, verseNumberString; + // functionLog(`Running CVCheck(${bookID}, ${givenText.length}, ${CVlocation}) using USFM-JS (can take quite a while for a large book)…`); + let chapterNumberString, verseNumberString; const MINIMUM_TEXT_WORDS = 4; const MINIMUM_WORD_LENGTH = 2; @@ -398,7 +410,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex let expectedVersesPerChapterList = []; try { logicAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in usfm-text-check1"); - expectedVersesPerChapterList = books.chaptersInBook(lowercaseBookID); // A list of integers -- numVerses for each chapter + expectedVersesPerChapterList = books.expectedVersesPerChapterList(bookID); // A list of integers -- numVerses for each chapter // debugLog("Got chapterList", JSON.stringify(expectedVersesPerChapterList)); } catch { } @@ -482,7 +494,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex } } } - addSuccessMessage(`Checked CV patterns for ${bookID}${CVlocation}`); + addSuccessMessage(`Checked C:V patterns for ${bookID}${CVlocation}`); } // end of CVCheck function @@ -506,23 +518,23 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // Updates the global list of notices // debugLog(`cUSFM ourCheckTextField(${lineNumber}, ${C}:${V}, ${fieldName}, (${fieldText.length} chars), ${allowedLinks}, ${fieldLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(lineNumber !== undefined, "cUSFM ourCheckTextField: 'lineNumber' parameter should be defined"); - parameterAssert(typeof lineNumber === 'number', `cUSFM ourCheckTextField: 'lineNumber' parameter should be a number not a '${typeof lineNumber}'`); - parameterAssert(C !== undefined, "cUSFM ourCheckTextField: 'C' parameter should be defined"); - parameterAssert(typeof C === 'string', `cUSFM ourCheckTextField: 'C' parameter should be a string not a '${typeof C}'`); - parameterAssert(V !== undefined, "cUSFM ourCheckTextField: 'V' parameter should be defined"); - parameterAssert(typeof V === 'string', `cUSFM ourCheckTextField: 'V' parameter should be a string not a '${typeof V}'`); - parameterAssert(fieldType !== undefined, "cUSFM ourCheckTextField: 'fieldType' parameter should be defined"); - parameterAssert(typeof fieldType === 'string', `cUSFM ourCheckTextField: 'fieldType' parameter should be a string not a '${typeof fieldType}'`); - parameterAssert(fieldType === 'USFM' || fieldType === 'raw', `cUSFM ourCheckTextField: Unrecognized 'fieldType' parameter: ${fieldType}`); - parameterAssert(fieldName !== undefined, "cUSFM ourCheckTextField: 'fieldName' parameter should be defined"); - parameterAssert(typeof fieldName === 'string', `cUSFM ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); - parameterAssert(fieldName !== '', `cUSFM ourCheckTextField: ${fieldType} 'fieldName' parameter should be not be an empty string`); - parameterAssert(fieldText !== undefined, "cUSFM ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `cUSFM ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "cUSFM ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(fieldLocation !== undefined, "cUSFM ourCheckTextField: 'fieldLocation' parameter should be defined"); - parameterAssert(typeof fieldLocation === 'string', `cUSFM ourCheckTextField: 'fieldLocation' parameter should be a string not a '${typeof fieldLocation}'`); + //parameterAssert(lineNumber !== undefined, "cUSFM ourCheckTextField: 'lineNumber' parameter should be defined"); + //parameterAssert(typeof lineNumber === 'number', `cUSFM ourCheckTextField: 'lineNumber' parameter should be a number not a '${typeof lineNumber}'`); + //parameterAssert(C !== undefined, "cUSFM ourCheckTextField: 'C' parameter should be defined"); + //parameterAssert(typeof C === 'string', `cUSFM ourCheckTextField: 'C' parameter should be a string not a '${typeof C}'`); + //parameterAssert(V !== undefined, "cUSFM ourCheckTextField: 'V' parameter should be defined"); + //parameterAssert(typeof V === 'string', `cUSFM ourCheckTextField: 'V' parameter should be a string not a '${typeof V}'`); + //parameterAssert(fieldType !== undefined, "cUSFM ourCheckTextField: 'fieldType' parameter should be defined"); + //parameterAssert(typeof fieldType === 'string', `cUSFM ourCheckTextField: 'fieldType' parameter should be a string not a '${typeof fieldType}'`); + //parameterAssert(fieldType === 'USFM' || fieldType === 'raw', `cUSFM ourCheckTextField: Unrecognized 'fieldType' parameter: ${fieldType}`); + //parameterAssert(fieldName !== undefined, "cUSFM ourCheckTextField: 'fieldName' parameter should be defined"); + //parameterAssert(typeof fieldName === 'string', `cUSFM ourCheckTextField: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + //parameterAssert(fieldName !== '', `cUSFM ourCheckTextField: ${fieldType} 'fieldName' parameter should be not be an empty string`); + //parameterAssert(fieldText !== undefined, "cUSFM ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `cUSFM ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "cUSFM ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(fieldLocation !== undefined, "cUSFM ourCheckTextField: 'fieldLocation' parameter should be defined"); + //parameterAssert(typeof fieldLocation === 'string', `cUSFM ourCheckTextField: 'fieldLocation' parameter should be a string not a '${typeof fieldLocation}'`); const dbtcResultObject = checkTextField(languageCode, repoCode, fieldType, fieldName, fieldText, allowedLinks, fieldLocation, checkingOptions); @@ -544,11 +556,11 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // We assume that checking for compulsory fields is done elsewhere // Updates the global list of notices - parameterAssert(filename !== undefined, "cUSFM ourBasicFileChecks: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `cUSFM ourBasicFileChecks: 'filename' parameter should be a string not a '${typeof filename}'`); - parameterAssert(fileText !== undefined, "cUSFM ourBasicFileChecks: 'fileText' parameter should be defined"); - parameterAssert(typeof fileText === 'string', `cUSFM ourBasicFileChecks: 'fileText' parameter should be a string not a '${typeof fileText}'`); - parameterAssert(checkingOptions !== undefined, "cUSFM ourBasicFileChecks: 'checkingOptions' parameter should be defined"); + //parameterAssert(filename !== undefined, "cUSFM ourBasicFileChecks: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `cUSFM ourBasicFileChecks: 'filename' parameter should be a string not a '${typeof filename}'`); + //parameterAssert(fileText !== undefined, "cUSFM ourBasicFileChecks: 'fileText' parameter should be defined"); + //parameterAssert(typeof fileText === 'string', `cUSFM ourBasicFileChecks: 'fileText' parameter should be a string not a '${typeof fileText}'`); + //parameterAssert(checkingOptions !== undefined, "cUSFM ourBasicFileChecks: 'checkingOptions' parameter should be defined"); const resultObject = checkTextfileContents(languageCode, repoCode, 'USFM', filename, fileText, fileLocation, checkingOptions); @@ -590,6 +602,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // and close ')' in another. So the USFM line check can’t check that. // Also, the USFM v3.0 spec seems to allow/require whitespace reduction, // i.e., newLines can conceivably appear WITHIN a footnote for example. + // functionLog(`checkUSFMFileContents(${filename}, ${fileText.length}, ${markerSet}, ${fileLocation}, ${JSON.stringify(checkingOptions)})…`); // Check markers like \add ... \add*, \f .. \f* checkUSFMCharacterFields(filename, fileText, fileLocation) @@ -597,13 +610,15 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // Now do the general global checks (e.g., for general punctuation) ourBasicFileChecks(filename, fileText, fileLocation, checkingOptions); - for (const compulsoryMarker of COMPULSORY_MARKERS) - if (!markerSet.has(compulsoryMarker)) - addNoticePartial({ priority: 819, message: "Missing compulsory USFM line", excerpt: `missing \\${compulsoryMarker}`, location: fileLocation }); + // Handled elsewhere + // for (const compulsoryMarker of COMPULSORY_MARKERS) + // if (!markerSet.has(compulsoryMarker)) + // addNoticePartial({ priority: 819, message: "Missing compulsory USFM line", excerpt: `missing \\${compulsoryMarker}`, location: fileLocation }); for (const expectedMarker of EXPECTED_MARKERS) if (!markerSet.has(expectedMarker) && (!expectedMarker.endsWith('1') || !markerSet.has(expectedMarker.substring(0, expectedMarker.length - 1)))) - addNoticePartial({ priority: 519, message: "Missing expected USFM line", excerpt: `missing \\${expectedMarker}`, location: fileLocation }); + // NOTE: \mt(1) is required by Proskomma so increased this priority + addNoticePartial({ priority: expectedMarker === 'mt1' ? 921 : 519, message: "Missing expected USFM line", excerpt: `missing \\${expectedMarker}`, location: fileLocation }); if (books.isExtraBookID(bookID)) for (const expectedMarker of EXPECTED_PERIPHERAL_BOOK_MARKERS) if (!markerSet.has(expectedMarker)) @@ -636,6 +651,19 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex const details = `line marker='\\${marker}'` + // Check for invalid character combinations + if (languageCode === 'hbo') { + // TODO: How should we check other potential bad combinations + const match = BAD_HEBREW_VOWEL_DAGESH_REGEX.exec(rest); + if (match) { // it's null if no matches + // debugLog(`Got bad dagesh after vowel character order match: ${typeof match} ${match.length} '${JSON.stringify(match)}'`); + const characterIndex = rest.indexOf(match[0][0]); + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + rest.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus) + (characterIndex + excerptHalfLengthPlus < rest.length ? '…' : '') + addNoticePartial({ priority: 805, message: "Unexpected Hebrew dagesh after vowel", details: `Found ${match.length} '${match}'`, lineNumber, C, V, characterIndex, excerpt, location: lineLocation }); + } + + } + // Check that no \w markers touch, i.e., shouldn't have '\w*\w' in file let characterIndex; if ((characterIndex = rest.indexOf('\\w*\\w')) !== -1) { @@ -649,6 +677,18 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex } } + // Check that no \f or \x markers follow a space + if ((characterIndex = rest.indexOf(' \\f ')) !== -1) { + const badCount = countOccurrences(rest, ' \\f '); + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + rest.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < rest.length ? '…' : '') + addNoticePartial({ priority: 443, message: "Shouldn’t have a footnote after a space", details: badCount > 1 ? details + `${badCount} occurrences found in line` : details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation }); + } + if ((characterIndex = rest.indexOf(' \\x ')) !== -1) { + const badCount = countOccurrences(rest, ' \\x '); + const excerpt = (characterIndex > excerptHalfLength ? '…' : '') + rest.substring(characterIndex - excerptHalfLength, characterIndex + excerptHalfLengthPlus).replace(/ /g, '␣') + (characterIndex + excerptHalfLengthPlus < rest.length ? '…' : '') + addNoticePartial({ priority: 442, message: "Shouldn’t have a cross-reference after a space", details: badCount > 1 ? details + `${badCount} occurrences found in line` : details, lineNumber, C, V, characterIndex, excerpt, location: lineLocation }); + } + // Remove any self-closed milestones and internal \v markers // NOTE: replaceAll() is not generally available in browsers yet, so need to use RegExps let adjustedRest = rest.replace(/\\zaln-e\\\*/g, '').replace(/\\ts\\\*/g, '').replace(/\\k-e\\\*/g, '') @@ -756,11 +796,11 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex adjustedRest = ''; // Avoid follow-on errors break; } - dataAssert(ixWordEnd > nextWIndex + 3, `Why2 is +w| = ${ixWordEnd}? nextWIndex=${nextWIndex} ${languageCode} ${bookID} ${C}:${V} ${lineNumber}`); + dataAssert(ixWordEnd > nextWIndex + 4, `Why2 is +w| = ${ixWordEnd}? nextWIndex=${nextWIndex} ${languageCode} ${bookID} ${C}:${V} ${lineNumber}`); const ixWEnd = adjustedRest.indexOf('\\+w*'); if (ixWEnd >= 0) { dataAssert(ixWEnd > nextWIndex, `Expected closure at ${ixWEnd} to be AFTER \\+w (${nextWIndex})`); - adjustedRest = adjustedRest.substring(0, nextWIndex) + adjustedRest.substring(nextWIndex + 3, ixWordEnd) + adjustedRest.substring(ixWEnd + 3, adjustedRest.length); + adjustedRest = adjustedRest.substring(0, nextWIndex) + adjustedRest.substring(nextWIndex + 4, ixWordEnd) + adjustedRest.substring(ixWEnd + 4, adjustedRest.length); // debugLog(`After removing w field, got '${adjustedRest}'`); } else { userLog(`\\+w seems unclosed: 'adjustedRest' from '${rest}'`); @@ -819,7 +859,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex * @param {string} lineLocation * @param {Object} checkingOptions */ - function checkUSFMLineAttributes(lineNumber, C, V, marker, rest, lineLocation, checkingOptions) { + async function checkUSFMLineAttributes(lineNumber, C, V, marker, rest, lineLocation, checkingOptions) { // Looks for USFM fields with attributes, e.g., \w, \zaln-s, \k-s // functionLog(`checkUSFMLineAttributes(${lineNumber}, ${C}:${V}, ${marker}='${rest}', ${lineLocation}, ${JSON.stringify(checkingOptions)})…`); // functionLog(`checkUSFMLineAttributes(${lineNumber}, ${C}:${V}, ${marker}=${rest.length} chars, ${lineLocation}, ${JSON.stringify(checkingOptions)})…`); @@ -836,50 +876,59 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // dataAssert(countOccurrences(adjustedRest, '\\zaln-s ') === countOccurrences(adjustedRest, '\\zaln-s*'), `checkUSFMLineAttributes expected all \\zaln-s fields to be closed in ${adjustedRest}`); // dataAssert(countOccurrences(adjustedRest, '\\k-s ') === countOccurrences(adjustedRest, '\\k-s*'), `checkUSFMLineAttributes expected all \\k-s fields to be closed in ${adjustedRest}`); - let regexResultArray1, regexResultArray2; - while ((regexResultArray1 = W_REGEX.exec(adjustedRest))) { - // debugLog(`Got ${repoCode} \\w Regex in ${C}:${V} line: '${JSON.stringify(regexResultArray1)}`); - let attributeCounter = 0; - while ((regexResultArray2 = ATTRIBUTE_REGEX.exec(regexResultArray1[1]))) { + /** + * + * @param {string} wContents + */ + async function checkWAttributes(wContents) { + // functionLog(`checkWAttributes(${wContents})…`); + let regexResultArray, attributeCounter = 0; + while ((regexResultArray = ATTRIBUTE_REGEX.exec(wContents))) { attributeCounter += 1; // debugLog(` Got attribute Regex in \\w: ${attributeCounter} '${JSON.stringify(regexResultArray2)}`); - const attributeName = regexResultArray2[1], attributeValue = regexResultArray2[2]; + const attributeName = regexResultArray[1], attributeValue = regexResultArray[2]; if (repoCode === 'UHB' || repoCode === 'UGNT') { if (attributeCounter === 1) { if (attributeName !== 'lemma') - addNoticePartial({ priority: 857, message: "Unexpected first original \\w attribute", details: "expected 'lemma'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 857, message: "Unexpected first original \\w attribute", details: "expected 'lemma'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else if (attributeCounter === 2) { if (attributeName !== 'strong') - addNoticePartial({ priority: 856, message: "Unexpected second original \\w attribute", details: "expected 'strong'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 856, message: "Unexpected second original \\w attribute", details: "expected 'strong'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else if (attributeCounter === 3) { if (attributeName !== 'x-morph') - addNoticePartial({ priority: 855, message: "Unexpected third original \\w attribute", details: "expected 'x-morph'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 855, message: "Unexpected third original \\w attribute", details: "expected 'x-morph'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else if (attributeCounter === 4) { if (attributeName !== 'x-tw') // we can have TWO of these -- THREE EVEN in EXO 15:23 and 1KI 21:9!!! - addNoticePartial({ priority: 854, message: "Unexpected fourth original \\w attribute", details: "expected 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 854, message: "Unexpected fourth original \\w attribute", details: "expected 'x-tw'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else if (attributeCounter === 5) { if (attributeName !== 'x-tw') - addNoticePartial({ priority: 854, message: "Unexpected fifth original \\w attribute", details: "expected second 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 854, message: "Unexpected fifth original \\w attribute", details: "expected second 'x-tw'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else if (attributeCounter === 6) { if (attributeName !== 'x-tw') - addNoticePartial({ priority: 854, message: "Unexpected sixth original \\w attribute", details: "expected third 'x-tw'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 854, message: "Unexpected sixth original \\w attribute", details: "expected third 'x-tw'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else // #7 or more - addNoticePartial({ priority: 853, message: "Unexpected extra original \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); - if (attributeName === 'x-morph' + addNoticePartial({ priority: 853, message: "Unexpected extra original \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); + if (attributeName === 'lemma' && repoCode === 'UHB') { + const match = HEBREW_CANTILLATION_REGEX.exec(attributeValue); + if (match) { // it's null if no matches + // debugLog(`Got cantillation match: ${typeof match} ${match.length} '${JSON.stringify(match)}'`); + addNoticePartial({ priority: 905, message: "Unexpected Hebrew cantillation mark in lemma field", details: `Found ${match.length} '${match}'`, lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); + } + } else if (attributeName === 'x-morph' && ((repoCode === 'UHB' && !attributeValue.startsWith('He,') && !attributeValue.startsWith('Ar,')) || (repoCode === 'UGNT' && !attributeValue.startsWith('Gr,')))) - addNoticePartial({ priority: 852, message: "Unexpected original \\w x-morph language prefix", details: "Expected 'He,' 'Ar,' or 'Gr,'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 852, message: "Unexpected original \\w x-morph language prefix", details: "Expected 'He,' 'Ar,' or 'Gr,'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); else if (attributeName === 'x-tw') - ourCheckNotesLinksToOutside(lineNumber, C, V, marker, attributeValue, lineLocation, checkingOptions); + await ourCheckNotesLinksToOutside(lineNumber, C, V, marker, attributeValue, lineLocation, checkingOptions); } else { // a translation -- not UHB or UGNT if (attributeCounter === 1) { if (attributeName !== 'x-occurrence') - addNoticePartial({ priority: 848, message: "Unexpected first translation \\w attribute", details: "expected 'x-occurrence'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 848, message: "Unexpected first translation \\w attribute", details: "expected 'x-occurrence'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else if (attributeCounter === 2) { if (attributeName !== 'x-occurrences') - addNoticePartial({ priority: 847, message: "Unexpected second translation \\w attribute", details: "expected 'x-occurrences'", lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 847, message: "Unexpected second translation \\w attribute", details: "expected 'x-occurrences'", lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } else // #3 or more - addNoticePartial({ priority: 846, message: "Unexpected extra translation \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray2[0], location: lineLocation }); + addNoticePartial({ priority: 846, message: "Unexpected extra translation \\w attribute", details, lineNumber, C, V, excerpt: regexResultArray[0], location: lineLocation }); } } if (repoCode === 'UHB' || repoCode === 'UGNT') { @@ -888,6 +937,14 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex } else if (attributeCounter < 2) addNoticePartial({ priority: 836, message: "Seems too few translation \\w attributes", details: `Expected two attributes but only found ${attributeCounter}`, lineNumber, C, V, excerpt: regexResultArray1[0], location: lineLocation }); } + // end of checkWAttributes function + + let regexResultArray1; + while ((regexResultArray1 = W_REGEX.exec(adjustedRest))) { + // debugLog(`Got ${repoCode} \\w Regex in ${C}:${V} line: '${JSON.stringify(regexResultArray1)}`); + await checkWAttributes(regexResultArray1[1]); + } + let regexResultArray2; while ((regexResultArray1 = KS_REGEX.exec(adjustedRest))) { // debugLog(`Got ${repoCode} \\k-s Regex in ${C}:${V} line: '${JSON.stringify(regexResultArray1)}`); dataAssert(repoCode === 'UHB' || repoCode === 'UGNT', `checkUSFMLineAttributes expected an original language repo not '${repoCode}'`); @@ -951,11 +1008,11 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex * @param {string} lineLocation * @param {Object} checkingOptions */ - function checkUSFMLineContents(lineNumber, C, V, marker, rest, lineLocation, checkingOptions) { + async function checkUSFMLineContents(lineNumber, C, V, marker, rest, lineLocation, checkingOptions) { // Looks at the marker and determines what content is allowed/expected on the rest of the line // 'SPECIAL' is used internally here when a character other than a backslash starts a line - function checkUSFMLineInternals(lineNumber, C, V, marker, rest, lineLocation, checkingOptions) { + async function checkUSFMLineInternals(lineNumber, C, V, marker, rest, lineLocation, checkingOptions) { // Handles character formatting within the line contents // functionLog(`checkUSFMLineInternals(${lineNumber}, ${C}:${V}, ${marker}='${rest}', ${lineLocation}, ${JSON.stringify(checkingOptions)})…`); @@ -974,7 +1031,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex checkUSFMLineText(lineNumber, C, V, marker, rest, lineLocation, checkingOptions); if (rest.indexOf('=') >= 0 || rest.indexOf('"') >= 0) - checkUSFMLineAttributes(lineNumber, C, V, marker, rest, lineLocation, checkingOptions); + await checkUSFMLineAttributes(lineNumber, C, V, marker, rest, lineLocation, checkingOptions); const allowedLinks = (marker === 'w' || marker === 'k-s' || marker === 'f' || marker === 'SPECIAL') // (because we don’t know what marker SPECIAL is, so default to "no false alarms") @@ -997,7 +1054,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex } else // it’s not a recognised line marker // Lower priority of deprecated \s5 markers (compared to all other unknown markers) addNoticePartial({ priority: marker === 's5' ? 111 : 809, message: `${marker === 's5' ? 'Deprecated' : 'Unexpected'} '\\${marker}' marker at start of line`, C, V, lineNumber, characterIndex: 1, location: lineLocation }); - if (rest) checkUSFMLineInternals(lineNumber, C, V, marker, rest, lineLocation, checkingOptions); + if (rest) await checkUSFMLineInternals(lineNumber, C, V, marker, rest, lineLocation, checkingOptions); } // end of checkUSFMLineContents function @@ -1008,20 +1065,16 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // Updates the global list of notices // functionLog(`checkUSFMText ourCheckNotesLinksToOutside(${lineNumber}, ${C}:${V}, ${marker}, (${twLinkText.length}) '${twLinkText}', ${location}, ${JSON.stringify(checkingOptions)})`); - parameterAssert(marker !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'marker' parameter should be defined"); - parameterAssert(typeof marker === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'marker' parameter should be a string not a '${typeof marker}': ${marker}`); - parameterAssert(twLinkText !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'twLinkText' parameter should be defined"); - parameterAssert(typeof twLinkText === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'twLinkText' parameter should be a string not a '${typeof twLinkText}': ${twLinkText}`); - - // NOTE: This language problem will go away once we move to TSV TWLs - let adjustedLanguageCode = languageCode; - if (languageCode === 'el-x-koine' || languageCode === 'hbo') adjustedLanguageCode = 'en'; // Just a guess for x-tw - const coTNlResultObject = await checkNotesLinksToOutside(adjustedLanguageCode, repoCode, bookID, C, V, 'TWLink', twLinkText, location, { ...checkingOptions, defaultLanguageCode: languageCode }); + //parameterAssert(marker !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'marker' parameter should be defined"); + //parameterAssert(typeof marker === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'marker' parameter should be a string not a '${typeof marker}': ${marker}`); + //parameterAssert(twLinkText !== undefined, "checkUSFMText ourCheckNotesLinksToOutside: 'twLinkText' parameter should be defined"); + //parameterAssert(typeof twLinkText === 'string', `checkUSFMText ourCheckNotesLinksToOutside: 'twLinkText' parameter should be a string not a '${typeof twLinkText}': ${twLinkText}`); + + let adjustedLanguageCode = languageCode; // This is the language code of the resource with the link + if (languageCode === 'hbo' || languageCode === 'el-x-koine') adjustedLanguageCode = 'en' // This is a guess (and won't be needed for TWs when we switch to TWLs) + const coTNlResultObject = await checkNotesLinksToOutside(languageCode, repoCode, bookID, C, V, 'TWLink', twLinkText, location, { ...checkingOptions, defaultLanguageCode: adjustedLanguageCode }); // debugLog(`coTNlResultObject=${JSON.stringify(coTNlResultObject)}`); - // Choose only ONE of the following - // This is the fast way of append the results from this field - // result.noticeList = result.noticeList.concat(coTNlResultObject.noticeList); // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const coqNoticeEntry of coTNlResultObject.noticeList) { @@ -1050,8 +1103,15 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // end of ourCheckNotesLinksToOutside function - function mainUSFMCheck(bookID, filename, givenText, location) { - // debugLog("Running mainUSFMCheck() (can take quite a while for a large book)…"); + /** + * + * @param {string} bookID + * @param {string} filename + * @param {string} givenText -- text of the USFM file + * @param {string} location -- optional + */ + async function mainUSFMCheck(bookID, filename, givenText, location) { + // functionLog(`checkUSFMText mainUSFMCheck(${bookID}, ${filename}, ${givenText.length}, ${location}) (can take quite a while for a large book)…`); let ourLocation = location; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -1061,7 +1121,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex let numChaptersThisBook = 0; try { logicAssert(lowercaseBookID !== 'obs', "Shouldn’t happen in usfm-text-check2"); - numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + numChaptersThisBook = books.chaptersInBook(bookID); } catch { if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. @@ -1091,6 +1151,16 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex let lines = givenText.split('\n'); // debugLog(` '${ourLocation}' has ${lines.length.toLocaleString()} total lines`); + if (lines.length === 0 || !lines[0].startsWith('\\id ') || lines[0].length < 7 || !books.isValidBookID(lines[0].slice(4, 7))) + addNoticePartial({ priority: 994, message: "USFM file must start with a valid \\id line", lineNumber: 1, location: ourLocation }); + const haveUSFM3Line = lines.length > 1 && lines[1] === '\\usfm 3.0'; + const ideIndex = haveUSFM3Line ? 2 : 1; + if (lines.length < ideIndex || !lines[ideIndex].startsWith('\\ide ') || lines[ideIndex].length < 7) + addNoticePartial({ priority: 719, message: "USFM file is recommended to have \\ide line", lineNumber: ideIndex + 1, location: ourLocation }); + else if (!lines[ideIndex].endsWith(' UTF-8')) + addNoticePartial({ priority: 619, message: "USFM \\ide field is recommended to be set to 'UTF-8'", lineNumber: ideIndex + 1, characterIndex: 5, excerpt: lines[ideIndex], location: ourLocation }); + + // let lastB = ''; let lastC = '', lastV = '', C = '0', V = '0'; let lastIntC = 0, lastIntV = 0; @@ -1123,7 +1193,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex rest = line; if (validLineStartCharacters.indexOf(line[0]) === -1) { // These are the often expected characters // Drop the priority if it’s a "half-likely" character - addNoticePartial({ priority: `"`.indexOf(line[0]) < 0 ? 880 : 180, C, V, message: "Expected line to start with backslash", lineNumber: n, characterIndex: 0, excerpt: line[0], location: ourLocation }); + addNoticePartial({ priority: line[0] === ' ' || line[0] === '"' ? 180 : 880, C, V, message: "Expected line to start with backslash", lineNumber: n, characterIndex: 0, excerpt: line[0], location: ourLocation }); if (line[1] === '\\') { // Let’s drop the leading punctuation and try to check the rest of the line marker = line.substring(2).split(' ', 1)[0]; rest = line.substring(marker.length + 2 + 1); // Skip leading character, backslash, marker, and space after marker @@ -1219,7 +1289,7 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex addNoticePartial({ priority: C === '1' ? 657 : 457, C, V, message: "Paragraph marker expected before first verse", lineNumber: n, characterIndex: 1, details: `'\\${marker}' after '\\${lastMarker}'`, location: ourLocation }); // Do general checks - checkUSFMLineContents(n, C, V, marker, rest, ourLocation, checkingOptions); + await checkUSFMLineContents(n, C, V, marker, rest, ourLocation, checkingOptions); lastMarker = marker; lastRest = rest; } @@ -1244,26 +1314,36 @@ export function checkUSFMText(languageCode, repoCode, bookID, filename, givenTex // Main code for checkUSFMText() // debugLog("Starting USFM checking tasks…"); - /* - const tasks = [1,2].map(runSlowTask); - const allResults = await Promise.all(tasks); - userLog(` Finished all tasks with ${JSON.stringify(allResults)}.`); - userLog(" Finished all tasks."); - if (!allResults[1].isValidUSFM) - addNoticePartial({priority: 942, "USFM Grammar check fails", location}); - userLog(" Warnings:", JSON.stringify(allResults[1].warnings)); - // Display these warnings but with a lower priority - for (const warningString of allResults[1].warnings) - addNoticePartial({priority:103, `USFMGrammar: ${warningString.trim()}`, location}); - */ + + // const tasks = [1,2].map(runSlowTask); + // const allResults = await Promise.all(tasks); + // userLog(` Finished all tasks with ${JSON.stringify(allResults)}.`); + // userLog(" Finished all tasks."); + // if (!allResults[1].isValidUSFM) + // addNoticePartial({priority: 942, "USFM Grammar check fails", location}); + // userLog(" Warnings:", JSON.stringify(allResults[1].warnings)); + // // Display these warnings but with a lower priority + // for (const warningString of allResults[1].warnings) + // addNoticePartial({priority:103, `USFMGrammar: ${warningString.trim()}`, location}); // NOTE: If we're careful about how/when we add their notices to our global list, // we should be able to run these three slowish checks in parallel on different threads/processes let allResults = []; - allResults.push(mainUSFMCheck(bookID, filename, givenText, ourLocation)); + allResults.push(await mainUSFMCheck(bookID, filename, givenText, ourLocation)); allResults.push(CVCheck(bookID, givenText, ourLocation)); - if (!books.isExtraBookID(bookID)) - allResults.push(ourRunBCSGrammarCheck(filename, givenText, ourLocation)); + if (!books.isExtraBookID(bookID)) { + const numChapters = books.chaptersInBook(bookID); + const kB = Math.trunc(givenText.length / 1024); + if (numChapters < 20 || kB < 2048) { // 2MB -- large files can run the grammar checker out of memory + userLog(`Running the BCS USFMGrammar checker for ${repoCode} ${bookID} (${kB.toLocaleString()} KB) -- may take several ${kB > 1200 ? 'minutes' : 'seconds'}…`); + allResults.push(ourRunBCSGrammarCheck(filename, givenText, ourLocation)); + } else { + userLog(`Skipped running BCS USFMGrammar checker for ${repoCode} ${bookID} (${kB.toLocaleString()} KB with ${numChapters} chapters)`); + // Success message seems not to be displayed in the demos + addSuccessMessage(`Skipped running BCS USFMGrammar checker for ${repoCode} ${bookID} (${kB.toLocaleString()} KB with ${numChapters} chapters)`); + addNoticePartial({ priority: 25, message: "Note: skipped running BCS USFMGrammar checker for large book", details: `${numChapters} chapters (${kB.toLocaleString()} KB)`, location: ourLocation }); + } + } // logicAssert(allResults.length === 2); // debugLog("allResults", JSON.stringify(allResults)); // if (!allResults[1].isValidUSFM) diff --git a/src/core/usfm-text-check.md b/src/core/usfm-text-check.md index 2f658c681..2a84ae042 100644 --- a/src/core/usfm-text-check.md +++ b/src/core/usfm-text-check.md @@ -13,11 +13,14 @@ Note that unfoldingWord has three distinct forms of USFM files (and these functi 1. Some of our USFM Bible books simply contain the (normal) Bible text. (Of course, these files are much smaller and quicker to validate.) ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. +import React, { useState, useEffect } from 'react'; import { checkUSFMText } from './usfm-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderRawResults } from '../demos/RenderProcessedResults'; // USFM samples const textS = `\\id GEN Short test @@ -179,18 +182,43 @@ const textB = `\\id GEN Bad USFM test \\v 2 Not good here `; -// You can choose any of the above texts here -// (to demonstrate differing results) -const chosenText = textH; - -// Fourth (unused) parameter is filename -const checkingOptions = {}; -const rawResults = checkUSFMText('en', 'UHB', 'GEN', '', chosenText, 'that was supplied', checkingOptions); -if (!rawResults.successList || !rawResults.successList.length) - rawResults.successList = ["Done USFM text checks"]; - -<> -Check - - +const data = { + // You can choose any of the above lines here + // (to demonstrate differing results) + languageCode: 'el-x-koine', + repoCode: 'UGNT', + USFMTextName : 'textG', + USFMText : textG, + bookID : 'GEN', + filename: 'dummyFilename', + givenLocation : 'that was supplied', +} + +function OurCheckUSFMText(props) { + const { languageCode, repoCode, bookID, filename, USFMText, USFMTextName, givenLocation } = props.data; + + const [results, setResults] = useState(null); + + // We need the following construction because checkUSFMText is an ASYNC function + useEffect(() => { + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // Display our "waiting" message + setResults(

Checking {languageCode} {repoCode} for {USFMTextName} {bookID}

); + const checkingOptions = {}; + const rawResults = await checkUSFMText(languageCode, repoCode, bookID, filename, USFMText, givenLocation, checkingOptions); + setResults( +
+ Check {USFMTextName}: "{USFMText.substr(0,256)}…"

+ +
+ ); + })(); // end of async part in unnamedFunction + }, []); // end of useEffect part + + return results; +} // end of OurCheckUSFMText function + + ``` diff --git a/src/core/utilities.js b/src/core/utilities.js index 35fc0e13d..2815697e0 100644 --- a/src/core/utilities.js +++ b/src/core/utilities.js @@ -140,8 +140,8 @@ export function ourParseInt(givenString) { throw "String is not a simple integer"; return int1; */ - parameterAssert(typeof givenString === 'string', `ourParseInt: 'givenString' parameter should be a string not a '${typeof givenString}': ${givenString}`); - parameterAssert(givenString.length > 0, "ourParseInt: 'givenString' parameter should be not be an empty string!"); + //parameterAssert(typeof givenString === 'string', `ourParseInt: 'givenString' parameter should be a string not a '${typeof givenString}': ${givenString}`); + //parameterAssert(givenString.length > 0, "ourParseInt: 'givenString' parameter should be not be an empty string!"); // eslint-disable-next-line no-throw-literal if (givenString.length === 0) throw `String '${givenString}'is empty`; diff --git a/src/core/yaml-text-check.js b/src/core/yaml-text-check.js index 425c5c1c2..1ffe88760 100644 --- a/src/core/yaml-text-check.js +++ b/src/core/yaml-text-check.js @@ -1,8 +1,10 @@ import yaml from 'yaml'; +// eslint-disable-next-line no-unused-vars import { DEFAULT_EXCERPT_LENGTH, REPO_CODES_LIST } from './defaults' import { checkTextField } from './field-text-check'; import { checkTextfileContents } from './file-text-check'; import { removeDisabledNotices } from './disabled-notices'; +// eslint-disable-next-line no-unused-vars import { parameterAssert } from './utilities'; @@ -26,21 +28,21 @@ export function checkYAMLText(languageCode, repoCode, textName, YAMLText, givenL */ // functionLog(`checkYAMLText(${textName}, ${YAMLText.length}, ${givenLocation})…`); - parameterAssert(languageCode !== undefined, "checkYAMLText: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkYAMLText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(repoCode !== undefined, "checkYAMLText: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkYAMLText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkYAMLText: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(textName !== undefined, "checkYAMLText: 'textName' parameter should be defined"); - parameterAssert(typeof textName === 'string', `checkYAMLText: 'textName' parameter should be a string not a '${typeof textName}': ${textName}`); - parameterAssert(YAMLText !== undefined, "checkYAMLText: 'YAMLText' parameter should be defined"); - parameterAssert(typeof YAMLText === 'string', `checkYAMLText: 'YAMLText' parameter should be a string not a '${typeof YAMLText}': ${YAMLText}`); - parameterAssert(givenLocation !== undefined, "checkYAMLText: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkYAMLText: 'optionalFieldLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); - parameterAssert(givenLocation.indexOf('true') === -1, `checkYAMLText: 'optionalFieldLocation' parameter should not be '${givenLocation}'`); - parameterAssert(checkingOptions !== undefined, "checkYAMLText: 'checkingOptions' parameter should be defined"); - if (checkingOptions !== undefined) - parameterAssert(typeof checkingOptions === 'object', `checkYAMLText: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + //parameterAssert(languageCode !== undefined, "checkYAMLText: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkYAMLText: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(repoCode !== undefined, "checkYAMLText: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkYAMLText: 'repoCode' parameter should be a string not a '${typeof repoCode}': ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `checkYAMLText: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(textName !== undefined, "checkYAMLText: 'textName' parameter should be defined"); + //parameterAssert(typeof textName === 'string', `checkYAMLText: 'textName' parameter should be a string not a '${typeof textName}': ${textName}`); + //parameterAssert(YAMLText !== undefined, "checkYAMLText: 'YAMLText' parameter should be defined"); + //parameterAssert(typeof YAMLText === 'string', `checkYAMLText: 'YAMLText' parameter should be a string not a '${typeof YAMLText}': ${YAMLText}`); + //parameterAssert(givenLocation !== undefined, "checkYAMLText: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkYAMLText: 'optionalFieldLocation' parameter should be a string not a '${typeof givenLocation}': ${givenLocation}`); + //parameterAssert(givenLocation.indexOf('true') === -1, `checkYAMLText: 'optionalFieldLocation' parameter should not be '${givenLocation}'`); + //parameterAssert(checkingOptions !== undefined, "checkYAMLText: 'checkingOptions' parameter should be defined"); + if (checkingOptions !== undefined) { //parameterAssert(typeof checkingOptions === 'object', `checkYAMLText: 'checkingOptions' parameter should be an object not a '${typeof checkingOptions}': ${JSON.stringify(checkingOptions)}`); + } let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -68,16 +70,18 @@ export function checkYAMLText(languageCode, repoCode, textName, YAMLText, givenL } function addNotice(noticeObject) { // functionLog(`checkYAMLText Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cYt addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cManT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cYt addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cManT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(characterIndex!==undefined, "cYt addNotice: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cManT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt!==undefined, "cYt addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cManT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cYt addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cYt addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.priority !== undefined, "cYt addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cManT addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cYt addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cManT addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(characterIndex!==undefined, "cYt addNotice: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cManT addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); + } + // //parameterAssert(excerpt!==undefined, "cYt addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cManT addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cYt addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cYt addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkYAMLText ${noticeObject.debugChain}`; cytResult.noticeList.push(noticeObject); } @@ -97,11 +101,11 @@ export function checkYAMLText(languageCode, repoCode, textName, YAMLText, givenL // Updates the global list of notices // debugLog(`cYt ourCheckTextField(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${fieldLocation}, …)`); - parameterAssert(fieldText !== undefined, "cYt ourCheckTextField: 'fieldText' parameter should be defined"); - parameterAssert(typeof fieldText === 'string', `cYt ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - parameterAssert(allowedLinks === true || allowedLinks === false, "cYt ourCheckTextField: allowedLinks parameter must be either true or false"); - parameterAssert(optionalFieldLocation !== undefined, "cYt ourCheckTextField: 'optionalFieldLocation' parameter should be defined"); - parameterAssert(typeof optionalFieldLocation === 'string', `cYt ourCheckTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); + //parameterAssert(fieldText !== undefined, "cYt ourCheckTextField: 'fieldText' parameter should be defined"); + //parameterAssert(typeof fieldText === 'string', `cYt ourCheckTextField: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + //parameterAssert(allowedLinks === true || allowedLinks === false, "cYt ourCheckTextField: allowedLinks parameter must be either true or false"); + //parameterAssert(optionalFieldLocation !== undefined, "cYt ourCheckTextField: 'optionalFieldLocation' parameter should be defined"); + //parameterAssert(typeof optionalFieldLocation === 'string', `cYt ourCheckTextField: 'optionalFieldLocation' parameter should be a string not a '${typeof optionalFieldLocation}'`); const resultObject = checkTextField(languageCode, repoCode, 'YAML', '', fieldText, allowedLinks, optionalFieldLocation, checkingOptions); @@ -144,18 +148,18 @@ export function checkYAMLText(languageCode, repoCode, textName, YAMLText, givenL // We assume that checking for compulsory fields is done elsewhere // Updates the global list of notices - parameterAssert(filename !== undefined, "cYT ourBasicFileChecks: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `cYT ourBasicFileChecks: 'filename' parameter should be a string not a '${typeof filename}'`); - parameterAssert(fileText !== undefined, "cYT ourBasicFileChecks: 'fileText' parameter should be defined"); - parameterAssert(typeof fileText === 'string', `cYT ourBasicFileChecks: 'fileText' parameter should be a string not a '${typeof fileText}'`); - parameterAssert(checkingOptions !== undefined, "cYT ourBasicFileChecks: 'checkingOptions' parameter should be defined"); + //parameterAssert(filename !== undefined, "cYT ourBasicFileChecks: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `cYT ourBasicFileChecks: 'filename' parameter should be a string not a '${typeof filename}'`); + //parameterAssert(fileText !== undefined, "cYT ourBasicFileChecks: 'fileText' parameter should be defined"); + //parameterAssert(typeof fileText === 'string', `cYT ourBasicFileChecks: 'fileText' parameter should be a string not a '${typeof fileText}'`); + //parameterAssert(checkingOptions !== undefined, "cYT ourBasicFileChecks: 'checkingOptions' parameter should be defined"); const resultObject = checkTextfileContents(languageCode, repoCode, 'YAML', filename, fileText, fileLocation, checkingOptions); // If we need to put everything through addNoticePartial, e.g., for debugging or filtering // process results line by line for (const noticeEntry of resultObject.noticeList) { - parameterAssert(Object.keys(noticeEntry).length >= 5, `USFM ourBasicFileChecks notice length=${Object.keys(noticeEntry).length}`); + //parameterAssert(Object.keys(noticeEntry).length >= 5, `USFM ourBasicFileChecks notice length=${Object.keys(noticeEntry).length}`); addNotice(noticeEntry); } } diff --git a/src/core/yaml-text-check.md b/src/core/yaml-text-check.md index 39280cd4c..cec1f5870 100644 --- a/src/core/yaml-text-check.md +++ b/src/core/yaml-text-check.md @@ -9,11 +9,13 @@ These raw notice components can then be filtered and/or sorted as required by th Note that we have a more specialised function for checking `manifest.yaml` files. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkYAMLText } from './yaml-text-check'; -import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; +import { RenderNumberedLines, RenderRawResults } from '../demos/RenderProcessedResults'; // YAML empty, good and bad text samples const textE = ''; @@ -224,7 +226,7 @@ const checkingOptions = {}; const rawResults = checkYAMLText('en', '', chosenTextName, chosenText, 'in YAML data that was supplied', checkingOptions); <> -YAML contents: +YAML contents: ``` diff --git a/src/demos/RenderProcessedResults.js b/src/demos/RenderProcessedResults.js index b8ad74bd5..9614378f3 100644 --- a/src/demos/RenderProcessedResults.js +++ b/src/demos/RenderProcessedResults.js @@ -42,11 +42,11 @@ const tableIcons = { }; -// const RENDER_PROCESSED_RESULTS_VERSION = '0.6.3'; +// const RENDER_PROCESSED_RESULTS_VERSION = '0.6.7'; export function RenderSuccesses({ username, results }) { - if (results.checkedFileCount > 0) + if (results?.checkedFileCount > 0) return (

    Successfully checked {results.checkedFileCount.toLocaleString()} file{results.checkedFileCount === 1 ? '' : 's'} from {results.checkedRepoNames.length.toLocaleString()} {username} repo{results.checkedRepoNames.length === 1 ? '' : 's'}: {results.checkedRepoNames.join(', ')}
        including {results.checkedFilenameExtensions.length} file type{results.checkedFilenameExtensions.size === 1 ? '' : 's'}: {results.checkedFilenameExtensions.join(', ')}.

); else @@ -54,10 +54,10 @@ export function RenderSuccesses({ username, results }) { } export function RenderTotals({ rawNoticeListLength, results }) { - if (results.numIgnoredNotices || results.numDisabledNotices) { + if (results?.numIgnoredNotices || results?.numDisabledNotices) { const netNumNotices = rawNoticeListLength - results.numIgnoredNotices - results.numDisabledNotices; return (

    Finished in with {netNumNotices === 0 ? 'no' : netNumNotices.toLocaleString()} notice{netNumNotices === 1 ? ' ' : 's '} - ({rawNoticeListLength === 0 ? 'no' : rawNoticeListLength.toLocaleString()} raw notice{rawNoticeListLength === 1 ? '' : 's'} but + ({rawNoticeListLength === 0 ? 'no' : rawNoticeListLength.toLocaleString()} raw notice{rawNoticeListLength === 1 ? '' : 's'} but {results.numIgnoredNotices ? ` ${results.numIgnoredNotices.toLocaleString()} ignored notice${results.numIgnoredNotices === 1 ? '' : 's'}` : ""} {results.numIgnoredNotices && results.numDisabledNotices ? ' and' : ''} {results.numDisabledNotices ? ` ${results.numDisabledNotices.toLocaleString()} expected/disabled notice${results.numDisabledNotices === 1 ? '' : 's'}` : ""} @@ -74,15 +74,14 @@ export function RenderTotals({ rawNoticeListLength, results }) { * @param {string} text - text to render as numbered lines * @return {String} - rendered HTML for the numbered list of lines */ -/* export function RenderNumberedLines({ text }) { + // This function is only used in some of the demos return

    {text.split('\n').map(function (line, index) { return
  1. {line}
  2. ; })}
; } -*/ const MAX_ARRAY_ITEMS_TO_DISPLAY = 8; // Or do we want this as a parameter? @@ -218,8 +217,11 @@ export function RenderRawResults({ results }) { */ function RenderMessage({ color, message, details }) { let detailsString = ''; - if (details && details.length) - detailsString = ' with ' + (details[0] === '(' ? details : `'${details}'`); + if (details) + if (details.startsWith('verse text ►')) + detailsString = <> with verse text ►{details.slice(12, -1)}◄; + else if (details.length) + detailsString = <> with '{details}'; return <>{message}{detailsString}; } @@ -270,8 +272,10 @@ function RenderFileDetails({ givenEntry }) { let adjustedRepoName = givenEntry.repoName; const firstMsgWord = givenEntry.message.split(' ')[0]; // This might be the former 'extra' field if (['TA', 'TW'].indexOf(firstMsgWord) >= 0) { - adjustedRepoName = `${givenEntry.repoName.split('_')[0]}_${firstMsgWord.toLowerCase()}`; - if (adjustedRepoName!==givenEntry.repoName) debugLog(`RenderFileDetails: trying adjusting repoName from '${givenEntry.repoName}' to '${adjustedRepoName}' for ${JSON.stringify(givenEntry)}`); + let adjustedLanguageCode = givenEntry.repoName.split('_')[0]; + if (adjustedLanguageCode === 'hbo' || adjustedLanguageCode === 'el-x-koine') adjustedLanguageCode = 'en'; // This is a guess (and won't be needed for TWs when we switch to TWLs) + adjustedRepoName = `${adjustedLanguageCode}_${firstMsgWord.toLowerCase()}`; + if (adjustedRepoName !== givenEntry.repoName) debugLog(`RenderFileDetails: trying adjusting repoName from '${givenEntry.repoName}' to '${adjustedRepoName}' for ${JSON.stringify(givenEntry)}`); } let resultStart = '', lineResult = '', resultEnd = '', fileLineLink = '', fileLink = ''; @@ -283,9 +287,9 @@ function RenderFileDetails({ givenEntry }) { let folder = ''; if (givenEntry.filename !== 'README.md' && givenEntry.filename !== 'LICENSE.md') { if (adjustedRepoName.endsWith('_obs')) folder = 'content/'; - else if (adjustedRepoName.endsWith('_tw')) { + else if (adjustedRepoName.endsWith('_tw') && !givenEntry.filename.startsWith('bible/')) { folder = 'bible/'; - dataAssert(givenEntry.filename.indexOf('/') > 0); // filename actually contains the subfolder + dataAssert(givenEntry.filename.indexOf('/') === 1); // filename actually contains the subfolder } } fileLink = `https://git.door43.org/${givenEntry.username}/${adjustedRepoName}/blame/branch/${givenEntry.branch}/${folder}${givenEntry.filename}`; @@ -303,12 +307,17 @@ function RenderFileDetails({ givenEntry }) { // else if (!username) resultEnd += " no username"; // else if (!repoName) resultEnd += " no repoName"; // else if (!filename) resultEnd += " no filename"; - if (givenEntry.rowID && givenEntry.rowID.length) resultEnd += ` with row ID ${givenEntry.rowID}`; - if (givenEntry.fieldName && givenEntry.fieldName.length) resultEnd += ` in ${givenEntry.fieldName} field`; - - if (fileLineLink) return <>{resultStart}{lineResult}{resultEnd}; - else if (fileLink) return <>{resultStart} in file {givenEntry.filename}{resultEnd}; - else return <>{resultStart}{lineResult}{resultEnd}; + if (givenEntry.rowID && givenEntry.rowID.length) + resultEnd = <>{resultEnd} with row ID {givenEntry.rowID}; + if (givenEntry.fieldName && givenEntry.fieldName.length) + resultEnd = <>{resultEnd} in {givenEntry.fieldName} field; + + if (fileLineLink) + return <>{resultStart}{lineResult}{resultEnd}; + else if (fileLink) + return <>{resultStart} in file {givenEntry.filename}{resultEnd}; + else + return <>{resultStart}{lineResult}{resultEnd}; } // end of RenderFileDetails @@ -321,17 +330,20 @@ function RenderExcerpt({ excerpt, message }) { || message.endsWith("Error loading general link") || message.endsWith("Should http link be https")) { // debugLog(`Here1 RenderExcerpt(${excerpt}, ${message})`); - if (excerpt && excerpt[0] === '[' && excerpt.slice(-1) === ')') { + if (excerpt && excerpt[0] === '[' && excerpt.slice(-1) === ')') { // then the excerpt is a link so let's liven it // debugLog(`Here2 RenderExcerpt(${excerpt}, ${message})`); const ix = excerpt.indexOf(']('); - const displayPart = excerpt.substring(1, ix); // Start after the [ unril before the ]( + const displayPart = excerpt.substring(1, ix); // Start after the [ until before the ]( const linkPart = excerpt.substring(ix + 2, excerpt.length - 1); // Step past the ]( but don't include the final ) const adjLinkPart = message === "Should http link be https" ? linkPart.replace('http:', 'https:') : linkPart; // debugLog(`RenderExcerpt from '${excerpt}' got ix=${ix}, displayPart='${displayPart}', linkPart='${linkPart}', adjLinkPart='${adjLinkPart}'`); return <>` around ►[{displayPart}]({linkPart})◄` } } - return <>{excerpt ? ` around ►${excerpt}◄` : ""} + if (excerpt && excerpt.length) + return <> around ►{excerpt}◄; + // else + return null; } // end of RenderExcerpt @@ -383,7 +395,7 @@ function RenderProcessedArray({ arrayType, results }) { // bookID, C, V, repoName, filename, lineNumber // characterIindex (integer), excerpt (string), location (string) // - debugLog("In RenderProcessedArray with ", arrayType); + // debugLog("In RenderProcessedArray with ", arrayType); // consoleLogObject('RenderProcessedArray results', results); if (arrayType === 's') @@ -621,6 +633,6 @@ export function RenderElapsedTime({ elapsedSeconds }) { remainingTime = Math.floor(remainingTime / 60); const hours = Math.round(remainingTime % 24); remainingTime = Math.floor(remainingTime / 24); - parameterAssert(remainingTime === 0, `Elapsed time also contains ${remainingTime} days`); + //parameterAssert(remainingTime === 0, `Elapsed time also contains ${remainingTime} days`); return <>{hours ? `${hours} hour` : ''}{hours && hours !== 1 ? 's' : ''}{hours ? ', ' : ''}{minutes ? `${minutes} minute` : ''}{minutes && minutes !== 1 ? 's' : ''}{minutes ? ', ' : ''}{seconds} second{seconds === 1 ? '' : 's'}; } diff --git a/src/demos/all-book-packages-check/AllBookPackagesCheck.js b/src/demos/all-book-packages-check/AllBookPackagesCheck.js index 27e2f673c..df538696c 100644 --- a/src/demos/all-book-packages-check/AllBookPackagesCheck.js +++ b/src/demos/all-book-packages-check/AllBookPackagesCheck.js @@ -5,205 +5,227 @@ import { clearCaches, clearCheckedArticleCache, ourParseInt, preloadReposIfNeces import { checkBookPackages } from '../book-packages-check/checkBookPackages'; import { processNoticesToErrorsWarnings, processNoticesToSevereMediumLow, processNoticesToSingleList } from '../notice-processing-functions'; import { RenderSuccesses, RenderSuccessesErrorsWarnings, RenderSuccessesSevereMediumLow, RenderSuccessesWarningsGradient, RenderTotals } from '../RenderProcessedResults'; -import { userLog } from '../../core/utilities'; +// eslint-disable-next-line no-unused-vars +import { logicAssert, userLog, debugLog } from '../../core/utilities'; -// const ALL_BPS_VALIDATOR_VERSION_STRING = '0.3.4'; +// const ALL_BPS_VALIDATOR_VERSION_STRING = '0.3.8'; const OLD_TESTAMENT_BOOK_CODES = 'GEN,EXO,LEV,NUM,DEU,JOS,JDG,RUT,1SA,2SA,1KI,2KI,1CH,2CH,EZR,NEH,EST,JOB,PSA,PRO,ECC,SNG,ISA,JER,LAM,EZK,DAN,HOS,JOL,AMO,OBA,JON,MIC,NAM,HAB,ZEP,HAG,ZEC,MAL'; const NEW_TESTAMENT_BOOK_CODES = 'MAT,MRK,LUK,JHN,ACT,ROM,1CO,2CO,GAL,EPH,PHP,COL,1TH,2TH,1TI,2TI,TIT,PHM,HEB,JAS,1PE,2PE,1JN,2JN,3JN,JUD,REV'; function AllBookPackagesCheck(/*username, languageCode, bookIDs,*/ props) { - // Check a single Bible book across many repositories - const [result, setResultValue] = useState("Waiting-CheckAllBookPackages"); - - // debugLog(`I'm here in AllBookPackagesCheckBookPackagesCheck v${ALL_BPS_VALIDATOR_VERSION_STRING}`); - // consoleLogObject("props", props); - // consoleLogObject("props.classes", props.classes); - - let username = props.username; - // debugLog(`username='${username}'`); - let languageCode = props.languageCode; - // debugLog(`languageCode='${languageCode}'`); - let testament = props.testament; - // debugLog(`testament='${testament}'`); - let includeOBS = props.includeOBS; - // debugLog(`includeOBS='${includeOBS}'`); - let dataSet = props.dataSet; - // debugLog(`dataSet='${dataSet}'`); - let branch = props.branch; - // debugLog(`branch='${branch}'`); - - // Clear cached files if we've changed repo - // autoClearCache(bookIDs); // This technique avoids the complications of needing a button - - // Enter a string containing UPPERCASE USFM book identifiers separated only by commas - // and can also include OBS (for Open Bible Stories) - let bookIDs = ''; - if (testament.toUpperCase() === 'OT' || testament.toUpperCase() === 'OLD') - bookIDs = OLD_TESTAMENT_BOOK_CODES; - else if (testament.toUpperCase() === 'NT' || testament.toUpperCase() === 'NEW') - bookIDs = NEW_TESTAMENT_BOOK_CODES; - else if (testament.toUpperCase() === 'ALL') - bookIDs = `${OLD_TESTAMENT_BOOK_CODES},${NEW_TESTAMENT_BOOK_CODES}`; - else - setResultValue(

No testament selected

); - if (includeOBS.toUpperCase() === 'Y' || includeOBS.toUpperCase() === 'YES') - bookIDs += ',OBS'; - - let bookIDList = []; - let bookIDInvalid; - for (let bookID of bookIDs.split(',')) { - bookID = bookID.trim(); - if (!books.isValidBookID(bookID) && bookID!=='OBS') { - bookIDInvalid = bookID; - } - bookIDList.push(bookID); + // Check a single Bible book across many repositories + const [result, setResultValue] = useState("Waiting-CheckAllBookPackages"); + + // debugLog(`I'm here in AllBookPackagesCheckBookPackagesCheck v${ALL_BPS_VALIDATOR_VERSION_STRING}`); + // consoleLogObject("props", props); + // consoleLogObject("props.classes", props.classes); + + let username = props.username; + // debugLog(`username='${username}'`); + let languageCode = props.languageCode; + // debugLog(`languageCode='${languageCode}'`); + let testament = props.testament; + // debugLog(`testament='${testament}'`); + let includeOBS = props.includeOBS; + // debugLog(`includeOBS='${includeOBS}'`); + let dataSet = props.dataSet; + // debugLog(`dataSet='${dataSet}'`); + let branch = props.branch; + // debugLog(`branch='${branch}'`); + + // Enter a string containing UPPERCASE USFM book identifiers separated only by commas + // and can also include OBS (for Open Bible Stories) + let bookIDsString = ''; + let haveOT = false, haveNT = false; + if (testament.toUpperCase() === 'OT' || testament.toUpperCase() === 'OLD') { + bookIDsString = OLD_TESTAMENT_BOOK_CODES; + haveOT = true; + } else if (testament.toUpperCase() === 'NT' || testament.toUpperCase() === 'NEW') { + bookIDsString = NEW_TESTAMENT_BOOK_CODES; + haveNT = true; + } else if (testament.toUpperCase() === 'ALL' || testament.toUpperCase() === 'BOTH') { + bookIDsString = `${OLD_TESTAMENT_BOOK_CODES},${NEW_TESTAMENT_BOOK_CODES}`; + haveOT = true; haveNT = true; + }else + setResultValue(

No testament selected

); + if (includeOBS.toUpperCase() === 'Y' || includeOBS.toUpperCase() === 'YES') + bookIDsString += ',OBS'; + + let bookIDList = []; + let bookIDInvalid; + for (let bookID of bookIDsString.split(',')) { + bookID = bookID.trim(); + if (!books.isValidBookID(bookID) && bookID !== 'OBS') { + bookIDInvalid = bookID; } - userLog(`AllBookPackagesCheck bookIDList (${bookIDList.length}) = ${bookIDList.join(', ')}`); - - const checkingOptions = { // Uncomment any of these to test them - // excerptLength: 25, - suppressNoticeDisablingFlag: true, // Leave this one as true (otherwise demo checks are less efficient) - }; - // Or this allows the parameters to be specified as a BookPackagesCheck property - if (props.excerptLength) checkingOptions.excerptLength = ourParseInt(props.excerptLength); - if (props.cutoffPriorityLevel) checkingOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); - - useEffect(() => { - // debugLog("BookPackagesCheck.useEffect() called with ", JSON.stringify(props)); - - // Use an IIFE (Immediately Invoked Function Expression) - // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 - (async () => { - // debugLog("Started BookPackagesCheck.unnamedFunction()"); - - // NOTE from RJH: I can’t find the correct React place for this / way to do this - // so it shows a warning for the user, and doesn’t continue to try to process - if (!props.wait || props.wait !== 'N') { - setResultValue(

Waiting for user… (Adjust settings below as necessary and then set wait='N' to start)

); - return; - } - - if (props.reloadAllFilesFirst && props.reloadAllFilesFirst.slice(0).toUpperCase() === 'Y') { - userLog("Clearing cache before running all book packages check…"); - setResultValue(

Clearing cache before running all book packages check…

); - await clearCaches(); - } - else await clearCheckedArticleCache(); - - // Load whole repos, especially if we are going to check files in manifests - let repoPreloadList = ['UHB', 'UGNT', 'TWL', 'LT', 'ST', 'TN', 'TA', 'TW', 'TQ']; // for DEFAULT + bookIDList.push(bookID); + } + // TODO: I don't understand why this command gets executed multiple times!!! + userLog(`AllBookPackagesCheck bookIDList (${bookIDList.length}) = ${bookIDList.join(', ')}`); + + const checkingOptions = { // Uncomment any of these to test them + // excerptLength: 25, + suppressNoticeDisablingFlag: true, // Leave this one as true (otherwise demo checks are less efficient) + }; + // Or this allows the parameters to be specified as a BookPackagesCheck property + if (props.excerptLength) checkingOptions.excerptLength = ourParseInt(props.excerptLength); + if (props.cutoffPriorityLevel) checkingOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); + + useEffect(() => { + // debugLog("BookPackagesCheck.useEffect() called with ", JSON.stringify(props)); + + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // debugLog("Started BookPackagesCheck.unnamedFunction()"); + + // NOTE from RJH: I can’t find the correct React place for this / way to do this + // so it shows a warning for the user, and doesn’t continue to try to process + if (!props.wait || props.wait !== 'N') { + setResultValue(

Waiting for user… (Adjust settings below as necessary and then set wait='N' to start)

); + return; + } + + if (props.reloadAllFilesFirst && props.reloadAllFilesFirst.slice(0).toUpperCase() === 'Y') { + userLog("Clearing cache before running all book packages check…"); + setResultValue(

Clearing cache before running all book packages check…

); + await clearCaches(); + } + else await clearCheckedArticleCache(); // otherwise we wouldn't see any of the warnings again from checking these + + // Load whole repos, especially if we are going to check files in manifests + let repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TA', 'TW', 'TQ']; // for DEFAULT + if (dataSet === 'OLD') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TA', 'TW', 'TQ']; + else if (dataSet === 'NEW') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN2', 'TA', 'TW', 'TQ2']; + else if (dataSet === 'BOTH') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TN2', 'TA', 'TW', 'TQ', 'TQ2']; + if (haveNT) repoPreloadList.unshift('UGNT'); + if (haveOT) repoPreloadList.unshift('UHB'); + if (!checkingOptions.disableAllLinkFetchingFlag) { + repoPreloadList.push('TW'); + repoPreloadList.push('TA'); + } + if (bookIDList.includes('OBS')) { + let obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; // for DEFAULT if (dataSet === 'OLD') - repoPreloadList = ['UHB', 'UGNT', 'LT', 'ST', 'TN', 'TA', 'TW', 'TQ']; + obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; else if (dataSet === 'NEW') - repoPreloadList = ['UHB', 'UGNT', 'TWL', 'LT', 'ST', 'TN2', 'TA', 'TW', 'TQ2']; + obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; else if (dataSet === 'BOTH') - repoPreloadList = ['UHB', 'UGNT', 'TWL', 'LT', 'ST', 'TN', 'TN2', 'TA', 'TW', 'TQ', 'TQ2']; - - setResultValue(

Preloading {repoPreloadList.length} repos for {username} {languageCode} ready for all book packages check…

); - const successFlag = await preloadReposIfNecessary(username, languageCode, bookIDList, branch, repoPreloadList); - if (!successFlag) - userLog(`AllBookPackagesCheck error: Failed to pre-load all repos`) - - // Display our "waiting" message - setResultValue(

Checking {username} {languageCode} {bookIDList.join(', ')} book packages…

); - - let rawCBPsResults = {}; - if (bookIDList.length) - rawCBPsResults = await checkBookPackages(username, languageCode, bookIDList, setResultValue, checkingOptions); - - // Add some extra fields to our rawCBPsResults object in case we need this information again later - rawCBPsResults.checkType = 'BookPackages'; - rawCBPsResults.username = username; - rawCBPsResults.languageCode = languageCode; - rawCBPsResults.bookIDs = bookIDs; - rawCBPsResults.bookIDList = bookIDList; - rawCBPsResults.checkedOptions = checkingOptions; - - // debugLog("Here with CBPs rawCBPsResults", typeof rawCBPsResults); - // Now do our final handling of the result -- we have some options available - let processOptions = { // Uncomment any of these to test them - // 'maximumSimilarMessages': 4, // default is 3 -- 0 means don’t suppress - // 'errorPriorityLevel': 800, // default is 700 - // 'cutoffPriorityLevel': 100, // default is 0 - // 'sortBy': 'ByRepo', // default is 'ByPriority', also have 'AsFound' - // 'ignorePriorityNumberList': [123, 202], // default is [] - }; - // Or this allows the parameters to be specified as a BookPackagesCheck property - if (props.maximumSimilarMessages) processOptions.maximumSimilarMessages = ourParseInt(props.maximumSimilarMessages); - if (props.errorPriorityLevel) processOptions.errorPriorityLevel = ourParseInt(props.errorPriorityLevel); - // if (props.cutoffPriorityLevel) processOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); - if (props.sortBy) processOptions.sortBy = props.sortBy; - // if (props.ignorePriorityNumberList) processOptions.ignorePriorityNumberList = props.ignorePriorityNumberList; - - let displayType = 'ErrorsWarnings'; // default - if (props.displayType) displayType = props.displayType; - - function renderSummary(processedResults) { - return (
-

Checked {username} {languageCode} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches)

- - - {/* */} -
); - } - - if (displayType === 'ErrorsWarnings') { - const processedResults = processNoticesToErrorsWarnings(rawCBPsResults, processOptions); - // userLog(`AllBookPackagesCheck got back processedResults with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) - // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); - - // debugLog("Here now in rendering bit!"); - - if (processedResults.errorList.length || processedResults.warningList.length) - setResultValue(<> - {renderSummary()} - - ); - else // no errors or warnings - setResultValue(<> - {renderSummary()} - - ); - } else if (displayType === 'SevereMediumLow') { - const processedResults = processNoticesToSevereMediumLow(rawCBPsResults, processOptions); - // userLog(`AllBookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) - // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); - - if (processedResults.severeList.length || processedResults.mediumList.length || processedResults.lowList.length) - setResultValue(<> - {renderSummary()} - - ); - else // no severe, medium, or low notices - setResultValue(<> - {renderSummary()} - - ); - } else if (displayType === 'SingleList') { - const processedResults = processNoticesToSingleList(rawCBPsResults, processOptions); - // userLog(`AllBookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s) and ${processedResults.warningList.length.toLocaleString()} notice(s) - // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); - - if (processedResults.warningList.length) - setResultValue(<> - {renderSummary()} - - ); - else // no warnings - setResultValue(<> - {renderSummary()} - - ); - } else setResultValue(Invalid displayType='{displayType}') - - // debugLog("Finished rendering bit."); - })(); // end of async part in unnamedFunction - // Doesn’t work if we add this to next line: bookIDList,bookIDs,username,branch,checkingOptions,languageCode,props - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [JSON.stringify(bookIDList), bookIDs, branch, JSON.stringify(checkingOptions), languageCode, JSON.stringify(props), username]); // end of useEffect part + obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SN', 'OBS-SN2', 'OBS-SQ2']; + repoPreloadList.push.apply(repoPreloadList, obsRepoPreloadList); + } + + setResultValue(

Preloading {repoPreloadList.length} repos for {username} {languageCode} ready for all book packages check…

); + const successFlag = await preloadReposIfNecessary(username, languageCode, bookIDList, branch, repoPreloadList); + if (!successFlag) + userLog(`AllBookPackagesCheck error: Failed to pre-load all repos`) + + // Display our "waiting" message + setResultValue(

Checking {username} {languageCode} {bookIDList.join(', ')} book packages…

); + + let rawABPsResults = {}; + if (bookIDList.length) { + rawABPsResults = await checkBookPackages(username, languageCode, bookIDList, setResultValue, checkingOptions); + // debugLog(`rawCBPsResults keys: ${Object.keys(rawABPsResults)}`); + // logicAssert('checkedFileCount' in rawABPsResults, `Expected rawCBPsResults to contain 'checkedFileCount': ${Object.keys(rawABPsResults)}`); + } + + // Add some extra fields to our rawCBPsResults object in case we need this information again later + rawABPsResults.checkType = 'AllBookPackages'; + rawABPsResults.username = username; + rawABPsResults.languageCode = languageCode; + rawABPsResults.bookIDs = bookIDsString; + rawABPsResults.bookIDList = bookIDList; + rawABPsResults.checkedOptions = checkingOptions; + + // debugLog("Here with CBPs rawCBPsResults", typeof rawCBPsResults); + // Now do our final handling of the result -- we have some options available + let processOptions = { // Uncomment any of these to test them + // 'maximumSimilarMessages': 4, // default is 3 -- 0 means don’t suppress + // 'errorPriorityLevel': 800, // default is 700 + // 'cutoffPriorityLevel': 100, // default is 0 + // 'sortBy': 'ByRepo', // default is 'ByPriority', also have 'AsFound' + // 'ignorePriorityNumberList': [123, 202], // default is [] + }; + // Or this allows the parameters to be specified as a BookPackagesCheck property + if (props.maximumSimilarMessages) processOptions.maximumSimilarMessages = ourParseInt(props.maximumSimilarMessages); + if (props.errorPriorityLevel) processOptions.errorPriorityLevel = ourParseInt(props.errorPriorityLevel); + // if (props.cutoffPriorityLevel) processOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); + if (props.sortBy) processOptions.sortBy = props.sortBy; + // if (props.ignorePriorityNumberList) processOptions.ignorePriorityNumberList = props.ignorePriorityNumberList; + + let displayType = 'ErrorsWarnings'; // default + if (props.displayType) displayType = props.displayType; + + function renderSummary(processedResults) { + return (
+

Checked {username} {languageCode} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches)

+ + + {/* */} +
); + } + + if (displayType === 'ErrorsWarnings') { + const processedResults = processNoticesToErrorsWarnings(rawABPsResults, processOptions); + // userLog(`AllBookPackagesCheck got back processedResults with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) + // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); + + // debugLog("Here now in rendering bit!"); + + if (processedResults.errorList.length || processedResults.warningList.length) + setResultValue(<> + {renderSummary(processedResults)} + + ); + else // no errors or warnings + setResultValue(<> + {renderSummary(processedResults)} + + ); + } else if (displayType === 'SevereMediumLow') { + const processedResults = processNoticesToSevereMediumLow(rawABPsResults, processOptions); + // userLog(`AllBookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) + // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); + + if (processedResults.severeList.length || processedResults.mediumList.length || processedResults.lowList.length) + setResultValue(<> + {renderSummary(processedResults)} + + ); + else // no severe, medium, or low notices + setResultValue(<> + {renderSummary(processedResults)} + + ); + } else if (displayType === 'SingleList') { + const processedResults = processNoticesToSingleList(rawABPsResults, processOptions); + // userLog(`AllBookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s) and ${processedResults.warningList.length.toLocaleString()} notice(s) + // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); + + if (processedResults.warningList.length) + setResultValue(<> + {renderSummary(processedResults)} + + ); + else // no warnings + setResultValue(<> + {renderSummary(processedResults)} + + ); + } else setResultValue(Invalid displayType='{displayType}') + + // debugLog("Finished rendering bit."); + })(); // end of async part in unnamedFunction + // Doesn’t work if we add this to next line: bookIDList,bookIDs,username,branch,checkingOptions,languageCode,props + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify(bookIDList), bookIDsString, branch, JSON.stringify(checkingOptions), languageCode, JSON.stringify(props), username]); // end of useEffect part if (bookIDInvalid) { return (

Please enter only valid USFM book identifiers separated by commas. ('{bookIDInvalid}' is not valid.)

); @@ -211,7 +233,7 @@ function AllBookPackagesCheck(/*username, languageCode, bookIDs,*/ props) { // {/*
*/} return ( -
+
{result}
); diff --git a/src/demos/all-book-packages-check/README.md b/src/demos/all-book-packages-check/README.md index 4da73c968..60cd9e531 100644 --- a/src/demos/all-book-packages-check/README.md +++ b/src/demos/all-book-packages-check/README.md @@ -1,6 +1,6 @@ ## Door43 All Book Packages Check - Readme -The code below requests some info and then checks the requested Bible books—NT or OT or ALL across several repos. OBS (Open Bible Stories) can also be added. This is convenient to see all these check results collected into one place. +The code below requests some info and then downloads and checks the requested Bible books—NT or OT or ALL across several repos. OBS (Open Bible Stories) can also be added. This is convenient to see all these check results collected into one place. `All Book Packages Check` calls `checkBookPackages()` which then calls `checkBookPackage()` for each given book identifier, which in turn calls `checkFileContents()` for the book file in each repo (or calls `checkRepo()` for **OBS**). @@ -9,8 +9,10 @@ The code below requests some info and then checks the requested Bible books—NT **Note**: This demonstration can use saved (cached) copies of files stored inside the local browser. This makes reruns of the checks faster, but it won’t notice if you have recently updated the files on Door43. If you want to clear the local caches, use either the `reloadAllFilesFirst` variable below, or the `Clear Cache` function from the menu. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import AllBookPackagesCheck from './AllBookPackagesCheck'; @@ -19,12 +21,13 @@ import AllBookPackagesCheck from './AllBookPackagesCheck'; wait='Y' // 'Y' (for Yes, i.e., to wait) or 'N' (for No, i.e., to start checking) // Set to N to rerun the check without fetching new copies of the files (slightly faster) + // If you're checking and then editing & saving files, ensure that it's set to Y before you recheck reloadAllFilesFirst='Y' // 'Y' (for Yes -- same as ClearCache in menu) or 'N' (for No) username='unfoldingWord' languageCode='en' - includeOBS='N' // 'Y' or 'N' for Open Bible Stories - testament='XX' // 'OT' or 'NT' or 'ALL' to start check + includeOBS='N' // 'Y' or 'N' for adding Open Bible Stories (OBS) to check + testament='NT' // 'OT' (~3 hrs) or 'NT' (1+ hrs) or 'ALL' (~4 hrs) // Default displayType is 'ErrorsWarnings' // Alternatives are `SevereMediumLow', 'SingleList' @@ -34,7 +37,7 @@ import AllBookPackagesCheck from './AllBookPackagesCheck'; // Specifying maximumSimilarMessages and excerptLength is just to show off options // —those fields are not necessary (or normal) here maximumSimilarMessages='4' // Default is 3 (0 means don’t suppress any) - // excerptLength='20' // Default is 15 + // excerptLength='25' // Default is 20 characters // cutoffPriorityLevel='200' // Default is to detect all errors/warnings /> ``` diff --git a/src/demos/book-package-check/BookPackageCheck.js b/src/demos/book-package-check/BookPackageCheck.js index eb4ee1547..5c8c4c89e 100644 --- a/src/demos/book-package-check/BookPackageCheck.js +++ b/src/demos/book-package-check/BookPackageCheck.js @@ -5,10 +5,11 @@ import { clearCaches, clearCheckedArticleCache, ourParseInt, preloadReposIfNeces import { processNoticesToErrorsWarnings, processNoticesToSevereMediumLow, processNoticesToSingleList } from '../notice-processing-functions'; import { RenderSuccesses, RenderSuccessesErrorsWarnings, RenderSuccessesSevereMediumLow, RenderSuccessesWarningsGradient, RenderTotals } from '../RenderProcessedResults'; import { checkBookPackage } from './checkBookPackage'; -import { userLog, debugLog, parameterAssert } from '../../core/utilities'; +// eslint-disable-next-line no-unused-vars +import { userLog, debugLog, parameterAssert, logicAssert } from '../../core/utilities'; -// const BP_VALIDATOR_VERSION_STRING = '0.5.2'; +// const BP_VALIDATOR_VERSION_STRING = '0.5.5'; function BookPackageCheck(/*username, languageCode, bookID,*/ props) { @@ -30,12 +31,9 @@ function BookPackageCheck(/*username, languageCode, bookID,*/ props) { let branch = props.branch; // debugLog(`branch='${branch}'`); - // Clear cached files if we've changed repo - // autoClearCache(bookID); // This technique avoids the complications of needing a button - const checkingOptions = { // Uncomment any of these to test them dataSet: dataSet, // Can be 'OLD' (Markdown, etc.), 'NEW' (TSV only), or 'BOTH', or 'DEFAULT' - // excerptLength: 25, // default is 15 + // excerptLength: 25, // default is 20 characters checkManifestFlag: true, checkReadmeFlag: true, checkLicenseFlag: true, @@ -79,35 +77,38 @@ function BookPackageCheck(/*username, languageCode, bookID,*/ props) { setResultValue(

Clearing cache before running book package check…

); await clearCaches(); } - else await clearCheckedArticleCache(); + else await clearCheckedArticleCache(); // otherwise we wouldn't see any of the warnings again from checking these - // Load whole repos, especially if we are going to check files in manifests + // Load whole repo zip files which is maybe faster than loading several individual files + // especially if we are going to also check the manifests, license, and ReadMe files as well as the book file. + // Remember that the manifest check actually checks the existence of all the projects, i.e., all files in the repo let repoPreloadList; if (bookID === 'OBS') { - repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; // for DEFAULT + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; // for DEFAULT if (dataSet === 'OLD') - repoPreloadList = ['OBS', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; else if (dataSet === 'NEW') repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; else if (dataSet === 'BOTH') - repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SN', 'OBS-SN2', 'OBS-SQ2']; } else { // not OBS repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ', 'SN', 'SQ']; // for DEFAULT if (dataSet === 'OLD') - repoPreloadList = ['LT', 'ST', 'TN', 'TQ']; + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ']; else if (dataSet === 'NEW') repoPreloadList = ['TWL', 'LT', 'ST', 'TN2', 'TQ2', 'SN', 'SQ']; else if (dataSet === 'BOTH') repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TN2', 'TQ', 'TQ2', 'SN', 'SQ']; const whichTestament = books.testament(bookID); // returns 'old' or 'new' + logicAssert(whichTestament === 'old' || whichTestament === 'new', `BookPackageCheck() couldn't find testament for '${bookID}'`); const origLangRepo = whichTestament === 'old' ? 'UHB' : 'UGNT'; repoPreloadList.unshift(origLangRepo); - if (!checkingOptions.disableAllLinkFetchingFlag) { - repoPreloadList.push('TW'); - repoPreloadList.push('TA'); - } } - debugLog(`BookPackageCheck got repoPreloadList=${repoPreloadList} for dataSet=${dataSet}`) + if (!checkingOptions.disableAllLinkFetchingFlag) { // Both Bible books and OBS refer to TW and TA + repoPreloadList.push('TW'); + repoPreloadList.push('TA'); + } + // debugLog(`BookPackageCheck got repoPreloadList=${repoPreloadList} for dataSet=${dataSet}`) // if (bookID !== 'OBS') { // Preload the reference repos setResultValue(

Preloading {repoPreloadList.length} repos for {username} {languageCode} ready for {bookID} book package check…

); @@ -143,7 +144,7 @@ function BookPackageCheck(/*username, languageCode, bookID,*/ props) { // if (props.cutoffPriorityLevel) processOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); if (props.sortBy) processOptions.sortBy = props.sortBy; if (props.ignorePriorityNumberList) { // We need to convert from string to Array - parameterAssert(props.ignorePriorityNumberList[0] === '[' && props.ignorePriorityNumberList[props.ignorePriorityNumberList.length - 1] === ']', `Format of props.ignorePriorityNumberList '${props.ignorePriorityNumberList}' is wrong should be enclosed in []`) + //parameterAssert(props.ignorePriorityNumberList[0] === '[' && props.ignorePriorityNumberList[props.ignorePriorityNumberList.length - 1] === ']', `Format of props.ignorePriorityNumberList '${props.ignorePriorityNumberList}' is wrong should be enclosed in []`) processOptions.ignorePriorityNumberList = []; for (const stringBit of props.ignorePriorityNumberList.substring(1, props.ignorePriorityNumberList.length - 1).split(',')) { const intBit = ourParseInt(stringBit.trim()); // trim allows comma,space to also be used as separator diff --git a/src/demos/book-package-check/README.md b/src/demos/book-package-check/README.md index e887e744a..70678daae 100644 --- a/src/demos/book-package-check/README.md +++ b/src/demos/book-package-check/README.md @@ -1,6 +1,6 @@ ## Door43 Book Package Check - Readme -The code below requests some info and then checks the single specified Bible book in several repos. This is convenient to see all these check results collected into one place. +The code below requests some info and then downloads and checks the single specified Bible book in several repos. This is convenient to see all these check results collected into one place. See a list of valid book identifiers [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. @@ -13,8 +13,10 @@ Note that `OBS` can also be entered here as a *pseudo book identifier* in order **Note**: This demonstration can use saved (cached) copies of files stored inside the local browser. This makes reruns of the checks faster, but it won’t notice if you have recently updated the files on Door43. If you want to clear the local caches, use either the `reloadAllFilesFirst` variable below, or the `Clear Cache` function from the menu. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import BookPackageCheck from './BookPackageCheck'; @@ -23,13 +25,14 @@ import BookPackageCheck from './BookPackageCheck'; wait='Y' // 'Y' (for Yes, i.e., to wait) or 'N' (for No, i.e., to start checking) // Set to N to rerun the check without fetching new copies of the files (slightly faster) + // If you're checking and then editing & saving files, ensure that it's set to Y before you recheck reloadAllFilesFirst='Y' // 'Y' (for Yes -- same as ClearCache in menu) or 'N' (for No) username='unfoldingWord' languageCode='en' // bookID can be a USFM bookID, e.g., 'GEN', 'MAT', '3JN' // and can also be 'OBS' (for Open Bible Stories) - bookID='LUK' + bookID='JAS' // We can choose the forthcoming new TSV formats or the existing formats // dataSet='BOTH' // 'OLD' (Markdown TQ, TSV9 TN, etc.), 'NEW' (TSV7 TQ2, TSV7 TN2, TSV6 TWL,etc.), 'DEFAULT', or 'BOTH' @@ -48,7 +51,7 @@ import BookPackageCheck from './BookPackageCheck'; // Lines starting with // are ignored -- you can add or remove // as desired // Specifying excerptLength and maximumSimilarMessages is just to show off options // —those fields are not necessary (or normal) here - excerptLength='20' // Default is 15 + excerptLength='25' // Default is 20 characters // cutoffPriorityLevel='200' // Default is to detect all errors/warnings maximumSimilarMessages='5' // Default is 3 (0 means don’t suppress any) // ignorePriorityNumberList='[]' diff --git a/src/demos/book-package-check/checkBookPackage.js b/src/demos/book-package-check/checkBookPackage.js index a72f0805f..4fae05d51 100644 --- a/src/demos/book-package-check/checkBookPackage.js +++ b/src/demos/book-package-check/checkBookPackage.js @@ -1,4 +1,5 @@ import React from 'react'; +// eslint-disable-next-line no-unused-vars import { REPO_CODES_LIST } from '../../core/defaults'; import * as books from '../../core/books/books'; import { formRepoName, repositoryExistsOnDoor43, getFileListFromZip, cachedGetFile, cachedGetBookFilenameFromManifest, checkManifestText, checkMarkdownText } from '../../core'; @@ -8,7 +9,7 @@ import { checkRepo } from '../repo-check/checkRepo'; import { userLog, functionLog, debugLog, parameterAssert, logicAssert } from '../../core/utilities'; -// const BP_VALIDATOR_VERSION_STRING = '0.7.3'; +// const BP_VALIDATOR_VERSION_STRING = '0.7.8'; const STANDARD_MANIFEST_FILENAME = 'manifest.yaml'; @@ -32,15 +33,15 @@ export async function checkBookPackage(username, languageCode, bookID, setResult Note that bookID here can also be the 'OBS' pseudo bookID. */ // functionLog(`checkBookPackage(un='${username}', lC='${languageCode}', bk='${bookID}', (fn), ${JSON.stringify(checkingOptions)})…`) - parameterAssert(username !== undefined, "checkBookPackage: 'username' parameter should be defined"); - parameterAssert(typeof username === 'string', `checkBookPackage: 'username' parameter should be a string not a '${typeof username}': ${username}`); - parameterAssert(languageCode !== undefined, "checkBookPackage: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkBookPackage: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); - parameterAssert(bookID !== undefined, "checkBookPackage: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkBookPackage: 'bookID' parameter should be a string not a '${typeof bookID}': ${bookID}`); - parameterAssert(bookID.length === 3, `checkBookPackage: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkBookPackage: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkBookPackage: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(username !== undefined, "checkBookPackage: 'username' parameter should be defined"); + //parameterAssert(typeof username === 'string', `checkBookPackage: 'username' parameter should be a string not a '${typeof username}': ${username}`); + //parameterAssert(languageCode !== undefined, "checkBookPackage: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkBookPackage: 'languageCode' parameter should be a string not a '${typeof languageCode}': ${languageCode}`); + //parameterAssert(bookID !== undefined, "checkBookPackage: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkBookPackage: 'bookID' parameter should be a string not a '${typeof bookID}': ${bookID}`); + //parameterAssert(bookID.length === 3, `checkBookPackage: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkBookPackage: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkBookPackage: '${bookID}' is not a valid USFM book identifier`); let abortFlag = false; const startTime = new Date(); @@ -63,7 +64,9 @@ export async function checkBookPackage(username, languageCode, bookID, setResult // coz if it’s not 'master', it’s unlikely to be common for all the repos let originalBranch = 'master'; - const generalLocation = ` in ${languageCode} ${bookID} book package from ${username} ${originalBranch} branch`; + // If it's a big book, drop this location string to reduce memory use in case of thousands of errors + let generalLocation = bookID === 'OBS' ? ` in ${languageCode} ${bookID} from ${username} ${originalBranch} branch` : + books.chaptersInBook(bookID) > 10 ? '' : ` in ${languageCode} ${bookID} book package from ${username} ${originalBranch} branch`; function addSuccessMessage(successString) { @@ -75,28 +78,32 @@ export async function checkBookPackage(username, languageCode, bookID, setResult function addNoticePartial(noticeObject) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // functionLog(`checkBookPackage addNoticePartial: (priority=${noticeObject.priority}) ${noticeObject.bookID} ${noticeObject.C}:${noticeObject.V} ${noticeObject.message}${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${excerpt ? ` ${excerpt}` : ""}${location}`); - parameterAssert(noticeObject.priority !== undefined, "cBP addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cBP addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); - parameterAssert(noticeObject.message !== undefined, "cBP addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cBP addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); - // parameterAssert(bookID !== undefined, "cBP addNoticePartial: 'bookID' parameter should be defined"); + //parameterAssert(noticeObject.priority !== undefined, "cBP addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cBP addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}': ${noticeObject.priority}`); + //parameterAssert(noticeObject.message !== undefined, "cBP addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cBP addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}': ${noticeObject.message}`); + // //parameterAssert(bookID !== undefined, "cBP addNoticePartial: 'bookID' parameter should be defined"); if (noticeObject.bookID) { - parameterAssert(typeof noticeObject.bookID === 'string', `cBP addNoticePartial: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}': ${noticeObject.bookID}`); - parameterAssert(noticeObject.bookID.length === 3, `cBP addNoticePartial: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(noticeObject.bookID), `cBP addNoticePartial: '${noticeObject.bookID}' is not a valid USFM book identifier`); + //parameterAssert(typeof noticeObject.bookID === 'string', `cBP addNoticePartial: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}': ${noticeObject.bookID}`); + //parameterAssert(noticeObject.bookID.length === 3, `cBP addNoticePartial: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(noticeObject.bookID), `cBP addNoticePartial: '${noticeObject.bookID}' is not a valid USFM book identifier`); + } + // //parameterAssert(C !== undefined, "cBP addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `cBP addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); + } + // //parameterAssert(V !== undefined, "cBP addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `cBP addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); + } + // //parameterAssert(characterIndex !== undefined, "cBP addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cBP addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); } - // parameterAssert(C !== undefined, "cBP addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `cBP addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}': ${noticeObject.C}`); - // parameterAssert(V !== undefined, "cBP addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `cBP addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}': ${noticeObject.V}`); - // parameterAssert(characterIndex !== undefined, "cBP addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cBP addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}': ${noticeObject.characterIndex}`); - // parameterAssert(excerpt !== undefined, "cBP addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cBP addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); - parameterAssert(noticeObject.location !== undefined, "cBP addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cBP addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); - parameterAssert(noticeObject.extra !== undefined, "cBP addNoticePartial: 'extra' parameter should be defined"); - parameterAssert(typeof noticeObject.extra === 'string', `cBP addNoticePartial: 'extra' parameter should be a string not a '${typeof noticeObject.extra}': ${noticeObject.extra}`); + // //parameterAssert(excerpt !== undefined, "cBP addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cBP addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}': ${noticeObject.excerpt}`); + } + //parameterAssert(noticeObject.location !== undefined, "cBP addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cBP addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}': ${noticeObject.location}`); + //parameterAssert(noticeObject.extra !== undefined, "cBP addNoticePartial: 'extra' parameter should be defined"); + //parameterAssert(typeof noticeObject.extra === 'string', `cBP addNoticePartial: 'extra' parameter should be a string not a '${typeof noticeObject.extra}': ${noticeObject.extra}`); if (noticeObject.debugChain) noticeObject.debugChain = `checkBookPackage ${noticeObject.debugChain}`; checkBookPackageResult.noticeList.push({ ...noticeObject, bookID, username }); } @@ -106,20 +113,20 @@ export async function checkBookPackage(username, languageCode, bookID, setResult // functionLog(`checkBookPackage ourCheckBPFileContents(rC='${repoCode}', rN='${repoName}', rBr='${repoBranch}', fn='${cfFilename}', ${fileContent.length}, ${fileLocation}, ${JSON.stringify(checkingOptions)})…`); // Updates the global list of notices - parameterAssert(repoCode !== undefined, "cBP ourCheckBPFileContents: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `cBP ourCheckBPFileContents: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `cBP ourCheckBPFileContents: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(repoName !== undefined, "cBP ourCheckBPFileContents: 'repoName' parameter should be defined"); - parameterAssert(typeof repoName === 'string', `cBP ourCheckBPFileContents: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); - parameterAssert(repoBranch !== undefined, "cBP ourCheckBPFileContents: 'repoBranch' parameter should be defined"); - parameterAssert(typeof repoBranch === 'string', `cBP ourCheckBPFileContents: 'repoBranch' parameter should be a string not a '${typeof repoBranch}': ${repoBranch}`); - parameterAssert(cfFilename !== undefined, "cBP ourCheckBPFileContents: 'cfFilename' parameter should be defined"); - parameterAssert(typeof cfFilename === 'string', `cBP ourCheckBPFileContents: 'cfFilename' parameter should be a string not a '${typeof cfFilename}'`); - parameterAssert(fileContent !== undefined, "cBP ourCheckBPFileContents: 'fileContent' parameter should be defined"); - parameterAssert(typeof fileContent === 'string', `cBP ourCheckBPFileContents: 'fileContent' parameter should be a string not a '${typeof fileContent}'`); - parameterAssert(fileLocation !== undefined, "cBP ourCheckBPFileContents: 'fileLocation' parameter should be defined"); - parameterAssert(typeof fileLocation === 'string', `cBP ourCheckBPFileContents: 'fileLocation' parameter should be a string not a '${typeof fileLocation}'`); - parameterAssert(checkingOptions !== undefined, "cBP ourCheckBPFileContents: 'checkingOptions' parameter should be defined"); + //parameterAssert(repoCode !== undefined, "cBP ourCheckBPFileContents: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `cBP ourCheckBPFileContents: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `cBP ourCheckBPFileContents: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(repoName !== undefined, "cBP ourCheckBPFileContents: 'repoName' parameter should be defined"); + //parameterAssert(typeof repoName === 'string', `cBP ourCheckBPFileContents: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); + //parameterAssert(repoBranch !== undefined, "cBP ourCheckBPFileContents: 'repoBranch' parameter should be defined"); + //parameterAssert(typeof repoBranch === 'string', `cBP ourCheckBPFileContents: 'repoBranch' parameter should be a string not a '${typeof repoBranch}': ${repoBranch}`); + //parameterAssert(cfFilename !== undefined, "cBP ourCheckBPFileContents: 'cfFilename' parameter should be defined"); + //parameterAssert(typeof cfFilename === 'string', `cBP ourCheckBPFileContents: 'cfFilename' parameter should be a string not a '${typeof cfFilename}'`); + //parameterAssert(fileContent !== undefined, "cBP ourCheckBPFileContents: 'fileContent' parameter should be defined"); + //parameterAssert(typeof fileContent === 'string', `cBP ourCheckBPFileContents: 'fileContent' parameter should be a string not a '${typeof fileContent}'`); + //parameterAssert(fileLocation !== undefined, "cBP ourCheckBPFileContents: 'fileLocation' parameter should be defined"); + //parameterAssert(typeof fileLocation === 'string', `cBP ourCheckBPFileContents: 'fileLocation' parameter should be a string not a '${typeof fileLocation}'`); + //parameterAssert(checkingOptions !== undefined, "cBP ourCheckBPFileContents: 'checkingOptions' parameter should be defined"); let adjustedLanguageCode = languageCode; // if (repoCode === 'UHB') adjustedLanguageCode = 'hbo'; // NO -- we need the languageCode of the BP being checked (so we can resolve TW links with * for language) !!! @@ -164,15 +171,15 @@ export async function checkBookPackage(username, languageCode, bookID, setResult async function ourCheckManifestFile(repoCode, repoName, repoBranch, manifestLocation, checkingOptions) { // Updates the global list of notices // functionLog(`checkBookPackage ourCheckManifestFile(${repoCode}, ${repoName}, ${repoBranch}, ${manifestLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(repoCode !== undefined, "cBP ourCheckManifestFile: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `cBP ourCheckManifestFile: 'repoCode' parameter should be a string not a '${typeof repoCode}' : ${repoCode}`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `cBP ourCheckManifestFile: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(repoName !== undefined, "cBP ourCheckManifestFile: 'repoName' parameter should be defined"); - parameterAssert(typeof repoName === 'string', `cBP ourCheckManifestFile: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); - parameterAssert(repoBranch !== undefined, "cBP ourCheckManifestFile: 'repoBranch' parameter should be defined"); - parameterAssert(typeof repoBranch === 'string', `cBP ourCheckManifestFile: 'repoBranch' parameter should be a string not a '${typeof repoBranch}': ${repoBranch}`); - parameterAssert(manifestLocation !== undefined, "cBP ourCheckManifestFile: 'manifestLocation' parameter should be defined"); - parameterAssert(typeof manifestLocation === 'string', `cBP ourCheckManifestFile: 'manifestLocation' parameter should be a string not a '${typeof manifestLocation}'`); + //parameterAssert(repoCode !== undefined, "cBP ourCheckManifestFile: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `cBP ourCheckManifestFile: 'repoCode' parameter should be a string not a '${typeof repoCode}' : ${repoCode}`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `cBP ourCheckManifestFile: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(repoName !== undefined, "cBP ourCheckManifestFile: 'repoName' parameter should be defined"); + //parameterAssert(typeof repoName === 'string', `cBP ourCheckManifestFile: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); + //parameterAssert(repoBranch !== undefined, "cBP ourCheckManifestFile: 'repoBranch' parameter should be defined"); + //parameterAssert(typeof repoBranch === 'string', `cBP ourCheckManifestFile: 'repoBranch' parameter should be a string not a '${typeof repoBranch}': ${repoBranch}`); + //parameterAssert(manifestLocation !== undefined, "cBP ourCheckManifestFile: 'manifestLocation' parameter should be defined"); + //parameterAssert(typeof manifestLocation === 'string', `cBP ourCheckManifestFile: 'manifestLocation' parameter should be a string not a '${typeof manifestLocation}'`); let manifestFileContent; try { @@ -227,17 +234,17 @@ export async function checkBookPackage(username, languageCode, bookID, setResult async function ourCheckMarkdownFile(repoCode, repoName, repoBranch, filename, markdownLocation, checkingOptions) { // Updates the global list of notices // functionLog(`checkBookPackage ourCheckMarkdownFile(${repoCode}, ${repoName}, ${filename}, ${repoBranch}, ${markdownLocation}, ${JSON.stringify(checkingOptions)})…`); - parameterAssert(repoCode !== undefined, "cBP ourCheckMarkdownFile: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `cBP ourCheckMarkdownFile: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `cBP ourCheckMarkdownFile: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(repoName !== undefined, "cBP ourCheckMarkdownFile: 'repoName' parameter should be defined"); - parameterAssert(typeof repoName === 'string', `cBP ourCheckMarkdownFile: 'repoName' parameter should be a string not a '${typeof repoName}'`); - parameterAssert(repoBranch !== undefined, "cBP ourCheckMarkdownFile: 'repoBranch' parameter should be defined"); - parameterAssert(typeof repoBranch === 'string', `cBP ourCheckMarkdownFile: 'repoBranch' parameter should be a string not a '${typeof repoBranch}'`); - parameterAssert(filename !== undefined, "cBP ourCheckMarkdownFile: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `cBP ourCheckMarkdownFile: 'filename' parameter should be a string not a '${typeof filename}': ${filename}`); - parameterAssert(markdownLocation !== undefined, "cBP ourCheckMarkdownFile: 'markdownLocation' parameter should be defined"); - parameterAssert(typeof markdownLocation === 'string', `cBP ourCheckMarkdownFile: 'markdownLocation' parameter should be a string not a '${typeof markdownLocation}'`); + //parameterAssert(repoCode !== undefined, "cBP ourCheckMarkdownFile: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `cBP ourCheckMarkdownFile: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `cBP ourCheckMarkdownFile: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(repoName !== undefined, "cBP ourCheckMarkdownFile: 'repoName' parameter should be defined"); + //parameterAssert(typeof repoName === 'string', `cBP ourCheckMarkdownFile: 'repoName' parameter should be a string not a '${typeof repoName}'`); + //parameterAssert(repoBranch !== undefined, "cBP ourCheckMarkdownFile: 'repoBranch' parameter should be defined"); + //parameterAssert(typeof repoBranch === 'string', `cBP ourCheckMarkdownFile: 'repoBranch' parameter should be a string not a '${typeof repoBranch}'`); + //parameterAssert(filename !== undefined, "cBP ourCheckMarkdownFile: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `cBP ourCheckMarkdownFile: 'filename' parameter should be a string not a '${typeof filename}': ${filename}`); + //parameterAssert(markdownLocation !== undefined, "cBP ourCheckMarkdownFile: 'markdownLocation' parameter should be defined"); + //parameterAssert(typeof markdownLocation === 'string', `cBP ourCheckMarkdownFile: 'markdownLocation' parameter should be a string not a '${typeof markdownLocation}'`); let markdownFileContent; try { @@ -257,7 +264,7 @@ export async function checkBookPackage(username, languageCode, bookID, setResult } } if (markdownFileContent) { - const cmtResultObject = await checkMarkdownText(languageCode, repoCode, repoName, markdownFileContent, markdownLocation, checkingOptions); + const cmtResultObject = await checkMarkdownText(languageCode, repoCode, filename.substring(0, filename.length - 3), markdownFileContent, markdownLocation, checkingOptions); // debugLog(`ourCheckMarkdownFile checkMarkdownText(${repoName}) returned ${cmtResultObject.successList.length} success message(s) and ${cmtResultObject.noticeList.length} notice(s)`); // debugLog(`ourCheckMarkdownFile checkMarkdownText(${repoName}) returned ${JSON.stringify(cmtResultObject)}`); // NOTE: We ignore the returned success messages here @@ -298,13 +305,13 @@ export async function checkBookPackage(username, languageCode, bookID, setResult if (bookID === 'OBS') { // NOTE: No code below to handle OBS TN and TQ which are markdown repos if (dataSet === 'DEFAULT') - repoCodeList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; + repoCodeList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; else if (dataSet === 'OLD') repoCodeList = ['OBS', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; else if (dataSet === 'NEW') - repoCodeList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; + repoCodeList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; else if (dataSet === 'BOTH') - repoCodeList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; + repoCodeList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SN', 'OBS-SN2', 'OBS-SQ2']; } else { // not OBS // We also need to know the number for USFM books try { @@ -324,7 +331,7 @@ export async function checkBookPackage(username, languageCode, bookID, setResult if (dataSet === 'DEFAULT') repoCodeList = languageCode === 'en' ? [origLangRepoCode, 'TWL', 'LT', 'ST', 'TN', 'TQ', 'SN', 'SQ'] : [origLangRepoCode, 'LT', 'ST', 'TN', 'TQ']; else if (dataSet === 'OLD') - repoCodeList = languageCode === 'en' ? [origLangRepoCode, 'LT', 'ST', 'TN', 'TQ'] : [origLangRepoCode, 'LT', 'ST', 'TN', 'TQ']; + repoCodeList = languageCode === 'en' ? [origLangRepoCode, 'TWL', 'LT', 'ST', 'TN', 'TQ'] : [origLangRepoCode, 'LT', 'ST', 'TN', 'TQ']; else if (dataSet === 'NEW') repoCodeList = languageCode === 'en' ? [origLangRepoCode, 'TWL', 'LT', 'ST', 'TN2', 'TQ2', 'SN', 'SQ'] : [origLangRepoCode, 'LT', 'ST', 'TN', 'TQ']; else if (dataSet === 'BOTH') @@ -338,13 +345,15 @@ export async function checkBookPackage(username, languageCode, bookID, setResult for (const repoCode of repoCodeList) { // debugLog(`checkBookPackage for ${bookID} got repoCode=${repoCode} abortFlag=${abortFlag} from ${repoCodeList}`); if (abortFlag) break; - const repoLocation = ` in ${repoCode}${generalLocation}`; let adjustedRepoCode = repoCode, adjustedBranch = originalBranch; if (adjustedRepoCode.endsWith('2')) { adjustedRepoCode = adjustedRepoCode.substring(0, adjustedRepoCode.length - 1); // Remove the '2' from the end adjustedBranch = 'newFormat'; - } + generalLocation = generalLocation.replace(originalBranch, adjustedBranch); + } else // doesn't end with 2 + generalLocation = generalLocation.replace(adjustedBranch, originalBranch); let repoName = formRepoName(languageCode, adjustedRepoCode); + const repoLocation = ` in ${repoCode}${generalLocation}`; if (adjustedRepoCode.startsWith('OBS-')) adjustedRepoCode = adjustedRepoCode.substring(4); // Remove the 'OBS-' from the beginning // if (bookID === 'OBS' && dataSet === 'OLD' && repoCode !== 'OBS' && repoCode !== 'TWL' && repoName === `${languageCode}_${adjustedRepoCode.toLowerCase()}`) @@ -376,11 +385,21 @@ export async function checkBookPackage(username, languageCode, bookID, setResult if (repoCode === 'OBS') { // debugLog("Calling OBS checkRepo()…"); - checkBookPackageResult = await checkRepo(username, `${languageCode}_obs`, originalBranch, generalLocation, setResultValue, newCheckingOptions); // Adds the notices to checkBookPackageResult - // functionLog(`checkRepo() returned ${checkBookPackageResult.successList.length} success message(s) and ${checkBookPackageResult.noticeList.length} notice(s)`); - // debugLog("crResultObject keys", JSON.stringify(Object.keys(checkBookPackageResult))); + const crResultObject = await checkRepo(username, `${languageCode}_obs`, originalBranch, generalLocation, setResultValue, newCheckingOptions); // Adds the notices to checkBookPackageResult + // debugLog(`checkRepo('OBS') returned ${crResultObject.successList.length} success message(s) and ${crResultObject.noticeList.length} notice(s)`); + // debugLog(`crResultObject keys: ${JSON.stringify(Object.keys(crResultObject))}`); + // debugLog(`crResultObject checkedRepoNames: ${crResultObject.checkedRepoNames}`); + checkBookPackageResult.successList = checkBookPackageResult.successList.concat(crResultObject.successList); + checkBookPackageResult.noticeList = checkBookPackageResult.noticeList.concat(crResultObject.noticeList); + if (crResultObject.checkedFileCount > 0) { + checkedFilenames = checkedFilenames.concat(crResultObject.checkedFilenames); + checkedFilenameExtensions = new Set([...checkedFilenameExtensions, ...crResultObject.checkedFilenameExtensions]); + checkedFileCount += crResultObject.checkedFileCount; + totalCheckedSize += crResultObject.totalCheckedSize; + checkedRepoNames.add(repoName); + } addSuccessMessage(`Checked ${languageCode} OBS repo from ${username}`); - } else if (adjustedRepoCode === 'TQ' || repoCode === 'OBS-TN') { // OBS-TN is markdown also for now + } else if (repoCode === 'TQ' || repoCode === 'OBS-TN'|| repoCode === 'OBS-TQ') { // These are still markdown for now // This is the old markdown resource with hundreds/thousands of files const tqResultObject = await checkTQMarkdownBook(username, languageCode, repoCode, repoName, originalBranch, bookID, newCheckingOptions); checkBookPackageResult.successList = checkBookPackageResult.successList.concat(tqResultObject.successList); @@ -412,7 +431,7 @@ export async function checkBookPackage(username, languageCode, bookID, setResult else { // eslint-disable-next-line eqeqeq if (cBPgfError != 'TypeError: repoFileContent is null') details += ` error=${cBPgfError}`; - addNoticePartial({ priority: 996, message: "Unable to load", details, repoCode, repoName, filename, location: repoLocation, extra: repoCode }); + addNoticePartial({ priority: repoCode === 'SN' || repoCode === 'SQ' ? 196 : 996, message: "Unable to load", details, repoCode, repoName, filename, location: repoLocation, extra: repoCode }); } } if (repoFileContent) { @@ -495,7 +514,7 @@ export async function checkBookPackage(username, languageCode, bookID, setResult checkBookPackageResult.elapsedSeconds = (new Date() - startTime) / 1000; // seconds // debugLog("checkBookPackageResult:", JSON.stringify(checkBookPackageResult)); - // functionLog(`checkBookPackageResult(${bookID}): elapsedSeconds = ${checkBookPackageResult.elapsedSeconds}, notices count = ${checkBookPackageResult.noticeList.length}`); + // debugLog(`checkBookPackageResult(${bookID}): elapsedSeconds = ${checkBookPackageResult.elapsedSeconds}, notices count = ${checkBookPackageResult.noticeList.length}`); return checkBookPackageResult; }; // end of checkBookPackage() @@ -517,22 +536,22 @@ export async function checkBookPackage(username, languageCode, bookID, setResult */ async function checkTQMarkdownBook(username, languageCode, repoCode, repoName, branch, bookID, checkingOptions) { // functionLog(`checkBookPackage checkTQMarkdownBook(${username}, ${languageCode}, ${repoCode} ${repoName}, ${branch}, ${bookID}, ${JSON.stringify(checkingOptions)})…`) - parameterAssert(username !== undefined, "checkTQMarkdownBook: 'username' parameter should be defined"); - parameterAssert(typeof username === 'string', `checkTQMarkdownBook: 'username' parameter should be a string not a '${typeof username}': '${username}'`); - parameterAssert(languageCode !== undefined, "checkTQMarkdownBook: 'languageCode' parameter should be defined"); - parameterAssert(typeof languageCode === 'string', `checkTQMarkdownBook: 'languageCode' parameter should be a string not a '${typeof languageCode}': '${languageCode}'`); - parameterAssert(repoCode !== undefined, "checkTQMarkdownBook: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `checkTQMarkdownBook: 'repoCode' parameter should be a string not a '${typeof repoCode}': '${repoCode}'`); - parameterAssert(repoCode === 'TQ' || repoCode === 'OBS-TQ', `checkTQMarkdownBook: 'repoCode' parameter should be 'TQ' or 'OBS-TQ' not '${repoCode}'`); - parameterAssert(repoName !== undefined, "checkTQMarkdownBook: 'repoName' parameter should be defined"); - parameterAssert(typeof repoName === 'string', `checkTQMarkdownBook: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); - parameterAssert(branch !== undefined, "checkTQMarkdownBook: 'branch' parameter should be defined"); - parameterAssert(typeof branch === 'string', `checkTQMarkdownBook: 'branch' parameter should be a string not a '${typeof branch}': '${branch}'`); - parameterAssert(bookID !== undefined, "checkTQMarkdownBook: 'bookID' parameter should be defined"); - parameterAssert(typeof bookID === 'string', `checkTQMarkdownBook: 'bookID' parameter should be a string not a '${typeof bookID}': ${bookID}`); - parameterAssert(bookID.length === 3, `checkTQMarkdownBook: 'bookID' parameter should be three characters long not ${bookID.length}`); - parameterAssert(bookID.toUpperCase() === bookID, `checkTQMarkdownBook: 'bookID' parameter should be UPPERCASE not '${bookID}'`); - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkTQMarkdownBook: '${bookID}' is not a valid USFM book identifier`); + //parameterAssert(username !== undefined, "checkTQMarkdownBook: 'username' parameter should be defined"); + //parameterAssert(typeof username === 'string', `checkTQMarkdownBook: 'username' parameter should be a string not a '${typeof username}': '${username}'`); + //parameterAssert(languageCode !== undefined, "checkTQMarkdownBook: 'languageCode' parameter should be defined"); + //parameterAssert(typeof languageCode === 'string', `checkTQMarkdownBook: 'languageCode' parameter should be a string not a '${typeof languageCode}': '${languageCode}'`); + //parameterAssert(repoCode !== undefined, "checkTQMarkdownBook: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `checkTQMarkdownBook: 'repoCode' parameter should be a string not a '${typeof repoCode}': '${repoCode}'`); + //parameterAssert(repoCode === 'TQ' || repoCode === 'OBS-TQ', `checkTQMarkdownBook: 'repoCode' parameter should be 'TQ' or 'OBS-TQ' not '${repoCode}'`); + //parameterAssert(repoName !== undefined, "checkTQMarkdownBook: 'repoName' parameter should be defined"); + //parameterAssert(typeof repoName === 'string', `checkTQMarkdownBook: 'repoName' parameter should be a string not a '${typeof repoName}': ${repoName}`); + //parameterAssert(branch !== undefined, "checkTQMarkdownBook: 'branch' parameter should be defined"); + //parameterAssert(typeof branch === 'string', `checkTQMarkdownBook: 'branch' parameter should be a string not a '${typeof branch}': '${branch}'`); + //parameterAssert(bookID !== undefined, "checkTQMarkdownBook: 'bookID' parameter should be defined"); + //parameterAssert(typeof bookID === 'string', `checkTQMarkdownBook: 'bookID' parameter should be a string not a '${typeof bookID}': ${bookID}`); + //parameterAssert(bookID.length === 3, `checkTQMarkdownBook: 'bookID' parameter should be three characters long not ${bookID.length}`); + //parameterAssert(bookID.toUpperCase() === bookID, `checkTQMarkdownBook: 'bookID' parameter should be UPPERCASE not '${bookID}'`); + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkTQMarkdownBook: '${bookID}' is not a valid USFM book identifier`); const generalLocation = ` in ${username} (${branch})`; @@ -546,26 +565,30 @@ async function checkTQMarkdownBook(username, languageCode, repoCode, repoName, b function addNoticePartial(noticeObject) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // functionLog(`checkTQMarkdownBook addNoticePartial: ${noticeObject.priority}:${noticeObject.message} ${noticeObject.bookID} ${noticeObject.C}:${noticeObject.V} ${noticeObject.filename}:${noticeObject.lineNumber} ${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? ` ${noticeObject.excerpt}` : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cTQ addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cTQ addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}'`); - parameterAssert(noticeObject.message !== undefined, "cTQ addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cTQ addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}'`); - parameterAssert(noticeObject.bookID !== undefined, "cTQ addNoticePartial: 'bookID' parameter should be defined"); - parameterAssert(typeof noticeObject.bookID === 'string', `cTQ addNoticePartial: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}'`); - parameterAssert(noticeObject.bookID.length === 3, `cTQ addNoticePartial: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); - parameterAssert(noticeObject.bookID === 'OBS' || books.isValidBookID(noticeObject.bookID), `cTQ addNoticePartial: '${noticeObject.bookID}' is not a valid USFM book identifier`); - // parameterAssert(C !== undefined, "cTQ addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `cTQ addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}'`); - // parameterAssert(V !== undefined, "cTQ addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `cTQ addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}'`); - // parameterAssert(characterIndex !== undefined, "cTQ addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cTQ addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}'`); - // parameterAssert(excerpt !== undefined, "cTQ addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cTQ addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}'`); - parameterAssert(noticeObject.location !== undefined, "cTQ addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cTQ addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}'`); - parameterAssert(noticeObject.extra !== undefined, "cTQ addNoticePartial: 'extra' parameter should be defined"); - parameterAssert(typeof noticeObject.extra === 'string', `cTQ addNoticePartial: 'extra' parameter should be a string not a '${typeof noticeObject.extra}'`); + //parameterAssert(noticeObject.priority !== undefined, "cTQ addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cTQ addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}'`); + //parameterAssert(noticeObject.message !== undefined, "cTQ addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cTQ addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}'`); + //parameterAssert(noticeObject.bookID !== undefined, "cTQ addNoticePartial: 'bookID' parameter should be defined"); + //parameterAssert(typeof noticeObject.bookID === 'string', `cTQ addNoticePartial: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}'`); + //parameterAssert(noticeObject.bookID.length === 3, `cTQ addNoticePartial: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); + //parameterAssert(noticeObject.bookID === 'OBS' || books.isValidBookID(noticeObject.bookID), `cTQ addNoticePartial: '${noticeObject.bookID}' is not a valid USFM book identifier`); + // //parameterAssert(C !== undefined, "cTQ addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `cTQ addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}'`); + } + // //parameterAssert(V !== undefined, "cTQ addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `cTQ addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}'`); + } + // //parameterAssert(characterIndex !== undefined, "cTQ addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cTQ addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}'`); + } + // //parameterAssert(excerpt !== undefined, "cTQ addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cTQ addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}'`); + } + //parameterAssert(noticeObject.location !== undefined, "cTQ addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cTQ addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}'`); + //parameterAssert(noticeObject.extra !== undefined, "cTQ addNoticePartial: 'extra' parameter should be defined"); + //parameterAssert(typeof noticeObject.extra === 'string', `cTQ addNoticePartial: 'extra' parameter should be a string not a '${typeof noticeObject.extra}'`); ctqResult.noticeList.push({ ...noticeObject, username, repoCode, repoName, bookID }); } @@ -585,16 +608,16 @@ async function checkTQMarkdownBook(username, languageCode, repoCode, repoName, b // functionLog(`checkBookPackage ourCheckTQFileContents(${repoCode}, ${bookID} ${C}:${V} ${cfFilename}…)…`); // Updates the global list of notices - parameterAssert(repoCode !== undefined, "cTQ ourCheckTQFileContents: 'repoCode' parameter should be defined"); - parameterAssert(typeof repoCode === 'string', `cTQ ourCheckTQFileContents: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); - parameterAssert(REPO_CODES_LIST.includes(repoCode), `cTQ ourCheckTQFileContents: 'repoCode' parameter should not be '${repoCode}'`); - parameterAssert(cfFilename !== undefined, "cTQ ourCheckTQFileContents: 'cfFilename' parameter should be defined"); - parameterAssert(typeof cfFilename === 'string', `cTQ ourCheckTQFileContents: 'cfFilename' parameter should be a string not a '${typeof cfFilename}'`); - parameterAssert(fileContent !== undefined, "cTQ ourCheckTQFileContents: 'fileContent' parameter should be defined"); - parameterAssert(typeof fileContent === 'string', `cTQ ourCheckTQFileContents: 'fileContent' parameter should be a string not a '${typeof fileContent}'`); - parameterAssert(fileLocation !== undefined, "cTQ ourCheckTQFileContents: 'fileLocation' parameter should be defined"); - parameterAssert(typeof fileLocation === 'string', `cTQ ourCheckTQFileContents: 'fileLocation' parameter should be a string not a '${typeof fileLocation}'`); - parameterAssert(checkingOptions !== undefined, "cTQ ourCheckTQFileContents: 'checkingOptions' parameter should be defined"); + //parameterAssert(repoCode !== undefined, "cTQ ourCheckTQFileContents: 'repoCode' parameter should be defined"); + //parameterAssert(typeof repoCode === 'string', `cTQ ourCheckTQFileContents: 'repoCode' parameter should be a string not a '${typeof repoCode}'`); + //parameterAssert(REPO_CODES_LIST.includes(repoCode), `cTQ ourCheckTQFileContents: 'repoCode' parameter should not be '${repoCode}'`); + //parameterAssert(cfFilename !== undefined, "cTQ ourCheckTQFileContents: 'cfFilename' parameter should be defined"); + //parameterAssert(typeof cfFilename === 'string', `cTQ ourCheckTQFileContents: 'cfFilename' parameter should be a string not a '${typeof cfFilename}'`); + //parameterAssert(fileContent !== undefined, "cTQ ourCheckTQFileContents: 'fileContent' parameter should be defined"); + //parameterAssert(typeof fileContent === 'string', `cTQ ourCheckTQFileContents: 'fileContent' parameter should be a string not a '${typeof fileContent}'`); + //parameterAssert(fileLocation !== undefined, "cTQ ourCheckTQFileContents: 'fileLocation' parameter should be defined"); + //parameterAssert(typeof fileLocation === 'string', `cTQ ourCheckTQFileContents: 'fileLocation' parameter should be a string not a '${typeof fileLocation}'`); + //parameterAssert(checkingOptions !== undefined, "cTQ ourCheckTQFileContents: 'checkingOptions' parameter should be defined"); const cfResultObject = await checkFileContents(username, languageCode, repoCode, branch, cfFilename, fileContent, fileLocation, checkingOptions); // debugLog("checkFileContents() returned", cfResultObject.successList.length, "success message(s) and", cfResultObject.noticeList.length, "notice(s)"); @@ -603,7 +626,7 @@ async function checkTQMarkdownBook(username, languageCode, repoCode, repoName, b // Process noticeList line by line, appending the repoCode as an extra field as we go for (const noticeEntry of cfResultObject.noticeList) { // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=characterIndex, 7=excerpt, 8=location - // parameterAssert(Object.keys(noticeEntry).length === 5, `cTQ ourCheckTQFileContents notice length=${Object.keys(noticeEntry).length}`); + // //parameterAssert(Object.keys(noticeEntry).length === 5, `cTQ ourCheckTQFileContents notice length=${Object.keys(noticeEntry).length}`); // We add the repoCode as an extra value addNoticePartial({ ...noticeEntry, bookID, C, V, extra: repoCode }); } @@ -629,7 +652,7 @@ async function checkTQMarkdownBook(username, languageCode, repoCode, repoName, b for (const thisPath of pathList) { // debugLog("checkTQMarkdownBook: Try to load", username, repoName, thisPath, branch); - parameterAssert(thisPath.endsWith('.md'), `Expected ${thisPath} to end with .md`); + //parameterAssert(thisPath.endsWith('.md'), `Expected ${thisPath} to end with .md`); // const filename = thisPath.split('/').pop(); const pathParts = thisPath.slice(0, -3).split('/'); const C = pathParts[pathParts.length - 2].replace(/^0+(?=\d)/, ''); // Remove leading zeroes diff --git a/src/demos/book-packages-check/BookPackagesCheck.js b/src/demos/book-packages-check/BookPackagesCheck.js index 29d3ddbbe..d006c7778 100644 --- a/src/demos/book-packages-check/BookPackagesCheck.js +++ b/src/demos/book-packages-check/BookPackagesCheck.js @@ -5,10 +5,11 @@ import { clearCaches, clearCheckedArticleCache, ourParseInt, preloadReposIfNeces import { checkBookPackages } from './checkBookPackages'; import { processNoticesToErrorsWarnings, processNoticesToSevereMediumLow, processNoticesToSingleList } from '../notice-processing-functions'; import { RenderSuccesses, RenderSuccessesErrorsWarnings, RenderSuccessesSevereMediumLow, RenderSuccessesWarningsGradient, RenderTotals } from '../RenderProcessedResults'; -import { userLog, debugLog } from '../../core/utilities'; +// eslint-disable-next-line no-unused-vars +import { userLog, debugLog, logicAssert } from '../../core/utilities'; -// const BPS_VALIDATOR_VERSION_STRING = '0.2.4'; +// const BPS_VALIDATOR_VERSION_STRING = '0.2.7'; /** @@ -16,197 +17,208 @@ import { userLog, debugLog } from '../../core/utilities'; * @param {Object} props */ function BookPackagesCheck(/*username, languageCode, bookIDs,*/ props) { - // Check a single Bible book across many repositories - const [result, setResultValue] = useState("Waiting-CheckBookPackages"); - - // debugLog(`I'm here in BookPackagesCheck v${BPS_VALIDATOR_VERSION_STRING}`); - // consoleLogObject("props", props); - // consoleLogObject("props.classes", props.classes); - - let username = props.username; - // debugLog(`username='${username}'`); - let languageCode = props.languageCode; - // debugLog(`languageCode='${languageCode}'`); - let bookIDs = props.bookIDs; - // debugLog(`bookIDs='${bookIDs}'`); - let dataSet = props.dataSet; - // debugLog(`dataSet='${dataSet}'`); - let branch = props.branch; - // debugLog(`branch='${branch}'`); - - const bookIDList = []; - let bookIDInvalid; - let haveOT = false, haveNT = false; - for (let bookID of bookIDs.split(',')) { - bookID = bookID.trim(); - if (!books.isValidBookID(bookID) && bookID!=='OBS') { - bookIDInvalid = bookID; - } - bookIDList.push(bookID); - if (books.isValidBookID(bookID)) { - const whichTestament = books.testament(bookID); - if (whichTestament==='old') haveOT = true; - if (whichTestament==='new') haveNT = true; - } + // Check a single Bible book across many repositories + const [result, setResultValue] = useState("Waiting-CheckBookPackages"); + + // debugLog(`I'm here in BookPackagesCheck v${BPS_VALIDATOR_VERSION_STRING}`); + // consoleLogObject("props", props); + // consoleLogObject("props.classes", props.classes); + + let username = props.username; + // debugLog(`username='${username}'`); + let languageCode = props.languageCode; + // debugLog(`languageCode='${languageCode}'`); + let bookIDs = props.bookIDs; + // debugLog(`bookIDs='${bookIDs}'`); + let dataSet = props.dataSet; + // debugLog(`dataSet='${dataSet}'`); + let branch = props.branch; + // debugLog(`branch='${branch}'`); + + const bookIDList = []; + let bookIDInvalid; + let haveOT = false, haveNT = false; + for (let bookID of bookIDs.split(',')) { + bookID = bookID.trim(); + if (!books.isValidBookID(bookID) && bookID !== 'OBS') { + bookIDInvalid = bookID; } - // debugLog(`bookIDList (${bookIDList.length}) = ${bookIDList.join(', ')}`); - - const checkingOptions = { // Uncomment any of these to test them - dataSet: dataSet, // Can be 'OLD' (Markdown, etc.), 'NEW' (TSV only), or 'BOTH', or 'DEFAULT' - // excerptLength: 25, - suppressNoticeDisablingFlag: true, // Leave this one as true (otherwise demo checks are less efficient) - }; - // Or this allows the parameters to be specified as a BookPackagesCheck property - if (props.excerptLength) checkingOptions.excerptLength = ourParseInt(props.excerptLength); - if (props.cutoffPriorityLevel) checkingOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); - if (props.disableAllLinkFetchingFlag) checkingOptions.disableAllLinkFetchingFlag = props.disableAllLinkFetchingFlag.toLowerCase() === 'true'; - if (props.disableLinkedTAArticlesCheckFlag) checkingOptions.disableLinkedTAArticlesCheckFlag = props.disableLinkedTAArticlesCheckFlag.toLowerCase() === 'true'; - if (props.disableLinkedTWArticlesCheckFlag) checkingOptions.disableLinkedTWArticlesCheckFlag = props.disableLinkedTWArticlesCheckFlag.toLowerCase() === 'true'; - // functionLog(`checkingOptions.disableLinkedTAArticlesCheckFlag ${checkingOptions.disableLinkedTAArticlesCheckFlag} from '${props.disableLinkedTAArticlesCheckFlag}'`); - // functionLog(`checkingOptions.disableLinkedTWArticlesCheckFlag ${checkingOptions.disableLinkedTWArticlesCheckFlag} from '${props.disableLinkedTWArticlesCheckFlag}'`); - - useEffect(() => { - // debugLog("BookPackagesCheck.useEffect() called with ", JSON.stringify(props)); - - // Use an IIFE (Immediately Invoked Function Expression) - // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 - (async () => { - // debugLog("Started BookPackagesCheck.unnamedFunction()"); - - // NOTE from RJH: I can’t find the correct React place for this / way to do this - // so it shows a warning for the user, and doesn’t continue to try to process - if (!props.wait || props.wait !== 'N') { - setResultValue(

Waiting for user… (Adjust settings below as necessary and then set wait='N' to start)

); - return; - } - - if (props.reloadAllFilesFirst && props.reloadAllFilesFirst.slice(0).toUpperCase() === 'Y') { - userLog("Clearing cache before running book packages check…"); - setResultValue(

Clearing cache before running book packages check…

); - await clearCaches(); - } - else await clearCheckedArticleCache(); - - // Load whole repos, especially if we are going to check files in manifests - let repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ', 'SN', 'SQ']; // for DEFAULT + bookIDList.push(bookID); + if (books.isValidBookID(bookID)) { + const whichTestament = books.testament(bookID); + logicAssert(whichTestament === 'old' || whichTestament === 'new', `BookPackagesCheck() couldn't find testament for '${bookID}'`); + if (whichTestament === 'old') haveOT = true; + if (whichTestament === 'new') haveNT = true; + } + } + // debugLog(`bookIDList (${bookIDList.length}) = ${bookIDList.join(', ')}`); + + const checkingOptions = { // Uncomment any of these to test them + dataSet: dataSet, // Can be 'OLD' (Markdown, etc.), 'NEW' (TSV only), or 'BOTH', or 'DEFAULT' + // excerptLength: 25, + suppressNoticeDisablingFlag: true, // Leave this one as true (otherwise demo checks are less efficient) + }; + // Or this allows the parameters to be specified as a BookPackagesCheck property + if (props.excerptLength) checkingOptions.excerptLength = ourParseInt(props.excerptLength); + if (props.cutoffPriorityLevel) checkingOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); + if (props.disableAllLinkFetchingFlag) checkingOptions.disableAllLinkFetchingFlag = props.disableAllLinkFetchingFlag.toLowerCase() === 'true'; + if (props.disableLinkedTAArticlesCheckFlag) checkingOptions.disableLinkedTAArticlesCheckFlag = props.disableLinkedTAArticlesCheckFlag.toLowerCase() === 'true'; + if (props.disableLinkedTWArticlesCheckFlag) checkingOptions.disableLinkedTWArticlesCheckFlag = props.disableLinkedTWArticlesCheckFlag.toLowerCase() === 'true'; + // functionLog(`checkingOptions.disableLinkedTAArticlesCheckFlag ${checkingOptions.disableLinkedTAArticlesCheckFlag} from '${props.disableLinkedTAArticlesCheckFlag}'`); + // functionLog(`checkingOptions.disableLinkedTWArticlesCheckFlag ${checkingOptions.disableLinkedTWArticlesCheckFlag} from '${props.disableLinkedTWArticlesCheckFlag}'`); + + useEffect(() => { + // debugLog("BookPackagesCheck.useEffect() called with ", JSON.stringify(props)); + + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // debugLog("Started BookPackagesCheck.unnamedFunction()"); + + // NOTE from RJH: I can’t find the correct React place for this / way to do this + // so it shows a warning for the user, and doesn’t continue to try to process + if (!props.wait || props.wait !== 'N') { + setResultValue(

Waiting for user… (Adjust settings below as necessary and then set wait='N' to start)

); + return; + } + + if (props.reloadAllFilesFirst && props.reloadAllFilesFirst.slice(0).toUpperCase() === 'Y') { + userLog("Clearing cache before running book packages check…"); + setResultValue(

Clearing cache before running book packages check…

); + await clearCaches(); + } + else await clearCheckedArticleCache(); // otherwise we wouldn't see any of the warnings again from checking these + + // Load whole repos, especially if we are going to check files in manifests + let repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ', 'SN', 'SQ']; // for DEFAULT + if (dataSet === 'OLD') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ']; + else if (dataSet === 'NEW') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN2', 'TQ2', 'SN', 'SQ']; + else if (dataSet === 'BOTH') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TN2', 'TQ', 'TQ2', 'SN', 'SQ']; + if (haveNT) repoPreloadList.unshift('UGNT'); + if (haveOT) repoPreloadList.unshift('UHB'); + if (!checkingOptions.disableAllLinkFetchingFlag) { + repoPreloadList.push('TW'); + repoPreloadList.push('TA'); + } + if (bookIDList.includes('OBS')) { + let obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; // for DEFAULT if (dataSet === 'OLD') - repoPreloadList = ['LT', 'ST', 'TN', 'TQ']; + obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; else if (dataSet === 'NEW') - repoPreloadList = ['TWL', 'LT', 'ST', 'TN2', 'TQ2', 'SN', 'SQ']; + obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; else if (dataSet === 'BOTH') - repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TN2', 'TQ', 'TQ2', 'SN', 'SQ']; - if (haveNT) repoPreloadList.unshift('UGNT'); - if (haveOT) repoPreloadList.unshift('UHB'); - if (!checkingOptions.disableAllLinkFetchingFlag) { - repoPreloadList.push('TW'); - repoPreloadList.push('TA'); + obsRepoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SN', 'OBS-SN2', 'OBS-SQ2']; + repoPreloadList.push.apply(repoPreloadList, obsRepoPreloadList); } - debugLog(`BookPackagesCheck got repoPreloadList=${repoPreloadList} for dataSet=${dataSet}`) - - setResultValue(

Preloading {repoPreloadList.length} repos for {username} {languageCode} ready for book packages check…

); - const successFlag = await preloadReposIfNecessary(username, languageCode, bookIDList, branch, repoPreloadList); - if (!successFlag) - console.error(`BookPackagesCheck error: Failed to pre-load all repos`) - - // Display our "waiting" message - setResultValue(

Checking {username} {languageCode} {bookIDList.join(', ')} book packages…

); - - const rawCBPsResults = await checkBookPackages(username, languageCode, bookIDList, setResultValue, checkingOptions); - - // Add some extra fields to our rawCBPsResults object in case we need this information again later - rawCBPsResults.checkType = 'BookPackages'; - rawCBPsResults.username = username; - rawCBPsResults.languageCode = languageCode; - rawCBPsResults.bookIDs = bookIDs; - rawCBPsResults.bookIDList = bookIDList; - rawCBPsResults.checkedOptions = checkingOptions; - - // debugLog("Here with CBPs rawCBPsResults", typeof rawCBPsResults); - // Now do our final handling of the result -- we have some options available - let processOptions = { // Uncomment any of these to test them - // 'maximumSimilarMessages': 4, // default is 3 -- 0 means don’t suppress - // 'errorPriorityLevel': 800, // default is 700 - // 'cutoffPriorityLevel': 100, // default is 0 - // 'sortBy': 'ByRepo', // default is 'ByPriority', also have 'AsFound' - // 'ignorePriorityNumberList': [123, 202], // default is [] - }; - // Or this allows the parameters to be specified as a BookPackagesCheck property - if (props.maximumSimilarMessages) processOptions.maximumSimilarMessages = ourParseInt(props.maximumSimilarMessages); - if (props.errorPriorityLevel) processOptions.errorPriorityLevel = ourParseInt(props.errorPriorityLevel); - // if (props.cutoffPriorityLevel) processOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); - if (props.sortBy) processOptions.sortBy = props.sortBy; - // if (props.ignorePriorityNumberList) processOptions.ignorePriorityNumberList = props.ignorePriorityNumberList; - if (props.showDisabledNoticesFlag) processOptions.showDisabledNoticesFlag = props.showDisabledNoticesFlag.toLowerCase() === 'true'; - - let displayType = 'ErrorsWarnings'; // default - if (props.displayType) displayType = props.displayType; + // debugLog(`BookPackagesCheck got repoPreloadList=${repoPreloadList} for dataSet=${dataSet}`) + + setResultValue(

Preloading {repoPreloadList.length} repos for {username} {languageCode} ready for book packages check…

); + const successFlag = await preloadReposIfNecessary(username, languageCode, bookIDList, branch, repoPreloadList); + if (!successFlag) + console.error(`BookPackagesCheck error: Failed to pre-load all repos`) + + // Display our "waiting" message + setResultValue(

Checking {username} {languageCode} {bookIDList.join(', ')} book packages…

); + + const rawCBPsResults = await checkBookPackages(username, languageCode, bookIDList, setResultValue, checkingOptions); + + // Add some extra fields to our rawCBPsResults object in case we need this information again later + rawCBPsResults.checkType = 'BookPackages'; + rawCBPsResults.username = username; + rawCBPsResults.languageCode = languageCode; + rawCBPsResults.bookIDs = bookIDs; + rawCBPsResults.bookIDList = bookIDList; + rawCBPsResults.checkedOptions = checkingOptions; + + // debugLog("Here with CBPs rawCBPsResults", typeof rawCBPsResults); + // Now do our final handling of the result -- we have some options available + let processOptions = { // Uncomment any of these to test them + // 'maximumSimilarMessages': 4, // default is 3 -- 0 means don’t suppress + // 'errorPriorityLevel': 800, // default is 700 + // 'cutoffPriorityLevel': 100, // default is 0 + // 'sortBy': 'ByRepo', // default is 'ByPriority', also have 'AsFound' + // 'ignorePriorityNumberList': [123, 202], // default is [] + }; + // Or this allows the parameters to be specified as a BookPackagesCheck property + if (props.maximumSimilarMessages) processOptions.maximumSimilarMessages = ourParseInt(props.maximumSimilarMessages); + if (props.errorPriorityLevel) processOptions.errorPriorityLevel = ourParseInt(props.errorPriorityLevel); + // if (props.cutoffPriorityLevel) processOptions.cutoffPriorityLevel = ourParseInt(props.cutoffPriorityLevel); + if (props.sortBy) processOptions.sortBy = props.sortBy; + // if (props.ignorePriorityNumberList) processOptions.ignorePriorityNumberList = props.ignorePriorityNumberList; + if (props.showDisabledNoticesFlag) processOptions.showDisabledNoticesFlag = props.showDisabledNoticesFlag.toLowerCase() === 'true'; + + let displayType = 'ErrorsWarnings'; // default + if (props.displayType) displayType = props.displayType; function renderSummary(processedResults) { - return (
-

Checked {username} {languageCode} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches)

- - - {/* */} -
); - } + return (
+

Checked {username} {languageCode} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches)

+ + + {/* */} +
); + } if (displayType === 'ErrorsWarnings') { - const processedResults = processNoticesToErrorsWarnings(rawCBPsResults, processOptions); - // userLog(`BookPackagesCheck got back processedResults with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) - // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); - - // debugLog("Here now in rendering bit!"); - - if (processedResults.errorList.length || processedResults.warningList.length) - setResultValue(<> - {renderSummary(processedResults)} - - ); - else // no errors or warnings - setResultValue(<> - {renderSummary(processedResults)} - - ); - - } else if (displayType === 'SevereMediumLow') { - const processedResults = processNoticesToSevereMediumLow(rawCBPsResults, processOptions); - // userLog(`BookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) - // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); - - if (processedResults.severeList.length || processedResults.mediumList.length || processedResults.lowList.length) - setResultValue(<> - {renderSummary(processedResults)} - - ); - else // no severe, medium, or low notices - setResultValue(<> - {renderSummary(processedResults)} - - ); - - } else if (displayType === 'SingleList') { - const processedResults = processNoticesToSingleList(rawCBPsResults, processOptions); - // userLog(`BookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s) and ${processedResults.warningList.length.toLocaleString()} notice(s) - // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); - - if (processedResults.warningList.length) - setResultValue(<> -
{renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""}
- - ); - else // no warnings - setResultValue(<> - {renderSummary(processedResults)} - - ); - } else setResultValue(Invalid displayType='{displayType}') - - // debugLog("Finished rendering bit."); - })(); // end of async part in unnamedFunction - // Doesn’t work if we add this to next line: bookIDList,bookIDs,username,branch,checkingOptions,languageCode,props + const processedResults = processNoticesToErrorsWarnings(rawCBPsResults, processOptions); + // userLog(`BookPackagesCheck got back processedResults with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) + // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); + + // debugLog("Here now in rendering bit!"); + + if (processedResults.errorList.length || processedResults.warningList.length) + setResultValue(<> + {renderSummary(processedResults)} + + ); + else // no errors or warnings + setResultValue(<> + {renderSummary(processedResults)} + + ); + + } else if (displayType === 'SevereMediumLow') { + const processedResults = processNoticesToSevereMediumLow(rawCBPsResults, processOptions); + // userLog(`BookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) + // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); + + if (processedResults.severeList.length || processedResults.mediumList.length || processedResults.lowList.length) + setResultValue(<> + {renderSummary(processedResults)} + + ); + else // no severe, medium, or low notices + setResultValue(<> + {renderSummary(processedResults)} + + ); + + } else if (displayType === 'SingleList') { + const processedResults = processNoticesToSingleList(rawCBPsResults, processOptions); + // userLog(`BookPackagesCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s) and ${processedResults.warningList.length.toLocaleString()} notice(s) + // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); + + if (processedResults.warningList.length) + setResultValue(<> +
{renderSummary(processedResults)} + {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""}
+ + ); + else // no warnings + setResultValue(<> + {renderSummary(processedResults)} + + ); + } else setResultValue(Invalid displayType='{displayType}') + + // debugLog("Finished rendering bit."); + })(); // end of async part in unnamedFunction + // Doesn’t work if we add this to next line: bookIDList,bookIDs,username,branch,checkingOptions,languageCode,props // eslint-disable-next-line react-hooks/exhaustive-deps - }, [JSON.stringify(bookIDList), bookIDs, branch, JSON.stringify(checkingOptions), languageCode, JSON.stringify(props), username]); // end of useEffect part + }, [JSON.stringify(bookIDList), bookIDs, branch, JSON.stringify(checkingOptions), languageCode, JSON.stringify(props), username]); // end of useEffect part if (bookIDInvalid) { return (

Please enter only valid USFM book identifiers separated by commas. ('{bookIDInvalid}' is not valid.)

); diff --git a/src/demos/book-packages-check/README.md b/src/demos/book-packages-check/README.md index 7951539dc..51ef7da95 100644 --- a/src/demos/book-packages-check/README.md +++ b/src/demos/book-packages-check/README.md @@ -1,6 +1,6 @@ ## Door43 Book Packages Check - Readme -The code below requests some info and then checks the given Bible books across several repos. This is convenient to see all these check results collected into one place. +The code below requests some info and then downloads and checks the given Bible books across several repos. This is convenient to see all these check results collected into one place. See a list of valid book identifiers [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. @@ -13,8 +13,10 @@ Note that `OBS` can also be entered here as a *pseudo book identifier* in order **Note**: This demonstration can use saved (cached) copies of files stored inside the local browser. This makes reruns of the checks faster, but it won’t notice if you have recently updated the files on Door43. If you want to clear the local caches, use either the `reloadAllFilesFirst` variable below, or the `Clear Cache` function from the menu. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import BookPackagesCheck from './BookPackagesCheck'; @@ -23,15 +25,17 @@ import BookPackagesCheck from './BookPackagesCheck'; wait='Y' // 'Y' (for Yes, i.e., to wait) or 'N' (for No, i.e., to start checking) // Set to N to rerun the check without fetching new copies of the files (slightly faster) + // If you're checking and then editing & saving files, ensure that it's set to Y before you recheck reloadAllFilesFirst='Y' // 'Y' (for Yes -- same as ClearCache in menu) or 'N' (for No) username='unfoldingWord' languageCode='en' // Enter a string containing UPPERCASE USFM book identifiers separated only by commas // and can also include OBS (for Open Bible Stories) - // bookIDs='RUT,EZR,NEH,EST,OBA,JON' // OT - bookIDs='EPH,1TI,2TI,TIT,1JN,2JN,3JN' // NT + bookIDs='RUT,EZR,NEH,EST,OBA,JON,LUK,EPH,1TI,2TI,TIT,JAS,1JN,2JN,3JN' // The above English book packages should all be finished or well along the way + // bookIDs='RUT,EZR,NEH,EST,OBA,JON' // Uncomment if you're interested in OT only + // bookIDs='LUK,EPH,1TI,2TI,TIT,JAS,1JN,2JN,3JN' // Uncomment if you're interested in NT only // We can choose the forthcoming new TSV formats or the existing formats // dataSet='OLD' // 'OLD' (Markdown TQ, TSV TN, etc.), 'NEW' (TSV TQ2, TN2, etc.), 'DEFAULT', or 'BOTH' @@ -43,9 +47,9 @@ import BookPackagesCheck from './BookPackagesCheck'; // Lines starting with // are ignored -- you can add or remove // as desired // Specifying maximumSimilarMessages and excerptLength is just to show off options // —those fields are not necessary (or normal) here - maximumSimilarMessages='4' // Default is 3 (0 means don’t suppress any) - // excerptLength='20' // Default is 15 - // cutoffPriorityLevel='200' // Default is to detect all errors/warnings + maximumSimilarMessages='8' // Default is 3 (0 means don’t suppress any) + // excerptLength='25' // Default is 20 characters + cutoffPriorityLevel='200' // Default is to detect all errors/warnings // sortBy='ByRepo' // Default is 'ByPriority'; also have 'ByRepo' and 'AsFound' // showDisabledNoticesFlag='false' // Display known specific non-issues: 'true' or 'false' /> diff --git a/src/demos/book-packages-check/checkBookPackages.js b/src/demos/book-packages-check/checkBookPackages.js index edff0bea8..6ab925023 100644 --- a/src/demos/book-packages-check/checkBookPackages.js +++ b/src/demos/book-packages-check/checkBookPackages.js @@ -1,9 +1,9 @@ import * as books from '../../core/books/books'; import { checkBookPackage } from '../book-package-check/checkBookPackage'; +// eslint-disable-next-line no-unused-vars import { userLog, parameterAssert } from '../../core/utilities'; -// import { consoleLogObject } from '../../core/utilities'; -// const BPs_VALIDATOR_VERSION_STRING = '0.2.5'; +// const BPs_VALIDATOR_VERSION_STRING = '0.2.6'; /** @@ -32,28 +32,32 @@ export async function checkBookPackages(username, languageCode, bookIDList, setR function addNotice(noticeObject) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. userLog(`cBPs addNotice: (priority=${noticeObject.priority}) ${noticeObject.extra} ${noticeObject.message}${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? ` ${noticeObject.excerpt}` : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cBPs addNotice: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cBPs addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}'`); - parameterAssert(noticeObject.message !== undefined, "cBPs addNotice: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cBPs addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}'`); - // parameterAssert(bookID !== undefined, "cBPs addNotice: 'bookID' parameter should be defined"); + //parameterAssert(noticeObject.priority !== undefined, "cBPs addNotice: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cBPs addNotice: 'priority' parameter should be a number not a '${typeof noticeObject.priority}'`); + //parameterAssert(noticeObject.message !== undefined, "cBPs addNotice: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cBPs addNotice: 'message' parameter should be a string not a '${typeof noticeObject.message}'`); + // //parameterAssert(bookID !== undefined, "cBPs addNotice: 'bookID' parameter should be defined"); if (noticeObject.bookID) { - parameterAssert(typeof noticeObject.bookID === 'string', `cBPs addNotice: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}'`); - parameterAssert(noticeObject.bookID.length === 3, `cBPs addNotice: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); - parameterAssert(books.isValidBookID(noticeObject.bookID), `cBPs addNotice: '${noticeObject.bookID}' is not a valid USFM book identifier`); + //parameterAssert(typeof noticeObject.bookID === 'string', `cBPs addNotice: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}'`); + //parameterAssert(noticeObject.bookID.length === 3, `cBPs addNotice: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); + //parameterAssert(books.isValidBookID(noticeObject.bookID), `cBPs addNotice: '${noticeObject.bookID}' is not a valid USFM book identifier`); } - // parameterAssert(C !== undefined, "cBPs addNotice: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `cBPs addNotice: 'C' parameter should be a string not a '${typeof noticeObject.C}'`); - // parameterAssert(V !== undefined, "cBPs addNotice: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `cBPs addNotice: 'V' parameter should be a string not a '${typeof noticeObject.V}'`); - // parameterAssert(characterIndex !== undefined, "cBPs addNotice: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cBPs addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}'`); - // parameterAssert(excerpt !== undefined, "cBPs addNotice: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cBPs addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}'`); - parameterAssert(noticeObject.location !== undefined, "cBPs addNotice: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cBPs addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}'`); - parameterAssert(noticeObject.extra !== undefined, "cBPs addNotice: 'extra' parameter should be defined"); - parameterAssert(typeof noticeObject.extra === 'string', `cBPs addNotice: 'extra' parameter should be a string not a '${typeof extra}'`); + // //parameterAssert(C !== undefined, "cBPs addNotice: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `cBPs addNotice: 'C' parameter should be a string not a '${typeof noticeObject.C}'`); + } + // //parameterAssert(V !== undefined, "cBPs addNotice: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `cBPs addNotice: 'V' parameter should be a string not a '${typeof noticeObject.V}'`); + } + // //parameterAssert(characterIndex !== undefined, "cBPs addNotice: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cBPs addNotice: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}'`); + } + // //parameterAssert(excerpt !== undefined, "cBPs addNotice: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cBPs addNotice: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}'`); + } + //parameterAssert(noticeObject.location !== undefined, "cBPs addNotice: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cBPs addNotice: 'location' parameter should be a string not a '${typeof noticeObject.location}'`); + //parameterAssert(noticeObject.extra !== undefined, "cBPs addNotice: 'extra' parameter should be defined"); + //parameterAssert(typeof noticeObject.extra === 'string', `cBPs addNotice: 'extra' parameter should be a string not a '${typeof extra}'`); checkBookPackagesResult.noticeList.push(noticeObject); } @@ -71,7 +75,6 @@ export async function checkBookPackages(username, languageCode, bookIDList, setR let bookNumberAndName; try { bookNumberAndName = books.usfmNumberName(bookID); - // whichTestament = books.testament(bookID); // returns 'old' or 'new' } catch (CBPsError) { addNotice({ priority: 900, message: "Bad parameter: should be given a valid book abbreviation", excerpt: bookIDList, location: ` (not '${bookIDList}')` }); return checkBookPackagesResult; @@ -80,12 +83,11 @@ export async function checkBookPackages(username, languageCode, bookIDList, setR } // We only want to check the manifest files for ONE Bible BP AND for OBS - let checkManifestFlag = false, checkReadmeFlag =false, checkLicenseFlag = false; -; - if (bookID === 'OBS') { checkManifestFlag = true; checkReadmeFlag =true; checkLicenseFlag = true; } + let checkManifestFlag = false, checkReadmeFlag = false, checkLicenseFlag = false; + if (bookID === 'OBS') { checkManifestFlag = true; checkReadmeFlag = true; checkLicenseFlag = true; } else // it’s a Bible book if (!checkedBibleBPManifestFlag) { - checkManifestFlag = true; checkReadmeFlag =true; checkLicenseFlag=true; + checkManifestFlag = true; checkReadmeFlag = true; checkLicenseFlag = true; checkedBibleBPManifestFlag = true; // so we only do it once for Bible books } checkingOptions.checkManifestFlag = checkManifestFlag; diff --git a/src/demos/clear-cache/README.md b/src/demos/clear-cache/README.md index ed34a17a7..3208d1f2d 100644 --- a/src/demos/clear-cache/README.md +++ b/src/demos/clear-cache/README.md @@ -11,8 +11,10 @@ Unless you use this `ClearCache` function below, these demos can cache files for Simply change `N` to `Y` below to clear the internal caches. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import ClearCache from './ClearCache'; diff --git a/src/demos/file-check/FileCheck.js b/src/demos/file-check/FileCheck.js index 026f77fa5..4f7d157c2 100644 --- a/src/demos/file-check/FileCheck.js +++ b/src/demos/file-check/FileCheck.js @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import { withStyles } from '@material-ui/core/styles'; -import { clearCaches, clearCheckedArticleCache, ourParseInt, cachedGetFile, cachedFetchFileFromServerTag } from '../../core'; +import { clearCaches, clearCheckedArticleCache, ourParseInt, cachedGetFile, cachedFetchFileFromServerWithTag } from '../../core'; import { processNoticesToErrorsWarnings, processNoticesToSevereMediumLow, processNoticesToSingleList } from '../notice-processing-functions'; import { RenderSuccessesErrorsWarnings, RenderSuccessesSevereMediumLow, RenderSuccessesWarningsGradient, RenderElapsedTime } from '../RenderProcessedResults'; import { checkFileContents } from './checkFileContents'; @@ -8,7 +8,7 @@ import { checkFileContents } from './checkFileContents'; import { debugLog, userLog } from '../../core/utilities'; -// const FILE_CHECK_VERSION_STRING = '0.3.1'; +// const FILE_CHECK_VERSION_STRING = '0.3.2'; function FileCheck(props) { @@ -49,15 +49,17 @@ function FileCheck(props) { setResultValue(

Clearing cache before running file check…

); await clearCaches(); } - else await clearCheckedArticleCache(); + else await clearCheckedArticleCache(); // otherwise we wouldn't see any of the warnings again from checking these // Display our "waiting" message setResultValue(

Fetching {username} {repoName} {filename}

); + + // Fetch the file that we need to check (but it might already be in the cache) // debugLog(`FileCheck about to call cachedGetFile(${username}, ${repoName}, ${filename}, ${branch})…`); let fileContent = await cachedGetFile({ username: username, repository: repoName, path: filename, branch: branchOrRelease }); if (!fileContent) { // could it be a release, not a branch??? userLog(`Unable to fetch ${filename} from branch ${branchOrRelease}, so trying a release instead…`) - fileContent = await cachedFetchFileFromServerTag({ username: username, repository: repoName, path: filename, tag: branchOrRelease }); + fileContent = await cachedFetchFileFromServerWithTag({ username: username, repository: repoName, path: filename, tag: branchOrRelease }); } setResultValue(

Checking {username} {repoName} {filename}

); diff --git a/src/demos/file-check/README.md b/src/demos/file-check/README.md index b6c2aca5f..478cff811 100644 --- a/src/demos/file-check/README.md +++ b/src/demos/file-check/README.md @@ -6,14 +6,17 @@ and then validates the content of one file selected from the repo. **Note**: This demonstration can use saved (cached) copies of files stored inside the local browser. This makes reruns of the checks faster, but it won’t notice if you have recently updated the files on Door43. If you want to clear the local caches, use either the `reloadAllFilesFirst` variable below, or the `Clear Cache` function from the menu. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. Clearing cache before running GL book packages check…

); await clearCaches(); } - else await clearCheckedArticleCache(); - - // Load whole repos, especially if we are going to check files in manifests - let repoPreloadList = ['UHB', 'UGNT', 'TWL', 'LT', 'ST', 'TN', 'TA', 'TW', 'TQ']; // for DEFAULT - if (dataSet === 'OLD') - repoPreloadList = ['UHB', 'UGNT', 'LT', 'ST', 'TN', 'TA', 'TW', 'TQ']; - else if (dataSet === 'NEW') - repoPreloadList = ['UHB', 'UGNT', 'TWL', 'LT', 'ST', 'TN2', 'TA', 'TW', 'TQ2']; - else if (dataSet === 'BOTH') - repoPreloadList = ['UHB', 'UGNT', 'TWL', 'LT', 'ST', 'TN', 'TN2', 'TA', 'TW', 'TQ', 'TQ2']; + else await clearCheckedArticleCache(); // otherwise we wouldn't see any of the warnings again from checking these + + // Load whole repo zip files which is maybe faster than loading several individual files + // especially if we are going to also check the manifests, license, and ReadMe files as well as the book file. + // Remember that the manifest check actually checks the existence of all the projects, i.e., all files in the repo + let repoPreloadList; + if (bookID === 'OBS') { + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN2', 'OBS-SQ2']; // for DEFAULT + if (dataSet === 'OLD') + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TQ', 'OBS-SN', 'OBS-SQ']; + else if (dataSet === 'NEW') + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN2', 'OBS-TQ2', 'OBS-SN', 'OBS-SQ']; + else if (dataSet === 'BOTH') + repoPreloadList = ['OBS', 'OBS-TWL', 'OBS-TN', 'OBS-TN2', 'OBS-TQ', 'OBS-TQ2', 'OBS-SN', 'OBS-SN', 'OBS-SN2', 'OBS-SQ2']; + } else { // not OBS + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ', 'SN', 'SQ']; // for DEFAULT + if (dataSet === 'OLD') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TQ']; + else if (dataSet === 'NEW') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN2', 'TQ2', 'SN', 'SQ']; + else if (dataSet === 'BOTH') + repoPreloadList = ['TWL', 'LT', 'ST', 'TN', 'TN2', 'TQ', 'TQ2', 'SN', 'SQ']; + const whichTestament = books.testament(bookID); // returns 'old' or 'new' + logicAssert(whichTestament === 'old' || whichTestament === 'new', `BookPackageCheck() couldn't find testament for '${bookID}'`); + const origLangRepo = whichTestament === 'old' ? 'UHB' : 'UGNT'; + repoPreloadList.unshift(origLangRepo); + } + if (!checkingOptions.disableAllLinkFetchingFlag) { // Both Bible books and OBS refer to TW and TA + repoPreloadList.push('TW'); + repoPreloadList.push('TA'); + } + // debugLog(`GlBookPackageCheck got repoPreloadList=${repoPreloadList} for dataSet=${dataSet}`) setResultValue(

Preloading {repoPreloadList.length} repos for {username} {languageCode} ready for GL book package check…

); const successFlag = await preloadReposIfNecessary(username, languageCode, [bookID], branch, repoPreloadList); @@ -92,14 +111,14 @@ function GlBookPackageCheck(/*username, languageCode, bookIDs,*/ props) { // Display our "waiting" message setResultValue(

Checking {username} {languageCode} {bookID} book packages…

); - const rawCBPsResults = await checkBookPackage(username, languageCode, bookID, setResultValue, checkingOptions); + const rawGlBPsResults = await checkBookPackage(username, languageCode, bookID, setResultValue, checkingOptions); // debugLog("checkBookPackage() returned", typeof rawCBPsResults); //, JSON.stringify(rawCBPsResults)); // Add some extra fields to our rawCBPsResults object in case we need this information again later - rawCBPsResults.checkType = 'BookPackages'; - rawCBPsResults.username = username; - rawCBPsResults.languageCode = languageCode; - rawCBPsResults.checkedOptions = checkingOptions; + rawGlBPsResults.checkType = 'GLBookPackages'; + rawGlBPsResults.username = username; + rawGlBPsResults.languageCode = languageCode; + rawGlBPsResults.checkedOptions = checkingOptions; // debugLog("Here with CBPs rawCBPsResults", typeof rawCBPsResults); // Now do our final handling of the result -- we have some options available @@ -124,13 +143,13 @@ function GlBookPackageCheck(/*username, languageCode, bookIDs,*/ props) { return (

Checked {username} {languageCode} {bookID} (from {branch === undefined ? 'DEFAULT' : branch} branches)

- + {/* */}
); } if (displayType === 'ErrorsWarnings') { - const processedResults = processNoticesToErrorsWarnings(rawCBPsResults, processOptions); + const processedResults = processNoticesToErrorsWarnings(rawGlBPsResults, processOptions); // userLog(`GlBookPackageCheck got back processedResults with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); @@ -148,7 +167,7 @@ function GlBookPackageCheck(/*username, languageCode, bookIDs,*/ props) { ); } else if (displayType === 'SevereMediumLow') { - const processedResults = processNoticesToSevereMediumLow(rawCBPsResults, processOptions); + const processedResults = processNoticesToSevereMediumLow(rawGlBPsResults, processOptions); // userLog(`GlBookPackageCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); @@ -164,7 +183,7 @@ function GlBookPackageCheck(/*username, languageCode, bookIDs,*/ props) { ); } else if (displayType === 'SingleList') { - const processedResults = processNoticesToSingleList(rawCBPsResults, processOptions); + const processedResults = processNoticesToSingleList(rawGlBPsResults, processOptions); // userLog(`GlBookPackageCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s) and ${processedResults.warningList.length.toLocaleString()} notice(s) // numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); diff --git a/src/demos/gl-book-package-check/README.md b/src/demos/gl-book-package-check/README.md index d6feb2c5f..474a34f82 100644 --- a/src/demos/gl-book-package-check/README.md +++ b/src/demos/gl-book-package-check/README.md @@ -1,6 +1,6 @@ ## Door43 Gateway Language Book Package Check - Readme -The code below requests some info and then checks the single specified Bible book in several repos. This is convenient to see all these check results collected into one place. +The code below requests some info and then downloads and checks the single specified Bible book in several repos. This is convenient to see all these check results collected into one place. See a list of valid book identifiers [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. @@ -13,8 +13,10 @@ Note that `OBS` can also be entered here as a *pseudo book identifier* in order **Note**: This demonstration can use saved (cached) copies of files stored inside the local browser. This makes reruns of the checks faster, but it won’t notice if you have recently updated the files on Door43. If you want to clear the local caches, use either the `reloadAllFilesFirst` variable below, or the `Clear Cache` function from the menu. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { clearCheckedArticleCache } from '../../core'; import GlBookPackageCheck from './GlBookPackageCheck'; @@ -49,7 +51,7 @@ clearCheckedArticleCache(); // Specifying maximumSimilarMessages and excerptLength is just to show off options // —those fields are not necessary (or normal) here maximumSimilarMessages='4' // Default is 3 (0 means don’t suppress any) - // excerptLength='20' // Default is 15 + // excerptLength='25' // Default is 20 characters // cutoffPriorityLevel='200' // Default is to detect all errors/warnings /> ``` diff --git a/src/demos/notice-processing-functions.js b/src/demos/notice-processing-functions.js index 2dff29227..f37119eb7 100644 --- a/src/demos/notice-processing-functions.js +++ b/src/demos/notice-processing-functions.js @@ -1,8 +1,9 @@ -import { userLog, parameterAssert } from '../core/utilities'; +// eslint-disable-next-line no-unused-vars +import { userLog, parameterAssert, logicAssert } from '../core/utilities'; import { isDisabledNotice } from '../core/disabled-notices'; -// const NOTICE_PROCESSOR_VERSION_STRING = '0.9.12'; +// const NOTICE_PROCESSOR_VERSION_STRING = '0.9.14'; // All of the following can be overriden with optionalProcessingOptions const DEFAULT_MAXIMUM_SIMILAR_MESSAGES = 3; // Zero means no suppression of similar messages @@ -142,6 +143,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // Run a check through the noticeList to help discover any programming errors that need fixing // This entire section may be commented out of production code if (givenNoticeObject.noticeList && givenNoticeObject.noticeList.length) { + // eslint-disable-next-line no-unused-vars const ALL_TSV_FIELDNAMES = ['Book', 'Chapter', 'Verse', 'Reference', 'ID', 'Tags', 'SupportReference', 'OrigWords', 'TWLink', @@ -151,8 +153,8 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { const numberStore = {}, duplicatePriorityList = []; for (const thisGivenNotice of standardisedNoticeList) { const thisPriority = thisGivenNotice.priority, thisMsg = thisGivenNotice.message; - parameterAssert(typeof thisPriority === 'number' && thisPriority > 0 && thisPriority < 10000, `BAD PRIORITY for ${JSON.stringify(thisGivenNotice)}`); - parameterAssert(typeof thisMsg === 'string' && thisMsg.length >= 10, `BAD MESSAGE for ${JSON.stringify(thisGivenNotice)}`); + //(typeof thisPriority === 'number' && thisPriority > 0 && thisPriority < 10000, `BAD PRIORITY for ${JSON.stringify(thisGivenNotice)}`); + //parameterAssert(typeof thisMsg === 'string' && thisMsg.length >= 10, `BAD MESSAGE for ${JSON.stringify(thisGivenNotice)}`); // Check that notice priority numbers are unique (to detect programming errors) const oldMsg = numberStore[thisPriority]; @@ -186,48 +188,48 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { thisRowID = thisGivenNotice.rowID, thisFieldName = thisGivenNotice.fieldName, thisLocation = thisGivenNotice.location, thisExtra = thisGivenNotice.extra; if (thisRepoName) { - parameterAssert(thisRepoName.indexOf(' ') < 0 && thisRepoName.indexOf('/') < 0 && thisRepoName.indexOf('\\') < 0, `repoName '${thisRepoName}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); - if (thisLocation) - parameterAssert(thisLocation.indexOf(thisRepoName) < 0, `repoName is repeated in location in ${JSON.stringify(thisGivenNotice)}`); + //parameterAssert(thisRepoName.indexOf(' ') < 0 && thisRepoName.indexOf('/') < 0 && thisRepoName.indexOf('\\') < 0, `repoName '${thisRepoName}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + if (thisLocation) { //parameterAssert(thisLocation.indexOf(thisRepoName) < 0, `repoName is repeated in location in ${JSON.stringify(thisGivenNotice)}`); + } } if (thisFilename) { - parameterAssert(thisFilename.indexOf(':') < 0 && thisFilename.indexOf('\\') < 0, `filename '${thisFilename}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); - parameterAssert(ALL_TSV_FIELDNAMES.indexOf(thisFilename) < 0, `filename '${thisFilename}' contains a TSV fieldName!`); + logicAssert(thisFilename.indexOf(':') < 0 && thisFilename.indexOf('\\') < 0, `filename '${thisFilename}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(ALL_TSV_FIELDNAMES.indexOf(thisFilename) < 0, `filename '${thisFilename}' contains a TSV fieldName!`); // NOTE: Some OBS and other messages have to include part of the part in the 'filename' (to prevent ambiguity) so we don’t disallow forward slash // if (!thisRepoName || !(thisRepoName.endsWith('_obs') || thisRepoName.endsWith('_ta') || thisRepoName.endsWith('_tw'))) // parameterAssert(thisFilename.indexOf('/') < 0, `filename '${thisFilename}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); if (thisLocation) - parameterAssert(thisLocation.indexOf(thisFilename) < 0, `filename is repeated in location in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisLocation.indexOf(thisFilename) < 0, `filename is repeated in location in ${JSON.stringify(thisGivenNotice)}`); } if (thisC) - parameterAssert(thisC === 'front' || !isNaN(thisC * 1), `C '${thisC}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisC === 'front' || !isNaN(thisC * 1), `C '${thisC}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); if (thisV) { // NOTE: We don't allow for a en-dash in verse ranges -- should we? if (thisV.indexOf('-') !== -1) { // it contains a hyphen, i.e., a verse range const vBits = thisV.split('-'); - parameterAssert(vBits.length === 2 && !isNaN(vBits[0] * 1) && !isNaN(vBits[1] * 1), `V '${thisV}' verse range contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(vBits.length === 2 && !isNaN(vBits[0] * 1) && !isNaN(vBits[1] * 1), `V '${thisV}' verse range contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); } else // NOTE: Question mark below is in "bad verse number" notices - parameterAssert(thisV === 'intro' || thisV === '?' || !isNaN(thisV * 1), `V '${thisV}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisV === 'intro' || thisV === '?' || !isNaN(thisV * 1), `V '${thisV}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); } if (thisRowID) { - parameterAssert(thisRowID.indexOf(' ') < 0 && thisRowID.indexOf('/') < 0 && thisRowID.indexOf('\\') < 0, `rowID '${thisRowID}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisRowID.indexOf(' ') < 0 && thisRowID.indexOf('/') < 0 && thisRowID.indexOf('\\') < 0, `rowID '${thisRowID}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); if (thisLocation) - parameterAssert(thisLocation.indexOf(thisRowID) < 0, `rowID is repeated in location in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisLocation.indexOf(thisRowID) < 0, `rowID is repeated in location in ${JSON.stringify(thisGivenNotice)}`); } if (thisFieldName) { // NOTE: fieldName can be a USFM marker, e.g., 'from \w' - parameterAssert(thisFieldName.indexOf('/') < 0, `fieldName '${thisFieldName}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisFieldName.indexOf('/') < 0, `fieldName '${thisFieldName}' contains unexpected characters in ${JSON.stringify(thisGivenNotice)}`); if (thisLocation) - parameterAssert(thisLocation.indexOf(thisFieldName) < 0, `fieldName is repeated in location in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisFieldName === 'w' // 'w' is just too likely to occur in the location string + || thisLocation.indexOf(thisFieldName) < 0, `fieldName is repeated in location in ${JSON.stringify(thisGivenNotice)}`); } if (thisLineNumber) { - parameterAssert(typeof thisLineNumber === 'number' && thisLineNumber > 0, `lineNumber '${thisLineNumber}' contains unexpected value in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(typeof thisLineNumber === 'number' && thisLineNumber > 0, `lineNumber '${thisLineNumber}' contains unexpected value in ${JSON.stringify(thisGivenNotice)}`); // Note: lineNumber can occur in location, e.g., in 3 in '3JN' or 'Door43' so have to take additional care not to give false alarms if (thisLocation && thisLineNumber > 4 && thisLineNumber !== 43) // && (!thisGivenNotice.bookID || thisGivenNotice.bookID.indexOf(thisLineNumber + '') < 0) - parameterAssert(thisLocation.indexOf(thisLineNumber + '') < 0 && thisLocation.indexOf(thisLineNumber.toLocaleString()) < 0, `lineNumber might be repeated in location in ${JSON.stringify(thisGivenNotice)}`); + logicAssert(thisLocation.indexOf(thisLineNumber + '') < 0 && thisLocation.indexOf(thisLineNumber.toLocaleString()) < 0, `lineNumber might be repeated in location in ${JSON.stringify(thisGivenNotice)}`); } - if (thisExtra) - parameterAssert(thisExtra !== '01', `extra should not be '${thisExtra}'`); + if (thisExtra) { logicAssert(thisExtra !== '01', `extra should not be '${thisExtra}'`); } numberStore[thisPriority] = thisMsg; } } @@ -254,7 +256,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // debugLog(`Using default ignorePriorityNumberList=${JSON.stringify(ignorePriorityNumberList)}`); } else userLog(`processNoticesCommon: Using supplied ignorePriorityNumberList=${JSON.stringify(ignorePriorityNumberList)} cf. default=${JSON.stringify(DEFAULT_IGNORE_PRIORITY_NUMBER_LIST)}`); - parameterAssert(Array.isArray(ignorePriorityNumberList), `ignorePriorityNumberList should be an Array, not ${typeof ignorePriorityNumberList}=${ignorePriorityNumberList}`); + //parameterAssert(Array.isArray(ignorePriorityNumberList), `ignorePriorityNumberList should be an Array, not ${typeof ignorePriorityNumberList}=${ignorePriorityNumberList}`); let sortBy; try { sortBy = optionalProcessingOptions.sortBy; @@ -289,6 +291,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { else { // successList is fairly long -- maybe we can shorten it by combining multiple similar messages const BibleRegex = /\d\d-(\w\w\w).usfm/; // "Checked JUD file: 66-JUD.usfm" const NotesRegex = /\d\d-(\w\w\w).tsv/; // "Checked EN_TN_01-GEN.TSV file: en_tn_01-GEN.tsv" + // const TWLRegex = /twl_(\w\w\w).tsv/; // From repoCheck "Checked en_twl BBB file: twl_BBB.tsv" const manifestRegex = /Checked ([\w\-_]{2,25}) manifest file/; const READMEregex = /Checked ([\w\-_]{2,25}) README file/; const LICENSEregex = /Checked ([\w\-_]{2,25}) LICENSE file/; @@ -303,6 +306,8 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { UHBBookList.push(thisParticularSuccessMsg.substring(18, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked UGNT file: ')) UGNTBookList.push(thisParticularSuccessMsg.substring(19, thisParticularSuccessMsg.length)) + else if (thisParticularSuccessMsg.startsWith('Checked TWL file: ')) + TWLList.push(thisParticularSuccessMsg.substring(18, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked LT file: ')) LTBookList.push(thisParticularSuccessMsg.substring(17, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked ST file: ')) @@ -310,9 +315,9 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { else if (thisParticularSuccessMsg.startsWith('Checked TN file: ')) TNBookList.push(thisParticularSuccessMsg.substring(17, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked TN2 file: ')) - TN2BookList.push(thisParticularSuccessMsg.substring(17, thisParticularSuccessMsg.length)) + TN2BookList.push(thisParticularSuccessMsg.substring(18, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked TQ2 file: ')) - TQ2BookList.push(thisParticularSuccessMsg.substring(17, thisParticularSuccessMsg.length)) + TQ2BookList.push(thisParticularSuccessMsg.substring(18, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked TN2 ') && thisParticularSuccessMsg.substring(14, 20) === ' file:') TNList.push(thisParticularSuccessMsg.substring(21, thisParticularSuccessMsg.length)) else if (thisParticularSuccessMsg.startsWith('Checked TQ2 ') && thisParticularSuccessMsg.substring(14, 20) === ' file:') @@ -327,6 +332,8 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // but don’t do it for Book Package checks (in different repos) && thisParticularSuccessMsg.startsWith(`Checked ${regexResult[1]} file`)) TSVNotesList.push(regexResult[1]); + // else if ((regexResult = TWLRegex.exec(thisParticularSuccessMsg)) !== null) + // TWLList.push(regexResult[1]); else if ((regexResult = manifestRegex.exec(thisParticularSuccessMsg)) !== null) manifestsList.push(regexResult[1]); else if ((regexResult = READMEregex.exec(thisParticularSuccessMsg)) !== null) @@ -341,6 +348,8 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { resultObject.successList.push(`Checked UHB file: ${UHBBookList[0]}`); if (UGNTBookList.length === 1) resultObject.successList.push(`Checked UGNT file: ${UGNTBookList[0]}`); + // if (TWLBookList.length === 1) + // resultObject.successList.push(`Checked TWL file: ${TWLBookList[0]}`); if (LTBookList.length === 1) resultObject.successList.push(`Checked LT file: ${LTBookList[0]}`); if (STBookList.length === 1) @@ -395,6 +404,8 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { resultObject.successList.unshift(`Checked ${STBookList.length} ST files: ${STBookList.join(', ')}`); if (LTBookList.length > 1) resultObject.successList.unshift(`Checked ${LTBookList.length} LT files: ${LTBookList.join(', ')}`); + // if (TWLBookList.length > 1) + // resultObject.successList.unshift(`Checked ${TWLBookList.length} TWL files: ${LTBookList.join(', ')}`); if (UGNTBookList.length > 1) resultObject.successList.unshift(`Checked ${UGNTBookList.length} UGNT files: ${UGNTBookList.join(', ')}`); if (UHBBookList.length > 1) @@ -483,7 +494,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { const newNoticeList = []; for (const thisNotice of remainingNoticeList) { const thisExtra = thisNotice.extra; - parameterAssert(thisExtra && thisExtra.length, `Expect thisNotice to have an "extra" field: ${JSON.stringify(thisNotice)}`) + logicAssert(thisExtra && thisExtra.length, `Expect thisNotice to have an "extra" field: ${JSON.stringify(thisNotice)}`) const newNotice = { ...thisNotice }; // We don’t need the extra field if we've already got this info if (thisExtra !== thisNotice.repoName && thisExtra !== thisNotice.bookID) @@ -569,12 +580,12 @@ export function processNoticesToErrorsWarnings(givenNoticeObject, optionalProces if (maximumSimilarMessages > 0 && allTotals[thisCombinedID] > maximumSimilarMessages + 1 && counter[thisCombinedID] === maximumSimilarMessages + 1) { if (thisPriority >= errorPriorityLevel) { const numSuppressed = allTotals[thisCombinedID] - maximumSimilarMessages; - parameterAssert(numSuppressed !== 1, `Shouldn’t suppress just one error of priority ${thisPriority}`); + logicAssert(numSuppressed !== 1, `Shouldn’t suppress just one error of priority ${thisPriority}`); resultObject.errorList.push({ priority: -1, message: thisMsg, location: ` ▲ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED` }); resultObject.numSuppressedErrors++; } else { const numSuppressed = allTotals[thisCombinedID] - maximumSimilarMessages; - parameterAssert(numSuppressed !== 1, `Shouldn’t suppress just one warning of priority ${thisPriority}`); + logicAssert(numSuppressed !== 1, `Shouldn’t suppress just one warning of priority ${thisPriority}`); resultObject.warningList.push({ priority: -1, message: thisMsg, location: ` ▲ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED` }); resultObject.numSuppressedWarnings++; } @@ -667,17 +678,17 @@ export function processNoticesToSevereMediumLow(givenNoticeObject, optionalProce if (maximumSimilarMessages > 0 && allTotals[thisCombinedID] > maximumSimilarMessages + 1 && counter[thisCombinedID] === maximumSimilarMessages + 1) { if (thisPriority >= severePriorityLevel) { const numSuppressed = allTotals[thisCombinedID] - maximumSimilarMessages; - parameterAssert(numSuppressed !== 1, `Shouldn’t suppress just one severe error of priority ${thisPriority}`); + logicAssert(numSuppressed !== 1, `Shouldn’t suppress just one severe error of priority ${thisPriority}`); resultObject.severeList.push({ priority: -1, message: thisMsg, location: ` ▲ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED` }); resultObject.numSevereSuppressed++; } else if (thisPriority >= mediumPriorityLevel) { const numSuppressed = allTotals[thisCombinedID] - maximumSimilarMessages; - parameterAssert(numSuppressed !== 1, `Shouldn’t suppress just one medium error of priority ${thisPriority}`); + logicAssert(numSuppressed !== 1, `Shouldn’t suppress just one medium error of priority ${thisPriority}`); resultObject.mediumList.push({ priority: -1, message: thisMsg, location: ` ▲ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED` }); resultObject.numMediumSuppressed++; } else { const numSuppressed = allTotals[thisCombinedID] - maximumSimilarMessages; - parameterAssert(numSuppressed !== 1, `Shouldn’t suppress just one low warning of priority ${thisPriority}`); + logicAssert(numSuppressed !== 1, `Shouldn’t suppress just one low warning of priority ${thisPriority}`); resultObject.lowList.push({ priority: -1, message: thisMsg, location: ` ▲ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED` }); resultObject.numLowSuppressed++; } @@ -752,7 +763,7 @@ export function processNoticesToSingleList(givenNoticeObject, optionalProcessing else counter[thisCombinedID]++; if (maximumSimilarMessages > 0 && allTotals[thisCombinedID] > maximumSimilarMessages + 1 && counter[thisCombinedID] === maximumSimilarMessages + 1) { const numSuppressed = allTotals[thisCombinedID] - maximumSimilarMessages; - parameterAssert(numSuppressed !== 1, `Shouldn’t suppress just one notice of priority ${thisPriority}`); + logicAssert(numSuppressed !== 1, `Shouldn’t suppress just one notice of priority ${thisPriority}`); resultObject.warningList.push({ priority: thisPriority, message: thisMsg, location: ` ▲ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED` }); resultObject.numSuppressedWarnings++; } else if (maximumSimilarMessages > 0 && counter[thisCombinedID] > maximumSimilarMessages + 1) { diff --git a/src/demos/notice-processing1.md b/src/demos/notice-processing1.md index 73a40113c..f7e07a7f1 100644 --- a/src/demos/notice-processing1.md +++ b/src/demos/notice-processing1.md @@ -20,8 +20,10 @@ Note below that the optional `processOptions` object allows the user to adjust t Although this demonstration here formats and colours the error and warning lists, it’s expected that the encapsulating program will format and use the fields as desired. Because they are returned as an array of fields rather than simply strings, it’s certainly possible for the encapsulating program to sort or filter the messages as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkTextField } from '../core/field-text-check'; import { processNoticesToErrorsWarnings } from './notice-processing-functions'; diff --git a/src/demos/notice-processing2.md b/src/demos/notice-processing2.md index fb4be818d..6d622bb5e 100644 --- a/src/demos/notice-processing2.md +++ b/src/demos/notice-processing2.md @@ -20,8 +20,10 @@ Note below that the optional `processOptions` object allows the user to adjust t Although this demonstration here formats and colours the error and warning lists, it’s expected that the encapsulating program will format and use the fields as desired. Because they are returned as an array of fields rather than simply strings, it’s certainly possible for the encapsulating program to sort or filter the messages as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkTextField } from '../core/field-text-check'; import { processNoticesToSevereMediumLow } from './notice-processing-functions'; diff --git a/src/demos/notice-processing3.md b/src/demos/notice-processing3.md index 82a268e51..1832b315c 100644 --- a/src/demos/notice-processing3.md +++ b/src/demos/notice-processing3.md @@ -20,8 +20,10 @@ Note below that the optional `processOptions` object allows the user to adjust t Although this demonstration here formats and colour the warning list, it’s expected that the encapsulating program will format and use the fields as desired. Because they are returned as an array of fields rather than simply strings, it’s certainly possible for the encapsulating program to sort or filter the messages as desired. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import { checkTextField } from '../core/field-text-check'; import { processNoticesToSingleList } from './notice-processing-functions'; diff --git a/src/demos/repo-check/README.md b/src/demos/repo-check/README.md index 6001021ad..3d185aacd 100644 --- a/src/demos/repo-check/README.md +++ b/src/demos/repo-check/README.md @@ -1,14 +1,16 @@ ## Door43 Repo Check - Readme -The code below requests some info and then checks a Door43 repository.You can enter the `repoName`, i.e., the `username/repoName` in the code below. (Unfortunately if you refresh the page from the browser controls, it will return to the default setting. If you want to restart the test without returning to the default repo, just change one letter in a `//` comment line below.) +The code below requests some info and then downloads and checks a Door43 repository.You can enter the `repoName`, i.e., the `username/repoName` in the code below. (Unfortunately if you refresh the page from the browser controls, it will return to the default setting. If you want to restart the test without returning to the default repo, just change one letter in a `//` comment line below.) **Warning**: Some repos contain many files and/or very large files, and downloading them all and then checking them might slow down your browser—maybe even causing pop-up messages asking to confirm that you want to keep waiting. **Note**: This demonstration can use saved (cached) copies of files stored inside the local browser. This makes reruns of the checks faster, but it won’t notice if you have recently updated the files on Door43. If you want to clear the local caches, use either the `reloadAllFilesFirst` variable below, or the `Clear Cache` function from the menu. ```js -// The code in this box is editable for changing settings— -// Simply click inside here and add, change, or delete text as required. +// The control code in this box is editable for changing settings— +// simply click inside here and add, change, or delete text as required. +// Note that (gray) lines starting with // are "comments", i.e., they are ignored by the software +// so if you want to enable those lines, you must remove the // from the beginning of the line. import RepoCheck from './RepoCheck'; @@ -17,6 +19,7 @@ import RepoCheck from './RepoCheck'; wait='Y' // 'Y' (for Yes, i.e., to wait) or 'N' (for No, i.e., to start checking) // Set to N to rerun the check without fetching new copies of the files (slightly faster) + // If you're checking and then editing & saving files, ensure that it's set to Y before you recheck reloadAllFilesFirst='Y' // 'Y' (for Yes -- same as ClearCache in menu) or 'N' (for No) // username = 'Door43-Catalog' @@ -53,7 +56,7 @@ import RepoCheck from './RepoCheck'; // Specifying maximumSimilarMessages and excerptLength is just to show off options // —those fields are not necessary (or normal) here maximumSimilarMessages='4' // Default is 3 (0 means don’t suppress any) - // excerptLength='20' // Default is 15 + // excerptLength='25' // Default is 20 characters // cutoffPriorityLevel='200' // Default is to detect all errors/warnings showDisabledNoticesFlag='false' // Display known specific non-issues: 'true' or 'false' /> diff --git a/src/demos/repo-check/RepoCheck.js b/src/demos/repo-check/RepoCheck.js index 93aa3cdb7..3cb418b31 100644 --- a/src/demos/repo-check/RepoCheck.js +++ b/src/demos/repo-check/RepoCheck.js @@ -4,7 +4,8 @@ import { processNoticesToErrorsWarnings, processNoticesToSevereMediumLow, proces import { RenderSuccesses, RenderSuccessesErrorsWarnings, RenderSuccessesSevereMediumLow, RenderSuccessesWarningsGradient, RenderTotals } from '../RenderProcessedResults'; import { clearCaches, clearCheckedArticleCache, preloadReposIfNecessary, ourParseInt } from '../../core'; import { checkRepo } from './checkRepo'; -import { logicAssert, userLog } from '../../core/utilities'; +// eslint-disable-next-line no-unused-vars +import { logicAssert, userLog, debugLog } from '../../core/utilities'; // const REPO_VALIDATOR_VERSION_STRING = '0.2.5'; @@ -76,7 +77,7 @@ function RepoCheck(/*username, languageCode,*/ props) { setResultValue(

Clearing cache before running repository check…

); await clearCaches(); } - else await clearCheckedArticleCache(); + else await clearCheckedArticleCache(); // otherwise we wouldn't see any of the warnings again from checking these let [languageCode, repoCode] = repoName.split('_'); repoCode = repoCode.toUpperCase(); @@ -109,6 +110,9 @@ function RepoCheck(/*username, languageCode,*/ props) { try { // Empty string below is for location rawCRResults = await checkRepo(username, repoName, branchOrRelease, "", setResultValue, checkingOptions); + // debugLog(`rawCRResults keys: ${Object.keys(rawCRResults)}`); + // debugLog(`rawCRResults: ${JSON.stringify(rawCRResults)}`); + // logicAssert('checkedFileCount' in rawCRResults, `Expected rawCBPsResults to contain 'checkedFileCount': ${Object.keys(rawCRResults)}`); } catch (checkRepoError) { rawCRResults = { successList: [], noticeList: [] }; rawCRResults.noticeList.push({ priority: 999, message: "checkRepo function FAILED", repoName, excerpt: checkRepoError, location: repoName }); diff --git a/src/demos/repo-check/checkRepo.js b/src/demos/repo-check/checkRepo.js index eeaac0219..e5f56aad0 100644 --- a/src/demos/repo-check/checkRepo.js +++ b/src/demos/repo-check/checkRepo.js @@ -1,5 +1,6 @@ import React from 'react'; import { REPO_CODES_LIST } from '../../core/defaults'; +// eslint-disable-next-line no-unused-vars import * as books from '../../core/books/books'; import { checkFileContents } from '../file-check/checkFileContents'; import { repositoryExistsOnDoor43, getFileListFromZip, cachedGetFile, cachedGetRepositoryZipFile } from '../../core/getApi'; @@ -7,7 +8,7 @@ import { repositoryExistsOnDoor43, getFileListFromZip, cachedGetFile, cachedGetR import { functionLog, debugLog, logicAssert, parameterAssert } from '../../core/utilities'; -// const REPO_VALIDATOR_VERSION_STRING = '0.4.9'; +// const REPO_VALIDATOR_VERSION_STRING = '0.4.11'; /** @@ -26,14 +27,14 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s noticeList: an array of 9 (i.e., with extra bookOrFileCode parameter at end) notice components */ // functionLog(`checkRepo(un='${username}', rN='${repoName}', rBr='${repoBranch}', ${givenLocation}, (fn), ${JSON.stringify(checkingOptions)})…`); - parameterAssert(username !== undefined, "checkRepo: 'username' parameter should be defined"); - parameterAssert(typeof username === 'string', `checkRepo: 'username' parameter should be a string not a '${typeof username}'`); - parameterAssert(repoName !== undefined, "checkRepo: 'repoName' parameter should be defined"); - parameterAssert(typeof repoName === 'string', `checkRepo: 'repoName' parameter should be a string not a '${typeof repoName}'`); - parameterAssert(repoBranch !== undefined, "checkRepo: 'repoBranch' parameter should be defined"); - parameterAssert(typeof repoBranch === 'string', `checkRepo: 'repoBranch' parameter should be a string not a '${typeof repoBranch}'`); - parameterAssert(givenLocation !== undefined, "checkRepo: 'givenRowLocation' parameter should be defined"); - parameterAssert(typeof givenLocation === 'string', `checkRepo: 'givenRowLocation' parameter should be a string not a '${typeof givenLocation}'`); + //parameterAssert(username !== undefined, "checkRepo: 'username' parameter should be defined"); + //parameterAssert(typeof username === 'string', `checkRepo: 'username' parameter should be a string not a '${typeof username}'`); + //parameterAssert(repoName !== undefined, "checkRepo: 'repoName' parameter should be defined"); + //parameterAssert(typeof repoName === 'string', `checkRepo: 'repoName' parameter should be a string not a '${typeof repoName}'`); + //parameterAssert(repoBranch !== undefined, "checkRepo: 'repoBranch' parameter should be defined"); + //parameterAssert(typeof repoBranch === 'string', `checkRepo: 'repoBranch' parameter should be a string not a '${typeof repoBranch}'`); + //parameterAssert(givenLocation !== undefined, "checkRepo: 'givenRowLocation' parameter should be defined"); + //parameterAssert(typeof givenLocation === 'string', `checkRepo: 'givenRowLocation' parameter should be a string not a '${typeof givenLocation}'`); let abortFlag = false; const startTime = new Date(); @@ -41,15 +42,22 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s let [languageCode, repoCode] = repoName.split('_'); repoCode = repoCode.toUpperCase(); // debugLog(`checkRepo got languageCode='${languageCode}' repoCode='${repoCode}' repoBranch='${repoBranch}'`); - logicAssert(REPO_CODES_LIST.includes(repoCode), `checkRepo: 'repoCode' parameter should not be '${repoCode}'`); if (repoCode === 'TN2') { repoCode = 'TN'; if (repoBranch === undefined) repoBranch = 'newFormat'; - }else if (repoCode === 'TQ2') { + } else if (repoCode === 'TQ2') { repoCode = 'TQ'; if (repoBranch === undefined) repoBranch = 'newFormat'; - } + } else if (repoCode === 'SN2') { + repoCode = 'SN'; + if (repoBranch === undefined) repoBranch = 'newFormat'; + } else if (repoCode === 'SQ2') { + repoCode = 'SQ'; + if (repoBranch === undefined) repoBranch = 'newFormat'; + } else if (repoCode.endsWith('LT')) repoCode = 'LT'; + else if (repoCode.endsWith('ST')) repoCode = 'ST'; // debugLog(`checkRepo now has languageCode='${languageCode}' repoCode='${repoCode}' repoBranch='${repoBranch}'`); + logicAssert(REPO_CODES_LIST.includes(repoCode), `checkRepo: 'repoCode' parameter should not be '${repoCode}'`); if (repoBranch === undefined) repoBranch = 'master'; // Ideally we should ask what the default branch is @@ -69,28 +77,32 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // Note that bookID,C,V might all be empty strings (as some repos don’t have BCV) // functionLog(`checkRepo addNoticePartial: ${noticeObject.priority}:${noticeObject.message} bookID=${noticeObject.bookID} ${noticeObject.C}:${noticeObject.V} ${noticeObject.filename}:${noticeObject.lineNumber} ${noticeObject.characterIndex > 0 ? ` (at character ${noticeObject.characterIndex})` : ""}${noticeObject.excerpt ? ` ${noticeObject.excerpt}` : ""}${noticeObject.location}`); - parameterAssert(noticeObject.priority !== undefined, "cR addNoticePartial: 'priority' parameter should be defined"); - parameterAssert(typeof noticeObject.priority === 'number', `cR addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}'`); - parameterAssert(noticeObject.message !== undefined, "cR addNoticePartial: 'message' parameter should be defined"); - parameterAssert(typeof noticeObject.message === 'string', `cR addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}'`); - // parameterAssert(bookID !== undefined, "cR addNoticePartial: 'bookID' parameter should be defined"); + //parameterAssert(noticeObject.priority !== undefined, "cR addNoticePartial: 'priority' parameter should be defined"); + //parameterAssert(typeof noticeObject.priority === 'number', `cR addNoticePartial: 'priority' parameter should be a number not a '${typeof noticeObject.priority}'`); + //parameterAssert(noticeObject.message !== undefined, "cR addNoticePartial: 'message' parameter should be defined"); + //parameterAssert(typeof noticeObject.message === 'string', `cR addNoticePartial: 'message' parameter should be a string not a '${typeof noticeObject.message}'`); + // //parameterAssert(bookID !== undefined, "cR addNoticePartial: 'bookID' parameter should be defined"); if (noticeObject.bookID) { - parameterAssert(typeof noticeObject.bookID === 'string', `cR addNoticePartial: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}'`); - parameterAssert(noticeObject.bookID.length === 3, `cR addNoticePartial: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); - parameterAssert(noticeObject.bookID === 'OBS' || books.isOptionalValidBookID(noticeObject.bookID), `cR addNoticePartial: '${noticeObject.bookID}' is not a valid USFM book identifier`); + //parameterAssert(typeof noticeObject.bookID === 'string', `cR addNoticePartial: 'bookID' parameter should be a string not a '${typeof noticeObject.bookID}'`); + //parameterAssert(noticeObject.bookID.length === 3, `cR addNoticePartial: 'bookID' parameter should be three characters long not ${noticeObject.bookID.length}`); + //parameterAssert(noticeObject.bookID === 'OBS' || books.isOptionalValidBookID(noticeObject.bookID), `cR addNoticePartial: '${noticeObject.bookID}' is not a valid USFM book identifier`); } - // parameterAssert(C !== undefined, "cR addNoticePartial: 'C' parameter should be defined"); - if (noticeObject.C) parameterAssert(typeof noticeObject.C === 'string', `cR addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}'`); - // parameterAssert(V !== undefined, "cR addNoticePartial: 'V' parameter should be defined"); - if (noticeObject.V) parameterAssert(typeof noticeObject.V === 'string', `cR addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}'`); - // parameterAssert(characterIndex !== undefined, "cR addNoticePartial: 'characterIndex' parameter should be defined"); - if (noticeObject.characterIndex) parameterAssert(typeof noticeObject.characterIndex === 'number', `cR addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}'`); - // parameterAssert(excerpt !== undefined, "cR addNoticePartial: 'excerpt' parameter should be defined"); - if (noticeObject.excerpt) parameterAssert(typeof noticeObject.excerpt === 'string', `cR addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}'`); - parameterAssert(noticeObject.location !== undefined, "cR addNoticePartial: 'location' parameter should be defined"); - parameterAssert(typeof noticeObject.location === 'string', `cR addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}'`); - // parameterAssert(noticeObject.extra !== undefined, "cR addNoticePartial: 'extra' parameter should be defined"); - parameterAssert(typeof noticeObject.extra === 'string', `cR addNoticePartial: 'extra' parameter should be a string not a '${typeof noticeObject.extra}'`); + // //parameterAssert(C !== undefined, "cR addNoticePartial: 'C' parameter should be defined"); + if (noticeObject.C) { //parameterAssert(typeof noticeObject.C === 'string', `cR addNoticePartial: 'C' parameter should be a string not a '${typeof noticeObject.C}'`); + } + // //parameterAssert(V !== undefined, "cR addNoticePartial: 'V' parameter should be defined"); + if (noticeObject.V) { //parameterAssert(typeof noticeObject.V === 'string', `cR addNoticePartial: 'V' parameter should be a string not a '${typeof noticeObject.V}'`); + } + // //parameterAssert(characterIndex !== undefined, "cR addNoticePartial: 'characterIndex' parameter should be defined"); + if (noticeObject.characterIndex) { //parameterAssert(typeof noticeObject.characterIndex === 'number', `cR addNoticePartial: 'characterIndex' parameter should be a number not a '${typeof noticeObject.characterIndex}'`); + } + // //parameterAssert(excerpt !== undefined, "cR addNoticePartial: 'excerpt' parameter should be defined"); + if (noticeObject.excerpt) { //parameterAssert(typeof noticeObject.excerpt === 'string', `cR addNoticePartial: 'excerpt' parameter should be a string not a '${typeof noticeObject.excerpt}'`); + } + //parameterAssert(noticeObject.location !== undefined, "cR addNoticePartial: 'location' parameter should be defined"); + //parameterAssert(typeof noticeObject.location === 'string', `cR addNoticePartial: 'location' parameter should be a string not a '${typeof noticeObject.location}'`); + // //parameterAssert(noticeObject.extra !== undefined, "cR addNoticePartial: 'extra' parameter should be defined"); + //parameterAssert(typeof noticeObject.extra === 'string', `cR addNoticePartial: 'extra' parameter should be a string not a '${typeof noticeObject.extra}'`); if (noticeObject.debugChain) noticeObject.debugChain = `checkRepo ${noticeObject.debugChain}`; // Add in the repoName from the outer scope checkRepoResult.noticeList.push({ ...noticeObject, username, repoCode, repoName }); @@ -111,24 +123,28 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s // functionLog(`checkRepo ourCheckRepoFileContents(bk/fC='${bookOrFileCode}', bk='${cfBookID}', fn='${filename}', ${fileContent.length}, ${fileLocation}, ${JSON.stringify(checkingOptions)})…`); // Updates the global list of notices - parameterAssert(bookOrFileCode !== undefined, "ourCheckRepoFileContents: 'bookOrFileCode' parameter should be defined"); - parameterAssert(typeof bookOrFileCode === 'string', `ourCheckRepoFileContents: 'bookOrFileCode' parameter should be a string not a '${typeof bookOrFileCode}'`); - parameterAssert(cfBookID !== undefined, "ourCheckRepoFileContents: 'cfBookID' parameter should be defined"); - parameterAssert(typeof cfBookID === 'string', `ourCheckRepoFileContents: 'cfBookID' parameter should be a string not a '${typeof cfBookID}'`); + //parameterAssert(bookOrFileCode !== undefined, "ourCheckRepoFileContents: 'bookOrFileCode' parameter should be defined"); + //parameterAssert(typeof bookOrFileCode === 'string', `ourCheckRepoFileContents: 'bookOrFileCode' parameter should be a string not a '${typeof bookOrFileCode}'`); + //parameterAssert(cfBookID !== undefined, "ourCheckRepoFileContents: 'cfBookID' parameter should be defined"); + //parameterAssert(typeof cfBookID === 'string', `ourCheckRepoFileContents: 'cfBookID' parameter should be a string not a '${typeof cfBookID}'`); if (cfBookID) { - parameterAssert(cfBookID.length === 3, `ourCheckRepoFileContents: 'cfBookID' parameter should be three characters long not ${cfBookID.length}`); - parameterAssert(cfBookID.toUpperCase() === cfBookID, `ourCheckRepoFileContents: 'cfBookID' parameter should be UPPERCASE not '${cfBookID}'`); - parameterAssert(cfBookID === 'OBS' || books.isValidBookID(cfBookID), `ourCheckRepoFileContents: '${cfBookID}' is not a valid USFM book identifier`); + //parameterAssert(cfBookID.length === 3, `ourCheckRepoFileContents: 'cfBookID' parameter should be three characters long not ${cfBookID.length}`); + //parameterAssert(cfBookID.toUpperCase() === cfBookID, `ourCheckRepoFileContents: 'cfBookID' parameter should be UPPERCASE not '${cfBookID}'`); + //parameterAssert(cfBookID === 'OBS' || books.isValidBookID(cfBookID), `ourCheckRepoFileContents: '${cfBookID}' is not a valid USFM book identifier`); } - parameterAssert(filename !== undefined, "ourCheckRepoFileContents: 'filename' parameter should be defined"); - parameterAssert(typeof filename === 'string', `ourCheckRepoFileContents: 'filename' parameter should be a string not a '${typeof filename}'`); - parameterAssert(fileContent !== undefined, "ourCheckRepoFileContents: 'fileContent' parameter should be defined"); - parameterAssert(typeof fileContent === 'string', `ourCheckRepoFileContents: 'fileContent' parameter should be a string not a '${typeof fileContent}'`); - parameterAssert(fileLocation !== undefined, "ourCheckRepoFileContents: 'fileLocation' parameter should be defined"); - parameterAssert(typeof fileLocation === 'string', `ourCheckRepoFileContents: 'fileLocation' parameter should be a string not a '${typeof fileLocation}'`); - parameterAssert(checkingOptions !== undefined, "ourCheckRepoFileContents: 'checkingOptions' parameter should be defined"); + //parameterAssert(filename !== undefined, "ourCheckRepoFileContents: 'filename' parameter should be defined"); + //parameterAssert(typeof filename === 'string', `ourCheckRepoFileContents: 'filename' parameter should be a string not a '${typeof filename}'`); + //parameterAssert(fileContent !== undefined, "ourCheckRepoFileContents: 'fileContent' parameter should be defined"); + //parameterAssert(typeof fileContent === 'string', `ourCheckRepoFileContents: 'fileContent' parameter should be a string not a '${typeof fileContent}'`); + //parameterAssert(fileLocation !== undefined, "ourCheckRepoFileContents: 'fileLocation' parameter should be defined"); + //parameterAssert(typeof fileLocation === 'string', `ourCheckRepoFileContents: 'fileLocation' parameter should be a string not a '${typeof fileLocation}'`); + //parameterAssert(checkingOptions !== undefined, "ourCheckRepoFileContents: 'checkingOptions' parameter should be defined"); - const cfcResultObject = await checkFileContents(username, languageCode, repoCode, repoBranch, filename, fileContent, fileLocation, checkingOptions); + let adjustedLanguageCode = languageCode; + if (filename === 'manifest.yaml' || filename === 'LICENSE.md' + || ((languageCode === 'el-x-koine' || languageCode === 'hbo') && filename === 'README.md')) + adjustedLanguageCode = 'en'; // Correct the language for these auxilliary files + const cfcResultObject = await checkFileContents(username, adjustedLanguageCode, repoCode, repoBranch, filename, fileContent, fileLocation, checkingOptions); // debugLog("checkFileContents() returned", resultObject.successList.length, "success message(s) and", resultObject.noticeList.length, "notice(s)"); // for (const successEntry of resultObject.successList) // userLog(" ", successEntry); @@ -229,7 +245,7 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s // debugLog(`Have USFM filenameMain=${bookOrFileCode}`); const bookID = bookOrFileCode.substring(bookOrFileCode.length - 3).toUpperCase(); // debugLog(`Have USFM bookcode=${bookID}`); - parameterAssert(books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier (for USFM)`); + //parameterAssert(books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier (for USFM)`); bookOrFileCode = bookID; ourBookID = bookID; } @@ -242,10 +258,11 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s bookID = bookOrFileCode.slice(-3).toUpperCase(); logicAssert(bookID !== 'twl' && bookID !== 'TWL', `Should get a valid bookID here, not '${bookID}'`) // debugLog(`Have TSV bookcode(${bookID.length})='${bookID}'`); - if (repoCode === 'TWL' || repoCode === 'SN' || repoCode === 'SQ' || repoCode === 'TN2' || repoCode === 'TQ2') // new repos allow `OBS` - parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier (for TSV)`); - else - parameterAssert(bookID !== 'OBS' && books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier (for TSV)`); + if (repoCode === 'TWL' || repoCode === 'SN' || repoCode === 'SQ' || repoCode === 'TN2' || repoCode === 'TQ2') {// new repos allow `OBS` + //parameterAssert(bookID === 'OBS' || books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier (for TSV)`); + } else { + //parameterAssert(bookID !== 'OBS' && books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier (for TSV)`); + } bookOrFileCode = bookID; ourBookID = bookID; } @@ -301,7 +318,7 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s checkRepoResult.checkedFilenames = checkedFilenames; checkRepoResult.checkedFilenameExtensions = [...checkRepoResult.checkedFilenameExtensions, ...checkedFilenameExtensions]; // convert Set to Array checkRepoResult.checkedFilesizes += totalCheckedSize; - checkRepoResult.checkedRepoNames.unshift([`${username}/${repoName}`]); + checkRepoResult.checkedRepoNames.unshift(`${username}/${repoName}`); // checkRepoResult.checkedOptions = checkingOptions; // This is done at the caller level addSuccessMessage(`Checked ${username} repo: ${repoName}`); @@ -315,7 +332,7 @@ export async function checkRepo(username, repoName, repoBranch, givenLocation, s } } checkRepoResult.elapsedSeconds = (new Date() - startTime) / 1000; // seconds - // functionLog(`checkRepo() returning ${JSON.stringify(checkRepoResult)}`); + // debugLog(`checkRepo() returning ${JSON.stringify(checkRepoResult)}`); return checkRepoResult; }; // end of checkRepo() diff --git a/yarn.lock b/yarn.lock index 5315dfcfb..81ae4de30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39,10 +39,10 @@ dependencies: "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.9.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea" - integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.9.0": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" + integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== "@babel/core@7.9.0": version "7.9.0" @@ -67,16 +67,16 @@ source-map "^0.5.0" "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.4.5", "@babel/core@^7.7.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.5.tgz#d281f46a9905f07d1b3bf71ead54d9c7d89cb1e3" - integrity sha512-RN/AwP2DJmQTZSfiDaD+JQQ/J99KsIpOCfBE5pL+5jJSt7nI3nYGoAXZu+ffYSQ029NLs2DstZb+eR81uuARgg== + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab" + integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA== dependencies: "@babel/code-frame" "^7.14.5" "@babel/generator" "^7.14.5" "@babel/helper-compilation-targets" "^7.14.5" "@babel/helper-module-transforms" "^7.14.5" - "@babel/helpers" "^7.14.5" - "@babel/parser" "^7.14.5" + "@babel/helpers" "^7.14.6" + "@babel/parser" "^7.14.6" "@babel/template" "^7.14.5" "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" @@ -121,10 +121,10 @@ browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.5.tgz#8842ec495516dd1ed8f6c572be92ba78b1e9beef" - integrity sha512-Uq9z2e7ZtcnDMirRqAGLRaLwJn+Lrh388v5ETrR3pALJnElVh2zqQmdbz4W2RUJYohAPh2mtyPUgyMHMzXMncQ== +"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.14.6", "@babel/helper-create-class-features-plugin@^7.8.3": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz#f114469b6c06f8b5c59c6c4e74621f5085362542" + integrity sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg== dependencies: "@babel/helper-annotate-as-pure" "^7.14.5" "@babel/helper-function-name" "^7.14.5" @@ -186,9 +186,9 @@ "@babel/types" "^7.14.5" "@babel/helper-member-expression-to-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz#d5c70e4ad13b402c95156c7a53568f504e2fb7b8" - integrity sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ== + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970" + integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA== dependencies: "@babel/types" "^7.14.5" @@ -285,10 +285,10 @@ "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helpers@^7.14.5", "@babel/helpers@^7.9.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.5.tgz#4870f8d9a6fdbbd65e5674a3558b4ff7fef0d9b2" - integrity sha512-xtcWOuN9VL6nApgVHtq3PPcQv5qFBJzoSZzJ/2c0QK/IP/gxVcoWSNQwFEGvmbQsuS9rhYqjILDGGXcTkA705Q== +"@babel/helpers@^7.14.6", "@babel/helpers@^7.9.0": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635" + integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA== dependencies: "@babel/template" "^7.14.5" "@babel/traverse" "^7.14.5" @@ -303,10 +303,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.5.tgz#4cd2f346261061b2518873ffecdf1612cb032829" - integrity sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" + integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": version "7.14.5" @@ -317,10 +317,10 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" "@babel/plugin-proposal-optional-chaining" "^7.14.5" -"@babel/plugin-proposal-async-generator-functions@^7.14.5", "@babel/plugin-proposal-async-generator-functions@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.5.tgz#4024990e3dd74181f4f426ea657769ff49a2df39" - integrity sha512-tbD/CG3l43FIXxmu4a7RBe4zH7MLJ+S/lFowPFO7HetS2hyOZ/0nnnznegDuzFzfkyQYTxqdTH/hKmuBngaDAA== +"@babel/plugin-proposal-async-generator-functions@^7.14.7", "@babel/plugin-proposal-async-generator-functions@^7.8.3": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz#784a48c3d8ed073f65adcf30b57bcbf6c8119ace" + integrity sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-remap-async-to-generator" "^7.14.5" @@ -424,12 +424,12 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.14.5", "@babel/plugin-proposal-object-rest-spread@^7.9.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.5.tgz#e581d5ccdfa187ea6ed73f56c6a21c1580b90fbf" - integrity sha512-VzMyY6PWNPPT3pxc5hi9LloKNr4SSrVCg7Yr6aZpW4Ym07r7KqSU/QXYwjXLVxqwSv0t/XSXkFoKBPUkZ8vb2A== +"@babel/plugin-proposal-object-rest-spread@^7.14.7", "@babel/plugin-proposal-object-rest-spread@^7.9.0": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" + integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== dependencies: - "@babel/compat-data" "^7.14.5" + "@babel/compat-data" "^7.14.7" "@babel/helper-compilation-targets" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" @@ -676,10 +676,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-destructuring@^7.14.5", "@babel/plugin-transform-destructuring@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.5.tgz#d32ad19ff1a6da1e861dc62720d80d9776e3bf35" - integrity sha512-wU9tYisEbRMxqDezKUqC9GleLycCRoUsai9ddlsq54r8QRLaeEhc+d+9DqCG+kV9W2GgQjTZESPTpn5bAFMDww== +"@babel/plugin-transform-destructuring@^7.14.7", "@babel/plugin-transform-destructuring@^7.8.3": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" + integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" @@ -781,10 +781,10 @@ "@babel/helper-module-transforms" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.14.5", "@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.5.tgz#d537e8ee083ee6f6aa4f4eef9d2081d555746e4c" - integrity sha512-+Xe5+6MWFo311U8SchgeX5c1+lJM+eZDBZgD+tvXu9VVQPXwwVzeManMMjYX6xw2HczngfOSZjoFYKwdeB/Jvw== +"@babel/plugin-transform-named-capturing-groups-regex@^7.14.7", "@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz#60c06892acf9df231e256c24464bfecb0908fd4e" + integrity sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.14.5" @@ -921,10 +921,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-spread@^7.14.5", "@babel/plugin-transform-spread@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.5.tgz#bd269fb4119754d2ce7f4cc39a96b4f71baae356" - integrity sha512-/3iqoQdiWergnShZYl0xACb4ADeYCJ7X/RgmwtXshn6cIvautRPAFzhd58frQlokLO6Jb4/3JXvmm6WNTPtiTw== +"@babel/plugin-transform-spread@^7.14.6", "@babel/plugin-transform-spread@^7.8.3": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" + integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" @@ -951,11 +951,11 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-typescript@^7.9.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.5.tgz#5b41b59072f765bd1ec1d0b694e08c7df0f6f8a0" - integrity sha512-cFD5PKp4b8/KkwQ7h71FdPXFvz1RgwTFF9akRZwFldb9G0AHf7CgoPx96c4Q/ZVjh6V81tqQwW5YiHws16OzPg== + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c" + integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.14.6" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript" "^7.14.5" @@ -1041,16 +1041,16 @@ semver "^5.5.0" "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.4.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.5.tgz#c0c84e763661fd0e74292c3d511cb33b0c668997" - integrity sha512-ci6TsS0bjrdPpWGnQ+m4f+JSSzDKlckqKIJJt9UZ/+g7Zz9k0N8lYU8IeLg/01o2h8LyNZDMLGgRLDTxpudLsA== + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.7.tgz#5c70b22d4c2d893b03d8c886a5c17422502b932a" + integrity sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA== dependencies: - "@babel/compat-data" "^7.14.5" + "@babel/compat-data" "^7.14.7" "@babel/helper-compilation-targets" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.5" + "@babel/plugin-proposal-async-generator-functions" "^7.14.7" "@babel/plugin-proposal-class-properties" "^7.14.5" "@babel/plugin-proposal-class-static-block" "^7.14.5" "@babel/plugin-proposal-dynamic-import" "^7.14.5" @@ -1059,7 +1059,7 @@ "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" "@babel/plugin-proposal-numeric-separator" "^7.14.5" - "@babel/plugin-proposal-object-rest-spread" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.14.7" "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" "@babel/plugin-proposal-optional-chaining" "^7.14.5" "@babel/plugin-proposal-private-methods" "^7.14.5" @@ -1085,7 +1085,7 @@ "@babel/plugin-transform-block-scoping" "^7.14.5" "@babel/plugin-transform-classes" "^7.14.5" "@babel/plugin-transform-computed-properties" "^7.14.5" - "@babel/plugin-transform-destructuring" "^7.14.5" + "@babel/plugin-transform-destructuring" "^7.14.7" "@babel/plugin-transform-dotall-regex" "^7.14.5" "@babel/plugin-transform-duplicate-keys" "^7.14.5" "@babel/plugin-transform-exponentiation-operator" "^7.14.5" @@ -1097,7 +1097,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.14.5" "@babel/plugin-transform-modules-systemjs" "^7.14.5" "@babel/plugin-transform-modules-umd" "^7.14.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.7" "@babel/plugin-transform-new-target" "^7.14.5" "@babel/plugin-transform-object-super" "^7.14.5" "@babel/plugin-transform-parameters" "^7.14.5" @@ -1105,7 +1105,7 @@ "@babel/plugin-transform-regenerator" "^7.14.5" "@babel/plugin-transform-reserved-words" "^7.14.5" "@babel/plugin-transform-shorthand-properties" "^7.14.5" - "@babel/plugin-transform-spread" "^7.14.5" + "@babel/plugin-transform-spread" "^7.14.6" "@babel/plugin-transform-sticky-regex" "^7.14.5" "@babel/plugin-transform-template-literals" "^7.14.5" "@babel/plugin-transform-typeof-symbol" "^7.14.5" @@ -1116,7 +1116,7 @@ babel-plugin-polyfill-corejs2 "^0.2.2" babel-plugin-polyfill-corejs3 "^0.2.2" babel-plugin-polyfill-regenerator "^0.2.2" - core-js-compat "^3.14.0" + core-js-compat "^3.15.0" semver "^6.3.0" "@babel/preset-modules@^0.1.3", "@babel/preset-modules@^0.1.4": @@ -1163,11 +1163,11 @@ "@babel/plugin-transform-typescript" "^7.9.0" "@babel/runtime-corejs3@^7.10.2", "@babel/runtime-corejs3@^7.12.1", "@babel/runtime-corejs3@^7.9.6": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.5.tgz#0d9bf00d59c0b73185c462c323efffd0f4c37283" - integrity sha512-cBbwXj3F2xjnQJ0ERaFRLjxhUSBYsQPXJ7CERz/ecx6q6hzQ99eTflAPFC3ks4q/IG4CWupNVdflc4jlFBJVsg== + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz#0ef292bbce40ca00f874c9724ef175a12476465c" + integrity sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA== dependencies: - core-js-pure "^3.14.0" + core-js-pure "^3.15.0" regenerator-runtime "^0.13.4" "@babel/runtime@7.9.0": @@ -1178,9 +1178,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.5.tgz#665450911c6031af38f81db530f387ec04cd9a98" - integrity sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA== + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== dependencies: regenerator-runtime "^0.13.4" @@ -1194,16 +1194,16 @@ "@babel/types" "^7.14.5" "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870" - integrity sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg== + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" + integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== dependencies: "@babel/code-frame" "^7.14.5" "@babel/generator" "^7.14.5" "@babel/helper-function-name" "^7.14.5" "@babel/helper-hoist-variables" "^7.14.5" "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.5" + "@babel/parser" "^7.14.7" "@babel/types" "^7.14.5" debug "^4.1.0" globals "^11.1.0" @@ -1629,13 +1629,13 @@ chalk "^4.0.0" "@material-ui/core@^4.11.0": - version "4.11.4" - resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.4.tgz#4fb9fe5dec5dcf780b687e3a40cff78b2b9640a4" - integrity sha512-oqb+lJ2Dl9HXI9orc6/aN8ZIAMkeThufA5iZELf2LQeBn2NtjVilF5D2w7e9RpntAzDb4jK5DsVhkfOvFY/8fg== + version "4.12.0" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.12.0.tgz#7f4c130fb585e4a4cdfbdb55e46bbe81c3763250" + integrity sha512-PB6gJdCLCgVdbCwBZgseKEP0zp+WiYao+YcEyJBLy3mTJ6sKoovmkI0fG/EjJ/S4mnjHlWl35T3SHxEBOVPztA== dependencies: "@babel/runtime" "^7.4.4" "@material-ui/styles" "^4.11.4" - "@material-ui/system" "^4.11.3" + "@material-ui/system" "^4.12.0" "@material-ui/types" "5.1.0" "@material-ui/utils" "^4.11.2" "@types/react-transition-group" "^4.2.0" @@ -1687,10 +1687,10 @@ jss-plugin-vendor-prefixer "^10.5.1" prop-types "^15.7.2" -"@material-ui/system@^4.11.3": - version "4.11.3" - resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.11.3.tgz#466bc14c9986798fd325665927c963eb47cc4143" - integrity sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw== +"@material-ui/system@^4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.12.0.tgz#e05593219f04a0fb4369cf72b3a2cc5a3b0a29ef" + integrity sha512-fXfiLeHBLwoBgCrsjwGkwWVmtaZSi4Rcm3SnQwQy9HWq6JzQ6EmZCa0jyCRhDeh0p9qL1/RszTXloaAsuRAM0A== dependencies: "@babel/runtime" "^7.4.4" "@material-ui/utils" "^4.11.2" @@ -1741,10 +1741,10 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@npmcli/arborist@^2.3.0", "@npmcli/arborist@^2.5.0", "@npmcli/arborist@^2.6.1": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-2.6.2.tgz#74ec5741afa6b6bf62603443793e33fc7a4f1245" - integrity sha512-CAo0HSziRdlpGUUheERmOrADnKHfBYpLAl/HmWGwGCtWKB3BCxfgb0rJ7MsFg38wy7YF3+fDs7R9dMVCH89K/A== +"@npmcli/arborist@^2.3.0", "@npmcli/arborist@^2.5.0", "@npmcli/arborist@^2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-2.6.4.tgz#bc413ae61dd57e23b8775a77c1f3199eea60b223" + integrity sha512-A/pDQ/VZpdxaqsQS5XOWrhrPuC+ER7HLq+4ZkEmnO2yo/USFCWEsiUPYKhfY+sWXK3pgKjN7B7CEFmAnSoAt3g== dependencies: "@npmcli/installed-package-contents" "^1.0.7" "@npmcli/map-workspaces" "^1.0.2" @@ -1752,6 +1752,7 @@ "@npmcli/move-file" "^1.1.0" "@npmcli/name-from-folder" "^1.0.1" "@npmcli/node-gyp" "^1.0.1" + "@npmcli/package-json" "^1.0.1" "@npmcli/run-script" "^1.8.2" bin-links "^2.2.1" cacache "^15.0.3" @@ -1765,6 +1766,7 @@ npm-registry-fetch "^11.0.0" pacote "^11.2.6" parse-conflict-json "^1.1.1" + proc-log "^1.0.0" promise-all-reject-late "^1.0.0" promise-call-limit "^1.0.1" read-package-json-fast "^2.0.2" @@ -1797,10 +1799,10 @@ dependencies: ansi-styles "^4.3.0" -"@npmcli/git@^2.0.1", "@npmcli/git@^2.0.7": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.0.9.tgz#915bbfe66300e67b4da5ef765a4475ffb2ca5b6b" - integrity sha512-hTMbMryvOqGLwnmMBKs5usbPsJtyEsMsgXwJbmNrsEuQQh1LAIMDU77IoOrwkCg+NgQWl+ySlarJASwM3SutCA== +"@npmcli/git@^2.0.7", "@npmcli/git@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6" + integrity sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw== dependencies: "@npmcli/promise-spawn" "^1.3.2" lru-cache "^6.0.0" @@ -1856,6 +1858,13 @@ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz#3cdc1f30e9736dbc417373ed803b42b1a0a29ede" integrity sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg== +"@npmcli/package-json@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-1.0.1.tgz#1ed42f00febe5293c3502fd0ef785647355f6e89" + integrity sha512-y6jnu76E9C23osz8gEMBayZmaZ69vFOIk8vR1FJL/wbEJ54+9aVG9rLTjQKSXfgYZEr50nw1txBBFfBZZe+bYg== + dependencies: + json-parse-even-better-errors "^2.3.1" + "@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": version "1.3.2" resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" @@ -1997,9 +2006,9 @@ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.7": - version "7.1.14" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" - integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== + version "7.1.15" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.15.tgz#2ccfb1ad55a02c83f8e0ad327cbc332f55eb1024" + integrity sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -2008,24 +2017,24 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" - integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== + version "7.6.3" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.3.tgz#f456b4b2ce79137f768aa130d2423d2f0ccfaba5" + integrity sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" - integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" - integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + version "7.14.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.1.tgz#46c2f9501a7a8f0596ddfd365e08c15285a47cce" + integrity sha512-DomsDK/nX3XXHs6jlQ8/YYE6jZAuhmoGAFfcYi1h1jbBNGS7Efdx74FKLTO3HCCyLqQyLlNbql87xqa7C3M/FQ== dependencies: "@babel/types" "^7.3.0" @@ -2035,9 +2044,9 @@ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== "@types/glob@^7.1.1": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" - integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + version "7.1.4" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" + integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== dependencies: "@types/minimatch" "*" "@types/node" "*" @@ -2096,20 +2105,15 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - "@types/minimatch@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== "@types/node@*": - version "15.12.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d" - integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww== + version "16.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.0.tgz#067a6c49dc7a5c2412a505628e26902ae967bf6f" + integrity sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2122,9 +2126,9 @@ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prettier@^2.0.0": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" - integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.1.tgz#54dd88bdc7f49958329666af3779561e47d5dab3" + integrity sha512-NVkb4p4YjI8E3O6+1m8I+8JlMpFZwfSbPGdaw0wXuyPRTEz0SLKwBUWNSO7Maoi8tQMPC8JLZNWkrcKPI7/sLA== "@types/prop-types@*": version "15.7.3" @@ -2159,18 +2163,18 @@ "@types/react" "*" "@types/react@*": - version "17.0.11" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" - integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.13.tgz#6b7c9a8f2868586ad87d941c02337c6888fb874f" + integrity sha512-D/G3PiuqTfE3IMNjLn/DCp6umjVCSvtZTPdtAFy5+Ved6CsdRvivfKeCzw79W4AatShtU4nGqgvOv5Gro534vQ== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" "@types/scheduler@*": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== "@types/stack-utils@^1.0.1": version "1.0.1" @@ -2178,21 +2182,21 @@ integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== "@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/styled-jsx@^2.2.8": - version "2.2.8" - resolved "https://registry.yarnpkg.com/@types/styled-jsx/-/styled-jsx-2.2.8.tgz#b50d13d8a3c34036282d65194554cf186bab7234" - integrity sha512-Yjye9VwMdYeXfS71ihueWRSxrruuXTwKCbzue4+5b2rjnQ//AtyM7myZ1BEhNhBQ/nL/RE7bdToUoLln2miKvg== + version "2.2.9" + resolved "https://registry.yarnpkg.com/@types/styled-jsx/-/styled-jsx-2.2.9.tgz#e50b3f868c055bcbf9bc353eca6c10fdad32a53f" + integrity sha512-W/iTlIkGEyTBGTEvZCey8EgQlQ5l0DwMqi3iOXlLs2kyBwYTXHKEiU6IZ5EwoRwngL8/dGYuzezSup89ttVHLw== dependencies: "@types/react" "*" "@types/unist@*", "@types/unist@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" - integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.5.tgz#fdd299f23205c3455af88ce618dd65c14cb73e22" + integrity sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g== "@types/vfile-message@*": version "2.0.0" @@ -2211,21 +2215,21 @@ "@types/vfile-message" "*" "@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== "@types/yargs@^13.0.0": - version "13.0.11" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.11.tgz#def2f0c93e4bdf2c61d7e34899b17e34be28d3b1" - integrity sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ== + version "13.0.12" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.12.tgz#d895a88c703b78af0465a9de88aa92c61430b092" + integrity sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ== dependencies: "@types/yargs-parser" "*" "@types/yargs@^15.0.0": - version "15.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" - integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== dependencies: "@types/yargs-parser" "*" @@ -2667,9 +2671,9 @@ acorn@^7.1.1: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4: - version "8.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.3.0.tgz#1193f9b96c4e8232f00b11a9edff81b2c8b98b88" - integrity sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw== + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== address@1.1.2, address@^1.0.1: version "1.1.2" @@ -2684,7 +2688,7 @@ adjust-sourcemap-loader@3.0.0: loader-utils "^2.0.0" regex-parser "^2.2.11" -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -2812,7 +2816,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3, anymatch@~3.1.1: +anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -3069,9 +3073,9 @@ aws4@^1.8.0: integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== axe-core@^4.0.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.2.2.tgz#0c987d82c8b82b4b9b7a945f1b5ef0d8fed586ed" - integrity sha512-OKRkKM4ojMEZRJ5UNJHmq9tht7cEnRnqKG6KyB/trYws00Xtkv12mHtlJ0SK7cmuNbrU8dPUova3ELTuilfBbw== + version "4.2.3" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.2.3.tgz#2a3afc332f0031b42f602f4a3de03c211ca98f72" + integrity sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ== axios-cache-adapter@^2.5.0: version "2.7.3" @@ -3228,12 +3232,12 @@ babel-plugin-polyfill-corejs2@^0.2.2: semver "^6.1.1" babel-plugin-polyfill-corejs3@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5" - integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A== + version "0.2.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz#72add68cf08a8bf139ba6e6dfc0b1d504098e57b" + integrity sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g== dependencies: "@babel/helper-define-polyfill-provider" "^0.2.2" - core-js-compat "^3.9.1" + core-js-compat "^3.14.0" babel-plugin-polyfill-regenerator@^0.2.2: version "0.2.2" @@ -3842,9 +3846,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219: - version "1.0.30001236" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001236.tgz#0a80de4cdf62e1770bb46a30d884fc8d633e3958" - integrity sha512-o0PRQSrSCGJKCPZcgMzl5fUaj5xHe8qA2m4QRvnyY4e1lITqoNkr7q/Oh1NcpGSy0Th97UZ35yoKcINPoq7YOQ== + version "1.0.30001242" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz#04201627abcd60dc89211f22cbe2347306cda46b" + integrity sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug== canvg@^3.0.6: version "3.0.7" @@ -3963,19 +3967,19 @@ chokidar@^2.0.4, chokidar@^2.1.8: fsevents "^1.2.7" chokidar@^3.3.0, chokidar@^3.4.0, chokidar@^3.4.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== dependencies: - anymatch "~3.1.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.5.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.3.1" + fsevents "~2.3.2" chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2: version "1.1.4" @@ -4103,15 +4107,6 @@ clipboard-copy@^3.0.0: resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" integrity sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ== -clipboard@^2.0.0: - version "2.0.8" - resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba" - integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ== - dependencies: - good-listener "^1.2.2" - select "^1.1.2" - tiny-emitter "^2.0.0" - cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -4414,7 +4409,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@1.7.0, convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -4426,6 +4421,13 @@ convert-source-map@^0.3.3: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -4467,18 +4469,18 @@ copy-webpack-plugin@^4.6.0: p-limit "^1.0.0" serialize-javascript "^1.4.0" -core-js-compat@^3.14.0, core-js-compat@^3.6.2, core-js-compat@^3.9.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.14.0.tgz#b574dabf29184681d5b16357bd33d104df3d29a5" - integrity sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A== +core-js-compat@^3.14.0, core-js-compat@^3.15.0, core-js-compat@^3.6.2: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.2.tgz#47272fbb479880de14b4e6081f71f3492f5bd3cb" + integrity sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ== dependencies: browserslist "^4.16.6" semver "7.0.0" -core-js-pure@^3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.14.0.tgz#72bcfacba74a65ffce04bf94ae91d966e80ee553" - integrity sha512-YVh+LN2FgNU0odThzm61BsdkwrbrchumFq3oztnE9vTKC4KS2fvnPmcx8t6jnqAyOTCTF4ZSiuK8Qhh7SNcL4g== +core-js-pure@^3.15.0: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.15.2.tgz#c8e0874822705f3385d3197af9348f7c9ae2e3ce" + integrity sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA== core-js@^2.4.0: version "2.6.12" @@ -4486,9 +4488,9 @@ core-js@^2.4.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.0.0, core-js@^3.5.0, core-js@^3.6.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.14.0.tgz#62322b98c71cc2018b027971a69419e2425c2a6c" - integrity sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA== + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61" + integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -4517,9 +4519,9 @@ cosmiconfig@^6.0.0: yaml "^1.7.2" coveralls@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.0.tgz#13c754d5e7a2dd8b44fe5269e21ca394fb4d615b" - integrity sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ== + version "3.1.1" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.1.tgz#f5d4431d8b5ae69c5079c8f8ca00d64ac77cf081" + integrity sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww== dependencies: js-yaml "^3.13.1" lcov-parse "^1.0.0" @@ -4936,9 +4938,9 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: ms "2.0.0" debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" @@ -4960,9 +4962,9 @@ decamelize@^1.2.0: integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decode-uri-component@^0.2.0: version "0.2.0" @@ -5053,11 +5055,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegate@^3.1.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" - integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== - delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -5269,9 +5266,9 @@ domhandler@^4.0.0, domhandler@^4.2.0: domelementtype "^2.2.0" dompurify@^2.0.12: - version "2.2.9" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.9.tgz#4b42e244238032d9286a0d2c87b51313581d9624" - integrity sha512-+9MqacuigMIZ+1+EwoEltogyWGFTJZWU3258Rupxs+2CGs4H914G9er6pZbsme/bvb5L67o2rade9n21e4RW/w== + version "2.3.0" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.0.tgz#07bb39515e491588e5756b1d3e8375b5964814e2" + integrity sha512-VV5C6Kr53YVHGOBKO/F86OYX6/iLTw2yVSI721gKetxpHCK/V5TaLEf9ODjRgl1KLSWRMY6cUhAbv/c+IUnwQw== domutils@^1.7.0: version "1.7.0" @@ -5344,9 +5341,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.723: - version "1.3.752" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz#0728587f1b9b970ec9ffad932496429aef750d09" - integrity sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A== + version "1.3.768" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.768.tgz#bbe47394f0073c947168589b7d19388518a7a9a9" + integrity sha512-I4UMZHhVSK2pwt8jOIxTi3GIuc41NkddtKT/hpuxp9GO5UWJgDKTBa4TACppbVAuKtKbMK6BhQZvT5tFF1bcNA== elliptic@^6.5.3: version "6.5.4" @@ -5616,9 +5613,9 @@ eslint-plugin-flowtype@4.6.0: lodash "^4.17.15" eslint-plugin-flowtype@^5.2.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.7.2.tgz#482a42fe5d15ee614652ed256d37543d584d7bc0" - integrity sha512-7Oq/N0+3nijBnYWQYzz/Mp/7ZCpwxYvClRyW/PLAmimY9uLCBvoXsNsERcJdkKceyOjgRbFhhxs058KTrne9Mg== + version "5.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.8.0.tgz#35b55e4ce559b90efbe913ed33630e391e301481" + integrity sha512-feK1xnUTsMSNTOw9jFw7aVgZl7Ep+ghpta/YEoaV6jbXU6Yso30B7BIj9ObHLzZ5TFJL7D98az080wfykLCrcw== dependencies: lodash "^4.17.15" string-natural-compare "^3.0.1" @@ -6176,26 +6173,18 @@ filefy@0.1.10: resolved "https://registry.yarnpkg.com/filefy/-/filefy-0.1.10.tgz#174677c8e2fa5bc39a3af0ed6fb492f16b8fbf42" integrity sha512-VgoRVOOY1WkTpWH+KBy8zcU1G7uQTVsXqhWEgzryB9A5hg2aqCyZ6aQ/5PSzlqM5+6cnVrX6oYV0XqD3HZSnmQ== -filename-reserved-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" - integrity sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q= - -filenamify-url@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/filenamify-url/-/filenamify-url-1.0.0.tgz#b32bd81319ef5863b73078bed50f46a4f7975f50" - integrity sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A= - dependencies: - filenamify "^1.0.0" - humanize-url "^1.0.0" +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= -filenamify@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-1.2.1.tgz#a9f2ffd11c503bed300015029272378f1f1365a5" - integrity sha1-qfL/0RxQO+0wABUCknI3jx8TZaU= +filenamify@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106" + integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg== dependencies: - filename-reserved-regex "^1.0.0" - strip-outer "^1.0.0" + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.1" trim-repeated "^1.0.0" filesize@3.6.1: @@ -6511,7 +6500,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.1.2, fsevents@~2.3.1: +fsevents@^2.1.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -6601,14 +6590,14 @@ getpass@^0.1.1: assert-plus "^1.0.0" gh-pages@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-3.2.0.tgz#ac5f9f03dae7622740ff39613ee2cfeacabc680b" - integrity sha512-VQTwyRtxoaId0YmDXdC/G854dojpwTuOdpZUL3PGG6WQZvSoGVD8ggedKARZltixIREMezoDywE+g3g2paLxPw== + version "3.2.3" + resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-3.2.3.tgz#897e5f15e111f42af57d21d430b83e5cdf29472c" + integrity sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg== dependencies: async "^2.6.1" commander "^2.18.0" email-addresses "^3.0.1" - filenamify-url "^1.0.0" + filenamify "^4.3.0" find-cache-dir "^3.3.1" fs-extra "^8.1.0" globby "^6.1.0" @@ -6628,7 +6617,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -6723,13 +6712,6 @@ glogg@^1.0.2: dependencies: sparkles "^1.0.0" -good-listener@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" - integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= - dependencies: - delegate "^3.1.2" - graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" @@ -6976,9 +6958,9 @@ html-webpack-plugin@4.0.0-beta.11: util.promisify "1.0.0" html2canvas@^1.0.0-rc.5: - version "1.0.0-rc.7" - resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.0.0-rc.7.tgz#70c159ce0e63954a91169531894d08ad5627ac98" - integrity sha512-yvPNZGejB2KOyKleZspjK/NruXVQuowu8NnV2HYG7gW7ytzl+umffbtUI62v2dCHQLDdsK6HIDtyJZ0W3neerA== + version "1.0.0" + resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.0.0.tgz#05c1966aeab08c17d9f113921b6b82d4d56740a4" + integrity sha512-0d/f2Aj1Brn+EeNWkuRdtnT13qu1NdvxhBMvts3ssme7jgPU7dtuwnm1P6cXvXmnDdUUerH5XdhveWvuLfqkew== dependencies: css-line-break "1.1.1" @@ -7111,14 +7093,6 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -humanize-url@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/humanize-url/-/humanize-url-1.0.1.tgz#f4ab99e0d288174ca4e1e50407c55fbae464efff" - integrity sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8= - dependencies: - normalize-url "^1.0.0" - strip-url-auth "^1.0.0" - hyphenate-style-name@^1.0.2, hyphenate-style-name@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" @@ -7240,13 +7214,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indefinite-observable@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/indefinite-observable/-/indefinite-observable-2.0.1.tgz#574af29bfbc17eb5947793797bddc94c9d859400" - integrity sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ== - dependencies: - symbol-observable "1.2.0" - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" @@ -8873,7 +8840,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.2: +json5@^2.1.2, json5@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== @@ -8969,73 +8936,72 @@ jss-nested@^6.0.1: warning "^3.0.0" jss-plugin-camel-case@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz#93d2cd704bf0c4af70cc40fb52d74b8a2554b170" - integrity sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.7.1.tgz#e7f7097cf97e9deec599cef3275e213452318b93" + integrity sha512-+ioIyWvmAfgDCWXsQcW1NMnLBvRinOVFkSYJUgewQ6TynOcSj5F1bSU23B7z0p1iqK0PPHIU62xY1iNJD33WGA== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.6.0" + jss "10.7.1" jss-plugin-default-unit@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz#af47972486819b375f0f3a9e0213403a84b5ef3b" - integrity sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.7.1.tgz#826270e2ee38d7024a281ac67c30d6944f124786" + integrity sha512-tW+dfYVNARBQb/ONzBwd8uyImigyzMiAEDai+AbH5rcHg5h3TtqhAkxx06iuZiT/dZUiFdSKlbe3q9jZGAPIwA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.7.1" jss-plugin-global@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz#3e8011f760f399cbadcca7f10a485b729c50e3ed" - integrity sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.7.1.tgz#9725c46d662aac2e596a0a8741944c060e2b90a1" + integrity sha512-FbxCnu44IkK/bw8X3CwZKmcAnJqjAb9LujlAc/aP0bMSdVa3/MugKQRyeQSu00uGL44feJJDoeXXiHOakBr/Zw== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.7.1" jss-plugin-nested@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz#5f83c5c337d3b38004834e8426957715a0251641" - integrity sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.7.1.tgz#35563a7a710a45307fd6b9742ffada1d72a62eb7" + integrity sha512-RNbICk7FlYKaJyv9tkMl7s6FFfeLA3ubNIFKvPqaWtADK0KUaPsPXVYBkAu4x1ItgsWx67xvReMrkcKA0jSXfA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.7.1" tiny-warning "^1.0.2" jss-plugin-props-sort@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz#297879f35f9fe21196448579fee37bcde28ce6bc" - integrity sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.7.1.tgz#1d12b26048541ed3a2ed1b69f7fc231605728362" + integrity sha512-eyd5FhA+J0QrpqXxO7YNF/HMSXXl4pB0EmUdY4vSJI4QG22F59vQ6AHtP6fSwhmBdQ98Qd9gjfO+RMxcE39P1A== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.7.1" jss-plugin-rule-value-function@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz#3c1a557236a139d0151e70a82c810ccce1c1c5ea" - integrity sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.7.1.tgz#123eb796eb9982f8efa7a7e362daddd90c0c69fe" + integrity sha512-fGAAImlbaHD3fXAHI3ooX6aRESOl5iBt3LjpVjxs9II5u9tzam7pqFUmgTcrip9VpRqYHn8J3gA7kCtm8xKwHg== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.7.1" tiny-warning "^1.0.2" jss-plugin-vendor-prefixer@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz#e1fcd499352846890c38085b11dbd7aa1c4f2c78" - integrity sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ== + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.7.1.tgz#217821be2d6dacee31d2d464886760ba7742e19a" + integrity sha512-1UHFmBn7hZNsHXTkLLOL8abRl8vi+D1EVzWD4WmLFj55vawHZfnH1oEz6TUf5Y61XHv0smdHabdXds6BgOXe3A== dependencies: "@babel/runtime" "^7.3.1" css-vendor "^2.0.8" - jss "10.6.0" + jss "10.7.1" -jss@10.6.0, jss@^10.5.1: - version "10.6.0" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.6.0.tgz#d92ff9d0f214f65ca1718591b68e107be4774149" - integrity sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw== +jss@10.7.1, jss@^10.5.1: + version "10.7.1" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.7.1.tgz#16d846e1a22fb42e857b99f9c6a0c5a27341c804" + integrity sha512-5QN8JSVZR6cxpZNeGfzIjqPEP+ZJwJJfZbXmeABNdxiExyO+eJJDy6WDtqTf8SDKnbL5kZllEpAP71E/Lt7PXg== dependencies: "@babel/runtime" "^7.3.1" csstype "^3.0.2" - indefinite-observable "^2.0.1" is-in-browser "^1.1.3" tiny-warning "^1.0.2" @@ -9214,10 +9180,10 @@ libnpmdiff@^2.0.4: pacote "^11.3.0" tar "^6.1.0" -libnpmexec@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-1.2.0.tgz#ab0294ab63bb599b3ac6921129b7a706d4d56da2" - integrity sha512-LkxnH2wsMUI4thsgUK0r+EFZ5iCjKlp21J68dFY7AzD5uaaIPqO3lqVvYbyl1Umz1R4rY9t3vFa1fF3hzo6Y2Q== +libnpmexec@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-2.0.0.tgz#9154549a30cd7825afee77de97e71336fb1792bf" + integrity sha512-9zHswx//Lp2ao+huWF2aL+6v4haMncyxNusk6Us2fbLNnPh3+rgSkv38LJ2v8gmKS2kAnkUmQf8pHjcZ+7Z3NA== dependencies: "@npmcli/arborist" "^2.3.0" "@npmcli/ci-detect" "^1.3.0" @@ -9289,10 +9255,10 @@ libnpmteam@^2.0.3: aproba "^2.0.0" npm-registry-fetch "^11.0.0" -libnpmversion@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/libnpmversion/-/libnpmversion-1.2.0.tgz#e181eb7ab750003b7fd29a578c31e84bb91a67b9" - integrity sha512-0pfmobLZbOvq1cLIONZk8ISvEM1k3JdkNXWhMDZvUeH+ijBNvMVdPu/CPUr1eDFbNINS3b6R/0PbTIZDVz7thg== +libnpmversion@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/libnpmversion/-/libnpmversion-1.2.1.tgz#689aa7fe0159939b3cbbf323741d34976f4289e9" + integrity sha512-AA7x5CFgBFN+L4/JWobnY5t4OAHjQuPbAwUYJ7/NtHuyLut5meb+ne/aj0n7PWNiTGCJcRw/W6Zd2LoLT7EZuQ== dependencies: "@npmcli/git" "^2.0.7" "@npmcli/run-script" "^1.8.4" @@ -9566,10 +9532,10 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" -make-fetch-happen@^9.0.1: - version "9.0.2" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.0.2.tgz#aa8c0e4a5e3a5f2be86c54d3abed44fe5a32ad5d" - integrity sha512-UkAWAuXPXSSlVviTjH2We20mtj1NnZW2Qq/oTY2dyMbRQ5CR3Xed3akCDMnM7j6axrMY80lhgM7loNE132PfAw== +make-fetch-happen@^9.0.1, make-fetch-happen@^9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.0.3.tgz#57bbfb5b859807cd28005ca85aa6a72568675e24" + integrity sha512-uZ/9Cf2vKqsSWZyXhZ9wHHyckBrkntgbnqV68Bfe8zZenlf7D6yuGMXvHZQ+jSnzPkjosuNP1HGasj1J4h8OlQ== dependencies: agentkeepalive "^4.1.3" cacache "^15.2.0" @@ -10241,7 +10207,7 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@1.9.1, normalize-url@^1.0.0: +normalize-url@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= @@ -10282,10 +10248,10 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-package-arg@^8.1.1, npm-package-arg@^8.1.2, npm-package-arg@^8.1.4: - version "8.1.4" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.4.tgz#8001cdbc4363997b8ef6c6cf7aaf543c5805879d" - integrity sha512-xLokoCFqj/rPdr3LvcdDL6Kj6ipXGEDHD/QGpzwU6/pibYUOXmp5DBmg76yukFyx4ZDbrXNOTn+BPyd8TD4Jlw== +npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-package-arg@^8.1.1, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5: + version "8.1.5" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" + integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== dependencies: hosted-git-info "^4.0.1" semver "^7.3.4" @@ -10350,13 +10316,14 @@ npm-user-validate@^1.0.1: integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw== npm@^7.11.2: - version "7.17.0" - resolved "https://registry.yarnpkg.com/npm/-/npm-7.17.0.tgz#f30b4e3aa00627ca858c47d0e98c3a0452b7a62c" - integrity sha512-yNzj4vQellvUGiBM/SzhfT89EV0vb7iILjTehSydTY/IgK2Vjk7/7J8WNJ2ysqcgfLY21ptI/j7uknt15IbbKQ== + version "7.19.1" + resolved "https://registry.yarnpkg.com/npm/-/npm-7.19.1.tgz#864310bce731f10e5602e4a97a44b80306b70b4d" + integrity sha512-aN3hZzGkPzKOyhjXtOhnQTGumorFhgpOU6xfuQsF1nJKh4DhsgfOMG4s/SNx56r4xHPvM5m/sk914wzDgKba3A== dependencies: - "@npmcli/arborist" "^2.6.1" + "@npmcli/arborist" "^2.6.4" "@npmcli/ci-detect" "^1.2.0" "@npmcli/config" "^2.2.0" + "@npmcli/package-json" "^1.0.1" "@npmcli/run-script" "^1.8.5" abbrev "~1.1.1" ansicolors "~0.3.2" @@ -10379,7 +10346,7 @@ npm@^7.11.2: leven "^3.1.0" libnpmaccess "^4.0.2" libnpmdiff "^2.0.4" - libnpmexec "^1.2.0" + libnpmexec "^2.0.0" libnpmfund "^1.1.0" libnpmhook "^6.0.2" libnpmorg "^2.0.2" @@ -10387,8 +10354,8 @@ npm@^7.11.2: libnpmpublish "^4.0.1" libnpmsearch "^3.1.1" libnpmteam "^2.0.3" - libnpmversion "^1.2.0" - make-fetch-happen "^9.0.1" + libnpmversion "^1.2.1" + make-fetch-happen "^9.0.3" minipass "^3.1.3" minipass-pipeline "^1.2.4" mkdirp "^1.0.4" @@ -10397,7 +10364,7 @@ npm@^7.11.2: node-gyp "^7.1.2" nopt "^5.0.0" npm-audit-report "^2.1.5" - npm-package-arg "^8.1.4" + npm-package-arg "^8.1.5" npm-pick-manifest "^6.1.1" npm-profile "^5.0.3" npm-registry-fetch "^11.0.0" @@ -10785,11 +10752,11 @@ p-try@^2.0.0: integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pacote@^11.1.11, pacote@^11.2.6, pacote@^11.3.0, pacote@^11.3.1, pacote@^11.3.3: - version "11.3.4" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.3.4.tgz#c290b790a5cee3082bb8fa223f3f3e2fdf3d0bfc" - integrity sha512-RfahPCunM9GI7ryJV/zY0bWQiokZyLqaSNHXtbNSoLb7bwTvBbJBEyCJ01KWs4j1Gj7GmX8crYXQ1sNX6P2VKA== + version "11.3.5" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.3.5.tgz#73cf1fc3772b533f575e39efa96c50be8c3dc9d2" + integrity sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg== dependencies: - "@npmcli/git" "^2.0.1" + "@npmcli/git" "^2.1.0" "@npmcli/installed-package-contents" "^1.0.6" "@npmcli/promise-spawn" "^1.2.0" "@npmcli/run-script" "^1.8.2" @@ -11782,9 +11749,9 @@ postcss@7.0.21: supports-color "^6.1.0" postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" - integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== + version "7.0.36" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb" + integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -11834,11 +11801,9 @@ pretty-format@^26.6.2: react-is "^17.0.1" prismjs@^1.16.0: - version "1.23.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" - integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA== - optionalDependencies: - clipboard "^2.0.0" + version "1.24.1" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.24.1.tgz#c4d7895c4d6500289482fa8936d9cdd192684036" + integrity sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow== private@^0.1.8: version "0.1.8" @@ -12584,10 +12549,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" @@ -12678,9 +12643,9 @@ regexpp@^2.0.1: integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpp@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== regexpu-core@^4.5.4, regexpu-core@^4.7.1: version "4.7.1" @@ -13178,11 +13143,6 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -select@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" - integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= - selfsigned@^1.10.7, selfsigned@^1.10.8: version "1.10.11" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" @@ -13493,11 +13453,11 @@ sockjs@^0.3.21: websocket-driver "^0.7.4" socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== dependencies: - agent-base "6" + agent-base "^6.0.2" debug "4" socks "^2.3.3" @@ -13957,18 +13917,13 @@ strip-json-comments@^3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-outer@^1.0.0: +strip-outer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== dependencies: escape-string-regexp "^1.0.2" -strip-url-auth@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-url-auth/-/strip-url-auth-1.0.1.tgz#22b0fa3a41385b33be3f331551bbb837fa0cd7ae" - integrity sha1-IrD6OkE4WzO+PzMVUbu4N/oM164= - style-loader@0.23.1: version "0.23.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" @@ -14049,7 +14004,7 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -symbol-observable@1.2.0, symbol-observable@^1.1.0: +symbol-observable@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== @@ -14197,11 +14152,6 @@ timsort@^0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= -tiny-emitter@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" - integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== - tiny-invariant@^1.0.6: version "1.1.0" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" @@ -14353,12 +14303,11 @@ ts-pnp@^1.1.6: integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + version "3.10.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz#79ae67a68c15289fdf5c51cb74f397522d795ed7" + integrity sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q== dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^2.2.0" minimist "^1.2.0" strip-bom "^3.0.0" @@ -14368,9 +14317,9 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== tsutils@^3.17.1: version "3.21.0" @@ -15181,9 +15130,9 @@ whatwg-url@^7.0.0: webidl-conversions "^4.0.2" whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c" - integrity sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw== + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" tr46 "^2.1.0" @@ -15453,9 +15402,9 @@ ws@^6.1.2, ws@^6.2.1: async-limiter "~1.0.0" ws@^7.4.5: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + version "7.5.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" + integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== x-is-string@^0.1.0: version "0.1.0" @@ -15531,9 +15480,9 @@ yargs-parser@^18.1.2: decamelize "^1.2.0" yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs@^13.3.0, yargs@^13.3.2: version "13.3.2"