@stats-forge/github-stats-forge-core 0.1.0 → 0.2.0

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.
Files changed (142) hide show
  1. package/build/api/contributed-to.d.ts +23 -0
  2. package/build/api/contributed-to.d.ts.map +1 -0
  3. package/build/api/contributed-to.js +43 -0
  4. package/build/api/gist.d.ts +8 -15
  5. package/build/api/gist.d.ts.map +1 -1
  6. package/build/api/gist.js +14 -29
  7. package/build/api/handler.d.ts +16 -0
  8. package/build/api/handler.d.ts.map +1 -0
  9. package/build/api/handler.js +29 -0
  10. package/build/api/index.d.ts +1 -0
  11. package/build/api/index.d.ts.map +1 -1
  12. package/build/api/index.js +1 -0
  13. package/build/api/params.d.ts +11 -5
  14. package/build/api/params.d.ts.map +1 -1
  15. package/build/api/params.js +26 -6
  16. package/build/api/pin.d.ts +11 -15
  17. package/build/api/pin.d.ts.map +1 -1
  18. package/build/api/pin.js +34 -46
  19. package/build/api/stats.d.ts +15 -22
  20. package/build/api/stats.d.ts.map +1 -1
  21. package/build/api/stats.js +59 -72
  22. package/build/api/top-langs.d.ts +11 -22
  23. package/build/api/top-langs.d.ts.map +1 -1
  24. package/build/api/top-langs.js +34 -51
  25. package/build/api/wakatime.d.ts +10 -24
  26. package/build/api/wakatime.d.ts.map +1 -1
  27. package/build/api/wakatime.js +27 -47
  28. package/build/cards/contributed-to.d.ts +19 -0
  29. package/build/cards/contributed-to.d.ts.map +1 -0
  30. package/build/cards/contributed-to.js +242 -0
  31. package/build/cards/gist.d.ts +1 -0
  32. package/build/cards/gist.d.ts.map +1 -1
  33. package/build/cards/gist.js +13 -9
  34. package/build/cards/repo.d.ts +12 -1
  35. package/build/cards/repo.d.ts.map +1 -1
  36. package/build/cards/repo.js +40 -18
  37. package/build/cards/stats.d.ts +15 -3
  38. package/build/cards/stats.d.ts.map +1 -1
  39. package/build/cards/stats.js +91 -76
  40. package/build/cards/top-languages.d.ts +13 -2
  41. package/build/cards/top-languages.d.ts.map +1 -1
  42. package/build/cards/top-languages.js +26 -9
  43. package/build/cards/wakatime.d.ts +13 -2
  44. package/build/cards/wakatime.d.ts.map +1 -1
  45. package/build/cards/wakatime.js +22 -9
  46. package/build/common/Card.d.ts +9 -0
  47. package/build/common/Card.d.ts.map +1 -1
  48. package/build/common/Card.js +44 -9
  49. package/build/common/I18n.d.ts +1 -1
  50. package/build/common/I18n.d.ts.map +1 -1
  51. package/build/common/I18n.js +4 -2
  52. package/build/common/brand.d.ts +76 -0
  53. package/build/common/brand.d.ts.map +1 -0
  54. package/build/common/brand.js +73 -0
  55. package/build/common/constants.d.ts +3 -1
  56. package/build/common/constants.d.ts.map +1 -1
  57. package/build/common/constants.js +3 -1
  58. package/build/common/date.d.ts +50 -3
  59. package/build/common/date.d.ts.map +1 -1
  60. package/build/common/date.js +104 -2
  61. package/build/common/icons.d.ts +4 -2
  62. package/build/common/icons.d.ts.map +1 -1
  63. package/build/common/icons.js +10 -5
  64. package/build/common/ops.d.ts +8 -3
  65. package/build/common/ops.d.ts.map +1 -1
  66. package/build/common/ops.js +8 -14
  67. package/build/common/render.d.ts +7 -1
  68. package/build/common/render.d.ts.map +1 -1
  69. package/build/common/render.js +60 -58
  70. package/build/fetchers/contributed-to.d.ts +62 -0
  71. package/build/fetchers/contributed-to.d.ts.map +1 -0
  72. package/build/fetchers/contributed-to.js +184 -0
  73. package/build/fetchers/graphql-error.d.ts +13 -0
  74. package/build/fetchers/graphql-error.d.ts.map +1 -0
  75. package/build/fetchers/graphql-error.js +29 -0
  76. package/build/fetchers/index.d.ts +2 -1
  77. package/build/fetchers/index.d.ts.map +1 -1
  78. package/build/fetchers/index.js +1 -0
  79. package/build/fetchers/stats.d.ts +14 -8
  80. package/build/fetchers/stats.d.ts.map +1 -1
  81. package/build/fetchers/stats.js +72 -195
  82. package/build/fetchers/top-languages.d.ts.map +1 -1
  83. package/build/fetchers/top-languages.js +3 -18
  84. package/build/fetchers/types.d.ts +24 -0
  85. package/build/fetchers/types.d.ts.map +1 -1
  86. package/build/graphql/contributionsCollection.d.ts +9 -0
  87. package/build/graphql/contributionsCollection.d.ts.map +1 -0
  88. package/build/graphql/contributionsCollection.js +12 -0
  89. package/build/graphql/contributionsDocument.d.ts +5 -5
  90. package/build/graphql/contributionsDocument.d.ts.map +1 -1
  91. package/build/graphql/contributionsDocument.js +8 -15
  92. package/build/graphql/generated/contributed-to.d.ts +22 -0
  93. package/build/graphql/generated/contributed-to.d.ts.map +1 -0
  94. package/build/graphql/generated/contributed-to.js +11 -0
  95. package/build/graphql/generated/stats.d.ts +13 -1
  96. package/build/graphql/generated/stats.d.ts.map +1 -1
  97. package/build/graphql/generated/stats.js +2 -2
  98. package/build/graphql/graphqlDocument.d.ts +1 -1
  99. package/build/graphql/reposContributedToDocument.d.ts.map +1 -1
  100. package/build/graphql/reposContributedToDocument.js +11 -5
  101. package/build/translations.d.ts +64 -1
  102. package/build/translations.d.ts.map +1 -1
  103. package/build/translations.js +65 -1
  104. package/package.json +1 -1
  105. package/src/api/contributed-to.ts +84 -0
  106. package/src/api/gist.ts +20 -37
  107. package/src/api/handler.ts +42 -0
  108. package/src/api/index.ts +1 -0
  109. package/src/api/params.ts +48 -9
  110. package/src/api/pin.ts +33 -45
  111. package/src/api/stats.ts +78 -89
  112. package/src/api/top-langs.ts +34 -56
  113. package/src/api/wakatime.ts +33 -54
  114. package/src/cards/contributed-to.ts +373 -0
  115. package/src/cards/gist.ts +17 -8
  116. package/src/cards/repo.ts +44 -20
  117. package/src/cards/stats.ts +119 -90
  118. package/src/cards/top-languages.ts +27 -18
  119. package/src/cards/wakatime.ts +23 -13
  120. package/src/common/Card.ts +56 -11
  121. package/src/common/I18n.ts +4 -2
  122. package/src/common/brand.ts +109 -0
  123. package/src/common/constants.ts +4 -1
  124. package/src/common/date.ts +135 -3
  125. package/src/common/icons.ts +10 -5
  126. package/src/common/ops.ts +10 -19
  127. package/src/common/render.ts +65 -62
  128. package/src/fetchers/contributed-to.ts +271 -0
  129. package/src/fetchers/graphql-error.ts +36 -0
  130. package/src/fetchers/index.ts +3 -0
  131. package/src/fetchers/stats.ts +123 -274
  132. package/src/fetchers/top-languages.ts +5 -19
  133. package/src/fetchers/types.ts +26 -0
  134. package/src/graphql/contributionsCollection.ts +18 -0
  135. package/src/graphql/contributionsDocument.ts +11 -18
  136. package/src/graphql/generated/contributed-to.ts +25 -0
  137. package/src/graphql/generated/stats.ts +19 -6
  138. package/src/graphql/graphqlDocument.ts +1 -1
  139. package/src/graphql/queries/contributed-to.graphql +8 -0
  140. package/src/graphql/queries/stats.graphql +14 -2
  141. package/src/graphql/reposContributedToDocument.ts +11 -9
  142. package/src/translations.ts +77 -0
@@ -1,4 +1,5 @@
1
1
  import { atRule, cssComment, el, renderMarkup, rule, style } from '../markup/index.js';
2
+ import { ACCENT, firefoxFontSize, font, TITLE_BAND, TITLE_FIREFOX_SIZE } from './brand.js';
2
3
  import { getCardColors, isPrefixedHexColor, isValidGradient } from './color.js';
3
4
  import { flexLayout } from './render.js';
4
5
  /** Stops every animation, whether the reader asked or the card did. */
@@ -59,7 +60,7 @@ class Card {
59
60
  this.css = [];
60
61
  this.darkCss = [];
61
62
  this.paddingX = 25;
62
- this.paddingY = 35;
63
+ this.paddingY = 30;
63
64
  this.titlePrefixIcon = titlePrefixIcon;
64
65
  this.animations = true;
65
66
  this.a11yTitle = '';
@@ -107,7 +108,7 @@ class Card {
107
108
  items: [
108
109
  this.titlePrefixIcon &&
109
110
  el('svg', {
110
- class: 'icon',
111
+ class: 'title-icon',
111
112
  x: 0,
112
113
  y: -13,
113
114
  viewBox: '0 0 16 16',
@@ -118,8 +119,36 @@ class Card {
118
119
  el('text', { x: 0, y: 0, class: 'header', 'data-testid': 'header' }, this.title),
119
120
  ],
120
121
  gap: 25,
122
+ }), el('rect', {
123
+ 'data-testid': 'title-accent',
124
+ class: 'title-accent',
125
+ x: 0,
126
+ y: ACCENT.y,
127
+ width: ACCENT.width,
128
+ height: ACCENT.height,
129
+ rx: ACCENT.height / 2,
121
130
  }));
122
131
  }
132
+ /** Where the body starts, and so where the title band ends. */
133
+ get bodyOffset() {
134
+ return this.hideTitle ? this.paddingX : this.paddingY + 25;
135
+ }
136
+ /**
137
+ * The band behind the title. Its top corners follow the card's own and its bottom
138
+ * ones stay square, so it meets the body as an edge rather than a floating box.
139
+ *
140
+ * @returns The rendered title band.
141
+ */
142
+ renderTitleBand() {
143
+ const height = this.bodyOffset - TITLE_BAND.gap;
144
+ const innerWidth = this.width - 1;
145
+ const r = Math.min(this.border_radius, height, innerWidth / 2);
146
+ return el('path', {
147
+ 'data-testid': 'title-band',
148
+ class: 'title-band',
149
+ d: `M0.5 ${0.5 + r}a${r} ${r} 0 0 1 ${r} ${-r}h${innerWidth - 2 * r}a${r} ${r} 0 0 1 ${r} ${r}v${height - r - 0.5}h${-innerWidth}z`,
150
+ });
151
+ }
123
152
  /** @returns The card's gradient definitions, or nothing when no color is a gradient. */
124
153
  renderGradient() {
125
154
  if (typeof this.colors.light.bgColor === 'object' &&
@@ -151,7 +180,7 @@ class Card {
151
180
  const bgFill = typeof this.colors.dark.bgColor === 'object'
152
181
  ? 'url(#gradient-dark)'
153
182
  : this.colors.dark.bgColor;
154
- return atRule('@media (prefers-color-scheme: dark)', rule('.header', { fill: this.colors.dark.titleColor }), rule('.card-bg', { fill: bgFill, stroke: this.colors.dark.borderColor }), this.darkCss);
183
+ return atRule('@media (prefers-color-scheme: dark)', rule('.header', { fill: this.colors.dark.titleColor }), rule('.title-icon', { fill: this.colors.dark.iconColor }), rule('.title-accent', { fill: this.colors.dark.iconColor }), rule('.title-band', { fill: this.colors.dark.titleColor }), rule('.card-bg', { fill: bgFill, stroke: this.colors.dark.borderColor }), this.darkCss);
155
184
  }
156
185
  /** @returns The rendered card. */
157
186
  render(body) {
@@ -176,12 +205,18 @@ class Card {
176
205
  fill: 'none',
177
206
  xmlns: 'http://www.w3.org/2000/svg',
178
207
  role: 'img',
179
- 'aria-labelledby': 'titleId descId',
180
- }, el('title', { id: 'titleId' }, this.a11yTitle), el('desc', { id: 'descId' }, this.a11yDesc), style(rule('.header', {
181
- font: "600 18px 'Segoe UI', Ubuntu, Sans-Serif",
208
+ 'aria-labelledby': 'title-id desc-id',
209
+ }, el('title', { id: 'title-id' }, this.a11yTitle), el('desc', { id: 'desc-id' }, this.a11yDesc), style(rule('.header', {
210
+ font: font('semibold', 'title'),
182
211
  fill: this.colors.light.titleColor,
183
212
  animation: 'fadeInAnimation 0.8s ease-in-out forwards',
184
- }), atRule('@supports(-moz-appearance: auto)', cssComment('Selector detects Firefox'), rule('.header', { 'font-size': '15.5px' })), this.css, this.renderDarkMediaBlock(), getAnimations(), !this.animations && rule('*', NO_MOTION)), this.renderGradient(), el('rect', {
213
+ }), cssComment('The icon reads against the title rather than with it, so it keeps its own color.'), rule('.title-icon', {
214
+ fill: this.colors.light.iconColor,
215
+ animation: 'fadeInAnimation 0.8s ease-in-out forwards',
216
+ }), rule('.title-accent', {
217
+ fill: this.colors.light.iconColor,
218
+ animation: 'fadeInAnimation 0.8s ease-in-out forwards',
219
+ }), rule('.title-band', { fill: this.colors.light.titleColor, opacity: TITLE_BAND.opacity }), firefoxFontSize(['.header'], TITLE_FIREFOX_SIZE), this.css, this.renderDarkMediaBlock(), getAnimations(), !this.animations && rule('*', NO_MOTION)), this.renderGradient(), el('rect', {
185
220
  'data-testid': 'card-bg',
186
221
  class: 'card-bg',
187
222
  x: 0.5,
@@ -194,9 +229,9 @@ class Card {
194
229
  ? 'url(#gradient)'
195
230
  : this.colors.light.bgColor,
196
231
  'stroke-opacity': this.hideBorder ? 0 : 1,
197
- }), !this.hideTitle && this.renderTitle(), el('g', {
232
+ }), !this.hideTitle && this.renderTitleBand(), !this.hideTitle && this.renderTitle(), el('g', {
198
233
  'data-testid': 'main-card-body',
199
- transform: `translate(0, ${this.hideTitle ? this.paddingX : this.paddingY + 20})`,
234
+ transform: `translate(0, ${this.bodyOffset})`,
200
235
  }, body)));
201
236
  }
202
237
  }
@@ -11,7 +11,7 @@ declare class I18n<Translations extends TranslationsMap = TranslationsMap> {
11
11
  translations: Translations;
12
12
  });
13
13
  /**
14
- * Get translation.
14
+ * Get translation, falling back to the English string when the locale has no entry for the key.
15
15
  *
16
16
  * @returns Translated string.
17
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"I18n.d.ts","sourceRoot":"","sources":["../../src/common/I18n.ts"],"names":[],"mappings":"AAEA,uDAAuD;AACvD,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D;;GAEG;AACH,cAAM,IAAI,CAAC,YAAY,SAAS,eAAe,GAAG,eAAe;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAE3B,YAAY,EACV,MAAM,EACN,YAAY,GACb,EAAE;QAED,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,YAAY,EAAE,YAAY,CAAC;KAC5B,EAGA;IAED;;;;OAIG;IACH,CAAC,CAAC,GAAG,EAAE,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAe1C;CACF;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"I18n.d.ts","sourceRoot":"","sources":["../../src/common/I18n.ts"],"names":[],"mappings":"AAEA,uDAAuD;AACvD,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D;;GAEG;AACH,cAAM,IAAI,CAAC,YAAY,SAAS,eAAe,GAAG,eAAe;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAE3B,YAAY,EACV,MAAM,EACN,YAAY,GACb,EAAE;QAED,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,YAAY,EAAE,YAAY,CAAC;KAC5B,EAGA;IAED;;;;OAIG;IACH,CAAC,CAAC,GAAG,EAAE,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAiB1C;CACF;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
@@ -10,7 +10,7 @@ class I18n {
10
10
  this.translations = translations;
11
11
  }
12
12
  /**
13
- * Get translation.
13
+ * Get translation, falling back to the English string when the locale has no entry for the key.
14
14
  *
15
15
  * @returns Translated string.
16
16
  */
@@ -22,7 +22,9 @@ class I18n {
22
22
  if (!translation) {
23
23
  throw new Error(`${str} Translation string not found`);
24
24
  }
25
- const localized = translation[this.locale];
25
+ // A key is written in `en` first and translated afterwards, so a locale the key has
26
+ // not reached yet reads the English string rather than failing the whole card.
27
+ const localized = translation[this.locale] ?? translation[FALLBACK_LOCALE];
26
28
  if (!localized) {
27
29
  throw new Error(`'${str}' translation not found for locale '${this.locale}'`);
28
30
  }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The visual vocabulary every card draws with: one font stack, one type scale,
3
+ * one set of widths and the accent rule that marks a card as this tool's.
4
+ * A card composes from here; it never writes a `font` shorthand or a size of its own.
5
+ */
6
+ import type { CssChild } from '../markup/index.ts';
7
+ /** The type scale, in px. */
8
+ declare const FONT_SIZE: {
9
+ readonly display: 22;
10
+ readonly title: 18;
11
+ readonly lead: 16;
12
+ readonly body: 14;
13
+ readonly meta: 13;
14
+ readonly small: 12;
15
+ readonly micro: 11;
16
+ };
17
+ /**
18
+ * The one size off the scale. Firefox is given 15.5px rather than the scale's next step down,
19
+ * because that half pixel is inherited tuning for long titles and nothing here can test the
20
+ * wrapping it protects; it lives with the scale so `brand.ts` still owns every size a card draws.
21
+ */
22
+ declare const TITLE_FIREFOX_SIZE = 15.5;
23
+ /** `regular` labels, `semibold` the values they label, `bold` the rank glyph alone. */
24
+ declare const FONT_WEIGHT: {
25
+ readonly regular: 400;
26
+ readonly semibold: 600;
27
+ readonly bold: 700;
28
+ };
29
+ type FontSize = keyof typeof FONT_SIZE;
30
+ type FontWeight = keyof typeof FONT_WEIGHT;
31
+ /** @returns The `font` shorthand for one step of the scale. */
32
+ declare const font: (weight: FontWeight, size: FontSize) => string;
33
+ /**
34
+ * Firefox lays Segoe UI out wider than the other engines, so text that fits
35
+ * elsewhere overflows there; each affected selector steps down a size.
36
+ *
37
+ * @returns The `@supports` block that detects Firefox and resizes those selectors.
38
+ */
39
+ declare const firefoxFontSize: (selectors: Array<string>, size: FontSize | number) => CssChild;
40
+ /**
41
+ * The widths a card may default to. A card picks the step nearest what its layout
42
+ * needs, so cards stacked in a README share an edge instead of forming a ragged one.
43
+ */
44
+ declare const CARD_WIDTH: {
45
+ readonly compact: 300;
46
+ readonly standard: 400;
47
+ readonly wide: 500;
48
+ };
49
+ /** The tinted band behind every card title: the mark a card is recognized by. */
50
+ declare const TITLE_BAND: {
51
+ /** Enough to read as a band on every theme, little enough to leave the title legible. */
52
+ readonly opacity: 0.08;
53
+ /** Clear air the band leaves between its foot and the first row of the body. */
54
+ readonly gap: 9;
55
+ };
56
+ /** The rule under the title icon, sitting inside the band. */
57
+ declare const ACCENT: {
58
+ readonly width: 32;
59
+ readonly height: 2;
60
+ /** Below the title's descenders, clear of the band's foot. */
61
+ readonly y: 8;
62
+ };
63
+ /**
64
+ * The title icon each card wears. They are distinct on purpose: with the band
65
+ * and the shared type, the icon is what tells one card from another at a glance.
66
+ */
67
+ declare const CARD_ICON: {
68
+ contributedTo: import("../markup/element.ts").MarkupElement;
69
+ gist: import("../markup/element.ts").MarkupElement;
70
+ repo: import("../markup/element.ts").MarkupElement;
71
+ stats: import("../markup/element.ts").MarkupElement;
72
+ topLanguages: import("../markup/element.ts").MarkupElement;
73
+ wakatime: import("../markup/element.ts").MarkupElement;
74
+ };
75
+ export { ACCENT, CARD_ICON, CARD_WIDTH, FONT_SIZE, FONT_WEIGHT, firefoxFontSize, font, TITLE_BAND, TITLE_FIREFOX_SIZE, };
76
+ //# sourceMappingURL=brand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand.d.ts","sourceRoot":"","sources":["../../src/common/brand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAS,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAO1D,6BAA6B;AAC7B,QAAA,MAAM,SAAS;aACb,OAAO,EAAE,EAAE;aACX,KAAK,EAAE,EAAE;aACT,IAAI,EAAE,EAAE;aACR,IAAI,EAAE,EAAE;aACR,IAAI,EAAE,EAAE;aACR,KAAK,EAAE,EAAE;aACT,KAAK,EAAE,EAAE;CACD,CAAC;AAEX;;;;GAIG;AACH,QAAA,MAAM,kBAAkB,OAAO,CAAC;AAEhC,uFAAuF;AACvF,QAAA,MAAM,WAAW;aACf,OAAO,EAAE,GAAG;aACZ,QAAQ,EAAE,GAAG;aACb,IAAI,EAAE,GAAG;CACD,CAAC;AAEX,KAAK,QAAQ,GAAG,MAAM,OAAO,SAAS,CAAC;AACvC,KAAK,UAAU,GAAG,MAAM,OAAO,WAAW,CAAC;AAE3C,+DAA+D;AAC/D,QAAA,MAAM,IAAI,WAAY,UAAU,QAAQ,QAAQ,KAAG,MAC0B,CAAC;AAE9E;;;;;GAKG;AACH,QAAA,MAAM,eAAe,cAAe,KAAK,CAAC,MAAM,CAAC,QAAQ,QAAQ,GAAG,MAAM,KAAG,QAO5E,CAAC;AAEF;;;GAGG;AACH,QAAA,MAAM,UAAU;aACd,OAAO,EAAE,GAAG;aACZ,QAAQ,EAAE,GAAG;aACb,IAAI,EAAE,GAAG;CACD,CAAC;AAEX,iFAAiF;AACjF,QAAA,MAAM,UAAU;IACd,yFAAyF;aACzF,OAAO,EAAE,IAAI;IACb,gFAAgF;aAChF,GAAG,EAAE,CAAC;CACE,CAAC;AAEX,8DAA8D;AAC9D,QAAA,MAAM,MAAM;aACV,KAAK,EAAE,EAAE;aACT,MAAM,EAAE,CAAC;IACT,8DAA8D;aAC9D,CAAC,EAAE,CAAC;CACI,CAAC;AAEX;;;GAGG;AACH,QAAA,MAAM,SAAS;;;;;;;CAOkB,CAAC;AAElC,OAAO,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,IAAI,EACJ,UAAU,EACV,kBAAkB,GACnB,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { atRule, cssComment, rule } from '../markup/index.js';
2
+ import { icons } from './icons.js';
3
+ const FONT_STACK = `'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif`;
4
+ /** The type scale, in px. */
5
+ const FONT_SIZE = {
6
+ display: 22,
7
+ title: 18,
8
+ lead: 16,
9
+ body: 14,
10
+ meta: 13,
11
+ small: 12,
12
+ micro: 11,
13
+ };
14
+ /**
15
+ * The one size off the scale. Firefox is given 15.5px rather than the scale's next step down,
16
+ * because that half pixel is inherited tuning for long titles and nothing here can test the
17
+ * wrapping it protects; it lives with the scale so `brand.ts` still owns every size a card draws.
18
+ */
19
+ const TITLE_FIREFOX_SIZE = 15.5;
20
+ /** `regular` labels, `semibold` the values they label, `bold` the rank glyph alone. */
21
+ const FONT_WEIGHT = {
22
+ regular: 400,
23
+ semibold: 600,
24
+ bold: 700,
25
+ };
26
+ /** @returns The `font` shorthand for one step of the scale. */
27
+ const font = (weight, size) => `${String(FONT_WEIGHT[weight])} ${String(FONT_SIZE[size])}px ${FONT_STACK}`;
28
+ /**
29
+ * Firefox lays Segoe UI out wider than the other engines, so text that fits
30
+ * elsewhere overflows there; each affected selector steps down a size.
31
+ *
32
+ * @returns The `@supports` block that detects Firefox and resizes those selectors.
33
+ */
34
+ const firefoxFontSize = (selectors, size) => {
35
+ const px = typeof size === 'number' ? size : FONT_SIZE[size];
36
+ return atRule('@supports(-moz-appearance: auto)', cssComment('Selector detects Firefox'), selectors.map((selector) => rule(selector, { 'font-size': `${String(px)}px` })));
37
+ };
38
+ /**
39
+ * The widths a card may default to. A card picks the step nearest what its layout
40
+ * needs, so cards stacked in a README share an edge instead of forming a ragged one.
41
+ */
42
+ const CARD_WIDTH = {
43
+ compact: 300,
44
+ standard: 400,
45
+ wide: 500,
46
+ };
47
+ /** The tinted band behind every card title: the mark a card is recognized by. */
48
+ const TITLE_BAND = {
49
+ /** Enough to read as a band on every theme, little enough to leave the title legible. */
50
+ opacity: 0.08,
51
+ /** Clear air the band leaves between its foot and the first row of the body. */
52
+ gap: 9,
53
+ };
54
+ /** The rule under the title icon, sitting inside the band. */
55
+ const ACCENT = {
56
+ width: 32,
57
+ height: 2,
58
+ /** Below the title's descenders, clear of the band's foot. */
59
+ y: 8,
60
+ };
61
+ /**
62
+ * The title icon each card wears. They are distinct on purpose: with the band
63
+ * and the shared type, the icon is what tells one card from another at a glance.
64
+ */
65
+ const CARD_ICON = {
66
+ contributedTo: icons.prs_merged,
67
+ gist: icons.gist,
68
+ repo: icons.repo,
69
+ stats: icons.pulse,
70
+ topLanguages: icons.code,
71
+ wakatime: icons.clock,
72
+ };
73
+ export { ACCENT, CARD_ICON, CARD_WIDTH, FONT_SIZE, FONT_WEIGHT, firefoxFontSize, font, TITLE_BAND, TITLE_FIREFOX_SIZE, };
@@ -1,9 +1,11 @@
1
1
  import type { RepositoryAffiliation } from '../graphql/generated/common.ts';
2
+ /** The year GitHub launched, and so the earliest one a card can be asked to count from. */
3
+ declare const GITHUB_EPOCH_YEAR = 2008;
2
4
  /** A GitHub login: alphanumerics and single inner hyphens, 39 characters at most. */
3
5
  declare const GITHUB_USERNAME_PATTERN: RegExp;
4
6
  /**
5
7
  * Valid owner affiliations for GitHub API queries.
6
8
  */
7
9
  declare const OWNER_AFFILIATIONS: Array<RepositoryAffiliation>;
8
- export { GITHUB_USERNAME_PATTERN, OWNER_AFFILIATIONS };
10
+ export { GITHUB_EPOCH_YEAR, GITHUB_USERNAME_PATTERN, OWNER_AFFILIATIONS };
9
11
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,qFAAqF;AACrF,QAAA,MAAM,uBAAuB,QAA6C,CAAC;AAE3E;;GAEG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,qBAAqB,CAIpD,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,2FAA2F;AAC3F,QAAA,MAAM,iBAAiB,OAAO,CAAC;AAE/B,qFAAqF;AACrF,QAAA,MAAM,uBAAuB,QAA6C,CAAC;AAE3E;;GAEG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,qBAAqB,CAIpD,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,3 +1,5 @@
1
+ /** The year GitHub launched, and so the earliest one a card can be asked to count from. */
2
+ const GITHUB_EPOCH_YEAR = 2008;
1
3
  /** A GitHub login: alphanumerics and single inner hyphens, 39 characters at most. */
2
4
  const GITHUB_USERNAME_PATTERN = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i;
3
5
  /**
@@ -8,4 +10,4 @@ const OWNER_AFFILIATIONS = [
8
10
  'COLLABORATOR',
9
11
  'ORGANIZATION_MEMBER',
10
12
  ];
11
- export { GITHUB_USERNAME_PATTERN, OWNER_AFFILIATIONS };
13
+ export { GITHUB_EPOCH_YEAR, GITHUB_USERNAME_PATTERN, OWNER_AFFILIATIONS };
@@ -1,4 +1,5 @@
1
- /** A span between two dates, as GitHub's range arguments take it. */
1
+ /** @file A range reaches GitHub one calendar year at a time; `contributionsCollection` refuses a longer one. */
2
+ /** A range between two dates, as GitHub's range arguments take it. */
2
3
  interface GitHubDateRange {
3
4
  /** Start of the range, inclusive. */
4
5
  from: Date;
@@ -13,7 +14,7 @@ interface GitHubDateRange {
13
14
  */
14
15
  declare const toGitHubDateTime: (date: Date) => string;
15
16
  /**
16
- * The full UTC span of a calendar year, both ends inclusive.
17
+ * The full UTC range of a calendar year, both ends inclusive.
17
18
  *
18
19
  * The end matters to callers that would otherwise leave a range open:
19
20
  * GitHub's `contributionsCollection` defaults `to` to one year after `from`,
@@ -22,6 +23,52 @@ declare const toGitHubDateTime: (date: Date) => string;
22
23
  * @returns The range covering it.
23
24
  */
24
25
  declare const getGitHubYearRange: (year: number) => GitHubDateRange;
25
- export { getGitHubYearRange, toGitHubDateTime };
26
+ /**
27
+ * The widest range a card can be asked for: GitHub's first year through the end of this one.
28
+ * The far end is the end of the year, not today, because a bare `to=2026` widens to its 31st of December.
29
+ *
30
+ * @returns The range, in UTC.
31
+ */
32
+ declare const getWidestRange: () => GitHubDateRange;
33
+ /**
34
+ * The range a card counts within, from the ends the query named.
35
+ *
36
+ * @returns The range, each open end filled from {@link getWidestRange}.
37
+ */
38
+ declare const toRange: (from: Date | undefined, to: Date | undefined) => GitHubDateRange;
39
+ /**
40
+ * Read one end of a range, written as `2024`, `2024-03` or `2024-03-15`.
41
+ * A partial date covers the whole of what it names, so `2024` starts on the 1st of January
42
+ * and ends on the 31st of December.
43
+ *
44
+ * @returns The instant, or `undefined` when the text does not name a date that exists.
45
+ */
46
+ declare const parseRangeDate: (value: string, end: 'from' | 'to') => Date | undefined;
47
+ /**
48
+ * Split a range into one per calendar year, each clipped to it.
49
+ *
50
+ * @returns Them, oldest first; empty when the range is inverted.
51
+ */
52
+ declare const toYearRanges: ({ from, to }: GitHubDateRange) => Array<GitHubDateRange>;
53
+ /**
54
+ * Whole years as a card writes them.
55
+ *
56
+ * @returns e.g. `2024` or `2020–2024`.
57
+ */
58
+ declare const formatYears: (first: number, last: number) => string;
59
+ /**
60
+ * A range as a card writes it, at the coarsest granularity that stays true.
61
+ *
62
+ * @returns e.g. `2024`, `2020–2024` or `2024-03-15 – 2024-06-30`.
63
+ */
64
+ declare const formatRange: ({ from, to }: GitHubDateRange) => string;
65
+ /**
66
+ * The ranges a walk asks GitHub for: one per calendar year the account contributed in.
67
+ * Ordered here, which is what makes a walk's ties chronological.
68
+ *
69
+ * @returns Them, oldest first.
70
+ */
71
+ declare const toContributionRanges: (contributionYears: ReadonlyArray<number>, range: GitHubDateRange) => Array<GitHubDateRange>;
72
+ export { formatRange, formatYears, getWidestRange, getGitHubYearRange, parseRangeDate, toContributionRanges, toGitHubDateTime, toRange, toYearRanges, };
26
73
  export type { GitHubDateRange };
27
74
  //# sourceMappingURL=date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/common/date.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,UAAU,eAAe;IACvB,qCAAqC;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,mCAAmC;IACnC,EAAE,EAAE,IAAI,CAAC;CACV;AAED;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB,SAAU,IAAI,KAAG,MAA+C,CAAC;AAEvF;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB,SAAU,MAAM,KAAG,eAGzC,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/common/date.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAIhH,sEAAsE;AACtE,UAAU,eAAe;IACvB,qCAAqC;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,mCAAmC;IACnC,EAAE,EAAE,IAAI,CAAC;CACV;AAKD;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB,SAAU,IAAI,KAAG,MAA+C,CAAC;AAEvF;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB,SAAU,MAAM,KAAG,eAGzC,CAAC;AAEH;;;;;GAKG;AACH,QAAA,MAAM,cAAc,QAAO,eAGzB,CAAC;AAEH;;;;GAIG;AACH,QAAA,MAAM,OAAO,SAAU,IAAI,GAAG,SAAS,MAAM,IAAI,GAAG,SAAS,KAAG,eAG/D,CAAC;AAEF;;;;;;GAMG;AACH,QAAA,MAAM,cAAc,UAAW,MAAM,OAAO,MAAM,GAAG,IAAI,KAAG,IAAI,GAAG,SA2BlE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,YAAY,iBAAkB,eAAe,KAAG,KAAK,CAAC,eAAe,CAW1E,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,WAAW,UAAW,MAAM,QAAQ,MAAM,KAAG,MACD,CAAC;AAEnD;;;;GAIG;AACH,QAAA,MAAM,WAAW,iBAAkB,eAAe,KAAG,MAWpD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB,sBACL,aAAa,CAAC,MAAM,CAAC,SACjC,eAAe,KACrB,KAAK,CAAC,eAAe,CAGvB,CAAC;AAEF,OAAO,EACL,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,OAAO,EACP,YAAY,GACb,CAAC;AACF,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -1,3 +1,7 @@
1
+ /** @file A range reaches GitHub one calendar year at a time; `contributionsCollection` refuses a longer one. */
2
+ import { GITHUB_EPOCH_YEAR } from './constants.js';
3
+ /** A year, a year and month, or a full date. */
4
+ const RANGE_DATE_PATTERN = /^(?<year>\d{4})(?:-(?<month>\d{2})(?:-(?<day>\d{2}))?)?$/;
1
5
  /**
2
6
  * Format a date as a GitHub `DateTime` scalar.
3
7
  * Seconds precision, no milliseconds.
@@ -6,7 +10,7 @@
6
10
  */
7
11
  const toGitHubDateTime = (date) => `${date.toISOString().slice(0, 19)}Z`;
8
12
  /**
9
- * The full UTC span of a calendar year, both ends inclusive.
13
+ * The full UTC range of a calendar year, both ends inclusive.
10
14
  *
11
15
  * The end matters to callers that would otherwise leave a range open:
12
16
  * GitHub's `contributionsCollection` defaults `to` to one year after `from`,
@@ -18,4 +22,102 @@ const getGitHubYearRange = (year) => ({
18
22
  from: new Date(Date.UTC(year, 0, 1)),
19
23
  to: new Date(Date.UTC(year, 11, 31, 23, 59, 59)),
20
24
  });
21
- export { getGitHubYearRange, toGitHubDateTime };
25
+ /**
26
+ * The widest range a card can be asked for: GitHub's first year through the end of this one.
27
+ * The far end is the end of the year, not today, because a bare `to=2026` widens to its 31st of December.
28
+ *
29
+ * @returns The range, in UTC.
30
+ */
31
+ const getWidestRange = () => ({
32
+ from: getGitHubYearRange(GITHUB_EPOCH_YEAR).from,
33
+ to: getGitHubYearRange(new Date().getUTCFullYear()).to,
34
+ });
35
+ /**
36
+ * The range a card counts within, from the ends the query named.
37
+ *
38
+ * @returns The range, each open end filled from {@link getWidestRange}.
39
+ */
40
+ const toRange = (from, to) => {
41
+ const widest = getWidestRange();
42
+ return { from: from ?? widest.from, to: to ?? widest.to };
43
+ };
44
+ /**
45
+ * Read one end of a range, written as `2024`, `2024-03` or `2024-03-15`.
46
+ * A partial date covers the whole of what it names, so `2024` starts on the 1st of January
47
+ * and ends on the 31st of December.
48
+ *
49
+ * @returns The instant, or `undefined` when the text does not name a date that exists.
50
+ */
51
+ const parseRangeDate = (value, end) => {
52
+ const match = RANGE_DATE_PATTERN.exec(value);
53
+ if (!match) {
54
+ return undefined;
55
+ }
56
+ const { year: yearText, month: monthText, day: dayText } = match.groups ?? {};
57
+ const year = Number(yearText);
58
+ const month = monthText === undefined ? 1 : Number(monthText);
59
+ const day = dayText === undefined ? 1 : Number(dayText);
60
+ const start = new Date(Date.UTC(year, month - 1, day));
61
+ // Date.UTC rolls an impossible date forward rather than refusing it
62
+ if (start.getUTCMonth() + 1 !== month || start.getUTCDate() !== day) {
63
+ return undefined;
64
+ }
65
+ if (end === 'from') {
66
+ return start;
67
+ }
68
+ const nextUnit = dayText !== undefined
69
+ ? Date.UTC(year, month - 1, day + 1)
70
+ : monthText !== undefined
71
+ ? Date.UTC(year, month, 1)
72
+ : Date.UTC(year + 1, 0, 1);
73
+ return new Date(nextUnit - 1000);
74
+ };
75
+ /**
76
+ * Split a range into one per calendar year, each clipped to it.
77
+ *
78
+ * @returns Them, oldest first; empty when the range is inverted.
79
+ */
80
+ const toYearRanges = ({ from, to }) => {
81
+ const ranges = [];
82
+ for (let year = from.getUTCFullYear(); year <= to.getUTCFullYear(); year += 1) {
83
+ const yearRange = getGitHubYearRange(year);
84
+ const start = from > yearRange.from ? from : yearRange.from;
85
+ const end = to < yearRange.to ? to : yearRange.to;
86
+ if (start <= end) {
87
+ ranges.push({ from: start, to: end });
88
+ }
89
+ }
90
+ return ranges;
91
+ };
92
+ /**
93
+ * Whole years as a card writes them.
94
+ *
95
+ * @returns e.g. `2024` or `2020–2024`.
96
+ */
97
+ const formatYears = (first, last) => first === last ? `${first}` : `${first}–${last}`;
98
+ /**
99
+ * A range as a card writes it, at the coarsest granularity that stays true.
100
+ *
101
+ * @returns e.g. `2024`, `2020–2024` or `2024-03-15 – 2024-06-30`.
102
+ */
103
+ const formatRange = ({ from, to }) => {
104
+ const firstYear = from.getUTCFullYear();
105
+ const lastYear = to.getUTCFullYear();
106
+ const wholeYears = from.getTime() === getGitHubYearRange(firstYear).from.getTime() &&
107
+ to.getTime() === getGitHubYearRange(lastYear).to.getTime();
108
+ if (!wholeYears) {
109
+ return `${from.toISOString().slice(0, 10)} – ${to.toISOString().slice(0, 10)}`;
110
+ }
111
+ return formatYears(firstYear, lastYear);
112
+ };
113
+ /**
114
+ * The ranges a walk asks GitHub for: one per calendar year the account contributed in.
115
+ * Ordered here, which is what makes a walk's ties chronological.
116
+ *
117
+ * @returns Them, oldest first.
118
+ */
119
+ const toContributionRanges = (contributionYears, range) => {
120
+ const contributed = new Set(contributionYears);
121
+ return toYearRanges(range).filter((year) => contributed.has(year.from.getUTCFullYear()));
122
+ };
123
+ export { formatRange, formatYears, getWidestRange, getGitHubYearRange, parseRangeDate, toContributionRanges, toGitHubDateTime, toRange, toYearRanges, };
@@ -6,8 +6,7 @@ declare const icons: {
6
6
  prs_merged: import("../markup/element.ts").MarkupElement;
7
7
  prs_merged_percentage: import("../markup/element.ts").MarkupElement;
8
8
  issues: import("../markup/element.ts").MarkupElement;
9
- icon: import("../markup/element.ts").MarkupElement;
10
- contribs: import("../markup/element.ts").MarkupElement;
9
+ repo: import("../markup/element.ts").MarkupElement;
11
10
  fork: import("../markup/element.ts").MarkupElement;
12
11
  reviews: import("../markup/element.ts").MarkupElement;
13
12
  discussions_started: import("../markup/element.ts").MarkupElement;
@@ -15,6 +14,9 @@ declare const icons: {
15
14
  comments: import("../markup/element.ts").MarkupElement;
16
15
  contributions: import("../markup/element.ts").MarkupElement;
17
16
  gist: import("../markup/element.ts").MarkupElement;
17
+ pulse: import("../markup/element.ts").MarkupElement;
18
+ code: import("../markup/element.ts").MarkupElement;
19
+ clock: import("../markup/element.ts").MarkupElement;
18
20
  };
19
21
  /**
20
22
  * Get rank icon
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/common/icons.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGhD,QAAA,MAAM,KAAK;IACT,IAAI;IAIJ,OAAO;IAIP,GAAG;IAIH,UAAU;IAIV,qBAAqB;IAIrB,MAAM;IAIN,IAAI;IAIJ,QAAQ;IAIR,IAAI;IAIJ,OAAO;IAIP,mBAAmB;IAInB,oBAAoB;IAIpB,QAAQ;IAGR,aAAa;IAGb,IAAI;CAIL,CAAC;AAUF;;;;GAIG;AACH,QAAA,MAAM,QAAQ,SAAU,MAAM,aAAa,MAAM,cAAc,MAAM,KAAG,KAkDvE,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/common/icons.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGhD,QAAA,MAAM,KAAK;IACT,IAAI;IAIJ,OAAO;IAIP,GAAG;IAIH,UAAU;IAIV,qBAAqB;IAIrB,MAAM;IAIN,IAAI;IAIJ,IAAI;IAIJ,OAAO;IAIP,mBAAmB;IAInB,oBAAoB;IAIpB,QAAQ;IAGR,aAAa;IAGb,IAAI;IAIJ,KAAK;IAGL,IAAI;IAGJ,KAAK;CAGN,CAAC;AAUF;;;;GAIG;AACH,QAAA,MAAM,QAAQ,SAAU,MAAM,aAAa,MAAM,cAAc,MAAM,KAAG,KAkDvE,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC"}
@@ -24,11 +24,7 @@ const icons = {
24
24
  'fill-rule': 'evenodd',
25
25
  d: 'M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm9 3a1 1 0 11-2 0 1 1 0 012 0zm-.25-6.25a.75.75 0 00-1.5 0v3.5a.75.75 0 001.5 0v-3.5z',
26
26
  }),
27
- icon: el('path', {
28
- 'fill-rule': 'evenodd',
29
- d: 'M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z',
30
- }),
31
- contribs: el('path', {
27
+ repo: el('path', {
32
28
  'fill-rule': 'evenodd',
33
29
  d: 'M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z',
34
30
  }),
@@ -58,6 +54,15 @@ const icons = {
58
54
  'fill-rule': 'evenodd',
59
55
  d: 'M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z',
60
56
  }),
57
+ pulse: el('path', {
58
+ d: 'M6 2c.306 0 .582.187.696.471L10 10.731l1.304-3.26A.751.751 0 0 1 12 7h3.25a.75.75 0 0 1 0 1.5h-2.742l-1.812 4.529a.751.751 0 0 1-1.392 0L6 4.769l-1.304 3.26A.751.751 0 0 1 4 8.5H.75a.75.75 0 0 1 0-1.5h2.742l1.812-4.529A.751.751 0 0 1 6 2Z',
59
+ }),
60
+ code: el('path', {
61
+ d: 'M4.72 3.22a.75.75 0 0 1 1.06 1.06L2.06 8l3.72 3.72a.75.75 0 1 1-1.06 1.06L.47 8.53a.75.75 0 0 1 0-1.06Zm6.56 0a.75.75 0 1 0-1.06 1.06L13.94 8l-3.72 3.72a.75.75 0 1 0 1.06 1.06l4.25-4.25a.75.75 0 0 0 0-1.06Z',
62
+ }),
63
+ clock: el('path', {
64
+ d: 'M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7-3.25v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.75.75 0 0 1 7 8.25v-3.5a.75.75 0 0 1 1.5 0Z',
65
+ }),
61
66
  };
62
67
  /** Attributes every rank glyph shares, so the three variants differ only where they mean to. */
63
68
  const RANK_TEXT = {
@@ -14,9 +14,9 @@ declare const parseArray: (str: string | undefined) => Array<string>;
14
14
  /**
15
15
  * Clamp the given number between the given range.
16
16
  *
17
- * @returns The clamped number.
17
+ * @returns The clamped number; `min` for `NaN`.
18
18
  */
19
- declare const clampValue: (number: string | number, min: number, max: number) => number;
19
+ declare const clampValue: (number: number, min: number, max: number) => number;
20
20
  /**
21
21
  * Lowercase and trim string.
22
22
  *
@@ -43,6 +43,11 @@ declare const parseEmojis: (str: string) => string;
43
43
  * @returns Parsed affiliations.
44
44
  */
45
45
  declare const parseOwnerAffiliations: (affiliations: Array<string>) => Array<RepositoryAffiliation>;
46
- declare const buildSearchFilter: (repos?: Array<string> | string, owners?: Array<string> | string) => string;
46
+ /**
47
+ * The qualifiers that scope a REST search to repositories and owners.
48
+ *
49
+ * @returns e.g. `repo:a/b owner:c `, each qualifier followed by a space; empty when both lists are.
50
+ */
51
+ declare const buildSearchFilter: (repos: Array<string>, owners: Array<string>) => string;
47
52
  export { parseBoolean, parseArray, clampValue, lowercaseTrim, chunkArray, parseEmojis, parseOwnerAffiliations, buildSearchFilter, };
48
53
  //# sourceMappingURL=ops.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/common/ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAM5E;;;;GAIG;AACH,QAAA,MAAM,YAAY,UAAW,MAAM,GAAG,OAAO,GAAG,SAAS,KAAG,OAAO,GAAG,SAcrE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,UAAU,QAAS,MAAM,GAAG,SAAS,KAAG,KAAK,CAAC,MAAM,CAKzD,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,UAAU,WAAY,MAAM,GAAG,MAAM,OAAO,MAAM,OAAO,MAAM,KAAG,MAKvE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,aAAa,SAAU,MAAM,KAAG,MAAmC,CAAC;AAE1E;;;;GAIG;AACH,QAAA,MAAM,UAAU,GAAI,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,YAAY,MAAM,KAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAStE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,WAAW,QAAS,MAAM,KAAG,MASlC,CAAC;AAKF;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,iBAAkB,KAAK,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,qBAAqB,CAYxF,CAAC;AAEF,QAAA,MAAM,iBAAiB,WACd,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,WACrB,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,KAC7B,MAQF,CAAC;AAEF,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/common/ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAM5E;;;;GAIG;AACH,QAAA,MAAM,YAAY,UAAW,MAAM,GAAG,OAAO,GAAG,SAAS,KAAG,OAAO,GAAG,SAcrE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,UAAU,QAAS,MAAM,GAAG,SAAS,KAAG,KAAK,CAAC,MAAM,CAKzD,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,UAAU,WAAY,MAAM,OAAO,MAAM,OAAO,MAAM,KAAG,MACI,CAAC;AAEpE;;;;GAIG;AACH,QAAA,MAAM,aAAa,SAAU,MAAM,KAAG,MAAmC,CAAC;AAE1E;;;;GAIG;AACH,QAAA,MAAM,UAAU,GAAI,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,YAAY,MAAM,KAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAStE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,WAAW,QAAS,MAAM,KAAG,MASlC,CAAC;AAKF;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,iBAAkB,KAAK,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,qBAAqB,CAYxF,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,iBAAiB,UAAW,KAAK,CAAC,MAAM,CAAC,UAAU,KAAK,CAAC,MAAM,CAAC,KAAG,MACwB,CAAC;AAElG,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAClB,CAAC"}