text: import { warn } from '../log.js';
  import { createStringifyContext } from '../stringify/stringify.js';
  import { isScalar, isSeq, isAlias, isMap, isNode } from './Node.js';
  import { Scalar } from './Scalar.js';
  import { toJS } from './toJS.js';
  
  const MERGE_KEY = '<<';
  function addPairToJSMap(ctx, map, { key, value }) {
      if (ctx && ctx.doc.schema.merge && isMergeKey(key)) {
          if (isSeq(value))
              for (const it of value.items)
                  mergeToJSMap(ctx, map, it);
          else if (Array.isArray(value))
              for (const it of value)
                  mergeToJSMap(ctx, map, it);
          else
              mergeToJSMap(ctx, map, value);
      }
      else {
          const jsKey = toJS(key, '', ctx);
          if (map instanceof Map) {
              map.set(jsKey, toJS(value, jsKey, ctx));
          }
          else if (map instanceof Set) {
              map.add(jsKey);
          }
          else {
              const stringKey = stringifyKey(key, jsKey, ctx);
              const jsValue = toJS(value, stringKey, ctx);
              if (stringKey in map)
                  Object.defineProperty(map, stringKey, {
                      value: jsValue,
                      writable: true,
                      enumerable: true,
                      configurable: true
                  });
              else
                  map[stringKey] = jsValue;
          }
      }
      return map;
  }
  const isMergeKey = (key) => key === MERGE_KEY ||
      (isScalar(key) &&
          key.value === MERGE_KEY &&
          (!key.type || key.type === Scalar.PLAIN));
  // If the value associated with a merge key is a single mapping node, each of
  // its key/value pairs is inserted into the current mapping, unless the key
  // already exists in it. If the value associated with the merge key is a
  // sequence, then this sequence is expected to contain mapping nodes and each
  // of these nodes is merged in turn according to its order in the sequence.
  // Keys in mapping nodes earlier in the sequence override keys specified in
  // later mapping nodes. -- http://yaml.org/type/merge.html
  function mergeToJSMap(ctx, map, value) {
      const source = ctx && isAlias(value) ? value.resolve(ctx.doc) : null;
      if (!isMap(source))
          throw new Error('Merge sources must be map aliases');
      const srcMap = source.toJSON(null, ctx, Map);
      for (const [key, value] of srcMap) {
          if (map instanceof Map) {
              if (!map.has(key))
                  map.set(key, value);
          }
          else if (map instanceof Set) {
              map.add(key);
          }
          else if (!Object.prototype.hasOwnProperty.call(map, key)) {
              Object.defineProperty(map, key, {
                  value,
                  writable: true,
                  enumerable: true,
                  configurable: true
              });
          }
      }
      return map;
  }
  function stringifyKey(key, jsKey, ctx) {
      if (jsKey === null)
          return '';
      if (typeof jsKey !== 'object')
          return String(jsKey);
      if (isNode(key) && ctx && ctx.doc) {
          const strCtx = createStringifyContext(ctx.doc, {});
          strCtx.anchors = new Set();
          for (const node of ctx.anchors.keys())
              strCtx.anchors.add(node.anchor);
          strCtx.inFlow = true;
          strCtx.inStringifyKey = true;
          const strKey = key.toString(strCtx);
          if (!ctx.mapKeyWarned) {
              let jsonStr = JSON.stringify(strKey);
              if (jsonStr.length > 40)
                  jsonStr = jsonStr.substring(0, 36) + '..."';
              warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`);
              ctx.mapKeyWarned = true;
          }
          return strKey;
      }
      return JSON.stringify(jsKey);
  }
  
  export { addPairToJSMap };
  