profileShare

rasmusjy / profileshare

Read-only snapshot

No repository description.

main default branch 54 files Expires Sep 13, 2026, 9:06 AM
repository.ejs 37,062 bytes
1 <%- include("partials/head", { title: repository.name, bodyClass: "viewer-page repository-page" }) %>
2 <header class="viewer-header">
3 <a class="wordmark wordmark-light" href="/s/<%= share.id %>">profile<span>Share</span></a>
4 <form class="snapshot-search" action="/s/<%= share.id %>/search" method="get" role="search">
5 <input type="hidden" name="repository" value="<%= repository.id %>">
6 <% if (!selectedReference.isDefault) { %>
7 <input type="hidden" name="ref" value="<%= selectedReference.name %>">
8 <input type="hidden" name="refType" value="<%= selectedReference.type %>">
9 <% } %>
10 <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.5 3a7.5 7.5 0 1 1-4.7 13.34l-3.07 3.07-1.42-1.42 3.08-3.07A7.5 7.5 0 0 1 10.5 3Zm0 2a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11Z"/></svg>
11 <input data-search-input name="q" aria-label="Search <%= repository.name %>" placeholder="Search <%= repository.name %>">
12 <kbd>/</kbd>
13 <button class="sr-only" type="submit">Search</button>
14 </form>
15 <nav class="top-nav" aria-label="Snapshot navigation">
16 <a href="/s/<%= share.id %>">&larr; Back to profile</a>
17 <span class="meta-divider"></span>
18 <span>Snapshot from <%= formatDate(share.created_at) %></span>
19 </nav>
20 </header>
21
22 <section class="repo-mast">
23 <div class="repo-mast-inner">
24 <div class="repo-identity">
25 <span class="repo-mark" aria-hidden="true">
26 <svg class="repo-icon repo-icon-mark" width="20" height="20" viewBox="0 0 24 24"><path d="M4 4.75A2.75 2.75 0 0 1 6.75 2h10.5A2.75 2.75 0 0 1 20 4.75v14.5A2.75 2.75 0 0 1 17.25 22H6.75A2.75 2.75 0 0 1 4 19.25V4.75Zm3.5-.75A1.5 1.5 0 0 0 6 5.5v13A1.5 1.5 0 0 0 7.5 20H9V4H7.5Z"/></svg>
27 </span>
28 <h1>
29 <a href="/s/<%= share.id %>"><%= share.snapshot.profile.login %></a>
30 <span>/</span>
31 <strong><%= repository.name %></strong>
32 </h1>
33 <span class="repo-visibility">Read-only snapshot</span>
34 </div>
35 <p class="repo-summary"><%= repository.description || "No repository description." %></p>
36 <div class="repo-facts">
37 <span><strong><%= selectedReference.name %></strong> <%= selectedReference.isDefault ? "default branch" : selectedReference.type %></span>
38 <span><strong><%= repository.files.length %></strong> files</span>
39 <span>Expires <strong><%= formatDate(share.expires_at) %></strong></span>
40 </div>
41 </div>
42 </section>
43
44 <nav class="repo-tabs" aria-label="Repository sections">
45 <div class="repo-tabs-inner">
46 <a class="<%= tab === 'code' && !commit ? 'active' : '' %>" href="<%= repoHref() %>" <%- tab === "code" && !commit ? 'aria-current="page"' : "" %>>
47 <svg class="repo-icon repo-icon-tab" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="m8.7 17.3-5-5a1 1 0 0 1 0-1.4l5-5 1.4 1.4L5.8 11.6l4.3 4.3-1.4 1.4Zm6.6 0-1.4-1.4 4.3-4.3-4.3-4.3 1.4-1.4 5 5a1 1 0 0 1 0 1.4l-5 5Z"/></svg>
48 Code
49 </a>
50 <a class="<%= tab === 'issues' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'issues' }) %>" <%- tab === "issues" ? 'aria-current="page"' : "" %>>
51 <svg class="repo-icon repo-icon-tab" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20Zm0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-1 3h2v7h-2V7Zm0 9h2v2h-2v-2Z"/></svg>
52 Issues
53 <span class="tab-count"><%= repository.issues.filter((item) => item.state === "open").length %></span>
54 </a>
55 <a class="<%= tab === 'pulls' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'pulls' }) %>" <%- tab === "pulls" ? 'aria-current="page"' : "" %>>
56 <svg class="repo-icon repo-icon-tab" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 3a3 3 0 1 1-1 5.83v6.34A3 3 0 1 1 7 15V8.83A3 3 0 0 1 6 3Zm0 2a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm0 12a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm12-2a3 3 0 1 1-2 2.83V15a4 4 0 0 0-4-4h-1V8l-4 4 4 4v-3h1a2 2 0 0 1 2 2v.17A3 3 0 0 1 18 15Zm0 2a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>
57 Pull requests
58 <span class="tab-count"><%= repository.pullRequests.filter((item) => item.state === "open").length %></span>
59 </a>
60 <a class="<%= tab === 'releases' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'releases' }) %>" <%- tab === "releases" ? 'aria-current="page"' : "" %>>
61 <svg class="repo-icon repo-icon-tab" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 4a1 1 0 0 1 1-1h7.59a1 1 0 0 1 .7.29l8.42 8.42a1 1 0 0 1 0 1.41l-7.59 7.59a1 1 0 0 1-1.41 0L3.29 12.3A1 1 0 0 1 3 11.59V4Zm2 1v6.17l7.41 7.42 6.18-6.18L11.17 5H5Zm3 2a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Z"/></svg>
62 Releases
63 <span class="tab-count"><%= repository.releases.length %></span>
64 </a>
65 <a class="<%= tab === 'commits' || commit ? 'active' : '' %>" href="<%= repoHref({ tab: 'commits' }) %>" <%- tab === "commits" || commit ? 'aria-current="page"' : "" %>>
66 <svg class="repo-icon repo-icon-tab" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 7a5 5 0 1 1-4.9 6H2v-2h5.1A5 5 0 0 1 12 7Zm0 2a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm4.9 2H22v2h-5.1v-2Z"/></svg>
67 Commits
68 <span class="tab-count"><%= repository.commits.length %></span>
69 </a>
70 </div>
71 </nav>
72
73 <main class="repository-shell">
74 <% if (commit) { %>
75 <nav class="repo-breadcrumbs" aria-label="Commit navigation">
76 <a href="<%= repoHref({ tab: 'commits' }) %>">Commits</a>
77 <span>/</span>
78 <span><%= commit.sha.slice(0, 7) %></span>
79 </nav>
80 <section class="commit-detail-card">
81 <header class="commit-detail-heading">
82 <div class="commit-detail-main">
83 <p class="section-kicker">Commit</p>
84 <h2><%= commit.message.split("\n")[0] %></h2>
85 <% const commitBody = commit.message.split("\n").slice(1).join("\n").trim(); %>
86 <% if (commitBody) { %><pre class="commit-message-body"><%= commitBody %></pre><% } %>
87 <p class="commit-detail-byline">
88 <span class="commit-avatar" aria-hidden="true"><%= commit.author.slice(0, 1).toUpperCase() %></span>
89 <strong><%= commit.author %></strong> committed <%= formatDate(commit.date) %>
90 </p>
91 </div>
92 <div class="commit-detail-side">
93 <span class="commit-sha">
94 <span>commit</span>
95 <code><%= commit.sha.slice(0, 7) %></code>
96 </span>
97 <button class="quiet-button" type="button" data-copy-text="<%= commit.sha %>">Copy SHA</button>
98 </div>
99 </header>
100 <%- include("partials/diff-list", {
101 files: commit.files,
102 diffAdditions: commit.additions,
103 diffDeletions: commit.deletions,
104 emptyMessage: "No changed files are available for this commit."
105 }) %>
106 </section>
107 <% } else if (issue) { %>
108 <nav class="repo-breadcrumbs" aria-label="Issue navigation">
109 <a href="<%= globalRepoHref({ tab: 'issues' }) %>">Issues</a>
110 <span>/</span>
111 <span>#<%= issue.number %></span>
112 </nav>
113 <section class="discussion-page">
114 <header class="work-detail-heading">
115 <div>
116 <h2><%= issue.title %> <span>#<%= issue.number %></span></h2>
117 <p>
118 <span class="state-badge <%= issue.state %>"><%= issue.state %></span>
119 <strong><%= issue.author.login %></strong> opened this issue on <%= formatDate(issue.createdAt) %>
120 · <%= issue.comments.length %> <%= issue.comments.length === 1 ? "comment" : "comments" %>
121 </p>
122 </div>
123 <span class="read-only-badge">Read only</span>
124 </header>
125 <div class="discussion-layout">
126 <div class="discussion-timeline">
127 <article class="discussion-card">
128 <header>
129 <strong><%= issue.author.login %></strong>
130 <span>opened on <%= formatDate(issue.createdAt) %></span>
131 </header>
132 <div class="discussion-body">
133 <% if (issue.body) { %><%- renderMarkdown(issue.body) %><% } else { %><p>No description was provided.</p><% } %>
134 </div>
135 </article>
136 <% issue.comments.forEach((comment) => { %>
137 <article class="discussion-card">
138 <header>
139 <strong><%= comment.author.login %></strong>
140 <span>commented on <%= formatDate(comment.createdAt) %></span>
141 </header>
142 <div class="discussion-body">
143 <% if (comment.body) { %><%- renderMarkdown(comment.body) %><% } else { %><p>No comment text was included.</p><% } %>
144 </div>
145 </article>
146 <% }) %>
147 </div>
148 <aside class="work-sidebar">
149 <section>
150 <strong>Labels</strong>
151 <div class="work-labels">
152 <% issue.labels.forEach((label) => { %><span class="work-label"><%= label.name %></span><% }) %>
153 <% if (!issue.labels.length) { %><span>None</span><% } %>
154 </div>
155 </section>
156 <section>
157 <strong>Status</strong>
158 <span><%= issue.stateReason || issue.state %></span>
159 </section>
160 </aside>
161 </div>
162 </section>
163 <% } else if (pullRequest) { %>
164 <nav class="repo-breadcrumbs" aria-label="Pull request navigation">
165 <a href="<%= globalRepoHref({ tab: 'pulls' }) %>">Pull requests</a>
166 <span>/</span>
167 <span>#<%= pullRequest.number %></span>
168 </nav>
169 <section class="discussion-page">
170 <header class="work-detail-heading">
171 <div>
172 <h2><%= pullRequest.title %> <span>#<%= pullRequest.number %></span></h2>
173 <p>
174 <% const pullState = pullRequest.draft ? "draft" : pullRequest.merged ? "merged" : pullRequest.state; %>
175 <span class="state-badge <%= pullState %>"><%= pullState %></span>
176 <strong><%= pullRequest.author.login %></strong> opened this pull request on <%= formatDate(pullRequest.createdAt) %>
177 </p>
178 </div>
179 <span class="read-only-badge">Read only</span>
180 </header>
181 <div class="pull-summary">
182 <span><code><%= pullRequest.head %></code> into <code><%= pullRequest.base %></code></span>
183 <span><strong><%= pullRequest.commitCount %></strong> commits</span>
184 <span><strong><%= pullRequest.changedFiles %></strong> changed files</span>
185 <span class="commit-change"><b>+<%= pullRequest.additions %></b> <i>&minus;<%= pullRequest.deletions %></i></span>
186 </div>
187 <div class="discussion-layout">
188 <div class="discussion-timeline">
189 <article class="discussion-card">
190 <header>
191 <strong><%= pullRequest.author.login %></strong>
192 <span>opened on <%= formatDate(pullRequest.createdAt) %></span>
193 </header>
194 <div class="discussion-body">
195 <% if (pullRequest.body) { %><%- renderMarkdown(pullRequest.body) %><% } else { %><p>No description was provided.</p><% } %>
196 </div>
197 </article>
198 <% pullRequest.conversation.forEach((comment) => { %>
199 <article class="discussion-card">
200 <header>
201 <strong><%= comment.author.login %></strong>
202 <span>
203 <% if (comment.type === "review") { %>
204 submitted a <%= (comment.state || "review").toLocaleLowerCase("en") %> review on <%= formatDate(comment.createdAt) %>
205 <% } else if (comment.type === "review-comment") { %>
206 reviewed <%= comment.path || "a changed file" %><%= comment.line ? " at line " + comment.line : "" %> on <%= formatDate(comment.createdAt) %>
207 <% } else { %>
208 commented on <%= formatDate(comment.createdAt) %>
209 <% } %>
210 </span>
211 </header>
212 <div class="discussion-body">
213 <% if (comment.body) { %><%- renderMarkdown(comment.body) %><% } else { %><p>No review text was included.</p><% } %>
214 </div>
215 </article>
216 <% }) %>
217 <section class="pull-files">
218 <h3>Files changed <span><%= pullRequest.files.length %></span></h3>
219 <%- include("partials/diff-list", {
220 files: pullRequest.files,
221 diffAdditions: pullRequest.additions,
222 diffDeletions: pullRequest.deletions,
223 emptyMessage: "No changed files are included in this snapshot."
224 }) %>
225 </section>
226 </div>
227 <aside class="work-sidebar">
228 <section>
229 <strong>Labels</strong>
230 <div class="work-labels">
231 <% pullRequest.labels.forEach((label) => { %><span class="work-label"><%= label.name %></span><% }) %>
232 <% if (!pullRequest.labels.length) { %><span>None</span><% } %>
233 </div>
234 </section>
235 <section>
236 <strong>Merge status</strong>
237 <span><%= pullRequest.merged ? "Merged" : pullRequest.draft ? "Draft" : pullRequest.mergeableState || pullRequest.state %></span>
238 </section>
239 </aside>
240 </div>
241 </section>
242 <% } else if (release) { %>
243 <nav class="repo-breadcrumbs" aria-label="Release navigation">
244 <a href="<%= globalRepoHref({ tab: 'releases' }) %>">Releases</a>
245 <span>/</span>
246 <span><%= release.tagName %></span>
247 </nav>
248 <article class="release-detail">
249 <header>
250 <div>
251 <div class="release-kicker">
252 <span class="release-tag"><%= release.tagName %></span>
253 <% if (release.draft) { %><span class="release-status">Draft</span><% } %>
254 <% if (release.prerelease) { %><span class="release-status">Pre-release</span><% } %>
255 </div>
256 <h2><%= release.name %></h2>
257 <p>
258 <strong><%= release.author.login %></strong>
259 <%= release.publishedAt ? "published" : "created" %> this release on
260 <%= formatDate(release.publishedAt || release.createdAt) %>
261 </p>
262 </div>
263 <% const releaseTag = references.tags.find((tag) => tag.name === release.tagName); %>
264 <% if (releaseTag) { %><a class="quiet-button" href="<%= refHref({ ...releaseTag, type: 'tag' }) %>">Browse tag</a><% } %>
265 </header>
266 <div class="release-body discussion-body">
267 <% if (release.body) { %><%- renderMarkdown(release.body) %><% } else { %><p>No release notes were provided.</p><% } %>
268 </div>
269 <section class="release-assets">
270 <h3>Assets <span><%= release.assets.length %></span></h3>
271 <% if (release.assets.length) { %>
272 <ul>
273 <% release.assets.forEach((asset) => { %>
274 <li>
275 <strong><%= asset.label || asset.name %></strong>
276 <% if (asset.label) { %><code><%= asset.name %></code><% } %>
277 <span><%= asset.size.toLocaleString() %> bytes · <%= asset.downloadCount.toLocaleString() %> GitHub downloads</span>
278 </li>
279 <% }) %>
280 </ul>
281 <p>Assets are listed for reference and are not downloadable from this read-only snapshot.</p>
282 <% } else { %>
283 <p>No release assets are included.</p>
284 <% } %>
285 </section>
286 </article>
287 <% } else if (historyFile) { %>
288 <nav class="repo-breadcrumbs" aria-label="File history navigation">
289 <a href="<%= repoHref() %>"><%= repository.name %></a>
290 <span>/</span>
291 <a href="<%= repoHref({ file: historyFile.path }) %>"><%= historyFile.path %></a>
292 <span>/</span>
293 <span>History</span>
294 </nav>
295 <section class="commits-page file-history-page">
296 <header class="section-title-row">
297 <div>
298 <p class="section-kicker">File history</p>
299 <h2>History for <code><%= historyFile.path %></code></h2>
300 </div>
301 <a class="quiet-button" href="<%= repoHref({ file: historyFile.path }) %>">View file</a>
302 </header>
303 <ol class="commit-feed">
304 <% fileHistory.forEach((item) => { %>
305 <li>
306 <span class="commit-avatar" aria-hidden="true"><%= item.author.slice(0, 1).toUpperCase() %></span>
307 <a class="commit-main" href="<%= repoHref({ commit: item.sha }) %>">
308 <strong><%= item.message.split("\n")[0] %></strong>
309 <span><%= item.author %> committed <%= formatDate(item.date) %></span>
310 </a>
311 <span class="commit-change"><b>+<%= item.fileChange.additions %></b> <i>&minus;<%= item.fileChange.deletions %></i></span>
312 <code><%= item.sha.slice(0, 7) %></code>
313 </li>
314 <% }) %>
315 <% if (!fileHistory.length) { %>
316 <li class="empty-state">No file history is included in this snapshot.</li>
317 <% } %>
318 </ol>
319 </section>
320 <% } else if (file) { %>
321 <nav class="repo-breadcrumbs" aria-label="File path">
322 <a href="<%= repoHref() %>"><%= repository.name %></a>
323 <% let filePath = ""; file.path.split("/").forEach((part, index, parts) => { filePath += (filePath ? "/" : "") + part; %>
324 <span>/</span>
325 <% if (index < parts.length - 1) { %>
326 <a href="<%= repoHref({ path: filePath }) %>"><%= part %></a>
327 <% } else { %>
328 <span><%= part %></span>
329 <% } %>
330 <% }) %>
331 </nav>
332 <section class="file-view-card">
333 <header class="file-view-header">
334 <div>
335 <strong><%= file.path.split("/").pop() %></strong>
336 <span><%= file.size.toLocaleString() %> bytes</span>
337 </div>
338 <div class="file-view-actions">
339 <button class="quiet-button copy-path" type="button" data-copy-text="<%= file.path %>">Copy path</button>
340 <a class="quiet-button" href="<%= repoHref({ history: file.path }) %>">History</a>
341 <a href="<%= repoHref({ path: file.path.includes('/') ? file.path.slice(0, file.path.lastIndexOf('/')) : '' }) %>">&larr; Back to files</a>
342 </div>
343 </header>
344 <% if (markdownFile) { %>
345 <nav class="file-view-tabs" aria-label="File view">
346 <a class="<%= fileView === 'preview' ? 'active' : '' %>" href="<%= repoHref({ file: file.path }) %>"<% if (fileView === "preview") { %> aria-current="page"<% } %>>Preview</a>
347 <a class="<%= fileView === 'source' ? 'active' : '' %>" href="<%= repoHref({ file: file.path, view: 'source' }) %>"<% if (fileView === "source") { %> aria-current="page"<% } %>>Source</a>
348 </nav>
349 <% } %>
350 <% if (markdownFile && fileView === "preview" && file.content !== null) { %>
351 <article class="markdown-file-preview markdown-body"><%- renderMarkdown(file.content, {
352 baseUrl: "/s/" + share.id + "/repositories/" + repository.id,
353 readmePath: file.path,
354 files: repository.files,
355 repositoryUrl: repoHref
356 }) %></article>
357 <% } else if (file.binaryContent && file.mediaType) { %>
358 <div class="image-file-preview">
359 <img src="data:<%= file.mediaType %>;base64,<%= file.binaryContent %>" alt="<%= file.path.split('/').pop() %>">
360 </div>
361 <% } else if (file.content === null) { %>
362 <div class="empty-state">This file cannot be displayed as text<%= file.truncated ? " because it is larger than the snapshot preview limit." : "." %></div>
363 <% } else { %>
364 <div class="code-view">
365 <table class="code-table" aria-label="<%= file.path %> source">
366 <tbody>
367 <% file.content.split(/\r?\n/).forEach((line, index) => { const lineNumber = index + 1; %>
368 <tr id="L<%= lineNumber %>">
369 <th scope="row"><a href="#L<%= lineNumber %>" aria-label="Line <%= lineNumber %>"><%= lineNumber %></a></th>
370 <td><code><%= line %></code></td>
371 </tr>
372 <% }) %>
373 </tbody>
374 </table>
375 </div>
376 <% } %>
377 </section>
378 <% } else if (tab === "commits") { %>
379 <section class="commits-page">
380 <header class="section-title-row">
381 <div>
382 <p class="section-kicker"><%= selectedReference.name %> history</p>
383 <h2><%= repository.commits.length %> <%= repository.commits.length === 1 ? "commit" : "commits" %></h2>
384 </div>
385 <a class="quiet-button" href="<%= repoHref() %>">Browse code</a>
386 </header>
387 <ol class="commit-feed">
388 <% repository.commits.forEach((item) => { %>
389 <li>
390 <span class="commit-avatar" aria-hidden="true"><%= item.author.slice(0, 1).toUpperCase() %></span>
391 <a class="commit-main" href="<%= repoHref({ commit: item.sha }) %>">
392 <strong><%= item.message.split("\n")[0] %></strong>
393 <span><%= item.author %> committed <%= formatDate(item.date) %></span>
394 </a>
395 <span class="commit-change"><b>+<%= item.additions %></b> <i>&minus;<%= item.deletions %></i></span>
396 <code><%= item.sha.slice(0, 7) %></code>
397 </li>
398 <% }) %>
399 <% if (!repository.commits.length) { %>
400 <li class="empty-state">No commits are included in this snapshot.</li>
401 <% } %>
402 </ol>
403 </section>
404 <% } else if (tab === "issues") { %>
405 <section class="work-list-page">
406 <header class="work-list-header">
407 <div>
408 <h2>Issues</h2>
409 <p>Questions, bugs, and planned work captured with this snapshot.</p>
410 </div>
411 <nav aria-label="Issue state">
412 <a class="<%= stateFilter === 'all' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'issues' }) %>">All <span><%= repository.issues.length %></span></a>
413 <a class="<%= stateFilter === 'open' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'issues', state: 'open' }) %>">Open <span><%= repository.issues.filter((item) => item.state === "open").length %></span></a>
414 <a class="<%= stateFilter === 'closed' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'issues', state: 'closed' }) %>">Closed <span><%= repository.issues.filter((item) => item.state === "closed").length %></span></a>
415 </nav>
416 </header>
417 <div class="work-list">
418 <% visibleIssues.forEach((item) => { %>
419 <article>
420 <span class="work-state-icon <%= item.state %>" aria-label="<%= item.state %> issue"></span>
421 <div>
422 <a class="work-title" href="<%= globalRepoHref({ issue: item.number }) %>"><%= item.title %></a>
423 <div class="work-labels">
424 <% item.labels.forEach((label) => { %><span class="work-label"><%= label.name %></span><% }) %>
425 </div>
426 <p>#<%= item.number %> opened on <%= formatDate(item.createdAt) %> by <%= item.author.login %></p>
427 </div>
428 <span class="work-comments"><strong><%= item.comments.length %></strong> comments</span>
429 </article>
430 <% }) %>
431 <% if (!visibleIssues.length) { %>
432 <div class="empty-state">No <%= stateFilter === "all" ? "" : stateFilter + " " %>issues are included in this snapshot.</div>
433 <% } %>
434 </div>
435 </section>
436 <% } else if (tab === "pulls") { %>
437 <section class="work-list-page">
438 <header class="work-list-header">
439 <div>
440 <h2>Pull requests</h2>
441 <p>Proposed changes, reviews, and file diffs captured with this snapshot.</p>
442 </div>
443 <nav aria-label="Pull request state">
444 <a class="<%= stateFilter === 'all' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'pulls' }) %>">All <span><%= repository.pullRequests.length %></span></a>
445 <a class="<%= stateFilter === 'open' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'pulls', state: 'open' }) %>">Open <span><%= repository.pullRequests.filter((item) => item.state === "open").length %></span></a>
446 <a class="<%= stateFilter === 'closed' ? 'active' : '' %>" href="<%= globalRepoHref({ tab: 'pulls', state: 'closed' }) %>">Closed <span><%= repository.pullRequests.filter((item) => item.state === "closed").length %></span></a>
447 </nav>
448 </header>
449 <div class="work-list">
450 <% visiblePullRequests.forEach((item) => { const itemState = item.draft ? "draft" : item.merged ? "merged" : item.state; %>
451 <article>
452 <span class="work-state-icon <%= itemState %>" aria-label="<%= itemState %> pull request"></span>
453 <div>
454 <a class="work-title" href="<%= globalRepoHref({ pull: item.number }) %>"><%= item.title %></a>
455 <div class="work-labels">
456 <% item.labels.forEach((label) => { %><span class="work-label"><%= label.name %></span><% }) %>
457 </div>
458 <p>#<%= item.number %> opened on <%= formatDate(item.createdAt) %> by <%= item.author.login %> · <%= item.head %> into <%= item.base %></p>
459 </div>
460 <span class="work-comments"><strong><%= item.conversation.length %></strong> updates</span>
461 </article>
462 <% }) %>
463 <% if (!visiblePullRequests.length) { %>
464 <div class="empty-state">No <%= stateFilter === "all" ? "" : stateFilter + " " %>pull requests are included in this snapshot.</div>
465 <% } %>
466 </div>
467 </section>
468 <% } else if (tab === "releases") { %>
469 <section class="release-list-page">
470 <header>
471 <div>
472 <h2>Releases</h2>
473 <p>Published versions and release notes captured with this snapshot.</p>
474 </div>
475 <span><strong><%= repository.releases.length %></strong> total</span>
476 </header>
477 <div class="release-list">
478 <% repository.releases.forEach((item, index) => { %>
479 <article>
480 <aside>
481 <span class="release-tag"><%= item.tagName %></span>
482 <time><%= formatDate(item.publishedAt || item.createdAt) %></time>
483 </aside>
484 <div>
485 <div class="release-list-title">
486 <a href="<%= globalRepoHref({ release: item.id }) %>"><%= item.name %></a>
487 <% if (index === 0 && !item.draft && !item.prerelease) { %><span class="latest-release">Latest</span><% } %>
488 <% if (item.draft) { %><span class="release-status">Draft</span><% } %>
489 <% if (item.prerelease) { %><span class="release-status">Pre-release</span><% } %>
490 </div>
491 <p><%= item.body ? item.body.replace(/[#*_`>-]/g, "").trim().slice(0, 260) : "No release notes were provided." %></p>
492 <span>Published by <strong><%= item.author.login %></strong> · <%= item.assets.length %> <%= item.assets.length === 1 ? "asset" : "assets" %></span>
493 </div>
494 </article>
495 <% }) %>
496 <% if (!repository.releases.length) { %><div class="empty-state">No releases are included in this snapshot.</div><% } %>
497 </div>
498 </section>
499 <% } else { %>
500 <section class="code-overview">
501 <div class="code-toolbar">
502 <% if (references.branches.length + references.tags.length > 1) { %>
503 <details class="ref-switcher">
504 <summary class="branch-pill">
505 <svg class="repo-icon repo-icon-branch" width="14" height="14" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 3a3 3 0 1 1-1 5.83v6.34A3.001 3.001 0 1 1 8 18v-3h4a4 4 0 0 0 4-4V8.83a3.001 3.001 0 1 1 2 0V11a6 6 0 0 1-6 6H8v1a3 3 0 0 1-2-2.83V8.83A3.001 3.001 0 0 1 7 3Z"/></svg>
506 <span><%= selectedReference.name %></span>
507 <svg class="ref-chevron" width="12" height="12" viewBox="0 0 12 12" aria-hidden="true"><path d="m2.5 4 3.5 4 3.5-4Z"/></svg>
508 </summary>
509 <div class="ref-menu">
510 <header>
511 <strong>Switch branches or tags</strong>
512 <span><%= references.branches.length %> <%= references.branches.length === 1 ? "branch" : "branches" %>, <%= references.tags.length %> <%= references.tags.length === 1 ? "tag" : "tags" %></span>
513 </header>
514 <label class="sr-only" for="ref-filter">Find a branch or tag</label>
515 <input id="ref-filter" data-ref-filter type="search" placeholder="Find a branch or tag">
516 <div class="ref-options">
517 <% if (references.branches.length) { %><p>Branches</p><% } %>
518 <% references.branches.forEach((branch) => { const isSelected = selectedReference.type === "branch" && selectedReference.name === branch.name; %>
519 <a class="<%= isSelected ? 'selected' : '' %>" data-ref-option data-ref-name="<%= branch.name.toLocaleLowerCase('en') %>" href="<%= refHref({ ...branch, type: 'branch' }) %>">
520 <span class="ref-check" aria-hidden="true"></span>
521 <span><%= branch.name %></span>
522 <% if (branch.name === repository.defaultBranch) { %><small>default</small><% } %>
523 </a>
524 <% }) %>
525 <% if (references.tags.length) { %><p>Tags</p><% } %>
526 <% references.tags.forEach((tag) => { const isSelected = selectedReference.type === "tag" && selectedReference.name === tag.name; %>
527 <a class="<%= isSelected ? 'selected' : '' %>" data-ref-option data-ref-name="<%= tag.name.toLocaleLowerCase('en') %>" href="<%= refHref({ ...tag, type: 'tag' }) %>">
528 <span class="ref-check" aria-hidden="true"></span>
529 <span><%= tag.name %></span>
530 <small>tag</small>
531 </a>
532 <% }) %>
533 <p class="ref-no-results" data-ref-empty hidden>No branches or tags match.</p>
534 </div>
535 </div>
536 </details>
537 <% } else { %>
538 <span class="branch-pill">
539 <svg class="repo-icon repo-icon-branch" width="14" height="14" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 3a3 3 0 1 1-1 5.83v6.34A3.001 3.001 0 1 1 8 18v-3h4a4 4 0 0 0 4-4V8.83a3.001 3.001 0 1 1 2 0V11a6 6 0 0 1-6 6H8v1a3 3 0 0 1-2-2.83V8.83A3.001 3.001 0 1 1 7 3Z"/></svg>
540 <%= selectedReference.name %>
541 </span>
542 <% } %>
543 <% if (repository.headSha) { %>
544 <span class="head-reference">Snapshot head <code><%= repository.headSha.slice(0, 7) %></code></span>
545 <% } %>
546 <a class="commit-shortcut" href="<%= repoHref({ tab: 'commits' }) %>">
547 <svg class="repo-icon repo-icon-branch" width="14" height="14" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 7a5 5 0 1 1-4.9 6H2v-2h5.1A5 5 0 0 1 12 7Zm0 2a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm4.9 2H22v2h-5.1v-2Z"/></svg>
548 <strong><%= repository.commits.length %></strong> commits
549 </a>
550 </div>
551
552 <div class="<%= path ? 'repository-code-only' : 'repository-overview-layout' %>">
553 <div class="repository-code-column">
554 <section class="browser-card">
555 <% const latestCommit = repository.commits[0]; %>
556 <% if (latestCommit) { %>
557 <a class="latest-commit" href="<%= repoHref({ commit: latestCommit.sha }) %>">
558 <span class="commit-avatar" aria-hidden="true"><%= latestCommit.author.slice(0, 1).toUpperCase() %></span>
559 <strong><%= latestCommit.author %></strong>
560 <span class="latest-message"><%= latestCommit.message.split("\n")[0] %></span>
561 <code><%= latestCommit.sha.slice(0, 7) %></code>
562 <time><%= formatDate(latestCommit.date) %></time>
563 </a>
564 <% } %>
565 <nav class="path-bar" aria-label="File path">
566 <a href="<%= repoHref() %>"><%= repository.name %></a>
567 <% let builtPath = ""; path.split("/").filter(Boolean).forEach((part) => { builtPath += (builtPath ? "/" : "") + part; %>
568 <span>/</span><a href="<%= repoHref({ path: builtPath }) %>"><%= part %></a>
569 <% }) %>
570 </nav>
571 <div class="file-table" role="table" aria-label="Repository files">
572 <% if (path) { const parent = path.includes("/") ? path.slice(0, path.lastIndexOf("/")) : ""; %>
573 <a class="file-row" href="<%= repoHref({ path: parent }) %>">
574 <span class="file-symbol back-symbol" aria-hidden="true">&larr;</span>
575 <strong>..</strong>
576 <span>Parent folder</span>
577 </a>
578 <% } %>
579 <% browser.folders.forEach((folder) => { const nextPath = path ? path + "/" + folder : folder; %>
580 <a class="file-row" href="<%= repoHref({ path: nextPath }) %>">
581 <span class="file-symbol" aria-hidden="true"><svg class="repo-icon repo-icon-file" width="16" height="16" viewBox="0 0 24 24"><path d="M3 5.75C3 4.78 3.78 4 4.75 4h5.08c.46 0 .9.18 1.23.51L12.55 6H19.25C20.22 6 21 6.78 21 7.75v9.5c0 .97-.78 1.75-1.75 1.75H4.75C3.78 19 3 18.22 3 17.25V5.75Z"/></svg></span>
582 <strong><%= folder %></strong>
583 <span>Folder</span>
584 </a>
585 <% }) %>
586 <% browser.files.forEach((item) => { %>
587 <a class="file-row" href="<%= repoHref({ path, file: item.path }) %>">
588 <span class="file-symbol file-symbol-document" aria-hidden="true"><svg class="repo-icon repo-icon-file" width="16" height="16" viewBox="0 0 24 24"><path d="M6 2h8l5 5v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm7 2H6v16h11V8h-4V4Z"/></svg></span>
589 <strong><%= item.path.split("/").pop() %></strong>
590 <span><%= item.size.toLocaleString() %> bytes</span>
591 </a>
592 <% }) %>
593 <% if (!browser.folders.length && !browser.files.length) { %>
594 <p class="empty-state">This folder contains no files.</p>
595 <% } %>
596 </div>
597 </section>
598
599 <% if (!path && readme) { %>
600 <article class="readme-card">
601 <header>
602 <div>
603 <svg class="repo-icon repo-icon-file" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 3h6a3 3 0 0 1 2 .76A3 3 0 0 1 14 3h6a1 1 0 0 1 1 1v15a1 1 0 0 1-1 1h-6a2 2 0 0 0-1.45.62L12 21.2l-.55-.58A2 2 0 0 0 10 20H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm1 2v13h5c.35 0 .69.04 1 .13V6a1 1 0 0 0-1-1H5Zm9 0a1 1 0 0 0-1 1v12.13c.31-.09.65-.13 1-.13h5V5h-5Z"/></svg>
604 <strong><%= readme.path %></strong>
605 </div>
606 <a href="<%= repoHref({ file: readme.path, view: 'source' }) %>">View source</a>
607 </header>
608 <div class="markdown-body"><%- renderMarkdown(readme.content, {
609 baseUrl: "/s/" + share.id + "/repositories/" + repository.id,
610 readmePath: readme.path,
611 files: repository.files,
612 repositoryUrl: repoHref
613 }) %></div>
614 </article>
615 <% } else if (!path) { %>
616 <section class="readme-empty">
617 <strong>No README found</strong>
618 <p>Browse the repository files above to understand this project.</p>
619 </section>
620 <% } %>
621 </div>
622 <% if (!path) { %>
623 <aside class="repository-about">
624 <h2>About</h2>
625 <p><%= repository.description || "No repository description." %></p>
626 <% if (repository.homepage) { %><span class="about-homepage"><%= repository.homepage %></span><% } %>
627 <% if ((repository.topics || []).length) { %>
628 <div class="about-topics">
629 <% repository.topics.forEach((topic) => { %><span><%= topic %></span><% }) %>
630 </div>
631 <% } %>
632 <% if (repository.archived) { %><span class="archived-badge">Archived on GitHub</span><% } %>
633 <ul class="about-stats">
634 <li><strong><%= repository.stargazersCount || 0 %></strong> stars</li>
635 <li><strong><%= repository.watchersCount || 0 %></strong> watching</li>
636 <li><strong><%= repository.forksCount || 0 %></strong> forks</li>
637 <li><strong><%= references.branches.length %></strong> branches</li>
638 <li><strong><%= references.tags.length %></strong> tags</li>
639 <li><strong><%= repository.releases.length %></strong> releases</li>
640 </ul>
641 <% if (repository.license) { %>
642 <section class="about-section">
643 <h3>License</h3>
644 <p><%= repository.license.spdxId || repository.license.name %></p>
645 </section>
646 <% } %>
647 <% if (repository.languages.length) { %>
648 <section class="about-section">
649 <h3>Languages</h3>
650 <div class="language-breakdown">
651 <% repository.languages.forEach((language) => { %>
652 <div>
653 <span><%= language.name %></span>
654 <strong><%= language.percent.toLocaleString() %>%</strong>
655 </div>
656 <% }) %>
657 </div>
658 </section>
659 <% } %>
660 </aside>
661 <% } %>
662 </div>
663 </section>
664 <% } %>
665 </main>
666 <script src="/assets/app.js" defer></script>
667 <%- include("partials/foot") %>
668