kward 0.70.0 → 0.71.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.
- checksums.yaml +4 -4
- data/.github/workflows/pages.yml +1 -1
- data/CHANGELOG.md +48 -2
- data/Gemfile +2 -0
- data/Gemfile.lock +90 -2
- data/README.md +30 -6
- data/Rakefile +96 -0
- data/doc/agent-tools.md +43 -0
- data/doc/api.md +92 -0
- data/doc/authentication.md +39 -25
- data/doc/configuration.md +1 -15
- data/doc/context-tools.md +70 -0
- data/doc/plugins.md +2 -2
- data/doc/releasing.md +14 -5
- data/doc/rpc.md +3 -11
- data/doc/session-management.md +220 -0
- data/doc/usage.md +7 -8
- data/doc/workspace-tools.md +105 -0
- data/lib/kward/cli/commands.rb +8 -0
- data/lib/kward/cli/openrouter_commands.rb +55 -0
- data/lib/kward/cli/prompt_interface.rb +80 -6
- data/lib/kward/cli/rendering.rb +11 -6
- data/lib/kward/cli/sessions.rb +260 -11
- data/lib/kward/cli/settings.rb +0 -30
- data/lib/kward/cli/slash_commands.rb +24 -6
- data/lib/kward/cli.rb +13 -0
- data/lib/kward/compactor.rb +4 -1
- data/lib/kward/config_files.rb +4 -6
- data/lib/kward/conversation.rb +49 -20
- data/lib/kward/model/client.rb +37 -50
- data/lib/kward/model/context_usage.rb +13 -6
- data/lib/kward/model/model_info.rb +92 -16
- data/lib/kward/model/payloads.rb +2 -0
- data/lib/kward/openrouter_model_cache.rb +120 -0
- data/lib/kward/plugin_registry.rb +47 -1
- data/lib/kward/prompt_interface/banner.rb +16 -51
- data/lib/kward/prompt_interface/composer_controller.rb +60 -87
- data/lib/kward/prompt_interface/composer_renderer.rb +7 -1
- data/lib/kward/prompt_interface/key_handler.rb +31 -10
- data/lib/kward/prompt_interface/layout.rb +2 -2
- data/lib/kward/prompt_interface/prompt_renderer.rb +32 -13
- data/lib/kward/prompt_interface/question_prompt.rb +34 -42
- data/lib/kward/prompt_interface/runtime_state.rb +6 -1
- data/lib/kward/prompt_interface/screen.rb +1 -0
- data/lib/kward/prompt_interface/selection_prompt.rb +513 -54
- data/lib/kward/prompt_interface/transcript_buffer.rb +7 -16
- data/lib/kward/prompt_interface/transcript_renderer.rb +3 -3
- data/lib/kward/prompt_interface.rb +22 -28
- data/lib/kward/prompts/commands.rb +2 -1
- data/lib/kward/prompts.rb +2 -2
- data/lib/kward/rpc/server.rb +3 -8
- data/lib/kward/rpc/session_manager.rb +17 -6
- data/lib/kward/session_store.rb +23 -4
- data/lib/kward/telemetry/logger.rb +5 -3
- data/lib/kward/tool_output_compactor.rb +127 -0
- data/lib/kward/tools/base.rb +8 -2
- data/lib/kward/tools/registry.rb +37 -6
- data/lib/kward/tools/retrieve_tool_output.rb +71 -0
- data/lib/kward/tools/search/web.rb +2 -2
- data/lib/kward/tools/summarize_file_structure.rb +29 -0
- data/lib/kward/tools/tool_call.rb +2 -0
- data/lib/kward/version.rb +1 -1
- data/lib/kward/workspace.rb +58 -2
- data/templates/default/fulldoc/html/css/kward.css +256 -7
- data/templates/default/fulldoc/html/full_list.erb +107 -0
- data/templates/default/fulldoc/html/js/kward.js +161 -2
- data/templates/default/fulldoc/html/setup.rb +8 -0
- data/templates/default/kward_navigation.rb +91 -0
- data/templates/default/layout/html/layout.erb +39 -8
- data/templates/default/layout/html/setup.rb +33 -38
- metadata +13 -3
- data/lib/kward/resources/avatar_kward_logo.rb +0 -50
- data/lib/kward/resources/pixel_logo.rb +0 -232
|
@@ -5,17 +5,90 @@ const guideLinks = {
|
|
|
5
5
|
'doc/configuration.md': 'file.configuration.html',
|
|
6
6
|
'doc/authentication.md': 'file.authentication.html',
|
|
7
7
|
'doc/troubleshooting.md': 'file.troubleshooting.html',
|
|
8
|
+
'doc/session-management.md': 'file.session-management.html',
|
|
8
9
|
'doc/memory.md': 'file.memory.html',
|
|
9
10
|
'doc/personas.md': 'file.personas.html',
|
|
10
11
|
'doc/extensibility.md': 'file.extensibility.html',
|
|
11
12
|
'doc/plugins.md': 'file.plugins.html',
|
|
13
|
+
'doc/agent-tools.md': 'file.agent-tools.html',
|
|
14
|
+
'doc/workspace-tools.md': 'file.workspace-tools.html',
|
|
12
15
|
'doc/web-search.md': 'file.web-search.html',
|
|
13
16
|
'doc/code-search.md': 'file.code-search.html',
|
|
17
|
+
'doc/context-tools.md': 'file.context-tools.html',
|
|
14
18
|
'doc/rpc.md': 'file.rpc.html',
|
|
15
19
|
'doc/releasing.md': 'file.releasing.html'
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
let pageController = null
|
|
23
|
+
let navigating = false
|
|
24
|
+
|
|
25
|
+
const scrollToCurrentHash = () => {
|
|
26
|
+
if (!window.location.hash) {
|
|
27
|
+
window.scrollTo({ top: 0 })
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const id = decodeURIComponent(window.location.hash.slice(1))
|
|
32
|
+
const target = document.getElementById(id) || document.getElementsByName(id)[0]
|
|
33
|
+
if (target) target.scrollIntoView()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const replacePage = async (url, pushState = true) => {
|
|
37
|
+
if (navigating) return
|
|
38
|
+
navigating = true
|
|
39
|
+
document.documentElement.classList.add('kward-navigating')
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(url, { headers: { 'X-Requested-With': 'Kward-Docs' } })
|
|
43
|
+
if (!response.ok) throw new Error(`Navigation failed with ${response.status}`)
|
|
44
|
+
|
|
45
|
+
const html = await response.text()
|
|
46
|
+
const nextDocument = new DOMParser().parseFromString(html, 'text/html')
|
|
47
|
+
if (!nextDocument.body) throw new Error('Navigation response did not include a body')
|
|
48
|
+
|
|
49
|
+
document.title = nextDocument.title
|
|
50
|
+
document.body.className = nextDocument.body.className
|
|
51
|
+
document.body.innerHTML = nextDocument.body.innerHTML
|
|
52
|
+
|
|
53
|
+
if (pushState) window.history.pushState({ kwardDocs: true }, '', url)
|
|
54
|
+
initializePage()
|
|
55
|
+
scrollToCurrentHash()
|
|
56
|
+
} catch (_error) {
|
|
57
|
+
window.location.href = url
|
|
58
|
+
} finally {
|
|
59
|
+
navigating = false
|
|
60
|
+
document.documentElement.classList.remove('kward-navigating')
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const isNavigableLink = (event, link) => {
|
|
65
|
+
if (event.defaultPrevented || event.button !== 0) return false
|
|
66
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false
|
|
67
|
+
if (link.target && link.target !== '_self') return false
|
|
68
|
+
if (link.download || link.dataset.noTurbo) return false
|
|
69
|
+
|
|
70
|
+
const url = new URL(link.href, window.location.href)
|
|
71
|
+
if (url.origin !== window.location.origin) return false
|
|
72
|
+
if (url.pathname === window.location.pathname && url.search === window.location.search) return false
|
|
73
|
+
|
|
74
|
+
return url.pathname === '/' || url.pathname.endsWith('/') || url.pathname.endsWith('.html')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const visitLink = (link) => replacePage(link.href)
|
|
78
|
+
|
|
79
|
+
const setupTurbolinks = (signal) => {
|
|
80
|
+
document.addEventListener('click', (event) => {
|
|
81
|
+
const link = event.target.closest('a[href]')
|
|
82
|
+
if (!link || !isNavigableLink(event, link)) return
|
|
83
|
+
|
|
84
|
+
event.preventDefault()
|
|
85
|
+
visitLink(link)
|
|
86
|
+
}, { signal })
|
|
87
|
+
|
|
88
|
+
window.addEventListener('popstate', () => {
|
|
89
|
+
replacePage(window.location.href, false)
|
|
90
|
+
}, { signal })
|
|
91
|
+
}
|
|
19
92
|
|
|
20
93
|
const setupGuideSearch = (signal) => {
|
|
21
94
|
const form = document.querySelector('.kward-guide-search')
|
|
@@ -151,7 +224,7 @@ const setupGuideSearch = (signal) => {
|
|
|
151
224
|
} else if (event.key === 'Enter') {
|
|
152
225
|
if (selectedIndex >= 0 && items[selectedIndex]) {
|
|
153
226
|
event.preventDefault()
|
|
154
|
-
|
|
227
|
+
visitLink(items[selectedIndex])
|
|
155
228
|
}
|
|
156
229
|
}
|
|
157
230
|
}, { signal })
|
|
@@ -159,7 +232,7 @@ const setupGuideSearch = (signal) => {
|
|
|
159
232
|
form.addEventListener('submit', (event) => {
|
|
160
233
|
event.preventDefault()
|
|
161
234
|
const firstResult = results.querySelector('a')
|
|
162
|
-
if (firstResult)
|
|
235
|
+
if (firstResult) visitLink(firstResult)
|
|
163
236
|
}, { signal })
|
|
164
237
|
|
|
165
238
|
document.addEventListener('click', (event) => {
|
|
@@ -252,6 +325,90 @@ const rewriteGuideLinks = () => {
|
|
|
252
325
|
})
|
|
253
326
|
}
|
|
254
327
|
|
|
328
|
+
const setupTableOfContents = () => {
|
|
329
|
+
const existingToc = document.getElementById('toc')
|
|
330
|
+
if (document.querySelector('.kward-no-toc')) {
|
|
331
|
+
if (existingToc) existingToc.remove()
|
|
332
|
+
return
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const fileContents = document.getElementById('filecontents')
|
|
336
|
+
const content = document.getElementById('content')
|
|
337
|
+
if (!fileContents || !content || content.querySelector('#toc')) return
|
|
338
|
+
|
|
339
|
+
const headingTags = ['h2', 'h3', 'h4', 'h5', 'h6']
|
|
340
|
+
if (fileContents.querySelectorAll('h1').length > 1) headingTags.unshift('h1')
|
|
341
|
+
|
|
342
|
+
const headings = Array.from(fileContents.querySelectorAll(headingTags.join(', ')))
|
|
343
|
+
.filter((heading) => !heading.closest('.method_details .docstring') && heading.id !== 'filecontents')
|
|
344
|
+
if (headings.length === 0) return
|
|
345
|
+
|
|
346
|
+
const topLevel = document.createElement('ol')
|
|
347
|
+
topLevel.className = 'top'
|
|
348
|
+
|
|
349
|
+
let currentList = topLevel
|
|
350
|
+
let currentItem = null
|
|
351
|
+
let counter = 0
|
|
352
|
+
let lastLevel = parseInt(headingTags[0].slice(1), 10)
|
|
353
|
+
|
|
354
|
+
headings.forEach((heading) => {
|
|
355
|
+
const level = parseInt(heading.tagName.slice(1), 10)
|
|
356
|
+
|
|
357
|
+
if (!heading.id) {
|
|
358
|
+
let proposedId = heading.getAttribute('toc-id')
|
|
359
|
+
if (!proposedId) {
|
|
360
|
+
proposedId = heading.textContent.replace(/[^a-z0-9-]/gi, '_')
|
|
361
|
+
if (document.getElementById(proposedId)) {
|
|
362
|
+
proposedId += counter
|
|
363
|
+
counter += 1
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
heading.id = proposedId
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (level > lastLevel) {
|
|
370
|
+
while (level > lastLevel) {
|
|
371
|
+
if (!currentItem) {
|
|
372
|
+
currentItem = document.createElement('li')
|
|
373
|
+
currentList.appendChild(currentItem)
|
|
374
|
+
}
|
|
375
|
+
const nestedList = document.createElement('ol')
|
|
376
|
+
currentItem.appendChild(nestedList)
|
|
377
|
+
currentList = nestedList
|
|
378
|
+
currentItem = null
|
|
379
|
+
lastLevel += 1
|
|
380
|
+
}
|
|
381
|
+
} else if (level < lastLevel) {
|
|
382
|
+
while (level < lastLevel && currentList.parentElement) {
|
|
383
|
+
currentList = currentList.parentElement.parentElement
|
|
384
|
+
lastLevel -= 1
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const title = heading.getAttribute('toc-title') || heading.textContent
|
|
389
|
+
const item = document.createElement('li')
|
|
390
|
+
const link = document.createElement('a')
|
|
391
|
+
link.href = `#${heading.id}`
|
|
392
|
+
link.textContent = title
|
|
393
|
+
item.appendChild(link)
|
|
394
|
+
currentList.appendChild(item)
|
|
395
|
+
currentItem = item
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
const toc = document.createElement('div')
|
|
399
|
+
toc.id = 'toc'
|
|
400
|
+
toc.innerHTML = '<p class="title hide_toc"><a href="#"><strong>Table of Contents</strong></a></p>'
|
|
401
|
+
toc.appendChild(topLevel)
|
|
402
|
+
content.insertBefore(toc, content.firstChild)
|
|
403
|
+
|
|
404
|
+
const hideLink = toc.querySelector('.hide_toc')
|
|
405
|
+
hideLink.addEventListener('click', (event) => {
|
|
406
|
+
event.preventDefault()
|
|
407
|
+
const hidden = toc.classList.toggle('hidden')
|
|
408
|
+
topLevel.style.display = hidden ? 'none' : ''
|
|
409
|
+
})
|
|
410
|
+
}
|
|
411
|
+
|
|
255
412
|
const setupCodeCopy = () => {
|
|
256
413
|
document.querySelectorAll('pre').forEach((block) => {
|
|
257
414
|
if (block.closest('.code-copy-wrapper')) return
|
|
@@ -285,9 +442,11 @@ const initializePage = () => {
|
|
|
285
442
|
if (pageController) pageController.abort()
|
|
286
443
|
pageController = new AbortController()
|
|
287
444
|
|
|
445
|
+
setupTurbolinks(pageController.signal)
|
|
288
446
|
setupGuideSearch(pageController.signal)
|
|
289
447
|
setupNavigation(pageController.signal)
|
|
290
448
|
rewriteGuideLinks()
|
|
449
|
+
setupTableOfContents()
|
|
291
450
|
setupCodeCopy()
|
|
292
451
|
}
|
|
293
452
|
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../../kward_navigation"
|
|
4
|
+
|
|
5
|
+
include KwardDocsNavigationData
|
|
6
|
+
|
|
3
7
|
def generate_assets
|
|
4
8
|
super
|
|
5
9
|
asset('css/kward.css', file('css/kward.css', true))
|
|
6
10
|
asset('js/kward.js', file('js/kward.js', true))
|
|
7
11
|
asset('images/kward_logo.png', file('images/kward_logo.png', true))
|
|
8
12
|
end
|
|
13
|
+
|
|
14
|
+
def stylesheets_full_list
|
|
15
|
+
super + %w(css/kward.css)
|
|
16
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KwardDocsNavigationData
|
|
4
|
+
GUIDE_GROUPS = [
|
|
5
|
+
[
|
|
6
|
+
"Start here",
|
|
7
|
+
[
|
|
8
|
+
["Getting started", "file.getting-started.html"],
|
|
9
|
+
["Usage", "file.usage.html"],
|
|
10
|
+
["Configuration", "file.configuration.html"],
|
|
11
|
+
["Authentication", "file.authentication.html"],
|
|
12
|
+
["Troubleshooting", "file.troubleshooting.html"]
|
|
13
|
+
]
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
"Feature guides",
|
|
17
|
+
[
|
|
18
|
+
["Sessions", "file.session-management.html"],
|
|
19
|
+
["Memory", "file.memory.html"],
|
|
20
|
+
["Personas", "file.personas.html"]
|
|
21
|
+
]
|
|
22
|
+
]
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
EXTENSION_GROUPS = [
|
|
26
|
+
[
|
|
27
|
+
"Customize",
|
|
28
|
+
[
|
|
29
|
+
["Extensibility", "file.extensibility.html"],
|
|
30
|
+
["Plugins", "file.plugins.html"]
|
|
31
|
+
]
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
"Integrate",
|
|
35
|
+
[
|
|
36
|
+
["RPC protocol", "file.rpc.html"],
|
|
37
|
+
["Releasing", "file.releasing.html"]
|
|
38
|
+
]
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
"Agent tools",
|
|
42
|
+
[
|
|
43
|
+
["Overview", "file.agent-tools.html"],
|
|
44
|
+
["Workspace tools", "file.workspace-tools.html"],
|
|
45
|
+
["Web search", "file.web-search.html"],
|
|
46
|
+
["Code search", "file.code-search.html"],
|
|
47
|
+
["Context tools", "file.context-tools.html"]
|
|
48
|
+
]
|
|
49
|
+
]
|
|
50
|
+
].freeze
|
|
51
|
+
|
|
52
|
+
API_OVERVIEW = "file.api.html"
|
|
53
|
+
API_GROUPS = [
|
|
54
|
+
[
|
|
55
|
+
"Reference",
|
|
56
|
+
[
|
|
57
|
+
["Overview", API_OVERVIEW],
|
|
58
|
+
["Classes & Modules", "class_list.html"],
|
|
59
|
+
["Methods", "method_list.html"],
|
|
60
|
+
["Files", "file_list.html"]
|
|
61
|
+
]
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
"Key namespaces",
|
|
65
|
+
[
|
|
66
|
+
["Kward", "Kward.html"],
|
|
67
|
+
["Tools", "Kward/Tools.html"],
|
|
68
|
+
["RPC", "Kward/RPC.html"],
|
|
69
|
+
["CLI", "Kward/CLI.html"],
|
|
70
|
+
["Prompts", "Kward/Prompts.html"],
|
|
71
|
+
["Skills", "Kward/Skills.html"]
|
|
72
|
+
]
|
|
73
|
+
]
|
|
74
|
+
].freeze
|
|
75
|
+
|
|
76
|
+
def guide_groups
|
|
77
|
+
GUIDE_GROUPS
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def extension_groups
|
|
81
|
+
EXTENSION_GROUPS
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def api_groups
|
|
85
|
+
API_GROUPS
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def api_overview
|
|
89
|
+
API_OVERVIEW
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
<nav id="kward-primary-nav" class="kward-topnav" aria-label="Primary navigation">
|
|
23
23
|
<a href="<%= url_for('index.html') %>" class="<%= 'active' if home_page? %>">Home</a>
|
|
24
24
|
<div class="kward-nav-menu <%= 'active' if guide_page? %>">
|
|
25
|
-
<a class="kward-nav-menu-link" href="<%= url_for(
|
|
26
|
-
<button class="kward-nav-menu-button" type="button" aria-label="Expand
|
|
25
|
+
<a class="kward-nav-menu-link" href="<%= url_for(guide_overview) %>">Guides</a>
|
|
26
|
+
<button class="kward-nav-menu-button" type="button" aria-label="Expand guides" aria-expanded="false">⌄</button>
|
|
27
27
|
<div class="kward-nav-dropdown">
|
|
28
28
|
<% guide_groups.each do |title, items| %>
|
|
29
29
|
<section>
|
|
@@ -35,13 +35,44 @@
|
|
|
35
35
|
<% end %>
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
38
|
-
<
|
|
38
|
+
<div class="kward-nav-menu <%= 'active' if extension_page? %>">
|
|
39
|
+
<a class="kward-nav-menu-link" href="<%= url_for(extension_overview) %>">Advanced</a>
|
|
40
|
+
<button class="kward-nav-menu-button" type="button" aria-label="Expand advanced guides" aria-expanded="false">⌄</button>
|
|
41
|
+
<div class="kward-nav-dropdown kward-advanced-nav-dropdown">
|
|
42
|
+
<% extension_groups.each do |title, items| %>
|
|
43
|
+
<section>
|
|
44
|
+
<h2><%= h title %></h2>
|
|
45
|
+
<% items.each do |label, link| %>
|
|
46
|
+
<a href="<%= url_for(link) %>"><%= h label %></a>
|
|
47
|
+
<% end %>
|
|
48
|
+
</section>
|
|
49
|
+
<% end %>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="kward-nav-menu <%= 'active' if api_page? %>">
|
|
53
|
+
<a class="kward-nav-menu-link" href="<%= url_for(api_overview) %>">API Docs</a>
|
|
54
|
+
<button class="kward-nav-menu-button" type="button" aria-label="Expand API docs" aria-expanded="false">⌄</button>
|
|
55
|
+
<div class="kward-nav-dropdown kward-api-nav-dropdown">
|
|
56
|
+
<% api_groups.each do |title, items| %>
|
|
57
|
+
<section>
|
|
58
|
+
<h2><%= h title %></h2>
|
|
59
|
+
<% items.each do |label, link| %>
|
|
60
|
+
<a href="<%= url_for(link) %>"><%= h label %></a>
|
|
61
|
+
<% end %>
|
|
62
|
+
</section>
|
|
63
|
+
<% end %>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
39
66
|
</nav>
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
67
|
+
<% if api_page? %>
|
|
68
|
+
<a class="kward-api-index-link" href="<%= url_for('class_list.html') %>">Search API index</a>
|
|
69
|
+
<% else %>
|
|
70
|
+
<form class="kward-guide-search" role="search">
|
|
71
|
+
<label class="kward-sr-only" for="kward-guide-search-input">Search user guides</label>
|
|
72
|
+
<input id="kward-guide-search-input" type="search" placeholder="Search guides" autocomplete="off" aria-label="Search user guides" aria-controls="kward-guide-search-results">
|
|
73
|
+
<div id="kward-guide-search-results" class="kward-guide-search-results" role="listbox" aria-label="Search results"></div>
|
|
74
|
+
</form>
|
|
75
|
+
<% end %>
|
|
45
76
|
<script type="application/json" id="kward-guide-search-index"><%= guide_search_index_json %></script>
|
|
46
77
|
</header>
|
|
47
78
|
|
|
@@ -1,44 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "json"
|
|
4
|
+
require_relative "../../kward_navigation"
|
|
4
5
|
|
|
5
6
|
module KwardDocsNavigation
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
["Troubleshooting", "file.troubleshooting.html"]
|
|
15
|
-
]
|
|
16
|
-
],
|
|
17
|
-
[
|
|
18
|
-
"Feature guides",
|
|
19
|
-
[
|
|
20
|
-
["Memory", "file.memory.html"],
|
|
21
|
-
["Personas", "file.personas.html"],
|
|
22
|
-
["Extensibility", "file.extensibility.html"],
|
|
23
|
-
["Plugins", "file.plugins.html"],
|
|
24
|
-
["Web search", "file.web-search.html"],
|
|
25
|
-
["Code search", "file.code-search.html"]
|
|
26
|
-
]
|
|
27
|
-
],
|
|
28
|
-
[
|
|
29
|
-
"Advanced/reference",
|
|
30
|
-
[
|
|
31
|
-
["RPC protocol", "file.rpc.html"],
|
|
32
|
-
["Releasing", "file.releasing.html"]
|
|
33
|
-
]
|
|
34
|
-
]
|
|
35
|
-
].freeze
|
|
7
|
+
include KwardDocsNavigationData
|
|
8
|
+
API_FILE_LINKS = {
|
|
9
|
+
"doc/api.md" => API_OVERVIEW
|
|
10
|
+
}.freeze
|
|
11
|
+
API_LINKS = ([API_OVERVIEW] + API_GROUPS.flat_map { |_title, items| items.map(&:last) }).freeze
|
|
12
|
+
|
|
13
|
+
EXTENSION_OVERVIEW = "file.extensibility.html"
|
|
14
|
+
EXTENSION_LINKS = ([EXTENSION_OVERVIEW] + EXTENSION_GROUPS.flat_map { |_title, items| items.map(&:last) }).uniq.freeze
|
|
36
15
|
|
|
37
16
|
GUIDE_OVERVIEW = "file.README.html"
|
|
38
17
|
GUIDE_LINKS = ([GUIDE_OVERVIEW] + GUIDE_GROUPS.flat_map { |_title, items| items.map(&:last) }).freeze
|
|
39
18
|
GUIDE_SEARCH_FILES = [
|
|
40
19
|
["Overview", "README.md", GUIDE_OVERVIEW],
|
|
41
|
-
*GUIDE_GROUPS.flat_map do |_title, items|
|
|
20
|
+
*(GUIDE_GROUPS + EXTENSION_GROUPS).flat_map do |_title, items|
|
|
42
21
|
items.map do |label, link|
|
|
43
22
|
source = "doc/#{link.delete_prefix("file.").delete_suffix(".html")}.md"
|
|
44
23
|
[label, source, link]
|
|
@@ -51,24 +30,28 @@ module KwardDocsNavigation
|
|
|
51
30
|
"doc/configuration.md" => "file.configuration.html",
|
|
52
31
|
"doc/authentication.md" => "file.authentication.html",
|
|
53
32
|
"doc/troubleshooting.md" => "file.troubleshooting.html",
|
|
33
|
+
"doc/session-management.md" => "file.session-management.html",
|
|
54
34
|
"doc/memory.md" => "file.memory.html",
|
|
55
35
|
"doc/personas.md" => "file.personas.html",
|
|
56
36
|
"doc/extensibility.md" => "file.extensibility.html",
|
|
57
37
|
"doc/plugins.md" => "file.plugins.html",
|
|
38
|
+
"doc/agent-tools.md" => "file.agent-tools.html",
|
|
39
|
+
"doc/workspace-tools.md" => "file.workspace-tools.html",
|
|
58
40
|
"doc/web-search.md" => "file.web-search.html",
|
|
59
41
|
"doc/code-search.md" => "file.code-search.html",
|
|
42
|
+
"doc/context-tools.md" => "file.context-tools.html",
|
|
60
43
|
"doc/rpc.md" => "file.rpc.html",
|
|
61
44
|
"doc/releasing.md" => "file.releasing.html"
|
|
62
45
|
}.freeze
|
|
63
46
|
|
|
64
|
-
def guide_groups
|
|
65
|
-
GUIDE_GROUPS
|
|
66
|
-
end
|
|
67
|
-
|
|
68
47
|
def guide_overview
|
|
69
48
|
GUIDE_OVERVIEW
|
|
70
49
|
end
|
|
71
50
|
|
|
51
|
+
def extension_overview
|
|
52
|
+
EXTENSION_OVERVIEW
|
|
53
|
+
end
|
|
54
|
+
|
|
72
55
|
def guide_search_index_json
|
|
73
56
|
JSON.generate(guide_search_index).gsub("</", "<\\/")
|
|
74
57
|
end
|
|
@@ -99,7 +82,15 @@ module KwardDocsNavigation
|
|
|
99
82
|
end
|
|
100
83
|
|
|
101
84
|
def guide_file?
|
|
102
|
-
defined?(@file) &&
|
|
85
|
+
defined?(@file) && GUIDE_LINKS.include?(GUIDE_FILE_LINKS[@file&.filename.to_s])
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def extension_file?
|
|
89
|
+
defined?(@file) && EXTENSION_LINKS.include?(GUIDE_FILE_LINKS[@file&.filename.to_s])
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def api_file?
|
|
93
|
+
defined?(@file) && API_FILE_LINKS.key?(@file&.filename.to_s)
|
|
103
94
|
end
|
|
104
95
|
|
|
105
96
|
def home_page?
|
|
@@ -110,8 +101,12 @@ module KwardDocsNavigation
|
|
|
110
101
|
(readme_file? && !options.index) || guide_file? || GUIDE_LINKS.include?(current_docs_path)
|
|
111
102
|
end
|
|
112
103
|
|
|
104
|
+
def extension_page?
|
|
105
|
+
extension_file? || EXTENSION_LINKS.include?(current_docs_path)
|
|
106
|
+
end
|
|
107
|
+
|
|
113
108
|
def api_page?
|
|
114
|
-
!home_page? && !guide_page?
|
|
109
|
+
api_file? || API_LINKS.include?(current_docs_path) || (!home_page? && !guide_page? && !extension_page?)
|
|
115
110
|
end
|
|
116
111
|
|
|
117
112
|
def diskfile
|
|
@@ -121,7 +116,7 @@ module KwardDocsNavigation
|
|
|
121
116
|
end
|
|
122
117
|
|
|
123
118
|
def rewrite_guide_links(html)
|
|
124
|
-
GUIDE_FILE_LINKS.each do |source, target|
|
|
119
|
+
GUIDE_FILE_LINKS.merge(API_FILE_LINKS).each do |source, target|
|
|
125
120
|
html = html.gsub(%(href="#{source}"), %(href="#{target}"))
|
|
126
121
|
end
|
|
127
122
|
html
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kward
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.71.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kai Wood
|
|
@@ -124,9 +124,12 @@ files:
|
|
|
124
124
|
- LICENSE
|
|
125
125
|
- README.md
|
|
126
126
|
- Rakefile
|
|
127
|
+
- doc/agent-tools.md
|
|
128
|
+
- doc/api.md
|
|
127
129
|
- doc/authentication.md
|
|
128
130
|
- doc/code-search.md
|
|
129
131
|
- doc/configuration.md
|
|
132
|
+
- doc/context-tools.md
|
|
130
133
|
- doc/extensibility.md
|
|
131
134
|
- doc/getting-started.md
|
|
132
135
|
- doc/memory.md
|
|
@@ -134,9 +137,11 @@ files:
|
|
|
134
137
|
- doc/plugins.md
|
|
135
138
|
- doc/releasing.md
|
|
136
139
|
- doc/rpc.md
|
|
140
|
+
- doc/session-management.md
|
|
137
141
|
- doc/troubleshooting.md
|
|
138
142
|
- doc/usage.md
|
|
139
143
|
- doc/web-search.md
|
|
144
|
+
- doc/workspace-tools.md
|
|
140
145
|
- exe/kward
|
|
141
146
|
- kward.gemspec
|
|
142
147
|
- lib/kward.rb
|
|
@@ -155,6 +160,7 @@ files:
|
|
|
155
160
|
- lib/kward/cli/doctor.rb
|
|
156
161
|
- lib/kward/cli/interactive_turn.rb
|
|
157
162
|
- lib/kward/cli/memory_commands.rb
|
|
163
|
+
- lib/kward/cli/openrouter_commands.rb
|
|
158
164
|
- lib/kward/cli/plugins.rb
|
|
159
165
|
- lib/kward/cli/prompt_interface.rb
|
|
160
166
|
- lib/kward/cli/rendering.rb
|
|
@@ -186,6 +192,7 @@ files:
|
|
|
186
192
|
- lib/kward/model/payloads.rb
|
|
187
193
|
- lib/kward/model/retry_message.rb
|
|
188
194
|
- lib/kward/model/stream_parser.rb
|
|
195
|
+
- lib/kward/openrouter_model_cache.rb
|
|
189
196
|
- lib/kward/pan/index.html.erb
|
|
190
197
|
- lib/kward/pan/server.rb
|
|
191
198
|
- lib/kward/plugin_registry.rb
|
|
@@ -211,8 +218,6 @@ files:
|
|
|
211
218
|
- lib/kward/prompts/commands.rb
|
|
212
219
|
- lib/kward/prompts/templates.rb
|
|
213
220
|
- lib/kward/question_contract.rb
|
|
214
|
-
- lib/kward/resources/avatar_kward_logo.rb
|
|
215
|
-
- lib/kward/resources/pixel_logo.rb
|
|
216
221
|
- lib/kward/rpc/attachment_normalizer.rb
|
|
217
222
|
- lib/kward/rpc/auth_manager.rb
|
|
218
223
|
- lib/kward/rpc/config_manager.rb
|
|
@@ -238,6 +243,7 @@ files:
|
|
|
238
243
|
- lib/kward/steering.rb
|
|
239
244
|
- lib/kward/telemetry/logger.rb
|
|
240
245
|
- lib/kward/telemetry/stats.rb
|
|
246
|
+
- lib/kward/tool_output_compactor.rb
|
|
241
247
|
- lib/kward/tools/ask_user_question.rb
|
|
242
248
|
- lib/kward/tools/base.rb
|
|
243
249
|
- lib/kward/tools/code_search.rb
|
|
@@ -248,10 +254,12 @@ files:
|
|
|
248
254
|
- lib/kward/tools/read_file.rb
|
|
249
255
|
- lib/kward/tools/read_skill.rb
|
|
250
256
|
- lib/kward/tools/registry.rb
|
|
257
|
+
- lib/kward/tools/retrieve_tool_output.rb
|
|
251
258
|
- lib/kward/tools/run_shell_command.rb
|
|
252
259
|
- lib/kward/tools/search/code.rb
|
|
253
260
|
- lib/kward/tools/search/web.rb
|
|
254
261
|
- lib/kward/tools/search/web_fetch.rb
|
|
262
|
+
- lib/kward/tools/summarize_file_structure.rb
|
|
255
263
|
- lib/kward/tools/tool_call.rb
|
|
256
264
|
- lib/kward/tools/web_search.rb
|
|
257
265
|
- lib/kward/tools/write_file.rb
|
|
@@ -260,9 +268,11 @@ files:
|
|
|
260
268
|
- lib/kward/workspace.rb
|
|
261
269
|
- lib/main.rb
|
|
262
270
|
- templates/default/fulldoc/html/css/kward.css
|
|
271
|
+
- templates/default/fulldoc/html/full_list.erb
|
|
263
272
|
- templates/default/fulldoc/html/images/kward_logo.png
|
|
264
273
|
- templates/default/fulldoc/html/js/kward.js
|
|
265
274
|
- templates/default/fulldoc/html/setup.rb
|
|
275
|
+
- templates/default/kward_navigation.rb
|
|
266
276
|
- templates/default/layout/html/breadcrumb.erb
|
|
267
277
|
- templates/default/layout/html/layout.erb
|
|
268
278
|
- templates/default/layout/html/setup.rb
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Generated from avatar_kward_32x32.png as RGB terminal cells.
|
|
2
|
-
# The interactive banner uses this data instead of decoding a PNG at runtime.
|
|
3
|
-
module Kward
|
|
4
|
-
# Static avatar logo data used by generated resources.
|
|
5
|
-
module Resources
|
|
6
|
-
# Static avatar logo data used by generated resources.
|
|
7
|
-
module AvatarKwardLogo
|
|
8
|
-
PIXELS = [
|
|
9
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
10
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, [36, 40, 24], [39, 42, 25], [39, 42, 25], [33, 36, 21], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
11
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, [33, 36, 23], [78, 86, 52], [85, 93, 56], [84, 93, 55], [65, 72, 43], [31, 33, 19], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
12
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, [49, 54, 33], [78, 86, 52], [85, 93, 56], [85, 93, 56], [85, 93, 56], [84, 93, 55], [75, 83, 49], [35, 38, 23], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
13
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, [61, 68, 40], [80, 88, 53], [85, 93, 56], [75, 83, 49], [72, 80, 48], [70, 78, 46], [78, 86, 52], [84, 93, 55], [76, 85, 51], [50, 55, 34], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
14
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, [42, 46, 27], [80, 88, 53], [84, 93, 55], [70, 78, 46], [23, 25, 15], [37, 38, 29], [34, 35, 26], [33, 37, 22], [74, 81, 48], [83, 92, 55], [78, 86, 52], [24, 26, 15], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
15
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, [34, 37, 22], [83, 92, 55], [85, 93, 56], [69, 77, 46], [18, 19, 12], [53, 53, 45], [135, 132, 115], [128, 125, 111], [40, 40, 36], [21, 23, 14], [72, 80, 48], [80, 88, 53], [39, 44, 26], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
16
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, [18, 20, 13], [58, 63, 38], [85, 93, 56], [55, 61, 36], [23, 25, 15], [43, 42, 35], [146, 142, 129], [176, 173, 156], [179, 175, 159], [146, 142, 129], [67, 65, 58], [27, 30, 19], [62, 68, 41], [80, 88, 53], [54, 60, 35], nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
17
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, [23, 26, 16], [74, 81, 48], [69, 77, 46], [21, 23, 14], [31, 31, 25], [108, 105, 91], [153, 150, 134], [134, 132, 118], [173, 169, 154], [183, 179, 163], [134, 132, 118], [27, 26, 21], [25, 28, 16], [70, 78, 46], [72, 80, 48], [21, 23, 14], nil, nil, nil, nil, nil, nil, nil, nil],
|
|
18
|
-
[nil, nil, nil, nil, nil, nil, nil, [8, 10, 6], [66, 73, 45], [58, 63, 37], [14, 15, 9], [3, 3, 2], [87, 85, 74], [160, 157, 139], [160, 157, 139], [134, 132, 118], [80, 78, 69], [173, 169, 154], [175, 171, 155], [76, 74, 65], [5, 5, 4], [14, 15, 9], [63, 70, 42], [66, 73, 45], [2, 3, 2], nil, nil, nil, nil, nil, nil, nil],
|
|
19
|
-
[nil, nil, nil, nil, nil, nil, nil, [18, 19, 12], [59, 65, 40], [23, 23, 21], [0, 0, 0], [100, 98, 86], [160, 157, 139], [163, 160, 143], [138, 136, 121], [70, 68, 58], [173, 169, 154], [175, 171, 155], [183, 179, 163], [179, 175, 159], [92, 90, 82], [1, 1, 1], [27, 30, 19], [62, 68, 41], [16, 17, 11], nil, nil, nil, nil, nil, nil, nil],
|
|
20
|
-
[nil, nil, nil, nil, nil, nil, [15, 15, 11], [62, 68, 42], [72, 70, 61], [87, 85, 74], [44, 43, 36], [77, 76, 65], [108, 105, 91], [149, 146, 130], [123, 119, 105], [158, 155, 140], [168, 164, 149], [144, 140, 126], [160, 156, 142], [118, 115, 104], [77, 76, 65], [53, 53, 45], [103, 102, 85], [76, 74, 65], [66, 72, 43], [20, 20, 13], nil, nil, nil, nil, nil, nil],
|
|
21
|
-
[nil, nil, nil, nil, nil, nil, [35, 38, 23], [78, 86, 52], [135, 132, 115], [113, 109, 94], [129, 128, 109], [23, 25, 15], [33, 55, 8], [96, 108, 72], [87, 85, 74], [168, 164, 149], [158, 155, 140], [97, 94, 83], [96, 108, 72], [24, 40, 6], [30, 33, 20], [142, 141, 122], [104, 102, 90], [153, 150, 134], [75, 83, 49], [37, 41, 25], nil, nil, nil, nil, nil, nil],
|
|
22
|
-
[nil, nil, nil, nil, nil, [2, 2, 1], [63, 70, 42], [87, 95, 60], [134, 132, 118], [77, 76, 65], [104, 102, 90], [5, 5, 4], [72, 133, 6], [100, 184, 10], [39, 44, 26], [160, 156, 142], [146, 142, 129], [47, 70, 19], [103, 188, 10], [56, 105, 5], [10, 10, 8], [128, 125, 111], [72, 70, 61], [149, 146, 130], [84, 93, 55], [54, 60, 36], [2, 3, 2], nil, nil, nil, nil, nil],
|
|
23
|
-
[nil, nil, nil, nil, nil, [46, 51, 30], [67, 74, 44], [44, 48, 30], [114, 111, 97], [80, 78, 69], [103, 102, 85], [34, 35, 26], [33, 55, 8], [59, 97, 13], [82, 84, 65], [166, 162, 147], [156, 152, 138], [76, 85, 51], [59, 97, 13], [29, 46, 8], [43, 42, 35], [134, 132, 118], [92, 90, 82], [128, 125, 111], [39, 44, 26], [65, 72, 43], [43, 48, 29], nil, nil, nil, nil, nil],
|
|
24
|
-
[nil, nil, nil, nil, [17, 19, 12], [63, 70, 42], [31, 35, 21], [5, 5, 4], [39, 39, 33], [70, 68, 58], [53, 53, 45], [103, 102, 85], [58, 56, 48], [77, 76, 65], [113, 109, 94], [171, 167, 151], [163, 160, 143], [108, 105, 91], [72, 70, 61], [64, 62, 54], [108, 105, 91], [59, 58, 50], [84, 82, 71], [39, 39, 33], [3, 3, 2], [39, 44, 26], [58, 64, 39], nil, nil, nil, nil, nil],
|
|
25
|
-
[nil, nil, nil, [2, 3, 2], [43, 47, 28], [68, 75, 45], [15, 17, 11], [0, 0, 0], [0, 0, 0], [8, 8, 7], [12, 12, 11], [59, 58, 50], [92, 89, 75], [27, 26, 21], [100, 96, 82], [171, 167, 151], [163, 160, 143], [70, 68, 58], [44, 43, 36], [114, 111, 97], [58, 56, 48], [15, 14, 13], [5, 5, 4], [0, 0, 0], [0, 0, 0], [23, 25, 15], [69, 77, 46], [30, 33, 20], nil, nil, nil, nil],
|
|
26
|
-
[nil, nil, nil, [37, 41, 26], [63, 70, 42], [27, 30, 19], [1, 1, 1], [0, 0, 0], [8, 8, 7], [32, 33, 30], [20, 20, 18], [6, 6, 5], [64, 62, 54], [31, 31, 25], [100, 96, 82], [171, 167, 151], [163, 160, 143], [70, 68, 58], [51, 49, 43], [70, 68, 58], [6, 6, 5], [23, 23, 21], [35, 35, 33], [6, 6, 5], [0, 0, 0], [1, 1, 1], [33, 37, 22], [58, 63, 37], [32, 35, 21], nil, nil, nil],
|
|
27
|
-
[nil, nil, nil, [52, 58, 35], [80, 88, 53], [52, 58, 34], [10, 10, 8], [5, 5, 4], [32, 33, 30], [23, 23, 21], [0, 0, 0], [23, 23, 21], [59, 58, 50], [70, 68, 58], [72, 70, 61], [166, 162, 147], [153, 150, 134], [67, 65, 58], [76, 74, 65], [62, 61, 57], [19, 19, 17], [0, 0, 0], [31, 31, 25], [32, 33, 30], [3, 3, 2], [15, 17, 11], [55, 61, 36], [80, 88, 53], [39, 42, 25], nil, nil, nil],
|
|
28
|
-
[nil, nil, nil, [23, 24, 16], [54, 60, 36], [83, 92, 55], [27, 30, 19], [44, 44, 40], [19, 19, 17], [1, 1, 1], [1, 1, 1], [49, 48, 45], [44, 44, 40], [103, 102, 85], [44, 44, 40], [158, 155, 140], [144, 140, 126], [64, 62, 54], [92, 89, 75], [49, 48, 45], [40, 40, 36], [0, 0, 0], [3, 3, 2], [19, 19, 17], [49, 48, 45], [36, 40, 24], [83, 92, 55], [44, 48, 30], [23, 25, 16], nil, nil, nil],
|
|
29
|
-
[nil, nil, nil, [50, 55, 34], [49, 54, 33], [62, 68, 41], [67, 74, 44], [30, 33, 20], [12, 12, 11], [30, 30, 28], [20, 20, 18], [30, 30, 28], [12, 12, 11], [92, 89, 75], [51, 49, 43], [160, 156, 142], [144, 140, 126], [64, 62, 54], [77, 76, 65], [12, 12, 11], [35, 35, 33], [17, 17, 16], [35, 35, 33], [10, 10, 8], [34, 35, 26], [68, 75, 45], [58, 63, 37], [51, 56, 34], [43, 48, 29], nil, nil, nil],
|
|
30
|
-
[nil, nil, [30, 33, 21], [68, 75, 45], [70, 78, 46], [39, 44, 26], [59, 65, 40], [67, 74, 44], [21, 23, 14], [8, 8, 7], [19, 19, 17], [32, 33, 30], [10, 10, 8], [15, 14, 13], [92, 89, 75], [168, 164, 149], [160, 157, 139], [70, 68, 58], [12, 12, 11], [10, 10, 8], [35, 35, 33], [17, 17, 16], [10, 10, 8], [21, 23, 14], [72, 80, 48], [55, 61, 36], [47, 52, 31], [72, 80, 48], [66, 72, 43], [25, 26, 18], nil, nil],
|
|
31
|
-
[nil, nil, [22, 24, 14], [27, 30, 18], [55, 61, 36], [84, 93, 55], [44, 48, 30], [54, 60, 36], [74, 81, 48], [25, 28, 16], [1, 1, 1], [49, 48, 45], [32, 33, 30], [1, 1, 1], [92, 89, 75], [123, 119, 105], [118, 115, 104], [67, 63, 54], [1, 1, 1], [44, 44, 40], [40, 40, 36], [1, 1, 1], [30, 33, 20], [76, 85, 51], [52, 58, 34], [51, 56, 34], [81, 90, 54], [47, 52, 31], [26, 28, 17], nil, nil, nil],
|
|
32
|
-
[nil, [30, 33, 21], [66, 72, 43], [80, 88, 53], [80, 88, 53], [45, 50, 29], [33, 37, 22], [51, 56, 34], [42, 47, 27], [68, 75, 45], [38, 42, 25], [19, 19, 17], [35, 35, 33], [12, 12, 11], [37, 35, 30], [70, 68, 58], [67, 63, 54], [27, 26, 21], [17, 17, 16], [35, 35, 33], [17, 17, 16], [39, 44, 26], [70, 78, 46], [42, 47, 27], [54, 60, 36], [31, 35, 21], [31, 35, 21], [63, 70, 42], [78, 86, 52], [65, 71, 42], nil, nil],
|
|
33
|
-
[nil, [14, 15, 9], [36, 39, 23], [63, 70, 42], [81, 90, 54], [62, 68, 41], [51, 56, 34], [39, 44, 26], [14, 15, 9], [49, 54, 33], [69, 77, 46], [25, 28, 16], [20, 20, 18], [8, 8, 7], [6, 6, 5], [43, 42, 35], [37, 35, 30], [3, 3, 2], [12, 12, 11], [19, 19, 17], [30, 33, 20], [70, 78, 46], [44, 48, 30], [14, 15, 9], [44, 48, 30], [49, 54, 33], [52, 58, 34], [72, 80, 48], [54, 60, 36], [36, 39, 23], [12, 14, 11], nil],
|
|
34
|
-
[nil, [5, 5, 5], nil, [53, 58, 35], [84, 93, 55], [84, 93, 55], [81, 90, 54], [69, 77, 46], [55, 61, 36], [15, 17, 11], [39, 44, 26], [68, 75, 45], [59, 65, 40], [18, 19, 12], [10, 10, 8], [62, 61, 57], [56, 55, 53], [6, 6, 5], [23, 25, 15], [63, 70, 42], [69, 77, 46], [36, 40, 24], [15, 17, 11], [58, 63, 37], [67, 74, 44], [80, 88, 53], [84, 93, 55], [83, 92, 55], [39, 43, 26], nil, [2, 2, 1], nil],
|
|
35
|
-
[nil, nil, nil, [25, 29, 18], [45, 50, 29], [27, 30, 19], [22, 25, 15], [75, 83, 50], [84, 93, 55], [54, 60, 36], [15, 17, 11], [18, 19, 12], [42, 47, 27], [74, 81, 48], [12, 12, 11], [23, 23, 21], [19, 19, 17], [30, 33, 20], [74, 81, 48], [38, 42, 25], [15, 17, 11], [15, 17, 11], [62, 68, 41], [83, 92, 55], [21, 23, 14], [33, 37, 22], [49, 54, 33], [21, 23, 14], nil, nil, nil, [4, 4, 4]],
|
|
36
|
-
[nil, nil, nil, [64, 71, 42], [43, 47, 28], [7, 7, 4], nil, [51, 56, 35], [83, 92, 55], [70, 78, 46], [47, 52, 31], [38, 42, 25], [31, 35, 21], [54, 60, 36], [17, 17, 16], [51, 51, 48], [46, 46, 43], [27, 30, 19], [52, 58, 34], [30, 33, 20], [39, 44, 26], [49, 54, 33], [76, 85, 51], [85, 93, 56], [43, 48, 29], [14, 14, 10], [8, 8, 7], [49, 54, 33], [62, 67, 41], nil, nil, nil],
|
|
37
|
-
[nil, nil, nil, [34, 38, 24], [37, 39, 24], nil, nil, [34, 37, 22], [75, 83, 50], [35, 39, 24], [1, 1, 1], [43, 48, 29], [66, 72, 43], [20, 21, 12], [3, 1, 1], [2, 2, 2], [2, 2, 2], [3, 3, 3], [27, 30, 18], [66, 72, 43], [35, 38, 23], [2, 1, 1], [42, 46, 28], [76, 85, 51], [5, 5, 4], nil, [2, 3, 2], [36, 40, 24], [22, 25, 15], nil, nil, nil],
|
|
38
|
-
[nil, nil, nil, nil, nil, nil, [14, 15, 10], [67, 74, 44], [29, 32, 19], nil, nil, nil, [25, 29, 18], nil, nil, nil, nil, nil, nil, [23, 25, 16], nil, nil, nil, [29, 32, 19], [52, 58, 35], nil, nil, nil, nil, nil, nil, nil],
|
|
39
|
-
[nil, nil, nil, nil, nil, nil, nil, [22, 24, 15], nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, [23, 26, 16], nil, nil, nil, nil, nil, nil, nil],
|
|
40
|
-
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
PIXELS.each do |row|
|
|
44
|
-
row.each { |color| color.freeze if color }
|
|
45
|
-
row.freeze
|
|
46
|
-
end
|
|
47
|
-
PIXELS.freeze
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|