CasperSecurity

Current Path : /var/www/hrms.uiet.co.in/node_modules/svgo/plugins/
Upload File :
Current File : /var/www/hrms.uiet.co.in/node_modules/svgo/plugins/cleanupIDs.js

'use strict';

/**
 * @typedef {import('../lib/types').XastElement} XastElement
 */

const { visitSkip } = require('../lib/xast.js');
const { referencesProps } = require('./_collections.js');

exports.type = 'visitor';
exports.name = 'cleanupIDs';
exports.active = true;
exports.description = 'removes unused IDs and minifies used';

const regReferencesUrl = /\burl\(("|')?#(.+?)\1\)/;
const regReferencesHref = /^#(.+?)$/;
const regReferencesBegin = /(\w+)\./;
const generateIDchars = [
  'a',
  'b',
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i',
  'j',
  'k',
  'l',
  'm',
  'n',
  'o',
  'p',
  'q',
  'r',
  's',
  't',
  'u',
  'v',
  'w',
  'x',
  'y',
  'z',
  'A',
  'B',
  'C',
  'D',
  'E',
  'F',
  'G',
  'H',
  'I',
  'J',
  'K',
  'L',
  'M',
  'N',
  'O',
  'P',
  'Q',
  'R',
  'S',
  'T',
  'U',
  'V',
  'W',
  'X',
  'Y',
  'Z',
];
const maxIDindex = generateIDchars.length - 1;

/**
 * Check if an ID starts with any one of a list of strings.
 *
 * @type {(string: string, prefixes: Array<string>) => boolean}
 */
const hasStringPrefix = (string, prefixes) => {
  for (const prefix of prefixes) {
    if (string.startsWith(prefix)) {
      return true;
    }
  }
  return false;
};

/**
 * Generate unique minimal ID.
 *
 * @type {(currentID: null | Array<number>) => Array<number>}
 */
const generateID = (currentID) => {
  if (currentID == null) {
    return [0];
  }
  currentID[currentID.length - 1] += 1;
  for (let i = currentID.length - 1; i > 0; i--) {
    if (currentID[i] > maxIDindex) {
      currentID[i] = 0;
      if (currentID[i - 1] !== undefined) {
        currentID[i - 1]++;
      }
    }
  }
  if (currentID[0] > maxIDindex) {
    currentID[0] = 0;
    currentID.unshift(0);
  }
  return currentID;
};

/**
 * Get string from generated ID array.
 *
 * @type {(arr: Array<number>, prefix: string) => string}
 */
const getIDstring = (arr, prefix) => {
  return prefix + arr.map((i) => generateIDchars[i]).join('');
};

/**
 * Remove unused and minify used IDs
 * (only if there are no any <style> or <script>).
 *
 * @author Kir Belevich
 *
 * @type {import('../lib/types').Plugin<{
 *   remove?: boolean,
 *   minify?: boolean,
 *   prefix?: string,
 *   preserve?: Array<string>,
 *   preservePrefixes?: Array<string>,
 *   force?: boolean,
 * }>}
 */
exports.fn = (_root, params) => {
  const {
    remove = true,
    minify = true,
    prefix = '',
    preserve = [],
    preservePrefixes = [],
    force = false,
  } = params;
  const preserveIDs = new Set(
    Array.isArray(preserve) ? preserve : preserve ? [preserve] : []
  );
  const preserveIDPrefixes = Array.isArray(preservePrefixes)
    ? preservePrefixes
    : preservePrefixes
    ? [preservePrefixes]
    : [];
  /**
   * @type {Map<string, XastElement>}
   */
  const nodeById = new Map();
  /**
   * @type {Map<string, Array<{element: XastElement, name: string, value: string }>>}
   */
  const referencesById = new Map();
  let deoptimized = false;

  return {
    element: {
      enter: (node) => {
        if (force == false) {
          // deoptimize if style or script elements are present
          if (
            (node.name === 'style' || node.name === 'script') &&
            node.children.length !== 0
          ) {
            deoptimized = true;
            return;
          }

          // avoid removing IDs if the whole SVG consists only of defs
          if (node.name === 'svg') {
            let hasDefsOnly = true;
            for (const child of node.children) {
              if (child.type !== 'element' || child.name !== 'defs') {
                hasDefsOnly = false;
                break;
              }
            }
            if (hasDefsOnly) {
              return visitSkip;
            }
          }
        }

        for (const [name, value] of Object.entries(node.attributes)) {
          if (name === 'id') {
            // collect all ids
            const id = value;
            if (nodeById.has(id)) {
              delete node.attributes.id; // remove repeated id
            } else {
              nodeById.set(id, node);
            }
          } else {
            // collect all references
            /**
             * @type {null | string}
             */
            let id = null;
            if (referencesProps.includes(name)) {
              const match = value.match(regReferencesUrl);
              if (match != null) {
                id = match[2]; // url() reference
              }
            }
            if (name === 'href' || name.endsWith(':href')) {
              const match = value.match(regReferencesHref);
              if (match != null) {
                id = match[1]; // href reference
              }
            }
            if (name === 'begin') {
              const match = value.match(regReferencesBegin);
              if (match != null) {
                id = match[1]; // href reference
              }
            }
            if (id != null) {
              let refs = referencesById.get(id);
              if (refs == null) {
                refs = [];
                referencesById.set(id, refs);
              }
              refs.push({ element: node, name, value });
            }
          }
        }
      },
    },

    root: {
      exit: () => {
        if (deoptimized) {
          return;
        }
        /**
         * @type {(id: string) => boolean}
         **/
        const isIdPreserved = (id) =>
          preserveIDs.has(id) || hasStringPrefix(id, preserveIDPrefixes);
        /**
         * @type {null | Array<number>}
         */
        let currentID = null;
        for (const [id, refs] of referencesById) {
          const node = nodeById.get(id);
          if (node != null) {
            // replace referenced IDs with the minified ones
            if (minify && isIdPreserved(id) === false) {
              /**
               * @type {null | string}
               */
              let currentIDString = null;
              do {
                currentID = generateID(currentID);
                currentIDString = getIDstring(currentID, prefix);
              } while (isIdPreserved(currentIDString));
              node.attributes.id = currentIDString;
              for (const { element, name, value } of refs) {
                if (value.includes('#')) {
                  // replace id in href and url()
                  element.attributes[name] = value.replace(
                    `#${id}`,
                    `#${currentIDString}`
                  );
                } else {
                  // replace id in begin attribute
                  element.attributes[name] = value.replace(
                    `${id}.`,
                    `${currentIDString}.`
                  );
                }
              }
            }
            // keep referenced node
            nodeById.delete(id);
          }
        }
        // remove non-referenced IDs attributes from elements
        if (remove) {
          for (const [id, node] of nodeById) {
            if (isIdPreserved(id) === false) {
              delete node.attributes.id;
            }
          }
        }
      },
    },
  };
};
Hacker Blog, Shell İndir, Sql İnjection, XSS Attacks, LFI Attacks, Social Hacking, Exploit Bot, Proxy Tools, Web Shell, PHP Shell, Alfa Shell İndir, Hacking Training Set, DDoS Script, Denial Of Service, Botnet, RFI Attacks, Encryption
Telegram @BIBIL_0DAY