dynamic_cstr.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. export var Axis;
  2. (function (Axis) {
  3. Axis["DOMAIN"] = "domain";
  4. Axis["STYLE"] = "style";
  5. Axis["LOCALE"] = "locale";
  6. Axis["TOPIC"] = "topic";
  7. Axis["MODALITY"] = "modality";
  8. })(Axis || (Axis = {}));
  9. export class DynamicProperties {
  10. static createProp(...cstrList) {
  11. const axes = DynamicCstr.DEFAULT_ORDER;
  12. const dynamicCstr = {};
  13. for (let i = 0, l = cstrList.length, k = axes.length; i < l && i < k; i++) {
  14. dynamicCstr[axes[i]] = cstrList[i];
  15. }
  16. return new DynamicProperties(dynamicCstr);
  17. }
  18. constructor(properties, order = Object.keys(properties)) {
  19. this.properties = properties;
  20. this.order = order;
  21. }
  22. getProperties() {
  23. return this.properties;
  24. }
  25. getOrder() {
  26. return this.order;
  27. }
  28. getAxes() {
  29. return this.order;
  30. }
  31. getProperty(key) {
  32. return this.properties[key];
  33. }
  34. updateProperties(props) {
  35. this.properties = props;
  36. }
  37. allProperties() {
  38. const propLists = [];
  39. this.order.forEach((key) => propLists.push(this.getProperty(key).slice()));
  40. return propLists;
  41. }
  42. toString() {
  43. const cstrStrings = [];
  44. this.order.forEach((key) => cstrStrings.push(key + ': ' + this.getProperty(key).toString()));
  45. return cstrStrings.join('\n');
  46. }
  47. }
  48. export class DynamicCstr extends DynamicProperties {
  49. static createCstr(...cstrList) {
  50. const axes = DynamicCstr.DEFAULT_ORDER;
  51. const dynamicCstr = {};
  52. for (let i = 0, l = cstrList.length, k = axes.length; i < l && i < k; i++) {
  53. dynamicCstr[axes[i]] = cstrList[i];
  54. }
  55. return new DynamicCstr(dynamicCstr);
  56. }
  57. static defaultCstr() {
  58. return DynamicCstr.createCstr.apply(null, DynamicCstr.DEFAULT_ORDER.map(function (x) {
  59. return DynamicCstr.DEFAULT_VALUES[x];
  60. }));
  61. }
  62. static validOrder(order) {
  63. const axes = DynamicCstr.DEFAULT_ORDER.slice();
  64. return order.every((x) => {
  65. const index = axes.indexOf(x);
  66. return index !== -1 && axes.splice(index, 1);
  67. });
  68. }
  69. constructor(components_, order) {
  70. const properties = {};
  71. for (const [key, value] of Object.entries(components_)) {
  72. properties[key] = [value];
  73. }
  74. super(properties, order);
  75. this.components = components_;
  76. }
  77. getComponents() {
  78. return this.components;
  79. }
  80. getValue(key) {
  81. return this.components[key];
  82. }
  83. getValues() {
  84. return this.order.map((key) => this.getValue(key));
  85. }
  86. allProperties() {
  87. const propLists = super.allProperties();
  88. for (let i = 0, props, key; (props = propLists[i]), (key = this.order[i]); i++) {
  89. const value = this.getValue(key);
  90. if (props.indexOf(value) === -1) {
  91. props.unshift(value);
  92. }
  93. }
  94. return propLists;
  95. }
  96. toString() {
  97. return this.getValues().join('.');
  98. }
  99. equal(cstr) {
  100. const keys1 = cstr.getAxes();
  101. if (this.order.length !== keys1.length) {
  102. return false;
  103. }
  104. for (let j = 0, key; (key = keys1[j]); j++) {
  105. const comp2 = this.getValue(key);
  106. if (!comp2 || cstr.getValue(key) !== comp2) {
  107. return false;
  108. }
  109. }
  110. return true;
  111. }
  112. }
  113. DynamicCstr.DEFAULT_ORDER = [
  114. Axis.LOCALE,
  115. Axis.MODALITY,
  116. Axis.DOMAIN,
  117. Axis.STYLE,
  118. Axis.TOPIC
  119. ];
  120. DynamicCstr.BASE_LOCALE = 'base';
  121. DynamicCstr.DEFAULT_VALUE = 'default';
  122. DynamicCstr.DEFAULT_VALUES = {
  123. [Axis.LOCALE]: 'en',
  124. [Axis.DOMAIN]: DynamicCstr.DEFAULT_VALUE,
  125. [Axis.STYLE]: DynamicCstr.DEFAULT_VALUE,
  126. [Axis.TOPIC]: DynamicCstr.DEFAULT_VALUE,
  127. [Axis.MODALITY]: 'speech'
  128. };
  129. export class DynamicCstrParser {
  130. constructor(order) {
  131. this.order = order;
  132. }
  133. parse(str) {
  134. const order = str.split('.');
  135. const cstr = {};
  136. if (order.length > this.order.length) {
  137. throw new Error('Invalid dynamic constraint: ' + cstr);
  138. }
  139. let j = 0;
  140. for (let i = 0, key; (key = this.order[i]), order.length; i++, j++) {
  141. const value = order.shift();
  142. cstr[key] = value;
  143. }
  144. return new DynamicCstr(cstr, this.order.slice(0, j));
  145. }
  146. }
  147. export class DefaultComparator {
  148. constructor(reference, fallback = new DynamicProperties(reference.getProperties(), reference.getOrder())) {
  149. this.reference = reference;
  150. this.fallback = fallback;
  151. this.order = this.reference.getOrder();
  152. }
  153. getReference() {
  154. return this.reference;
  155. }
  156. setReference(cstr, props) {
  157. this.reference = cstr;
  158. this.fallback =
  159. props || new DynamicProperties(cstr.getProperties(), cstr.getOrder());
  160. this.order = this.reference.getOrder();
  161. }
  162. match(cstr) {
  163. const keys1 = cstr.getAxes();
  164. return (keys1.length === this.reference.getAxes().length &&
  165. keys1.every((key) => {
  166. const value = cstr.getValue(key);
  167. return (value === this.reference.getValue(key) ||
  168. this.fallback.getProperty(key).indexOf(value) !== -1);
  169. }));
  170. }
  171. compare(cstr1, cstr2) {
  172. let ignore = false;
  173. for (let i = 0, key; (key = this.order[i]); i++) {
  174. const value1 = cstr1.getValue(key);
  175. const value2 = cstr2.getValue(key);
  176. if (!ignore) {
  177. const ref = this.reference.getValue(key);
  178. if (ref === value1 && ref !== value2) {
  179. return -1;
  180. }
  181. if (ref === value2 && ref !== value1) {
  182. return 1;
  183. }
  184. if (ref === value1 && ref === value2) {
  185. continue;
  186. }
  187. if (ref !== value1 && ref !== value2) {
  188. ignore = true;
  189. }
  190. }
  191. const prop = this.fallback.getProperty(key);
  192. const index1 = prop.indexOf(value1);
  193. const index2 = prop.indexOf(value2);
  194. if (index1 < index2) {
  195. return -1;
  196. }
  197. if (index2 < index1) {
  198. return 1;
  199. }
  200. }
  201. return 0;
  202. }
  203. toString() {
  204. return this.reference.toString() + '\n' + this.fallback.toString();
  205. }
  206. }