ukiryu 0.1.0 → 0.1.1
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/docs.yml +63 -0
- data/.github/workflows/links.yml +99 -0
- data/.github/workflows/rake.yml +19 -0
- data/.github/workflows/release.yml +27 -0
- data/.gitignore +18 -4
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +213 -0
- data/Gemfile +12 -8
- data/README.adoc +613 -0
- data/Rakefile +2 -2
- data/docs/assets/logo.svg +1 -0
- data/exe/ukiryu +11 -0
- data/lib/ukiryu/action/base.rb +77 -0
- data/lib/ukiryu/cache.rb +199 -0
- data/lib/ukiryu/cli.rb +133 -307
- data/lib/ukiryu/cli_commands/base_command.rb +155 -0
- data/lib/ukiryu/cli_commands/commands_command.rb +120 -0
- data/lib/ukiryu/cli_commands/commands_command.rb.fixed +40 -0
- data/lib/ukiryu/cli_commands/config_command.rb +249 -0
- data/lib/ukiryu/cli_commands/describe_command.rb +326 -0
- data/lib/ukiryu/cli_commands/describe_command.rb.fixed +254 -0
- data/lib/ukiryu/cli_commands/exec_inline_command.rb.fixed +180 -0
- data/lib/ukiryu/cli_commands/extract_command.rb +84 -0
- data/lib/ukiryu/cli_commands/info_command.rb +156 -0
- data/lib/ukiryu/cli_commands/list_command.rb +70 -0
- data/lib/ukiryu/cli_commands/opts_command.rb +106 -0
- data/lib/ukiryu/cli_commands/opts_command.rb.fixed +105 -0
- data/lib/ukiryu/cli_commands/response_formatter.rb +240 -0
- data/lib/ukiryu/cli_commands/run_command.rb +375 -0
- data/lib/ukiryu/cli_commands/run_file_command.rb +215 -0
- data/lib/ukiryu/cli_commands/system_command.rb +90 -0
- data/lib/ukiryu/cli_commands/validate_command.rb +87 -0
- data/lib/ukiryu/cli_commands/version_command.rb +16 -0
- data/lib/ukiryu/cli_commands/which_command.rb +166 -0
- data/lib/ukiryu/command_builder.rb +205 -0
- data/lib/ukiryu/config/env_provider.rb +64 -0
- data/lib/ukiryu/config/env_schema.rb +63 -0
- data/lib/ukiryu/config/override_resolver.rb +68 -0
- data/lib/ukiryu/config/type_converter.rb +59 -0
- data/lib/ukiryu/config.rb +249 -0
- data/lib/ukiryu/errors.rb +3 -0
- data/lib/ukiryu/executable_locator.rb +114 -0
- data/lib/ukiryu/execution/command_info.rb +64 -0
- data/lib/ukiryu/execution/metadata.rb +97 -0
- data/lib/ukiryu/execution/output.rb +144 -0
- data/lib/ukiryu/execution/result.rb +194 -0
- data/lib/ukiryu/execution.rb +15 -0
- data/lib/ukiryu/execution_context.rb +251 -0
- data/lib/ukiryu/executor.rb +76 -493
- data/lib/ukiryu/extractors/base_extractor.rb +63 -0
- data/lib/ukiryu/extractors/extractor.rb +150 -0
- data/lib/ukiryu/extractors/help_parser.rb +188 -0
- data/lib/ukiryu/extractors/native_extractor.rb +47 -0
- data/lib/ukiryu/io.rb +196 -0
- data/lib/ukiryu/logger.rb +544 -0
- data/lib/ukiryu/models/argument.rb +28 -0
- data/lib/ukiryu/models/argument_definition.rb +119 -0
- data/lib/ukiryu/models/arguments.rb +113 -0
- data/lib/ukiryu/models/command_definition.rb +176 -0
- data/lib/ukiryu/models/command_info.rb +37 -0
- data/lib/ukiryu/models/components.rb +107 -0
- data/lib/ukiryu/models/env_var_definition.rb +30 -0
- data/lib/ukiryu/models/error_response.rb +41 -0
- data/lib/ukiryu/models/execution_metadata.rb +31 -0
- data/lib/ukiryu/models/execution_report.rb +236 -0
- data/lib/ukiryu/models/exit_codes.rb +74 -0
- data/lib/ukiryu/models/flag_definition.rb +67 -0
- data/lib/ukiryu/models/option_definition.rb +102 -0
- data/lib/ukiryu/models/output_info.rb +25 -0
- data/lib/ukiryu/models/platform_profile.rb +153 -0
- data/lib/ukiryu/models/routing.rb +211 -0
- data/lib/ukiryu/models/search_paths.rb +39 -0
- data/lib/ukiryu/models/success_response.rb +85 -0
- data/lib/ukiryu/models/tool_definition.rb +145 -0
- data/lib/ukiryu/models/tool_metadata.rb +82 -0
- data/lib/ukiryu/models/validation_result.rb +80 -0
- data/lib/ukiryu/models/version_compatibility.rb +152 -0
- data/lib/ukiryu/models/version_detection.rb +39 -0
- data/lib/ukiryu/models.rb +23 -0
- data/lib/ukiryu/options/base.rb +95 -0
- data/lib/ukiryu/options_builder/formatter.rb +87 -0
- data/lib/ukiryu/options_builder/validator.rb +43 -0
- data/lib/ukiryu/options_builder.rb +311 -0
- data/lib/ukiryu/platform.rb +6 -6
- data/lib/ukiryu/registry.rb +143 -183
- data/lib/ukiryu/response/base.rb +217 -0
- data/lib/ukiryu/runtime.rb +179 -0
- data/lib/ukiryu/schema_validator.rb +8 -10
- data/lib/ukiryu/shell/bash.rb +3 -3
- data/lib/ukiryu/shell/cmd.rb +4 -4
- data/lib/ukiryu/shell/fish.rb +1 -1
- data/lib/ukiryu/shell/powershell.rb +3 -3
- data/lib/ukiryu/shell/sh.rb +1 -1
- data/lib/ukiryu/shell/zsh.rb +1 -1
- data/lib/ukiryu/shell.rb +146 -39
- data/lib/ukiryu/thor_ext.rb +208 -0
- data/lib/ukiryu/tool.rb +649 -258
- data/lib/ukiryu/tool_index.rb +224 -0
- data/lib/ukiryu/tools/base.rb +381 -0
- data/lib/ukiryu/tools/class_generator.rb +132 -0
- data/lib/ukiryu/tools/executable_finder.rb +29 -0
- data/lib/ukiryu/tools/generator.rb +154 -0
- data/lib/ukiryu/tools.rb +109 -0
- data/lib/ukiryu/type.rb +28 -43
- data/lib/ukiryu/validation/constraints.rb +281 -0
- data/lib/ukiryu/validation/validator.rb +188 -0
- data/lib/ukiryu/validation.rb +21 -0
- data/lib/ukiryu/version.rb +1 -1
- data/lib/ukiryu/version_detector.rb +51 -0
- data/lib/ukiryu.rb +31 -15
- data/ukiryu-proposal.md +2952 -0
- data/ukiryu.gemspec +18 -14
- metadata +137 -5
- data/.github/workflows/test.yml +0 -143
data/README.adoc
CHANGED
|
@@ -19,6 +19,120 @@ Ukiryu provides a Ruby framework for executing external commands with:
|
|
|
19
19
|
|
|
20
20
|
== Features
|
|
21
21
|
|
|
22
|
+
=== Default Command Resolution
|
|
23
|
+
|
|
24
|
+
When a tool implements its own name (e.g., `ping` tool implements `ping` command), you can omit the command name:
|
|
25
|
+
|
|
26
|
+
[source,ruby]
|
|
27
|
+
----
|
|
28
|
+
# Both syntaxes work
|
|
29
|
+
tool.execute(:ping, { host: '127.0.0.1', count: 1 })
|
|
30
|
+
tool.execute(:ping, :ping, { host: '127.0.0.1', count: 1 })
|
|
31
|
+
----
|
|
32
|
+
|
|
33
|
+
The CLI also supports this shorthand:
|
|
34
|
+
|
|
35
|
+
[source,shell]
|
|
36
|
+
----
|
|
37
|
+
# Both syntaxes work
|
|
38
|
+
ukiryu exec-inline ping host=127.0.0.1 count=1
|
|
39
|
+
ukiryu exec-inline ping ping host=127.0.0.1 count=1
|
|
40
|
+
===
|
|
41
|
+
|
|
42
|
+
=== Configuration Management
|
|
43
|
+
|
|
44
|
+
Centralized configuration system supporting multiple sources:
|
|
45
|
+
|
|
46
|
+
[source,ruby]
|
|
47
|
+
----
|
|
48
|
+
# Programmatic configuration
|
|
49
|
+
Ukiryu::Config.configure do |config|
|
|
50
|
+
config.format = :json
|
|
51
|
+
config.debug = true
|
|
52
|
+
config.timeout = 60
|
|
53
|
+
config.registry = '/path/to/register'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Or via environment variables
|
|
57
|
+
ENV['UKIRYU_FORMAT'] = 'json'
|
|
58
|
+
ENV['UKIRYU_DEBUG'] = '1'
|
|
59
|
+
ENV['UKIRYU_TIMEOUT'] = '60'
|
|
60
|
+
----
|
|
61
|
+
|
|
62
|
+
Configuration priority (highest to lowest):
|
|
63
|
+
. CLI options (`--format`, `--registry`, etc.)
|
|
64
|
+
. Environment variables (`UKIRYU_*`)
|
|
65
|
+
. Programmatic configuration (`Config.configure`)
|
|
66
|
+
. Default values
|
|
67
|
+
|
|
68
|
+
=== Debug Mode
|
|
69
|
+
|
|
70
|
+
Comprehensive debug output for troubleshooting:
|
|
71
|
+
|
|
72
|
+
[source,shell]
|
|
73
|
+
----
|
|
74
|
+
# Enable debug mode
|
|
75
|
+
UKIRYU_DEBUG=1 ukiryu exec-inline ping host=127.0.0.1 count=1
|
|
76
|
+
|
|
77
|
+
# Debug sections output to stderr:
|
|
78
|
+
# - Ukiryu CLI Options
|
|
79
|
+
# - Tool Resolution Process
|
|
80
|
+
# - Structured Options (tool command options)
|
|
81
|
+
# - Shell Command (actual command to execute)
|
|
82
|
+
# - Raw Command Response (stdout/stderr)
|
|
83
|
+
# - Structured Response (final result)
|
|
84
|
+
----
|
|
85
|
+
|
|
86
|
+
Debug output uses structured borders with color support (when Paint gem is available).
|
|
87
|
+
|
|
88
|
+
=== Stdin Support
|
|
89
|
+
|
|
90
|
+
Ukiryu supports passing data to commands via standard input (stdin), enabling Unix pipe composition and integration with other tools.
|
|
91
|
+
|
|
92
|
+
[source,shell]
|
|
93
|
+
----
|
|
94
|
+
# Read from pipe using --stdin flag
|
|
95
|
+
echo '{"name": "value"}' | ukiryu exec jq --stdin filter="."
|
|
96
|
+
|
|
97
|
+
# Read from pipe using stdin=- parameter
|
|
98
|
+
echo '{"name": "value"}' | ukiryu exec jq stdin=- filter="."
|
|
99
|
+
|
|
100
|
+
# Read from file using stdin=@filename syntax
|
|
101
|
+
ukiryu exec jq stdin=@/path/to/data.json filter="."
|
|
102
|
+
|
|
103
|
+
# Pass data directly via stdin parameter
|
|
104
|
+
ukiryu exec jq stdin='{"data": "value"}' filter="."
|
|
105
|
+
----
|
|
106
|
+
|
|
107
|
+
The `stdin` parameter is a special execution parameter that is not passed to the tool's command arguments but is instead written to the child process's stdin stream. This enables composition with other Unix tools:
|
|
108
|
+
|
|
109
|
+
[source,shell]
|
|
110
|
+
----
|
|
111
|
+
# Compose with other tools
|
|
112
|
+
cat large_data.json | ukiryu exec jq --stdin filter=".name" | sort
|
|
113
|
+
|
|
114
|
+
# Process output from another command
|
|
115
|
+
curl -s https://api.example.com/data | ukiryu exec jq --stdin filter=".[0:5]"
|
|
116
|
+
----
|
|
117
|
+
|
|
118
|
+
In dry-run mode, stdin data is previewed (first 100 characters) to show what would be passed to the command.
|
|
119
|
+
|
|
120
|
+
=== OOP API
|
|
121
|
+
|
|
122
|
+
Tool-specific classes with a fully object-oriented API:
|
|
123
|
+
|
|
124
|
+
[source,ruby]
|
|
125
|
+
----
|
|
126
|
+
Ukiryu::Tools::Imagemagick.new.tap do |im|
|
|
127
|
+
convert_options = im.options_for(:convert)
|
|
128
|
+
convert_options.set(inputs: ["image.png"], resize: "50%")
|
|
129
|
+
convert_options.output = "output.jpg"
|
|
130
|
+
convert_options.run
|
|
131
|
+
end
|
|
132
|
+
----
|
|
133
|
+
|
|
134
|
+
See <<oop-api,OOP API>> for more details.
|
|
135
|
+
|
|
22
136
|
=== Tool Registry
|
|
23
137
|
|
|
24
138
|
Load tool definitions from YAML profiles:
|
|
@@ -133,6 +247,253 @@ Or install it yourself as:
|
|
|
133
247
|
gem install ukiryu
|
|
134
248
|
----
|
|
135
249
|
|
|
250
|
+
== Command Line Interface
|
|
251
|
+
|
|
252
|
+
Ukiryu includes a command-line interface (CLI) for exploring and interacting with tool profiles. The CLI requires the `thor` gem.
|
|
253
|
+
|
|
254
|
+
=== CLI Commands
|
|
255
|
+
|
|
256
|
+
==== list
|
|
257
|
+
|
|
258
|
+
List all available tools in the registry:
|
|
259
|
+
|
|
260
|
+
[source,shell]
|
|
261
|
+
----
|
|
262
|
+
ukiryu list
|
|
263
|
+
----
|
|
264
|
+
|
|
265
|
+
Example output:
|
|
266
|
+
|
|
267
|
+
[source,shell]
|
|
268
|
+
----
|
|
269
|
+
Available tools (3):
|
|
270
|
+
[✓] ghostscript v10.0.0
|
|
271
|
+
[✓] inkscape v1.3
|
|
272
|
+
[✗] imagemagick version unknown
|
|
273
|
+
----
|
|
274
|
+
|
|
275
|
+
==== info
|
|
276
|
+
|
|
277
|
+
Show detailed information about a specific tool:
|
|
278
|
+
|
|
279
|
+
[source,shell]
|
|
280
|
+
----
|
|
281
|
+
ukiryu info inkscape
|
|
282
|
+
----
|
|
283
|
+
|
|
284
|
+
Example output:
|
|
285
|
+
|
|
286
|
+
[source,shell]
|
|
287
|
+
----
|
|
288
|
+
Tool: inkscape
|
|
289
|
+
Display Name: Inkscape Vector Graphics Editor
|
|
290
|
+
Version: 1.3
|
|
291
|
+
Homepage: https://inkscape.org
|
|
292
|
+
|
|
293
|
+
Aliases: ink, inksc
|
|
294
|
+
|
|
295
|
+
Version Detection:
|
|
296
|
+
Command: --version
|
|
297
|
+
Pattern: (\d+\.\d+)
|
|
298
|
+
Modern Threshold: 1.0
|
|
299
|
+
|
|
300
|
+
Search Paths:
|
|
301
|
+
macos:
|
|
302
|
+
- /Applications/Inkscape.app/Contents/MacOS/inkscape
|
|
303
|
+
- /opt/homebrew/bin/inkscape
|
|
304
|
+
|
|
305
|
+
Profiles (1):
|
|
306
|
+
default:
|
|
307
|
+
Platforms: macos, linux
|
|
308
|
+
Shells: bash, zsh, fish
|
|
309
|
+
Version: any
|
|
310
|
+
|
|
311
|
+
Status: INSTALLED
|
|
312
|
+
Executable: /opt/homebrew/bin/inkscape
|
|
313
|
+
Detected Version: 1.3.2
|
|
314
|
+
----
|
|
315
|
+
|
|
316
|
+
==== commands
|
|
317
|
+
|
|
318
|
+
List all commands available for a tool:
|
|
319
|
+
|
|
320
|
+
[source,shell]
|
|
321
|
+
----
|
|
322
|
+
ukiryu commands imagemagick
|
|
323
|
+
----
|
|
324
|
+
|
|
325
|
+
Example output:
|
|
326
|
+
|
|
327
|
+
[source,shell]
|
|
328
|
+
----
|
|
329
|
+
Commands for imagemagick:
|
|
330
|
+
convert Convert between image formats
|
|
331
|
+
Usage: magick convert [options] input output
|
|
332
|
+
Subcommand: convert
|
|
333
|
+
identify Describe image format and characteristics
|
|
334
|
+
Usage: magick identify [options] input
|
|
335
|
+
----
|
|
336
|
+
|
|
337
|
+
==== opts
|
|
338
|
+
|
|
339
|
+
Show options for a tool or specific command:
|
|
340
|
+
|
|
341
|
+
[source,shell]
|
|
342
|
+
----
|
|
343
|
+
# Show all options for a tool
|
|
344
|
+
ukiryu opts inkscape
|
|
345
|
+
|
|
346
|
+
# Show options for a specific command
|
|
347
|
+
ukiryu opts imagemagick convert
|
|
348
|
+
----
|
|
349
|
+
|
|
350
|
+
Example output:
|
|
351
|
+
|
|
352
|
+
[source,shell]
|
|
353
|
+
----
|
|
354
|
+
Options for imagemagick convert:
|
|
355
|
+
Convert between image formats
|
|
356
|
+
|
|
357
|
+
Arguments:
|
|
358
|
+
inputs (filevariadic)
|
|
359
|
+
Position: last
|
|
360
|
+
Description: Input files to process
|
|
361
|
+
|
|
362
|
+
Options:
|
|
363
|
+
--resize -resize
|
|
364
|
+
Type: string
|
|
365
|
+
Values: 50%, 100x100, 50x50!
|
|
366
|
+
|
|
367
|
+
--quality -quality
|
|
368
|
+
Type: integer
|
|
369
|
+
Range: 0..100
|
|
370
|
+
Description: JPEG/MIFF/PNG compression level
|
|
371
|
+
|
|
372
|
+
Flags:
|
|
373
|
+
-strip -strip (default: false)
|
|
374
|
+
Remove all profiles and text attributes from image
|
|
375
|
+
----
|
|
376
|
+
|
|
377
|
+
==== exec
|
|
378
|
+
|
|
379
|
+
Execute a tool command inline with key=value parameters:
|
|
380
|
+
|
|
381
|
+
[source,shell]
|
|
382
|
+
----
|
|
383
|
+
# With default command (shorthand)
|
|
384
|
+
ukiryu exec ping host=127.0.0.1 count=1
|
|
385
|
+
|
|
386
|
+
# With explicit command
|
|
387
|
+
ukiryu exec imagemagick convert inputs=input.jpg output=output.jpg resize=50%
|
|
388
|
+
|
|
389
|
+
# With output format
|
|
390
|
+
ukiryu exec ping host=127.0.0.1 count=1 --format json
|
|
391
|
+
|
|
392
|
+
# With output to file
|
|
393
|
+
ukiryu exec ping host=127.0.0.1 count=1 --output result.yaml
|
|
394
|
+
|
|
395
|
+
# Read from stdin (pipe)
|
|
396
|
+
echo '{"name": "value"}' | ukiryu exec jq --stdin filter="."
|
|
397
|
+
|
|
398
|
+
# Read from file via stdin parameter
|
|
399
|
+
ukiryu exec jq stdin=@/path/to/data.json filter="."
|
|
400
|
+
|
|
401
|
+
# Debug mode (shows detailed execution info to stderr)
|
|
402
|
+
UKIRYU_DEBUG=1 ukiryu exec ping host=127.0.0.1 count=1
|
|
403
|
+
----
|
|
404
|
+
|
|
405
|
+
Available options:
|
|
406
|
+
|
|
407
|
+
* `--registry`, `-r`: Path to tool registry
|
|
408
|
+
* `--format`, `-f`: Response format (`yaml`, `json`, `table`)
|
|
409
|
+
* `--output`, `-o`: Output file for response (default: stdout)
|
|
410
|
+
* `--dry-run`, `-d`: Show execution request without executing
|
|
411
|
+
* `--shell`: Shell to use for command execution (`bash`, `zsh`, `fish`, `sh`, `powershell`, `cmd`)
|
|
412
|
+
* `--stdin`: Read input from stdin and pass to command
|
|
413
|
+
|
|
414
|
+
==== execute-file
|
|
415
|
+
|
|
416
|
+
Execute a tool command from a YAML request file:
|
|
417
|
+
|
|
418
|
+
[source,shell]
|
|
419
|
+
----
|
|
420
|
+
# Create request file
|
|
421
|
+
cat > request.yaml << EOF
|
|
422
|
+
tool: ping
|
|
423
|
+
command: ping
|
|
424
|
+
arguments:
|
|
425
|
+
host: 127.0.0.1
|
|
426
|
+
count: 1
|
|
427
|
+
EOF
|
|
428
|
+
|
|
429
|
+
# Execute from file
|
|
430
|
+
ukiryu execute-file request.yaml
|
|
431
|
+
====
|
|
432
|
+
|
|
433
|
+
==== execute
|
|
434
|
+
|
|
435
|
+
Execute a tool command with options:
|
|
436
|
+
|
|
437
|
+
[source,shell]
|
|
438
|
+
----
|
|
439
|
+
# Basic execution
|
|
440
|
+
ukiryu execute imagemagick convert --resize 50x50 -i input.png -o output.jpg
|
|
441
|
+
|
|
442
|
+
# Dry run (show command without executing)
|
|
443
|
+
ukiryu execute inkscape export_pdf --dry-run -i input.svg -o output.pdf
|
|
444
|
+
----
|
|
445
|
+
|
|
446
|
+
Example output:
|
|
447
|
+
|
|
448
|
+
[source,shell]
|
|
449
|
+
----
|
|
450
|
+
Command completed successfully
|
|
451
|
+
Exit status: 0
|
|
452
|
+
Duration: 1.2s
|
|
453
|
+
|
|
454
|
+
STDOUT:
|
|
455
|
+
----
|
|
456
|
+
|
|
457
|
+
==== version
|
|
458
|
+
|
|
459
|
+
Show Ukiryu CLI version:
|
|
460
|
+
|
|
461
|
+
[source,shell]
|
|
462
|
+
----
|
|
463
|
+
ukiryu version
|
|
464
|
+
----
|
|
465
|
+
|
|
466
|
+
Example output:
|
|
467
|
+
|
|
468
|
+
[source,shell]
|
|
469
|
+
----
|
|
470
|
+
Ukiryu version 0.1.0
|
|
471
|
+
----
|
|
472
|
+
|
|
473
|
+
=== Registry Configuration
|
|
474
|
+
|
|
475
|
+
The CLI searches for tool profiles in the following locations:
|
|
476
|
+
|
|
477
|
+
1. Environment variable: `UKIRYU_REGISTRY`
|
|
478
|
+
2. Sibling `register/` directory relative to gem installation
|
|
479
|
+
3. `../register/` relative to current working directory (development)
|
|
480
|
+
|
|
481
|
+
Set a custom registry path:
|
|
482
|
+
|
|
483
|
+
[source,shell]
|
|
484
|
+
----
|
|
485
|
+
export UKIRYU_REGISTRY=/path/to/register
|
|
486
|
+
ukiryu list
|
|
487
|
+
----
|
|
488
|
+
|
|
489
|
+
Or use the `--registry` option:
|
|
490
|
+
|
|
491
|
+
[source,shell]
|
|
492
|
+
----
|
|
493
|
+
ukiryu list --registry /path/to/register
|
|
494
|
+
ukiryu info inkscape -r /path/to/register
|
|
495
|
+
----
|
|
496
|
+
|
|
136
497
|
== Usage
|
|
137
498
|
|
|
138
499
|
=== Basic Command Execution
|
|
@@ -163,6 +524,35 @@ else
|
|
|
163
524
|
end
|
|
164
525
|
----
|
|
165
526
|
|
|
527
|
+
=== Passing Stdin
|
|
528
|
+
|
|
529
|
+
Pass data to commands via stdin using the `:stdin` parameter:
|
|
530
|
+
|
|
531
|
+
[source,ruby]
|
|
532
|
+
----
|
|
533
|
+
# Pass string data to stdin
|
|
534
|
+
result = tool.execute(:process, {
|
|
535
|
+
stdin: '{"name": "value"}',
|
|
536
|
+
filter: '.'
|
|
537
|
+
})
|
|
538
|
+
|
|
539
|
+
# Read from file and pass to stdin
|
|
540
|
+
result = tool.execute(:process, {
|
|
541
|
+
stdin: File.read('/path/to/data.json'),
|
|
542
|
+
filter: '.name'
|
|
543
|
+
})
|
|
544
|
+
|
|
545
|
+
# Pass IO object (file, pipe, etc.)
|
|
546
|
+
File.open('/path/to/data.json', 'r') do |file|
|
|
547
|
+
result = tool.execute(:process, {
|
|
548
|
+
stdin: file,
|
|
549
|
+
filter: '.'
|
|
550
|
+
})
|
|
551
|
+
end
|
|
552
|
+
----
|
|
553
|
+
|
|
554
|
+
The `:stdin` parameter is a special execution parameter that is extracted before building command arguments and written to the child process's stdin stream.
|
|
555
|
+
|
|
166
556
|
=== Accessing Result Details
|
|
167
557
|
|
|
168
558
|
[source,ruby]
|
|
@@ -214,6 +604,229 @@ else
|
|
|
214
604
|
end
|
|
215
605
|
----
|
|
216
606
|
|
|
607
|
+
[[oop-api]]
|
|
608
|
+
== OOP API
|
|
609
|
+
|
|
610
|
+
Ukiryu provides a fully object-oriented API for tool interaction. Tool-specific classes are dynamically generated from YAML profiles and available under `Ukiryu::Tools::*`.
|
|
611
|
+
|
|
612
|
+
=== Tool Classes
|
|
613
|
+
|
|
614
|
+
Tool classes are generated automatically when first accessed:
|
|
615
|
+
|
|
616
|
+
[source,ruby]
|
|
617
|
+
----
|
|
618
|
+
# Access a tool class (autogenerated on first access)
|
|
619
|
+
tool = Ukiryu::Tools::Imagemagick.new
|
|
620
|
+
|
|
621
|
+
# Check availability and version
|
|
622
|
+
tool.available? # => true
|
|
623
|
+
tool.version # => "7.1"
|
|
624
|
+
|
|
625
|
+
# List available commands
|
|
626
|
+
tool.class.profile[:commands].keys
|
|
627
|
+
# => [:convert, :identify, :mogrify, ...]
|
|
628
|
+
----
|
|
629
|
+
|
|
630
|
+
Available tool classes include:
|
|
631
|
+
* `Ukiryu::Tools::Imagemagick`
|
|
632
|
+
* `Ukiryu::Tools::Ffmpeg`
|
|
633
|
+
* `Ukiryu::Tools::Pandoc`
|
|
634
|
+
* `Ukiryu::Tools::Ghostscript`
|
|
635
|
+
* `Ukiryu::Tools::Inkscape`
|
|
636
|
+
* `Ukiryu::Tools::Optipng`
|
|
637
|
+
* `Ukiryu::Tools::Jpegoptim`
|
|
638
|
+
|
|
639
|
+
=== Options Classes
|
|
640
|
+
|
|
641
|
+
Options classes are generated per-command and provide a fluent interface:
|
|
642
|
+
|
|
643
|
+
[source,ruby]
|
|
644
|
+
----
|
|
645
|
+
# Create an options object
|
|
646
|
+
convert_options = tool.options_for(:convert)
|
|
647
|
+
|
|
648
|
+
# Set options individually
|
|
649
|
+
convert_options.inputs = ["input.png"]
|
|
650
|
+
convert_options.resize = "50%"
|
|
651
|
+
convert_options.quality = 85
|
|
652
|
+
convert_options.strip = true
|
|
653
|
+
convert_options.output = "output.jpg"
|
|
654
|
+
|
|
655
|
+
# Or use set() for batch assignment
|
|
656
|
+
convert_options.set(
|
|
657
|
+
inputs: ["input.png"],
|
|
658
|
+
resize: "50%",
|
|
659
|
+
quality: 85,
|
|
660
|
+
strip: true
|
|
661
|
+
)
|
|
662
|
+
convert_options.output = "output.jpg"
|
|
663
|
+
|
|
664
|
+
# Execute the command
|
|
665
|
+
result = convert_options.run
|
|
666
|
+
|
|
667
|
+
# Check the result
|
|
668
|
+
puts result.success? # => true
|
|
669
|
+
puts result.exit_code # => 0
|
|
670
|
+
puts result.stdout # => ""
|
|
671
|
+
puts result.stderr # => ""
|
|
672
|
+
puts result.duration # => 0.5
|
|
673
|
+
----
|
|
674
|
+
|
|
675
|
+
=== Response Classes
|
|
676
|
+
|
|
677
|
+
Response classes wrap execution results in a structured object:
|
|
678
|
+
|
|
679
|
+
[source,ruby]
|
|
680
|
+
----
|
|
681
|
+
result = convert_options.run
|
|
682
|
+
|
|
683
|
+
# Status information
|
|
684
|
+
result.success? # => true
|
|
685
|
+
result.exit_code # => 0
|
|
686
|
+
|
|
687
|
+
# Output
|
|
688
|
+
result.stdout # Stripped stdout
|
|
689
|
+
result.stderr # Stripped stderr
|
|
690
|
+
result.stdout_lines # Array of lines
|
|
691
|
+
|
|
692
|
+
# Timing
|
|
693
|
+
result.duration # Float (seconds)
|
|
694
|
+
result.formatted_duration # "500ms"
|
|
695
|
+
|
|
696
|
+
# Full command info
|
|
697
|
+
result.executable # Full path to executable
|
|
698
|
+
result.arguments # Array of arguments
|
|
699
|
+
result.full_command # Complete command string
|
|
700
|
+
----
|
|
701
|
+
|
|
702
|
+
=== Action Pattern
|
|
703
|
+
|
|
704
|
+
An alternative pattern using action classes:
|
|
705
|
+
|
|
706
|
+
[source,ruby]
|
|
707
|
+
----
|
|
708
|
+
# Create an action
|
|
709
|
+
action = tool.action_for(:convert)
|
|
710
|
+
|
|
711
|
+
# Get options object
|
|
712
|
+
action_options = action.options
|
|
713
|
+
action_options.set(
|
|
714
|
+
inputs: ["input.png"],
|
|
715
|
+
resize: "50%"
|
|
716
|
+
)
|
|
717
|
+
action_options.output = "output.jpg"
|
|
718
|
+
|
|
719
|
+
# Execute with the action
|
|
720
|
+
result = action.run(action_options)
|
|
721
|
+
|
|
722
|
+
# Or pass a hash directly (action creates options)
|
|
723
|
+
result = action.run(
|
|
724
|
+
inputs: ["input.png"],
|
|
725
|
+
resize: "50%",
|
|
726
|
+
output: "output.jpg"
|
|
727
|
+
)
|
|
728
|
+
----
|
|
729
|
+
|
|
730
|
+
=== Manual Option Injection
|
|
731
|
+
|
|
732
|
+
When tool definitions don't cover all options, use `extra_args`:
|
|
733
|
+
|
|
734
|
+
[source,ruby]
|
|
735
|
+
----
|
|
736
|
+
# Pass undefined options via extra_args
|
|
737
|
+
convert_options = tool.options_for(:convert)
|
|
738
|
+
convert_options.set(
|
|
739
|
+
inputs: ["input.png"],
|
|
740
|
+
resize: "50%",
|
|
741
|
+
extra_args: ["-strip", "-quality", "95", "-interlace", "Plane"]
|
|
742
|
+
)
|
|
743
|
+
convert_options.output = "output.jpg"
|
|
744
|
+
|
|
745
|
+
result = convert_options.run
|
|
746
|
+
----
|
|
747
|
+
|
|
748
|
+
The `extra_args` parameter accepts either an array of strings or a single string. All arguments are properly escaped for the detected shell.
|
|
749
|
+
|
|
750
|
+
=== Complete Examples
|
|
751
|
+
|
|
752
|
+
.Batch Image Conversion
|
|
753
|
+
[source,ruby]
|
|
754
|
+
----
|
|
755
|
+
require 'ukiryu'
|
|
756
|
+
|
|
757
|
+
Ukiryu::Registry.default_registry_path = 'path/to/register'
|
|
758
|
+
|
|
759
|
+
im = Ukiryu::Tools::Imagemagick.new
|
|
760
|
+
|
|
761
|
+
Dir["*.tif"].each do |tif_file|
|
|
762
|
+
png_file = tif_file.sub('.tif', '.png')
|
|
763
|
+
|
|
764
|
+
im.options_for(:convert).tap do |opts|
|
|
765
|
+
opts.set(inputs: [tif_file], resize: "50%")
|
|
766
|
+
opts.output = png_file
|
|
767
|
+
opts.run
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
puts "Converted #{tif_file} -> #{png_file}"
|
|
771
|
+
end
|
|
772
|
+
----
|
|
773
|
+
|
|
774
|
+
.Video Processing with FFmpeg
|
|
775
|
+
[source,ruby]
|
|
776
|
+
----
|
|
777
|
+
ffmpeg = Ukiryu::Tools::Ffmpeg.new
|
|
778
|
+
|
|
779
|
+
# Convert video to MP4 with custom codec settings
|
|
780
|
+
ffmpeg.options_for(:transcode).tap do |opts|
|
|
781
|
+
opts.set(
|
|
782
|
+
inputs: ["input.mov"],
|
|
783
|
+
video_codec: "libx264",
|
|
784
|
+
bitrate: "2M",
|
|
785
|
+
extra_args: ["-preset", "slow", "-crf", "22"]
|
|
786
|
+
)
|
|
787
|
+
opts.output = "output.mp4"
|
|
788
|
+
opts.run
|
|
789
|
+
end
|
|
790
|
+
----
|
|
791
|
+
|
|
792
|
+
.Document Conversion with Pandoc
|
|
793
|
+
[source,ruby]
|
|
794
|
+
----
|
|
795
|
+
pandoc = Ukiryu::Tools::Pandoc.new
|
|
796
|
+
|
|
797
|
+
# Convert Markdown to PDF
|
|
798
|
+
pandoc.options_for(:convert).tap do |opts|
|
|
799
|
+
opts.set(
|
|
800
|
+
inputs: ["document.md"],
|
|
801
|
+
from: "markdown",
|
|
802
|
+
to: "pdf",
|
|
803
|
+
standalone: true,
|
|
804
|
+
extra_args: ["--pdf-engine", "xelatex", "-V", "geometry:margin=1in"]
|
|
805
|
+
)
|
|
806
|
+
opts.output = "document.pdf"
|
|
807
|
+
result = opts.run
|
|
808
|
+
|
|
809
|
+
puts "Conversion #{result.success? ? 'succeeded' : 'failed'}"
|
|
810
|
+
end
|
|
811
|
+
----
|
|
812
|
+
|
|
813
|
+
.SVG Export with Inkscape
|
|
814
|
+
[source,ruby]
|
|
815
|
+
----
|
|
816
|
+
inkscape = Ukiryu::Tools::Inkscape.new
|
|
817
|
+
|
|
818
|
+
# Export SVG to PNG at specific DPI
|
|
819
|
+
inkscape.options_for(:export).tap do |opts|
|
|
820
|
+
opts.set(
|
|
821
|
+
inputs: ["design.svg"],
|
|
822
|
+
dpi: 300,
|
|
823
|
+
export_area: "page"
|
|
824
|
+
)
|
|
825
|
+
opts.output = "design.png"
|
|
826
|
+
opts.run
|
|
827
|
+
end
|
|
828
|
+
----
|
|
829
|
+
|
|
217
830
|
== Tool Profiles
|
|
218
831
|
|
|
219
832
|
Tool profiles are defined in separate https://github.com/ukiryu/register[Ukiryu Register] repository.
|
data/Rakefile
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg id="uuid-2ec5d9c8-be06-4ba8-b613-da76df4ee347" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1500 400"><defs><linearGradient id="uuid-a16a9922-a651-4062-8ae0-de5562062656" x1="70.12" y1="1156.42" x2="68.88" y2="1262.41" gradientTransform="translate(122 -907)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#b9b99a"/><stop offset=".8" stop-color="#377a82"/><stop offset="1" stop-color="#215d6c"/></linearGradient><linearGradient id="uuid-ba15e022-772c-4b12-a16e-12bd59b147d5" x1="137.43" y1="1121.48" x2="176.72" y2="1203.86" gradientTransform="translate(122 -907)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ded3c4"/><stop offset="1" stop-color="#b8a691"/></linearGradient><linearGradient id="uuid-8234d38e-e6f1-40b6-897a-4f7f9502969a" x1="-12.01" y1="1094.55" x2="-88.65" y2="1109.05" gradientTransform="translate(122 -907)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ddd2c2"/><stop offset="1" stop-color="#c0af9b"/></linearGradient></defs><path d="M201.48,337.73c.48.83,1.07,2.07,1,3-.56,7.76-20.59,8.76-26,11-1.33-.02-24.34,2.96-25,3-9.69.62-19.31,2.35-29,3-21.78-11.22-43.01-28.48-58-48,9.86,1.27,19.2.09,29.04-2.46,6.34-1.64,12.96-7.97,12.96-7.97,0,0,53.95-.02,74.77-7.09,18.44-6.26-26.25-12.92-29.77-14.52-2.48-1.12-6.76-5.94-9.66-8.85-7.2-7.22-17.03-10.67-26.88-10.14-8.06.44-17.46,6.61-22.93-3-1.02-1.79-.57-5.1-1.53-6.97,4.14.98,10.12,2.61,14,1,7.79,7.27,10.28.02,14.33.22,1.88.1,5.3,3.21,8.24,3.71,5.95,1,17.56.28,23.4-1.46,2.87-.86,9.22-5.47,11.35-5.24.5.06,8.82,4.78,8.68,5.27-.84,2.82-20.17,5.89-11.44,7.45,5.47.98,13.05-.51,18.92.08,16.56,1.65,32.26,7.38,49.04,7.96,10.73.37,21.26-1.44,32.02-1.02,16,.64,25.36,7.1,39.46,8.04,5.94.39,12.05-.28,18,0,.17.38,3.1,1.36,2,2.98-.16.23-3.35.73-5.04,2.48-2.22,2.31-6.68,9.57-8.67,10.33-2.4.92-8.93.84-12.33,1.67-20.04,4.92-36.04,2.46-55.96,5.54l-3,1c-2.13.37-4.84,1.54-7,2-5.36,1.13-5.76,3.89-6.98,8.61-.39,1.5,14.68,7.57,14.61,9.22l-32.63,19.17ZM194.48,316.73c-.99.15,6.89,20.82,7,21" style="fill:url(#uuid-a16a9922-a651-4062-8ae0-de5562062656);"/><path d="M367.48,217.73c4.32,11.89.24,34.07-5,45.5-4.11,8.95-5.55,4.2-12.93,9.07-2.81,1.85-6.93,8.42-8.06,8.94-12.58,5.68-24.96-8.49-26-20-2.88-31.72,44.67-31.05,27,.49,14.01-7.59,9.26-26.91-6.01-29.99-.36-.07-.99-1.08-2.49-1.1-1.41-.02-2.16,1.04-2.51,1.1-22.7,3.71-22.89,25.67-15,43-5.95-.28-12.06.39-18,0-18.22-5.49-28.22-19.21-20.01-38-5.85,3.99-7.12,14.68-5.52,21.03,1.37,5.44,9.81,9.61-1.72,7.72-9.87-1.62-21.86-10.45-15.21-21.72,2.6-4.4,8.5-5.03,12.03-6.97,7.47-4.13-2.85-2.84-6.55-1.55-6.39,2.24-9.44,5.97-11.01,12.49-1.04,4.31-1.41,3.34,0,8,1.15,3.8,6.54,9.04,6,8.99-17.93-1.77-9-.99-33,.01l-5-1c-15.53-2.05-30.38-6.53-45.99-7.99,13.85-6.62,25.45.87,37.63,1.91s7.74-4.15,11.49-10.29c5.8-9.51,15.66,4.18,19.69-2.73.49-.84-3.05-9.97,9.18-22.96,15-15.94,20.93-14.95,35.44-14.88,9.29.04,7.19-.22,16.56-2.06,1.18-.23,2.84-.99,3-1,11.46-.65,17.23,6.84,20.48,6.98,1.94.08,9.5-5.75,13.47-6.54,11.72-2.33,23.72,1.6,28.06,13.56Z" style="fill:url(#uuid-ba15e022-772c-4b12-a16e-12bd59b147d5);"/><path d="M217.48,78.73c18.42,3.94,24.34,13.49,34.12,26.38.91,1.2,21.9,11.21,23.65,11.45,3.88.53,7.85-3.46,14.73-2.83,20.19,1.85,18.31,24.45,11.5,38,.7-4.1-1.5-4.91-4-7-13.22-11.06-17.19,3.64-23.27,2.84-3.34-.44-11.28-11.11-17.45-13.61-12.86-5.21-26.45.72-39.96-5.04-2.06-.88-8-6.48-9.3-5.18-3.44,3.42,10.86,9.98,12.96,10.53,11.59,3.05,21.5-1.71,32.74,2.26,6.75,2.38,14.76,13.09,19.03,14.01,9.23,1.97,13.65-12.36,23.27-3.8,1.38,1.23,2.37,6.01,5,7-2.85,4.77-12.63,11.72-12.85,12.61-1.03,4.07,12.1,20.26-.09,10.84-1.36-1.05-4.72-6.57-6.05-5.44-.79.68-7.33,20.85-12,15.99-.6-.62,4.38-14.01,1.99-16.99-.7-.87-10.44,9.89-19.51,10.08-16.58.34,9.55-9.62,3.6-18.66-1.68-2.54-19.15-10.1-22.88-11.14-6.21-1.72-12.89-1.16-17.21-2.29-6-1.57-17.92-5.69-23-9-12.16-7.93-15.87-20.08-22.99-31.51,12.41.79,3.24-10.19-2.01-14.49-.45-2.54,2.94-3.29,5-4,14.09,7.84,34.6-2.41,11.01-10.99,10.51-.75,23.64-2.23,33.99-.01ZM244.48,107.72c-8.16-14.79-21.04-14.02-35.99-11.98,1.36,4.08,12.52,2.49,13,2.98,1.3,1.35-2.61,14.67,12.43,11.94,4.53-.82,5.1-5.36,10.56-2.95ZM292.48,126.72c3.72-4.38-11.75-3.33-10.97,2.52.29,2.17,10.59-2.06,10.97-2.52Z" style="fill:#cfc49b;"/><path d="M62.48,156.73c4.2.78,10.1,6.97,13.72,7.78,12.21,2.75,20.02-6.57,30.25,5.75,5.99,7.2,8.95,18.08,4.92,26.86-1.29,2.8-5.47,6.07-5.75,7.32-.6,2.68,3.81,7.13,2.86,8.27-.63.76-15.79,5.26-18.51,7.01-4.87,3.12-9.18,14.72-10.06,14.97-.71.2-13.77-3.14-14.44-3.46-1.07-.51-8.26-13.43-11.51-16.49-6.37-6.01-14.84-9.11-23.49-10.01,1.24-18.29,6.88-52.66,32-48ZM68.48,181.73c-14.65,2.58-10.82,23.74,4.49,24,16.98.29,16.52-21.84.51-24-.69-1.57-4.31-1.57-5,0Z" style="fill:url(#uuid-8234d38e-e6f1-40b6-897a-4f7f9502969a);"/><path d="M217.48,78.73c-10.36-2.21-23.49-.74-33.99.01,23.6,8.58,3.08,18.82-11.01,10.99-1.95-1.08-6.91-7.7-9.3-7.8-5.37-.22-19.09,8.73-24.7,10.8-1.88-1.5-3.88-2.75-5-5,18.33-3.41,4.71-4.13-.34-8.16-4.6-3.66,5.25-4.73,8.81-4.88,5.69-.24,10.54,1.91,15.16,1.92,5.91,0-5.24-9.76-6.65-10.36-3.4-1.43-9.66-1.38-14.65-3.35-13.96-5.52-28.23-23.4-30.32-38.17l15.46,18.02c4.87,3.56,14.81,13.32,20.97,12.93,3.12-.2,6.92-4.42,10.6-3.54,3.34.8,13.8,16.69,19.04,18.09,3.16.85,16.49.37,22.92,1.49.59.1,1.45,1.63,3,.99.1-1.2-1.58-1.45-2-1.99-11.91-15.28-32-9.24-44.18-37.32-9.44-21.76,4.5-.31,8.21,3.79,4.01,4.43,13.98,14.19,19.7,15.31,5.42,1.06,8.77-2.66,12.22-1.28,4.85,1.93,21.17,22.78,26.04,27.51Z" style="fill:#204153;"/><path d="M91.48,260.73c6.92,8.4,15.02,10.34,15,24-8.28-5.01-18.87-9.66-28-10-6.53-.24-11.82-.6-17,4-1.19-2.78-14.46-6.11-18-6-4.63-10.81-6.56-16.36-9-28-.59-2.9,1.6-2.09,3.48-2.04,9.01.24,20.6,4.42,28.72,8.33s15.41,13.31,24.8,9.7Z" style="fill:#d7caba;"/><path d="M209.48,358.73c6.01-.09,13.49,2,18.5,2h26c4.23,0,10.81-1.73,15.5,1-39.53,17.16-81.79,18.93-123,6,19.47-4.1,43.12-8.71,63-9Z" style="fill:#1e4d5d;"/><path d="M129.48,88.73c1.71,3.7.89,6.27,1,9,.01.33,0,.67,0,1-4.17,1.39-6.2,5.12-9,8-15.88,16.34-21.39,31.29-24,54-5.08-1.25-5.59.22-9,0,.64-1.89,1.19-4.21,2-6,6.99-15.51,1.76-11.3-8-3-.97-.12-2.02.04-3,0-1.49-9.52,22.96-26.3,22.99-31.51s-22.72,7.22-13.41-3.41c5.36-6.13,27.16-12.35,28.42-15.59,1.37-3.52-15.08-4.18-14.99-4.98.66-5.72,23.12-6.81,26.99-7.51Z" style="fill:#1e4052;"/><path d="M214.48,313.73l42.54,1.04,66.67-6.39,13.79.35c-2.23,4.63-6.89,7.55-10,11-26.01-3.29-53.97,1.23-80.47,3.03-2.44.17-6.4.77-8.53,1.97-7.42-1.47-22.78-1.97-24-11Z" style="fill:#548888;"/><path d="M60.48,230.73c.17.06.82,1.96,2.01,2.45,7.07,2.88,11.62,1.03,18.52,7.53,7.44,7.01,4.57,12.86,10.48,20.02-9.39,3.61-16.74-5.82-24.8-9.7s-19.71-8.09-28.72-8.33c-1.88-.05-4.08-.86-3.48,2.04-1.66-7.92-2.34-12.93-3-21,10.15.71,19.46,3.56,29,7Z" style="fill:#ded3c3;"/><path d="M358.48,192.73c-24.52,2.48-50.67-2.08-73,10-8.37-.17-12.21-.19-20,3-5.26-5.19-14.74.97-20-3,11.74-3.99,13.61-4.23,26.47-3.97,2.58.05,7.09,2.08,8.91,1.72,1.19-.24,13.38-12.34,18.94-14.92,17.17-7.95,44.95-7.24,58.67,7.17Z" style="fill:#c5b5a2;"/><path d="M164.48,133.73l9.99.99c-8.46,1.22-12.49,4.15-16.99,11.01-9.6,14.64-4.36,27.4,8,38,5.89,5.05,7.49,5.12,14,8,15.15,6.7,31.06,8.13,46,14,7.54,2.96,13.93,8.35,21,12,.25,2.12.12,2.25-2,2-25.54-14.76-46.56-14.81-70.98-25.52-19.28-8.45-36.09-28.28-28.02-50.48.24-.66,3.31-5.18,4-6,1.36-1.61,4.52-3.19,6-5,2.3.7,6.45.75,9,1Z" style="fill:#214152;"/><path d="M167.48,93.73c5.25,4.3,14.42,15.28,2.01,14.49,7.12,11.43,10.83,23.58,22.99,31.51-3.15.41-4.07,2.34-6,4,.48-3.16-1.27-1.88-3.19-1.71-8.63.78-17.63.47-25.81,3.71,4.5-6.86,8.53-9.79,16.99-11.01l-9.99-.99c1.12-7.53-3.54-9.91-10-11l2-8c1.01.21,5.77,1.23,5.99.99-1.36-4.28.82-13.73-3.99-14.99,14.22.71,2.52-7.17,5.01-10,.16-.19,3.42,2.54,3.99,3Z" style="fill:#9f8b69;"/><path d="M196.98,305.44l141.49,1.29-.99,1.99-13.79-.35-66.67,6.39-42.54-1.04-27.99-3.5c4.31-3.69,3.56-5.21,10.49-4.79Z" style="fill:#5c8b8a;"/><path d="M327.48,319.73c-2.55,2.83-3.69,4.83-7,8l-48,2c-4.59-.85-9.38-1.3-14-2s-9.36-1.17-14-2l-4-1c-.62-.12-1.38.12-2,0,2.12-1.21,6.09-1.81,8.53-1.97,26.51-1.8,54.47-6.31,80.47-3.03Z" style="fill:#488286;"/><path d="M61.48,278.73c.11.26-.1.68,0,1-1.64.59-1.32,3.08,0,4,.83,2.76.93,3.36,4,3,.32-.04,1-2.03,1.47-1.99,2.19.18,11.26,10.91,16.53,9.99-2.99,10.16-11.77,10.69-21,10-8.63-12.03-13-17.99-19-32,3.54-.11,16.81,3.22,18,6Z" style="fill:#c8b9a6;"/><path d="M325.48,283.73c3.65,1.05,14.03,1.85,17.31.81,1.85-.59,11.64-15.39,15.69-11.79,1.29,1.14-14.29,28.57-17,29.99h-25s9-19,9-19Z" style="fill:#c8b9a7;"/><path d="M367.48,208.73l-1,2c-3.8-5.18-8.42-9.03-15-10-1.91-1.69-7.09-1.69-9,0-5.52.6-15.6,6.66-16.5,6.66-1.22,0-6.55-4.64-10.06-5.6-4.16-1.14-9.19-1.52-13.44-1.06l-3,1c-3.08.44-6.36,2.85-8.58,2.98-2.51.15-4.43-1.96-5.42-1.98,22.33-12.08,48.48-7.52,73-10,3.85,4.04,7.04,10.76,9,16Z" style="fill:#c1b09c;"/><path d="M151.48,354.73c6.01,2.98,16.03.81,23.54.96,11.34.24,46.39,2.66,46.39,2.66-19.88.29-55.45,5.28-74.92,9.38-9.28-2.91-15.4-5.57-24-10,9.69-.65,19.31-2.38,29-3Z" style="fill:#27737f;"/><path d="M325.48,283.73l-9,18.99h25s-100,0-100,0c1.46-2.41,6.98-2.75,9.53-2.96,12.72-1.08,24.4.68,37.68-1.32,2.65-.4,17.77-3.92,19.17-4.83,3.48-2.25,4.5-10.66,10.57-12.45s6.22,2.33,7.05,2.57Z" style="fill:#cfc1af;"/><path d="M285.48,353.73c-5.38,3.08-10.31,5.53-16,8-4.69-2.73-11.27-1-15.5-1h-26c-5.01,0-12.49-2.09-18.5-2,0,0,37.34-5.06,39-5,12.69.47,20.76-1.16,32.84-1.77,1.92-.1,3.38-.65,4.16,1.77Z" style="fill:#205766;"/><path d="M245.48,202.73c5.26,3.97,14.74-2.19,20,3-5.83,2.39-12.74,8.35-17,13-.67-.33-1.34-.66-2-1-7.07-3.65-13.46-9.04-21-12l9-5c6.55,2.74,2.26,4.97,11,2Z" style="fill:#bcab96;"/><path d="M60.48,230.73c-9.54-3.44-18.85-6.29-29-7-.42-5.14-1.09-9.74-1-15,12.73,2.08,24.27,10.57,30,22Z" style="fill:#e4dacc;"/><path d="M200.48,190.73c10.94,7.94,21.33,4.7,34,10l-9,5c-14.94-5.87-30.85-7.3-46-14l21-1Z" style="fill:#c4b4a2;"/><path d="M215.48,148.73c-3.54,3.36-7.59,5.93-12,8l-5-3c5.77-7.91-3.48-2.9-10-2-4.01.88-4.27-1.08-6-4,1.35-1.26,2.29-2.53,4-4,1.93-1.66,2.85-3.59,6-4,5.08,3.31,17,7.43,23,9Z" style="fill:#8c7656;"/><path d="M200.48,190.73l-21,1c-6.51-2.88-8.11-2.95-14-8,9.84-2.14,19.32-5.93,28.49,0,2.39,1.55,4.74,5.71,6.51,6.99Z" style="fill:#d1c3b2;"/><path d="M320.48,327.73c-2.62,2.51-5.24,4.68-8,7-6.27-.1-15.19-2.41-20,2-1.73-2.54-7.82-4.97-11-5-1.98-.35-4.04-.57-6-1-.4-.09-1.41-.71-3-1l48-2Z" style="fill:#3d7c83;"/><path d="M302.48,342.73c-5.54,4.01-11.05,7.6-17,11-.78-2.42-2.24-1.87-4.16-1.77-12.08.61-20.15,2.24-32.84,1.77,12.86-2.32,25.08-4.69,37.4-9.12,1.94-.7,3.3-2.76,3.6-2.88.49-.19,2.84-.99,3-1,2.22-.08,7.11,2,10,2Z" style="fill:#24616d;"/><path d="M79.48,151.73c.98.04,2.03-.12,3,0,1.33.17,5.64,3.28,8,3-.81,1.79-1.36,4.11-2,6-4.1-.27-7.61.44-11.83-.67-.89-.23-15.25-6.57-9.17-7.33,3.49-.35,8.81-1.14,12-1Z" style="fill:#c1af9b;"/><path d="M312.48,334.73c-3.56,3-6.15,5.22-10,8-2.89,0-7.78-2.08-10-2,.6-1.93,1.27-2.14,0-4,4.81-4.41,13.73-2.1,20-2Z" style="fill:#30727c;"/><path d="M133.48,87.73c1.12,2.25,3.12,3.5,5,5,.57.45.84,1.28,2,2l-4,8c-1.89-1.92-3.21-4.69-6-5-.11-2.73.71-5.3-1-9,1-.18,2.43-.71,4-1Z" style="fill:#615034;"/><path d="M203.48,156.73c-3.66,1.71-5.69,4.31-11,2.99.76-2.5,4.85-4.42,6-5.99l5,3Z" style="fill:#978160;"/><path d="M301.48,151.73c-.33.66-.62,1.37-1,2-2.63-.99-3.62-5.77-5-7l2-2c2.5,2.09,4.7,2.9,4,7Z" style="fill:#2a4e59;"/><path d="M182.48,147.73c1.73,2.92,1.99,4.88,6,4-1.03.14-2.04,1.12-4.45,1.11-11.26-.02-4.84-2.04-1.55-5.11Z" style="fill:#a08c6d;"/><path d="M368.48,209.73l1,3c.01.62.11,1.43,0,2-1.98-.66-2.1-2.77-3-4l1-2c.12.33.9.67,1,1Z" style="fill:#c5b5a2;"/><path d="M336.48,231.73h-5c.35-.06,1.1-1.13,2.51-1.1,1.5.03,2.13,1.03,2.49,1.1Z" style="fill:#d2c4b3;"/><path d="M195.48,70.73c.42.54,2.1.79,2,1.99-1.55.64-2.41-.89-3-.99l1-1Z" style="fill:#aeaea8;"/><path d="M236.48,297.73c-.16.02-1.54.74-3,1l3-1Z" style="fill:#78998f;"/><path d="M289.48,341.73c-.3.12-1.66,2.18-3.6,2.88-12.32,4.43-21.94,7.65-47.57,10.33-16.82-.81-37.48-.81-54.36-1.18-2.95-.06-6.62-2.02-7.48-2.03,5.41-2.24,25.44-3.24,26-11l87,1Z" style="fill:#378690;"/><path d="M192.7,310.23c-7.69,4.88,47.16,14.38,47.78,14.5.93.18,2.36.71,4,1,4.64.83,9.35,1.29,14,2l-67,4c-10.37-3.42-37.62-4.62-44-13,3.71.14,60.58-18.25,45.22-8.5Z" style="fill:#95b1a5;"/><path d="M281.48,331.73c3.18.03,9.27,2.46,11,5-29.79,2.04-60.76.54-91,1-.11-.18-2.83-2.88-3-3l83-3Z" style="fill:#63999c;"/><path d="M292.48,336.73c1.27,1.86.6,2.07,0,4-.16,0-2.51.81-3,1l-87-1c.07-.93-.52-2.17-1-3,30.24-.46,61.21,1.04,91-1Z" style="fill:#468b94;"/><path d="M231.81,280.73c9.67,12.22-14.12,18.34-16.42,18.34l-65.91,11.93c6.5-5.79,63.57-17.44,71-24.87,10.38-10.38-65.26-18.27-62.82-21.26s70.21,10.88,74.15,15.86Z" style="fill:#b5b99c;"/><path d="M272.48,329.73l3,1c1.96.43,4.02.65,6,1l-83,3c-.31-.22-6.24-2.75-7-3l67-4c4.62.7,9.41,1.15,14,2Z" style="fill:#80a9a5;"/><path d="M182.78,318.76c-1.37,4.03-31.59.1-35.3-.03-6.34-8.32,10.29-12.25,15.97-13.53,1.88-.42,30.15-9.21,30.03-6.47-.07,1.58,28.45-5.17,25.86-2.41-2.04,2.17-36.5,22.27-36.55,22.44Z" style="fill:#a4b29d;"/><path d="M100.48,240.73c1.14,2.38.6,5.83,4,9-3.88,1.61-9.86-.02-14-1-3.7-7.2-8.3-10.22-5-18,5.46,3.66,12.06,3.84,15,10Z" style="fill:#bcaa97;"/><path d="M176.48,351.73c.85.01,4.52,1.96,7.48,2.03,16.88.37,37.54.37,54.36,1.18-5.49.64-11.67,2.79-22.6,3.11-.33-.02-5.9-.3-6.23-.32-11.33-.78-23.12-1.8-34.46-2.04-7.51-.16-17.52,2.01-23.54-.96.66-.04,23.67-3.02,25-3Z" style="fill:#2c7b87;"/><path d="M250.48,255.73c-1.41-4.66-1.04-3.69,0-8v8Z" style="fill:#ded3c3;"/><path d="M223.48,264.73c-2.2-.21-3.8-.84-5-1l5,1Z" style="fill:#d6c9b8;"/><path d="M305.48,203.73c-.16,0-1.82.77-3,1l3-1Z" style="fill:#ded3c3;"/><path d="M172.48,89.73c-2.06.71-5.45,1.46-5,4-.57-.46-3.82-3.19-3.99-3-2.49,2.83,9.2,10.71-5.01,10-1.78-.09-4.21-.61-6-1-1.38-.3-4.56-1.43-6-2-1.79-.7-4.37-1.99-6-3-1.16-.72-1.43-1.55-2-2,5.61-2.06,19.33-11.02,24.7-10.8,2.4.1,7.36,6.72,9.3,7.8Z" style="fill:#bfb38c;"/><path d="M297.48,144.73l-2,2c-9.62-8.56-14.04,5.78-23.27,3.8-4.27-.91-12.28-11.62-19.03-14.01-11.24-3.97-21.15.79-32.74-2.26-2.1-.55-16.4-7.11-12.96-10.53,1.3-1.29,7.25,4.31,9.3,5.18,13.51,5.76,27.1-.18,39.96,5.04,6.17,2.5,14.11,13.17,17.45,13.61,6.08.8,10.06-13.89,23.27-2.84Z" style="fill:#1d4254;"/><path d="M244.48,107.72c-5.46-2.41-6.03,2.12-10.56,2.95-15.04,2.73-11.13-10.6-12.43-11.94-.48-.49-11.64,1.1-13-2.98,14.96-2.05,27.84-2.81,35.99,11.98Z" style="fill:#224151;"/><path d="M292.48,126.72c-.38.45-10.68,4.69-10.97,2.52-.78-5.85,14.69-6.9,10.97-2.52Z" style="fill:#254456;"/><path d="M73.48,181.73c-1.18-.16-3.88-.2-5,0,.69-1.57,4.31-1.57,5,0Z" style="fill:#dbcfbf;"/><path d="M145.48,143.73c-8.07,22.21,8.74,42.03,28.02,50.48,24.42,10.71,45.44,10.76,70.98,25.52.97.56,1.52,1.36,3,1-2.67,3.17-8,9.15-9,13-.65-.36-1.33-.68-2-1-10.24-4.96-14.47-6.7-26.67-3.17-6.74,1.95-11.06,11.46-19.69,8.04-2.42-.96-.25-8.95-9.66-12.33-11.07-3.98-18.74,2.31-27.44.43-4.3-.93-6.13-7.88-10.04-10.96-12.37-9.74-21.88,1.1-31.49-4.51-5.78-3.38,4.16-12.19,4.9-18.09,1.51-11.97-6.86-28.44-18.9-31.41,2.61-22.71,8.12-37.66,24-54,1.57,17.12,12,26.43,24,37Z" style="fill:#cfc49c;"/><path d="M147.48,227.73l4,20c-7.82,2.89-14.94,4.18-23.43,2.93-12.18-1.79.71-4.08,2.67-9.19,1.76-4.57-.04-5.55-.24-8.75-.08-1.22,1.04-1.67.06-5.55-.83-3.29-4.32-11.51-7.06-12.45,11.78-6.25,19.88,2.9,24,13Z" style="fill:#cebfad;"/><path d="M147.48,279.73c5.52,1.19,12.38,3.54,18,5l3,7c-4.22.64-32.63,4-34,2.99-.2-.15,1.94-3.04,1.99-4.59.18-5.67-5.04-9.86-9.99-11.4-2.24-.7-5.81-2.39-3,1v1c-.55-.05-10.63.59-11.01.99-.21.22-.32,3.79-.99,6.01.04-3.85.16-8.31-1-12,12.28-2.51,24.99,1.42,37,4Z" style="fill:#cabaa7;"/><path d="M193.48,240.73c8.8,6.72,18.04,0,27,2-4.33,3.49-2.79,6.22-4.94,8.56-3.48,3.8-19.43-2.92-24.68-3.44-4.64-.46-7.37.67-11.39.88l-6-21c14.92.83,7,12.08,20,13Z" style="fill:#e1d6c8;"/><path d="M147.48,279.73c-12.01-2.58-24.72-6.51-37-4-.96-3.06-5.5-8.17-7.98-10.5,15.72-8.99,35.16,1.52,44.98,14.5Z" style="fill:#cfc1af;"/><path d="M173.48,227.73l6,21c-1.83.1-4.05,1.68-5.48,1.56-1.35-.11-10.98-5.19-11.52-6.56l-1-14c3.48-.2,7.16-2.27,12-2Z" style="fill:#dacebe;"/><path d="M123.48,214.73c2.74.94,6.23,9.16,7.06,12.45.98,3.89-.14,4.33-.06,5.55-.86-3.23-4.03-5.02-7-6l-3-1c-2.81-.22-7.48.84-10,2l-8-9c7.08-2.95,11.57-7.23,21-4Z" style="fill:#c9b9a6;"/><path d="M123.48,280.73c5.97.49,13.5,7.93,8,13.51l-22,1.49c.88-2.55,1.23-5.45,2-7.99.67-2.22.79-5.78.99-6.01.37-.41,10.45-1.04,11.01-.99Z" style="fill:#c3b29e;"/><path d="M102.48,218.73l8,9c-5.73,2.65-7.87,7.42-10,13-2.94-6.16-9.54-6.34-15-10,3.72-8.77,9.6-8.91,17-12Z" style="fill:#c3b29f;"/><path d="M106.48,284.73c0,5.09-.65,5.85-3,10l-13.46-5.04c-.51.08-1,2.11-1.54,3.04,1.28-8.62-2.88-14.01-10-18,9.13.34,19.72,4.99,28,10Z" style="fill:#d2c4b3;"/><path d="M238.26,235.55c-.66,2.54.61,6.65.2,7.18-.58.75-10.1-6.37-17.99,0-8.96-2-18.2,4.72-27-2,8.59.6,13.16-8.5,19.51-9.53,8.34-1.36,12.63-.81,25.28,4.35Z" style="fill:#e5dccf;"/><path d="M161.48,229.73l1,14c-4.4-.43-7.18,2.59-11,4l-4-20c4.69,2.15,8.89,2.29,14,2Z" style="fill:#d4c7b6;"/><path d="M83.48,294.73c-5.27.92-14.34-9.81-16.53-9.99-.47-.04-1.15,1.95-1.47,1.99-4.43-6.84,5.69-10.29,11.58-8.07,7.05,2.65,8.35,9.51,6.42,16.07Z" style="fill:#cec0ae;"/><path d="M103.48,294.73c-4.83,8.54-12.47,10.57-22,9.99,4.18-3.27,4.8-8.18,7-11.99.54-.94,1.03-2.96,1.54-3.04l13.46,5.04Z" style="fill:#cbbba9;"/><path d="M168.48,291.73l-3-7c9.24,2.41,23.05,3.97,3,7Z" style="fill:#d2c4b3;"/><path d="M126.48,278.73l-3,1c-2.81-3.39.76-1.7,3-1Z" style="fill:#cfc1af;"/><path d="M61.48,283.73c-1.32-.92-1.64-3.41,0-4,.31,1.03-.31,2.97,0,4Z" style="fill:#d7caba;"/><path d="M117.25,229.92c9.45-1.07,15.85,8.55,7.15,14.23-1.62,1.06-13.82,5.78-15.19,5.4-9.8-2.7-3.26-18.34,8.04-19.62Z" style="fill:#c6b6a3;"/><path d="M351.48,200.73c-2.13-.31-6.78-.24-9,0,1.91-1.69,7.09-1.69,9,0Z" style="fill:#c5b5a2;"/><path d="M248.48,218.73c-.42.45-.57,1.49-1,2-1.48.36-2.03-.44-3-1,2.12.25,2.25.12,2-2,.66.34,1.33.67,2,1Z" style="fill:#334d59;"/><path d="M302.48,200.73c-.3.03-1.63.8-3,1l3-1Z" style="fill:#c5b5a2;"/><path d="M123.48,226.73c-.6-.2-2.84-.99-3-1l3,1Z" style="fill:#cebfad;"/><path d="M130.48,98.73c.43,17.45,2.33,26.4,15.94,38.41,1.26,1.12,2.5-.65,3.06.59-.69.82-3.76,5.34-4,6-12-10.57-22.43-19.88-24-37,2.8-2.88,4.83-6.61,9-8Z" style="fill:#c9be96;"/><path d="M136.48,102.73c1.77,1.8,3.9,4.53,6,6,1.82,3.71-2,10.4-2,12,0,3.19,12.16,11.13,15,12-1.48,1.81-4.64,3.39-6,5-.57-1.23-1.8.53-3.06-.59-13.61-12.01-15.5-20.96-15.94-38.41,0-.33.01-.67,0-1,2.79.31,4.11,3.08,6,5Z" style="fill:#c0b48d;"/><path d="M146.48,121.73c.79,1.5,2.65.94,4,1s2.84-.2,4,0c6.46,1.09,11.12,3.47,10,11-2.55-.25-6.7-.3-9-1-2.84-.87-15.01-8.81-15-12,2.02.23,3.98.74,6,1Z" style="fill:#937e5b;"/><path d="M145.48,109.73c2.48,1.42,3.12,1.91,6,3,1.75.66,2.58,1.5,5,2l-2,8c-1.16-.2-2.71.06-4,0-.8-1.59-2.71-.83-4-1-2.02-.26-3.98-.77-6-1,0-1.6,3.82-8.29,2-12,.45.32,2.04.45,3,1Z" style="fill:#ada17a;"/><path d="M158.48,100.73c4.81,1.27,2.63,10.72,3.99,14.99-.22.24-4.98-.79-5.99-.99-2.42-.5-3.25-1.34-5-2,4.36-.57-1.62-10.17,1-13,1.79.39,4.22.91,6,1Z" style="fill:#927d5c;"/><path d="M244.48,325.73c-1.64-.29-3.07-.82-4-1l4,1Z" style="fill:#548888;"/><path d="M275.48,330.73l-3-1c1.59.29,2.6.91,3,1Z" style="fill:#63999c;"/><path d="M146.48,97.73l-1,12c-.96-.55-2.55-.68-3-1-2.1-1.47-4.23-4.2-6-6l4-8c1.63,1.01,4.21,2.3,6,3Z" style="fill:#77603e;"/><path d="M152.48,99.73c-2.62,2.83,3.36,12.43-1,13-2.88-1.09-3.52-1.58-6-3l1-12c1.44.57,4.62,1.7,6,2Z" style="fill:#856f4e;"/><path d="M70.21,184.92c10.15-2.13,17.49,11.27,9.67,15.7-11.7,6.63-22.38-13.03-9.67-15.7Z" style="fill:#d9ccbb;"/><path d="M150.48,122.73c-1.35-.06-3.21.5-4-1,1.29.17,3.2-.59,4,1Z" style="fill:#9f8b69;"/><path d="M574.45,299.65c-.84-7.28-1.4-17.92-1.4-29.4-11.76,19.32-30.8,30.8-51.52,30.8-16.52,0-29.68-7.56-36.12-21-3.64-7.84-5.32-17.64-5.32-34.72v-3.92l.56-56.56c0-.84.28-1.4.28-2.24,0-11.2-.84-17.36-3.08-20.44-2.52-3.36-4.76-4.2-17.36-4.48v-6.72l56.28-3.64c-1.4,20.16-1.96,30.8-2.24,55.72l-.28,29.68v5.32c0,19.04.84,26.04,3.64,34.16,3.08,9.24,9.8,13.72,19.6,13.72,12.88,0,23.52-8.4,30.24-23.52,3.92-9.24,5.32-18.2,5.32-33.32v-44.24c0-15.4-1.12-21-4.2-24.08-2.8-2.24-4.48-2.8-16.24-3.08v-6.72l56.28-3.64q-1.68,38.36-1.68,56v58.24c0,24.36,2.8,28.84,18.2,29.12v6.44l-50.96,2.52Z" style="fill:#204153;"/><path d="M693.73,262.41c0,25.2,1.96,27.72,21,28v6.72h-75.88v-6.72c19.04-.28,21-3.08,21-28V121.29c0-24.64-1.96-27.16-21.28-27.16v-6.44l56.84-3.08c-1.12,20.72-1.68,38.64-1.68,57.4v88.2l37.52-43.12c5.6-6.72,8.68-12.6,8.68-17.64,0-7.56-5.88-11.2-19.32-12.04v-6.44h72.24v6.44c-8.96,1.12-15.68,3.08-23.52,7.28-9.52,5.04-15.12,9.8-26.88,22.68l-10.36,11.48,38.92,66.92c10.36,17.36,16.24,22.4,29.12,25.2v6.16h-51.52c-2.8-6.16-10.36-21.28-12.32-24.92l-26.88-48.16-15.68,17.64v20.72Z" style="fill:#204153;"/><path d="M867.61,147.33c-1.12,16.8-1.68,36.4-1.68,54.32v60.76c0,24.92,1.96,27.72,21.84,28v6.72h-77.84v-6.72c19.88-.28,21.84-3.08,21.84-28v-77.56c0-24.92-1.4-26.88-21-27.16v-6.72l56.84-3.64ZM849.13,82.93c11.2,0,20.16,8.96,20.16,20.16s-8.96,20.16-20.16,20.16-20.16-8.96-20.16-20.16,8.96-20.16,20.16-20.16Z" style="fill:#204153;"/><path d="M956.65,147.33c.56,10.64.84,17.08.84,22.68v8.4c11.2-20.72,25.48-31.64,41.44-31.64,13.72,0,23.8,9.24,23.8,21.28,0,10.08-8.4,17.08-20.16,17.08-7.56,0-11.2-2.52-13.16-8.96-2.24-7.84-3.64-9.8-8.12-9.8h-.56c-5.32.28-10.92,5.04-15.68,13.16-4.48,8.4-6.72,17.92-6.72,31.08v51.8c0,25.2,1.68,27.16,22.4,28v6.72h-77.84v-6.72c19.32-.28,21.28-3.08,21.28-28v-77.56c0-23.8-2.52-27.16-20.16-27.16v-6.72l52.64-3.64Z" style="fill:#204153;"/><path d="M1141.73,194.37c3.64-9.24,4.76-14.28,4.76-19.6,0-11.48-6.44-16.52-22.12-17.36v-6.44h61.04v6.44c-15.68,2.24-22.68,10.36-35.28,42l-47.6,120.96c-11.48,28.84-21.56,39.2-38.92,39.2-13.44,0-20.44-6.44-20.44-19.32,0-9.52,3.92-14.56,11.2-14.56,2.52,0,5.6.28,11.2,1.4,6.72,1.4,8.96,1.68,11.76,1.68,8.68,0,12.6-3.64,17.92-16.52l4.2-11.2-49-117.04c-9.52-22.4-12.04-25.48-25.2-26.6v-6.44h74.76v6.72c-12.04.28-16.8,3.36-16.8,10.92,0,4.2.84,7.28,4.2,16.24l28.84,75.6,25.48-66.08Z" style="fill:#204153;"/><path d="M1305.52,299.65c-.84-7.28-1.4-17.92-1.4-29.4-11.76,19.32-30.8,30.8-51.52,30.8-16.52,0-29.68-7.56-36.12-21-3.64-7.84-5.32-17.64-5.32-34.72v-3.92l.56-56.56c0-.84.28-1.4.28-2.24,0-11.2-.84-17.36-3.08-20.44-2.52-3.36-4.76-4.2-17.36-4.48v-6.72l56.28-3.64c-1.4,20.16-1.96,30.8-2.24,55.72l-.28,29.68v5.32c0,19.04.84,26.04,3.64,34.16,3.08,9.24,9.8,13.72,19.6,13.72,12.88,0,23.52-8.4,30.24-23.52,3.92-9.24,5.32-18.2,5.32-33.32v-44.24c0-15.4-1.12-21-4.2-24.08-2.8-2.24-4.48-2.8-16.24-3.08v-6.72l56.28-3.64q-1.68,38.36-1.68,56v58.24c0,24.36,2.8,28.84,18.2,29.12v6.44l-50.96,2.52Z" style="fill:#204153;"/></svg>
|