@lhncbc/ucum-lhc 7.1.5 → 7.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser-dist/ucum-lhc.min.js +1 -1
- package/browser-dist/ucum-lhc.min.js.map +1 -1
- package/package.json +6 -8
- package/source/unitString.js +169 -89
- package/source-cjs/config.js +1 -2
- package/source-cjs/config.js.map +1 -1
- package/source-cjs/dimension.js.map +1 -1
- package/source-cjs/prefixTables.js +2 -3
- package/source-cjs/prefixTables.js.map +1 -1
- package/source-cjs/ucumFunctions.js +1 -2
- package/source-cjs/ucumFunctions.js.map +1 -1
- package/source-cjs/ucumInternalUtils.js +2 -2
- package/source-cjs/ucumJsonDefs.js +1 -2
- package/source-cjs/ucumJsonDefs.js.map +1 -1
- package/source-cjs/ucumLhcUtils.js.map +1 -1
- package/source-cjs/ucumPkg.js +3 -6
- package/source-cjs/ucumPkg.js.map +1 -1
- package/source-cjs/ucumXmlDocument.js.map +1 -1
- package/source-cjs/unit.js.map +1 -1
- package/source-cjs/unitString.js +154 -83
- package/source-cjs/unitString.js.map +1 -1
- package/source-cjs/unitTables.js +1 -2
- package/source-cjs/unitTables.js.map +1 -1
package/source-cjs/unitString.js
CHANGED
|
@@ -990,34 +990,6 @@ class UnitString {
|
|
|
990
990
|
retUnit.ciCode_ = retUnit.ciCode_.replace('*', '^');
|
|
991
991
|
}
|
|
992
992
|
}
|
|
993
|
-
// If that didn't work, check to see if it should have brackets
|
|
994
|
-
// around it (uCode = degF when it should be [degF]
|
|
995
|
-
if (!retUnit) {
|
|
996
|
-
let addBrackets = '[' + uCode + ']';
|
|
997
|
-
retUnit = this.utabs_.getUnitByCode(addBrackets);
|
|
998
|
-
if (retUnit) {
|
|
999
|
-
retUnit = retUnit.clone();
|
|
1000
|
-
origString = origString.replace(uCode, addBrackets);
|
|
1001
|
-
this.retMsg_.push(`${uCode} is not a valid unit expression, but ` + `${addBrackets} is.\n` + this.vcMsgStart_ + `${addBrackets} (${retUnit.name_})${this.vcMsgEnd_}`);
|
|
1002
|
-
} // end if we found the unit after adding brackets
|
|
1003
|
-
} // end trying to add brackets
|
|
1004
|
-
|
|
1005
|
-
// If we didn't find it, try it as a name
|
|
1006
|
-
if (!retUnit) {
|
|
1007
|
-
let retUnitAry = this.utabs_.getUnitByName(uCode);
|
|
1008
|
-
if (retUnitAry && retUnitAry.length > 0) {
|
|
1009
|
-
retUnit = retUnitAry[0].clone();
|
|
1010
|
-
let mString = 'The UCUM code for ' + uCode + ' is ' + retUnit.csCode_ + '.\n' + this.vcMsgStart_ + retUnit.csCode_ + this.vcMsgEnd_;
|
|
1011
|
-
let dupMsg = false;
|
|
1012
|
-
for (let r = 0; r < this.retMsg_.length && !dupMsg; r++) dupMsg = this.retMsg_[r] === mString;
|
|
1013
|
-
if (!dupMsg) this.retMsg_.push(mString);
|
|
1014
|
-
let rStr = new RegExp('(^|[.\/({])(' + uCode + ')($|[.\/)}])');
|
|
1015
|
-
let res = origString.match(rStr);
|
|
1016
|
-
origString = origString.replace(rStr, res[1] + retUnit.csCode_ + res[3]);
|
|
1017
|
-
uCode = retUnit.csCode_;
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
993
|
// If we still don't have a unit, try assuming a modifier (prefix and/or
|
|
1022
994
|
// exponent) and look for a unit without the modifier
|
|
1023
995
|
if (!retUnit) {
|
|
@@ -1064,7 +1036,7 @@ class UnitString {
|
|
|
1064
1036
|
} else {
|
|
1065
1037
|
// If we still don't have a unit, separate out the prefix, if any,
|
|
1066
1038
|
// and try without it.
|
|
1067
|
-
if (!origUnit) {
|
|
1039
|
+
if (!origUnit && uCode.length > 1) {
|
|
1068
1040
|
// Try for a single character prefix first, then for a two-digit prefix
|
|
1069
1041
|
pfxCode = '';
|
|
1070
1042
|
do {
|
|
@@ -1076,7 +1048,7 @@ class UnitString {
|
|
|
1076
1048
|
// try again for the unit
|
|
1077
1049
|
origUnit = this.utabs_.getUnitByCode(uCode);
|
|
1078
1050
|
}
|
|
1079
|
-
} while (!origUnit && pfxCode.length < 2);
|
|
1051
|
+
} while (!origUnit && pfxCode.length < 2 && uCode.length > 1);
|
|
1080
1052
|
|
|
1081
1053
|
// Reject the unit we found if it might have another prefix. (??)
|
|
1082
1054
|
// Such things are in our tables through the LOINC source_
|
|
@@ -1091,12 +1063,21 @@ class UnitString {
|
|
|
1091
1063
|
// without the exponent, the unit string without a prefix,
|
|
1092
1064
|
// common errors, etc. That's all we can try).
|
|
1093
1065
|
if (!origUnit) {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1066
|
+
let bracketRet = this._getUnitAfterAddingBrackets(origCode, origString);
|
|
1067
|
+
retUnit = bracketRet[0];
|
|
1068
|
+
origString = bracketRet[1];
|
|
1069
|
+
if (!retUnit) {
|
|
1070
|
+
let nameRet = this._getUnitByName(origCode, origString);
|
|
1071
|
+
retUnit = nameRet[0];
|
|
1072
|
+
origString = nameRet[1];
|
|
1073
|
+
if (!retUnit) {
|
|
1074
|
+
// BUT if the user asked for suggestions, at least look for them
|
|
1075
|
+
if (this.suggestions_) {
|
|
1076
|
+
let suggestStat = this._getSuggestions(origCode);
|
|
1077
|
+
} else {
|
|
1078
|
+
this.retMsg_.push(`${origCode} is not a valid UCUM code.`);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1100
1081
|
}
|
|
1101
1082
|
} else {
|
|
1102
1083
|
// Otherwise we found a unit object. Clone it and then apply the
|
|
@@ -1114,62 +1095,83 @@ class UnitString {
|
|
|
1114
1095
|
// If there is an exponent for the unit, apply it to the dimension
|
|
1115
1096
|
// and magnitude now
|
|
1116
1097
|
if (exp) {
|
|
1117
|
-
|
|
1118
|
-
if (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1098
|
+
// Special units cannot be raised to a power
|
|
1099
|
+
if (retUnit.isSpecial_) {
|
|
1100
|
+
this.retMsg_.push(`Special units like ${retUnit.name_} cannot be raised to a power.`);
|
|
1101
|
+
retUnit = null;
|
|
1102
|
+
} else {
|
|
1103
|
+
exp = parseInt(exp);
|
|
1104
|
+
if (theDim) theDim = theDim.mul(exp);
|
|
1105
|
+
retUnit.equivalentExp_ *= exp;
|
|
1106
|
+
retUnit.moleExp_ *= exp;
|
|
1107
|
+
theMag = Math.pow(theMag, exp);
|
|
1108
|
+
retUnit.assignVals({
|
|
1109
|
+
'magnitude_': theMag
|
|
1110
|
+
});
|
|
1125
1111
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1112
|
+
// If there is also a prefix, apply the exponent to the prefix.
|
|
1113
|
+
if (pfxObj) {
|
|
1114
|
+
// We don't need to consider pfxObj.getExp(), because when
|
|
1115
|
+
// present that is reflected in the pfxVal. However, in some
|
|
1116
|
+
// cases one can avoid floating-point math inaccuracies by using
|
|
1117
|
+
// that exponent instead of relying on pfxVal. For example:
|
|
1118
|
+
// 1e-66 = Math.pow(10, -3*22) = Math.pow(0.001, 22) = 1.0000000000000005e-66
|
|
1119
|
+
// (This is the from the test case of the unit mg% raised to the 22nd power (mg%22).)
|
|
1120
|
+
// This does not help in all cases, but it does help the above
|
|
1121
|
+
// test case (which is in our web API service test code).
|
|
1122
|
+
let pfxExp = pfxObj.getExp();
|
|
1123
|
+
if (pfxExp) {
|
|
1124
|
+
// This is relying on the fact that pfxExp is null when
|
|
1125
|
+
// the prefix base is not 10.
|
|
1126
|
+
pfxVal = Math.pow(10, exp * pfxExp);
|
|
1127
|
+
} else {
|
|
1128
|
+
pfxVal = Math.pow(pfxVal, exp);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
} // end else - prefix and exponent handling for non-special units
|
|
1132
1132
|
} // end if there's an exponent
|
|
1133
1133
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
if (
|
|
1134
|
+
if (retUnit) {
|
|
1135
|
+
// Now apply the prefix, if there is one, to the conversion
|
|
1136
|
+
// prefix or the magnitude
|
|
1137
|
+
if (pfxObj) {
|
|
1138
|
+
if (retUnit.cnv_) {
|
|
1139
|
+
retUnit.assignVals({
|
|
1140
|
+
'cnvPfx_': pfxVal
|
|
1141
|
+
});
|
|
1142
|
+
} else {
|
|
1143
|
+
theMag *= pfxVal;
|
|
1144
|
+
retUnit.assignVals({
|
|
1145
|
+
'magnitude_': theMag
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// if we have a prefix and/or an exponent, add them to the unit
|
|
1150
|
+
// attributes - name, csCode, ciCode and print symbol
|
|
1151
|
+
let theCode = retUnit.csCode_;
|
|
1152
|
+
if (pfxObj) {
|
|
1153
|
+
theName = pfxObj.getName() + theName;
|
|
1154
|
+
theCode = pfxCode + theCode;
|
|
1155
|
+
theCiCode = pfxObj.getCiCode() + theCiCode;
|
|
1156
|
+
thePrintSymbol = pfxObj.getPrintSymbol() + thePrintSymbol;
|
|
1138
1157
|
retUnit.assignVals({
|
|
1139
|
-
'
|
|
1158
|
+
'name_': theName,
|
|
1159
|
+
'csCode_': theCode,
|
|
1160
|
+
'ciCode_': theCiCode,
|
|
1161
|
+
'printSymbol_': thePrintSymbol
|
|
1140
1162
|
});
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1163
|
+
}
|
|
1164
|
+
if (exp) {
|
|
1165
|
+
let expStr = exp.toString();
|
|
1166
|
+
const intergerUnitExpSign = isIntegerUnitWithExp && exp > 0 ? '+' : '';
|
|
1143
1167
|
retUnit.assignVals({
|
|
1144
|
-
'
|
|
1168
|
+
'name_': theName + '<sup>' + expStr + '</sup>',
|
|
1169
|
+
'csCode_': theCode + intergerUnitExpSign + expStr,
|
|
1170
|
+
'ciCode_': theCiCode + intergerUnitExpSign + expStr,
|
|
1171
|
+
'printSymbol_': thePrintSymbol + '<sup>' + expStr + '</sup>'
|
|
1145
1172
|
});
|
|
1146
1173
|
}
|
|
1147
1174
|
}
|
|
1148
|
-
// if we have a prefix and/or an exponent, add them to the unit
|
|
1149
|
-
// attributes - name, csCode, ciCode and print symbol
|
|
1150
|
-
let theCode = retUnit.csCode_;
|
|
1151
|
-
if (pfxObj) {
|
|
1152
|
-
theName = pfxObj.getName() + theName;
|
|
1153
|
-
theCode = pfxCode + theCode;
|
|
1154
|
-
theCiCode = pfxObj.getCiCode() + theCiCode;
|
|
1155
|
-
thePrintSymbol = pfxObj.getPrintSymbol() + thePrintSymbol;
|
|
1156
|
-
retUnit.assignVals({
|
|
1157
|
-
'name_': theName,
|
|
1158
|
-
'csCode_': theCode,
|
|
1159
|
-
'ciCode_': theCiCode,
|
|
1160
|
-
'printSymbol_': thePrintSymbol
|
|
1161
|
-
});
|
|
1162
|
-
}
|
|
1163
|
-
if (exp) {
|
|
1164
|
-
let expStr = exp.toString();
|
|
1165
|
-
const intergerUnitExpSign = isIntegerUnitWithExp && exp > 0 ? '+' : '';
|
|
1166
|
-
retUnit.assignVals({
|
|
1167
|
-
'name_': theName + '<sup>' + expStr + '</sup>',
|
|
1168
|
-
'csCode_': theCode + intergerUnitExpSign + expStr,
|
|
1169
|
-
'ciCode_': theCiCode + intergerUnitExpSign + expStr,
|
|
1170
|
-
'printSymbol_': thePrintSymbol + '<sup>' + expStr + '</sup>'
|
|
1171
|
-
});
|
|
1172
|
-
}
|
|
1173
1175
|
} // end if an original unit was found (without prefix and/or exponent)
|
|
1174
1176
|
} // end if an invalid exponent wasn't found
|
|
1175
1177
|
} // end if we didn't get a unit for the full unit code (w/out modifiers)
|
|
@@ -1177,6 +1179,75 @@ class UnitString {
|
|
|
1177
1179
|
return [retUnit, origString];
|
|
1178
1180
|
} // end _makeUnit
|
|
1179
1181
|
|
|
1182
|
+
/**
|
|
1183
|
+
* Checks whether an otherwise unresolved unit code matches a unit name.
|
|
1184
|
+
*
|
|
1185
|
+
* @param uCode the unit code or name to check
|
|
1186
|
+
* @param origString the original full string submitted to parseString
|
|
1187
|
+
* @returns an array containing the unit object found, or null, and origString
|
|
1188
|
+
*/
|
|
1189
|
+
_getUnitByName(uCode, origString) {
|
|
1190
|
+
let retUnit = null;
|
|
1191
|
+
let retUnitAry = this.utabs_.getUnitByName(uCode);
|
|
1192
|
+
if (retUnitAry && retUnitAry.length > 0) {
|
|
1193
|
+
retUnit = retUnitAry[0].clone();
|
|
1194
|
+
let mString = 'The UCUM code for ' + uCode + ' is ' + retUnit.csCode_ + '.\n' + this.vcMsgStart_ + retUnit.csCode_ + this.vcMsgEnd_;
|
|
1195
|
+
let dupMsg = false;
|
|
1196
|
+
for (let r = 0; r < this.retMsg_.length && !dupMsg; r++) dupMsg = this.retMsg_[r] === mString;
|
|
1197
|
+
if (!dupMsg) this.retMsg_.push(mString);
|
|
1198
|
+
const escapedCode = uCode.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1199
|
+
let rStr = new RegExp('(^|[./(])(' + escapedCode + ')($|[./)\\-\\d{])');
|
|
1200
|
+
const updatedOrigString = origString.replace(rStr, '$1' + retUnit.csCode_ + '$3');
|
|
1201
|
+
if (updatedOrigString == origString) {
|
|
1202
|
+
// This should not happen, if the processing has been correct. However, if it does happen, we
|
|
1203
|
+
// still have to change origString to signal that the input unit is invalid.
|
|
1204
|
+
// There is a test present to make sure this message does not appear from the top-level APIs in
|
|
1205
|
+
// ucumLhcUtils.js.
|
|
1206
|
+
// Ideally, this problem would be signalled some other way, but that would be a bigger change.
|
|
1207
|
+
origString += ' (Unable to update the unit expression with a suggested replacement.)';
|
|
1208
|
+
} else {
|
|
1209
|
+
origString = updatedOrigString;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return [retUnit, origString];
|
|
1213
|
+
} // end _getUnitByName
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Checks whether an otherwise unresolved unit code can be found after adding
|
|
1217
|
+
* square brackets, e.g., degF -> [degF]. If a bracketed unit is found,
|
|
1218
|
+
* origString is modified to include the suggested replacement.
|
|
1219
|
+
*
|
|
1220
|
+
* @param uCode the unit code to check
|
|
1221
|
+
* @param origString the original full string submitted to parseString
|
|
1222
|
+
* @returns an array containing the unit object found, or null, and the possibly
|
|
1223
|
+
* modified origString
|
|
1224
|
+
*/
|
|
1225
|
+
_getUnitAfterAddingBrackets(uCode, origString) {
|
|
1226
|
+
let retUnit = null;
|
|
1227
|
+
const addBrackets = '[' + uCode + ']';
|
|
1228
|
+
const bracketUnit = this.utabs_.getUnitByCode(addBrackets);
|
|
1229
|
+
if (bracketUnit) {
|
|
1230
|
+
retUnit = bracketUnit.clone();
|
|
1231
|
+
const escapedCode = uCode.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1232
|
+
const leadingUnitBoundary = '(^|[./(])';
|
|
1233
|
+
const trailingUnitBoundary = '($|[./)\\-\\d{])';
|
|
1234
|
+
const rStr = new RegExp(leadingUnitBoundary + '(' + escapedCode + ')' + trailingUnitBoundary);
|
|
1235
|
+
const updatedOrigString = origString.replace(rStr, '$1' + addBrackets + '$3');
|
|
1236
|
+
if (updatedOrigString == origString) {
|
|
1237
|
+
// This should not happen, if the processing has been correct. However, if it does happen, we
|
|
1238
|
+
// still have to change origString to signal that the input unit is invalid.
|
|
1239
|
+
// There is a test present to make sure this message does not appear from the top-level APIs in
|
|
1240
|
+
// ucumLhcUtils.js.
|
|
1241
|
+
// Ideally, this problem would be signalled some other way, but that would be a bigger change.
|
|
1242
|
+
origString += ' (Unable to update the unit expression with a suggested replacement.)';
|
|
1243
|
+
} else {
|
|
1244
|
+
origString = updatedOrigString;
|
|
1245
|
+
}
|
|
1246
|
+
this.retMsg_.push(`${uCode} is not a valid unit expression, but ` + `${addBrackets} is.\n` + this.vcMsgStart_ + `${addBrackets} (${retUnit.name_})${this.vcMsgEnd_}`);
|
|
1247
|
+
}
|
|
1248
|
+
return [retUnit, origString];
|
|
1249
|
+
} // end _getUnitAfterAddingBrackets
|
|
1250
|
+
|
|
1180
1251
|
/**
|
|
1181
1252
|
* This method handles unit creation when an annotation is included
|
|
1182
1253
|
* in the unit string. This basically isolates and retrieves the
|