15815213711
2024-08-26 67b8b6731811983447e053d4396b3708c14dfe3c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import * as v6 from './constants';
import { sprintf } from 'sprintf-js';
 
export function groupPossibilities(possibilities: string[]): string {
  return sprintf('(%s)', possibilities.join('|'));
}
 
export function padGroup(group: string): string {
  if (group.length < 4) {
    return sprintf('0{0,%d}%s', 4 - group.length, group);
  }
 
  return group;
}
 
export const ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]';
 
export function simpleRegularExpression(groups: string[]) {
  const zeroIndexes: number[] = [];
 
  groups.forEach((group, i) => {
    const groupInteger = parseInt(group, 16);
 
    if (groupInteger === 0) {
      zeroIndexes.push(i);
    }
  });
 
  // You can technically elide a single 0, this creates the regular expressions
  // to match that eventuality
  const possibilities = zeroIndexes.map((zeroIndex) =>
    groups
      .map((group, i) => {
        if (i === zeroIndex) {
          const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : '';
 
          return groupPossibilities([padGroup(group), elision]);
        }
 
        return padGroup(group);
      })
      .join(':')
  );
 
  // The simplest case
  possibilities.push(groups.map(padGroup).join(':'));
 
  return groupPossibilities(possibilities);
}
 
export function possibleElisions(
  elidedGroups: number,
  moreLeft?: boolean,
  moreRight?: boolean
): string {
  const left = moreLeft ? '' : ':';
  const right = moreRight ? '' : ':';
 
  const possibilities = [];
 
  // 1. elision of everything (::)
  if (!moreLeft && !moreRight) {
    possibilities.push('::');
  }
 
  // 2. complete elision of the middle
  if (moreLeft && moreRight) {
    possibilities.push('');
  }
 
  if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) {
    // 3. complete elision of one side
    possibilities.push(':');
  }
 
  // 4. elision from the left side
  possibilities.push(sprintf('%s(:0{1,4}){1,%d}', left, elidedGroups - 1));
 
  // 5. elision from the right side
  possibilities.push(sprintf('(0{1,4}:){1,%d}%s', elidedGroups - 1, right));
 
  // 6. no elision
  possibilities.push(sprintf('(0{1,4}:){%d}0{1,4}', elidedGroups - 1));
 
  // 7. elision (including sloppy elision) from the middle
  for (let groups = 1; groups < elidedGroups - 1; groups++) {
    for (let position = 1; position < elidedGroups - groups; position++) {
      possibilities.push(
        sprintf(
          '(0{1,4}:){%d}:(0{1,4}:){%d}0{1,4}',
          position,
          elidedGroups - position - groups - 1
        )
      );
    }
  }
 
  return groupPossibilities(possibilities);
}