disaster-broadcast-studio 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +109 -2
  3. package/assets/FONT-LICENSE.txt +93 -0
  4. package/assets/MONO-FONT-LICENSE.txt +93 -0
  5. package/assets/NORTH-KOREA-LICENSE.txt +25 -0
  6. package/assets/README.md +25 -0
  7. package/assets/REGION-LICENSE.txt +48 -0
  8. package/assets/attribution.json +71 -0
  9. package/assets/audio/README.md +9 -0
  10. package/assets/audio/notification.mjs +10 -0
  11. package/assets/audio/notification.wav +0 -0
  12. package/assets/countries.geojson.gz +0 -0
  13. package/assets/provinces.geojson.gz +0 -0
  14. package/assets/regions.geojson.gz +0 -0
  15. package/assets/workspace/README.md +14 -0
  16. package/assets/workspace/scenario.yaml +34 -0
  17. package/dist/assets.d.ts +2 -0
  18. package/dist/assets.js +9 -0
  19. package/dist/audio/browser.d.ts +13 -0
  20. package/dist/audio/browser.js +30 -0
  21. package/dist/audio/render.d.ts +12 -0
  22. package/dist/audio/render.js +83 -0
  23. package/dist/audio/wav.d.ts +9 -0
  24. package/dist/audio/wav.js +49 -0
  25. package/dist/cli.d.ts +2 -0
  26. package/dist/cli.js +172 -0
  27. package/dist/credits.d.ts +18 -0
  28. package/dist/credits.js +20 -0
  29. package/dist/load.d.ts +13 -0
  30. package/dist/load.js +98 -0
  31. package/dist/notifications.d.ts +9 -0
  32. package/dist/notifications.js +8 -0
  33. package/dist/output.d.ts +7 -0
  34. package/dist/output.js +51 -0
  35. package/dist/render.d.ts +12 -0
  36. package/dist/render.js +134 -0
  37. package/dist/scenario.d.ts +256 -0
  38. package/dist/scenario.js +381 -0
  39. package/dist/timeline.d.ts +56 -0
  40. package/dist/timeline.js +116 -0
  41. package/dist/video/Alerts.d.ts +6 -0
  42. package/dist/video/Alerts.js +62 -0
  43. package/dist/video/AudioTrack.d.ts +7 -0
  44. package/dist/video/AudioTrack.js +14 -0
  45. package/dist/video/Broadcast.d.ts +12 -0
  46. package/dist/video/Broadcast.js +190 -0
  47. package/dist/video/Bulletin.d.ts +9 -0
  48. package/dist/video/Bulletin.js +35 -0
  49. package/dist/video/Map.d.ts +13 -0
  50. package/dist/video/Map.js +237 -0
  51. package/dist/video/SignalEffects.d.ts +13 -0
  52. package/dist/video/SignalEffects.js +32 -0
  53. package/dist/video/fonts.d.ts +13 -0
  54. package/dist/video/fonts.js +11 -0
  55. package/dist/video/index.d.ts +1 -0
  56. package/dist/video/index.js +5 -0
  57. package/dist/video/useBundledFonts.d.ts +1 -0
  58. package/dist/video/useBundledFonts.js +27 -0
  59. package/dist/workspace.d.ts +6 -0
  60. package/dist/workspace.js +33 -0
  61. package/package.json +56 -4
  62. package/skills/README.md +47 -0
  63. package/skills/scenario-writing/SKILL.md +50 -0
  64. package/skills/scenario-writing/examples/receipt.mjs +10 -0
  65. package/skills/scenario-writing/examples/texture.mjs +11 -0
  66. package/skills/scenario-writing/references/README.md +18 -0
  67. package/skills/scenario-writing/references/audio.md +90 -0
  68. package/skills/scenario-writing/references/civil-defense.md +1664 -0
  69. package/skills/scenario-writing/references/direction.md +46 -0
  70. package/skills/scenario-writing/references/disaster-sms-rules.md +814 -0
  71. package/skills/scenario-writing/references/disaster-sms-templates.md +2036 -0
  72. package/skills/scenario-writing/references/format.md +152 -0
  73. package/skills/scenario-writing/references/hazard-information.md +120 -0
  74. package/skills/scenario-writing/references/news-writing.md +134 -0
  75. package/skills/scenario-writing/references/status-systems.md +89 -0
package/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 neuwcodebox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ Third-party map data, fonts and quoted reference materials retain their
24
+ respective licenses and attribution requirements; see assets/README.md and
25
+ skills/scenario-writing/references/.
package/README.md CHANGED
@@ -1,3 +1,110 @@
1
- # Temporary Holding Version
1
+ # 재난방송실 · Disaster Broadcast Studio
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ YAML/JSON 시나리오를 한국형 재난방송 호러 영상으로 만드는 CLI입니다. 문자·뉴스·지도·시계·음향을 텍스트로 연출하고, **1920×1080 · 60fps MP4**로 출력합니다.
4
+
5
+ ![재난방송실 출력 화면 — 허구의 기술 검증용 방송](https://raw.githubusercontent.com/neuwcodebox/disaster-broadcast-studio/main/docs/screenshots/broadcast.png)
6
+
7
+ ## 할 수 있는 일
8
+
9
+ - **방송 화면:** 최신순 재난문자·정정 이력, 독립 뉴스, 상태 박스, 장문 방송 안내.
10
+ - **지도 연출:** 실제 시도·시군구 경계, 채우기·윤곽선 중첩, 범례·지점·영역·진행선, 카메라 이동·보조 지도.
11
+ - **시간 연출:** 컷 안에서는 실시간으로, 컷 사이에서는 지정한 이야기 시각으로 전환. 임의 프레임에서도 같은 상태를 복원.
12
+ - **음향·효과:** 공통 수신음, 로컬 음원, Tone.js 코드의 WAV 합성, 페이드·침묵·신호 간섭·송출 종료.
13
+ - **텍스트 제작 흐름:** 검증, 렌더 없는 상태 조회, PNG 미리보기, 구간·전체 영상 출력, 게시용 출처 생성.
14
+
15
+ 실제 긴급 서비스에 연결하거나 문자를 발송하지 않습니다. 작품 제목과 필수 허구 고지는 영상 첫 5초에 표시합니다.
16
+
17
+ ## 설치와 시작
18
+
19
+ **Node.js 22 이상**과 Chromium 실행에 필요한 OS 라이브러리가 필요합니다.
20
+
21
+ 빈 작품 폴더에 npm 패키지를 설치합니다.
22
+
23
+ ```sh
24
+ mkdir my-film
25
+ cd my-film
26
+ npm install disaster-broadcast-studio
27
+ npx dbs init
28
+ ```
29
+
30
+ `init`은 유효한 `scenario.yaml`, 작품용 `README.md`, `audio/`, `audio-code/`를 만듭니다. 기존 파일과 충돌하면 생성 전에 중단합니다. 작품은 엔진 저장소 밖에서 관리합니다.
31
+
32
+ 창작 AI와 함께 제작한다면 [창작 스킬 설치 안내](skills/README.md)를 따르세요. 스킬에는 집필·연출 지침, 공식 문안 참고자료, 음향 코드 예제가 포함되어 있습니다. 사용자 범위에 한 번 설치하며 `dbs init`과 별도로 관리합니다.
33
+
34
+ ## 첫 영상 만들기
35
+
36
+ `scenario.yaml`의 제목·기관·컷·이벤트를 수정하고 다음 순서로 확인합니다.
37
+
38
+ ```sh
39
+ # 입력·참조·음원·시간 검증
40
+ npx dbs validate scenario.yaml
41
+
42
+ # 8초 지점의 상태와 화면 확인
43
+ npx dbs inspect scenario.yaml --frame 480
44
+ npx dbs frame scenario.yaml --frame 480 --out preview.png
45
+
46
+ # 5초 구간을 확인한 뒤 전체 영상 출력
47
+ npx dbs render scenario.yaml --from 300 --to 599 --out clip.mp4
48
+ npx dbs render scenario.yaml --out film.mp4
49
+ ```
50
+
51
+ 프레임은 **0부터 시작**하며 구간의 **끝 프레임도 포함**합니다. 300~599는 60fps에서 5초입니다. 컷 안의 시간은 실제 재생 시간과 같고, 컷 경계에서만 시간을 생략할 수 있습니다. 오프닝 이후에 중요한 사건을 배치하고, 읽기 시간 경고가 나오면 문자 사이 간격을 늘리세요.
52
+
53
+ 첫 렌더에서는 Remotion이 Chrome Headless Shell을 다운로드할 수 있습니다. `--browser /path/to/chromium`으로 설치된 브라우저를 지정할 수도 있습니다. 준비 후에는 로컬 지도·글꼴·음원으로 렌더합니다.
54
+
55
+ Linux에서 소프트웨어 WebGL을 사용하려면 `frame`·`render` 명령에 **`--gl swangle`**을 추가합니다. 기본값은 `--gl angle`, 동시 렌더 수는 `--concurrency 2`입니다. 60fps는 결과 영상 규격이며 렌더 속도는 환경에 따라 달라집니다.
56
+
57
+ ### 결과 파일
58
+
59
+ | 파일 | 용도 |
60
+ | --- | --- |
61
+ | `film.mp4` | H.264/yuv420p 영상과 AAC 오디오. 음원이 없어도 무음 트랙 포함 |
62
+ | `film.mp4.json` | 작품 정보, 출력 프레임 범위, 자산·출처 기록 |
63
+ | `film.mp4.credits.txt` | 영상 게시 설명란에 넣을 출처 문안 |
64
+
65
+ PNG 출력에도 `.json`과 `.credits.txt`가 함께 생성됩니다. 기존 결과나 부속 파일이 있으면 중단하며, 교체하려면 `--overwrite`를 지정합니다. 오류는 종료코드 1로 반환합니다.
66
+
67
+ 영상 게시 시 **`.credits.txt` 내용을 설명란 등에 함께 제공**하세요. 기본 지도에는 출처를 상시 표시하지 않습니다. 사용자 지도·음원의 추가 표시 조건은 작품별로 확인합니다.
68
+
69
+ ## 시나리오와 음향 작성
70
+
71
+ 정확한 필드와 이벤트 사용법은 [작품 형식·CLI](skills/scenario-writing/references/format.md)에 정리되어 있습니다. `cuts`는 이야기 시각과 길이, `events`는 문자·뉴스·지도·음향의 시점을 정합니다.
72
+
73
+ ```sh
74
+ npx dbs schema --out scenario.schema.json
75
+ npx dbs regions --search 철원 --json
76
+ npx dbs credits scenario.yaml --out description-credits.txt
77
+ ```
78
+
79
+ 문자 수신음은 기본 제공하며 문자별로 끄거나 교체할 수 있습니다. 작품 고유 음향은 사용권이 있는 로컬 파일을 연결하거나, [Tone.js 음향 가이드](skills/scenario-writing/references/audio.md)에 따라 ES 모듈을 작성해 WAV로 합성합니다.
80
+
81
+ ```sh
82
+ npx dbs audio audio-code/sound.mjs --duration 3 --seed 731 --out audio/sound.wav
83
+ ```
84
+
85
+ `audio-code/sound.mjs`는 직접 작성하는 파일입니다. 합성 결과 옆 `.json`에는 시드·음량 통계와 Tone.js·Chromium 버전을 기록합니다. 음원 경로는 시나리오 파일을 기준으로 해석하며, 자산마다 출처와 이용조건을 지정합니다.
86
+
87
+ ## 개발
88
+
89
+ 저장소에서 의존성을 설치하고 검증·빌드합니다.
90
+
91
+ ```sh
92
+ npm ci
93
+ npm test
94
+ npm run typecheck
95
+ npm run build
96
+ npm pack
97
+ ```
98
+
99
+ `npm pack`은 설치 가능한 `.tgz`를 만듭니다. 코드와 배포 자산·창작 스킬을 포함하며 실제 작품은 포함하지 않습니다. 렌더 검증용 입력은 `node scripts/render-fixtures.mjs /tmp/dbs-fixtures`로 저장소 밖에 생성할 수 있습니다.
100
+
101
+ | 문서 | 다루는 내용 |
102
+ | --- | --- |
103
+ | [SPEC](docs/SPEC.md) | 목표·요구사항 |
104
+ | [TECH](docs/TECH.md) | 구현 구조·설계 근거 |
105
+ | [PLAN](docs/PLAN.md) | 검증 범위·현재 상태·다음 작업 |
106
+ | [창작 스킬](skills/scenario-writing/SKILL.md) | 독립된 창작 AI의 제작 지침 |
107
+
108
+ ## 이용조건
109
+
110
+ 코드는 [MIT](LICENSE)입니다. 지도·글꼴·공통 수신음은 [자산 출처와 이용조건](assets/README.md)을 확인하세요. Remotion에는 [별도 라이선스 조건](https://www.remotion.dev/pricing)이 적용됩니다.
@@ -0,0 +1,93 @@
1
+ Copyright 2018 IBM Corp. All rights reserved. IBMPlexSansKR-ExtraLight.ttf: Copyright 2018 IBM Corp. All rights reserved. IBMPlexSansKR-Light.ttf: Copyright 2018 IBM Corp. All rights reserved. IBMPlexSansKR-Regular.ttf: Copyright 2018 IBM Corp. All rights reserved. IBMPlexSansKR-Medium.ttf: Copyright 2018 IBM Corp. All rights reserved. IBMPlexSansKR-SemiBold.ttf: Copyright 2018 IBM Corp. All rights reserved. IBMPlexSansKR-Bold.ttf: Copyright 2018 IBM Corp. All rights reserved.
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,93 @@
1
+ Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ThinItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLight.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Light.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-LightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Regular.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Italic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Medium.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-MediumItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Bold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-BoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved.
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,25 @@
1
+ North Korea (Democratic People's Republic of Korea) administrative boundary
2
+
3
+ Source: World Food Programme (WFP), OCHA Regional Office for Asia and the Pacific.
4
+ Dataset represented year: 2018.
5
+ Distribution: geoBoundaries gbOpen PRK ADM0, boundary ID PRK-ADM0-24118357,
6
+ revision 9469f09 (API metadata source update: 2023-01-19).
7
+
8
+ Original source:
9
+ https://data.humdata.org/dataset/dpr-korea-administrative-boundaries
10
+ Redistributed source geometry:
11
+ https://github.com/wmgeolab/geoBoundaries/blob/9469f09/releaseData/gbOpen/PRK/ADM0/geoBoundaries-PRK-ADM0.geojson
12
+ Source and license metadata:
13
+ https://www.geoboundaries.org/api/current/gbOpen/PRK/ADM0/
14
+
15
+ License: Creative Commons Attribution 3.0 Intergovernmental Organisations
16
+ (CC BY 3.0 IGO).
17
+ License and legal code:
18
+ https://creativecommons.org/licenses/by/3.0/igo/
19
+ https://creativecommons.org/licenses/by/3.0/igo/legalcode
20
+
21
+ The original boundary geometry is retained without simplification. Unused
22
+ attributes are replaced by a country name and code, and the geometry is
23
+ combined with separately licensed neighboring-country features and gzipped.
24
+ Maps are produced works; no endorsement by WFP, OCHA or the UN is implied.
25
+ Keep this attribution and the license link when redistributing the data.
@@ -0,0 +1,25 @@
1
+ # 출력 자산
2
+
3
+ | 파일 | 출처·판본 | 이용조건·가공 |
4
+ | --- | --- | --- |
5
+ | `regions.geojson.gz` | [vuski/admdongkor 2026-07-01 원본](https://github.com/vuski/admdongkor/blob/master/ver20260701/HangJeongDong_ver20260701.geojson), 원자료 통계청 SGIS | SGIS 공공누리 제1유형, 가공 데이터 CC BY 4.0. 행정동을 시군구로 병합하고 원본의 경계 좌표를 유지. `REGION-LICENSE.txt` 참조. |
6
+ | `provinces.geojson.gz` | 위 시군구 경계를 시도 코드로 병합 | 동일 이용조건. 지역 사이 공유 경계를 병합하여 시도 외곽선으로 사용. |
7
+ | `countries.geojson.gz` | [Natural Earth 5.1.2, 1:10m admin 0](https://github.com/nvkelso/natural-earth-vector/blob/v5.1.2/geojson/ne_10m_admin_0_countries.geojson), 북한은 [WFP·OCHA/geoBoundaries PRK ADM0](https://www.geoboundaries.org/api/current/gbOpen/PRK/ADM0/) 2018판, revision `9469f09` | Natural Earth는 [Public domain](https://www.naturalearthdata.com/about/terms-of-use/), 북한은 [CC BY 3.0 IGO](https://creativecommons.org/licenses/by/3.0/igo/). 동아시아 7개국의 원본 경계 좌표를 유지하고 설명 열만 정리. `NORTH-KOREA-LICENSE.txt` 참조. |
8
+ | IBM Plex Sans KR 400/600 | npm `@fontsource/ibm-plex-sans-kr` 5.3.0 | [SIL OFL 1.1](https://github.com/IBM/plex/blob/master/LICENSE.txt). 한글 본문용. `FONT-LICENSE.txt` 참조. |
9
+ | IBM Plex Mono 400 | npm `@fontsource/ibm-plex-mono` 5.3.0 | 동일 OFL. 시각·페이지 수에 고정폭 숫자 사용. `MONO-FONT-LICENSE.txt` 참조. |
10
+
11
+ 지도 자산은 원본 좌표를 단순화하거나 정밀도를 낮추지 않고 gzip으로 압축한다. `scripts/build-map-assets.mjs`로 재생성하며 렌더 중 다운로드하지 않는다. MapLibre의 GeoJSON 단순화도 비활성화한다. 기본 지도에서 대한민국 육지·해안·시군구 강조는 같은 SGIS 폴리곤을 사용한다. 시도 구분선은 그 폴리곤을 병합한 경계다. 배경의 대한민국 도형은 기본 지도에서 제외하여 서로 다른 해안선을 겹치지 않는다.
12
+
13
+ ```sh
14
+ node scripts/build-map-assets.mjs /path/HangJeongDong_ver20260701.geojson /path/ne_10m_admin_0_countries.geojson /path/geoBoundaries-PRK-ADM0.geojson
15
+ ```
16
+
17
+ 지도·글꼴은 설치된 패키지와 압축 파일에서 로컬로 로드한다. 지도 위에는 출처를 상시 표시하지 않는다. `attribution.json`의 제공자·원자료·라이선스 링크·가공 내용을 출력 옆 `.credits.txt`와 `.json`에 기록한다. 영상 게시 시 `.credits.txt` 내용을 유튜브 설명란 등 시청자가 접근할 수 있는 곳에 함께 제공한다. 원본 자산과 폰트를 재배포할 때는 동봉 라이선스도 유지한다.
18
+
19
+ 공공누리 1유형은 저작자·출처를 요구하지만 영상 내 고정 위치를 지정하지 않는다. [CC BY 4.0 제3조(a)(2)](https://creativecommons.org/licenses/by/4.0/legalcode)는 매체·상황에 합리적인 방식의 표시와 링크를 허용한다. [CC BY 3.0 IGO 제4조(b)](https://creativecommons.org/licenses/by/3.0/igo/legalcode)도 매체에 합리적인 저작자·출처·가공 표시를 요구하며, 공동 기여자 크레딧을 별도로 넣으면 그 안에서 동등한 비중으로 표시해야 한다. 이 배포물의 기본 지도에는 영상 위 고정 워터마크 의무가 확인되지 않아 공개 설명란 크레딧 방식을 사용한다. 기계 메타데이터만 남기고 게시 출처를 생략하지 않는다. Natural Earth는 public domain이며 OFL은 폰트 파일 재배포 조건이다. 사용자 경계 파일은 WGS84 Polygon/MultiPolygon FeatureCollection이며 `map.attribution`에 필요한 출처표시를 지정한다. 지도는 한반도와 주변 동아시아를 대상으로 한다.
20
+
21
+ 공통 문자 수신음은 직접 합성한 CC0 음원이며 [생성 코드·이용조건](audio/README.md)을 동봉한다. 실제 기관의 경보음을 모방하지 않는다. 작품 고유의 로컬 음원에는 각각 `source`, `license`를 기록한다. 기술 검증 스크립트의 사인파도 직접 생성한 CC0 음원이다.
22
+
23
+ Remotion은 [사용 주체별 라이선스 조건](https://www.remotion.dev/pricing)이 적용된다. MapLibre GL JS는 BSD-3-Clause, React는 MIT다.
24
+
25
+ Tone.js 15.1.22는 MIT 라이선스이며 의존성에 해당 라이선스가 포함된다. 창작 스킬의 `examples/receipt.mjs`, `examples/texture.mjs`는 직접 작성한 CC0-1.0 음향 코드다. `dbs audio`는 코드로 만든 소리와 사용자가 제공한 로컬 샘플을 WAV로 출력한다. 샘플 사용권은 작품별 출처에 보존한다.
@@ -0,0 +1,48 @@
1
+ DATA_LICENSE — admdongkor 경계 데이터 / boundary data
2
+
3
+ 이 파일은 admdongkor 저장소의 [데이터](행정동·시군구·시도 경계: geojson, parquet,
4
+ 중심점 등)에 적용됩니다. 소스 코드(js/, lib/ 등)는 별도로 MIT License(LICENSE)를 따릅니다.
5
+
6
+ This file covers the DATA in this repository (administrative boundary files:
7
+ geojson, parquet, centroids). Source code (js/, lib/) is licensed separately
8
+ under the MIT License (see LICENSE).
9
+
10
+ ──────────────────────────────────────────────────────────
11
+
12
+ 1. 가공물 라이선스 / License of this dataset
13
+
14
+ 이 저장소가 추가·가공한 부분(경계 보정, 행정동 변경이력 반영, 코드 매칭 인덱스,
15
+ 시계열 데이터 등)은 Creative Commons Attribution 4.0 International (CC BY 4.0)
16
+ 으로 제공됩니다.
17
+ SPDX-License-Identifier: CC-BY-4.0
18
+ 전문(Full text): https://creativecommons.org/licenses/by/4.0/ (국문: .../legalcode.ko)
19
+
20
+ 2. 원자료 조건 / Upstream source condition
21
+
22
+ 경계의 원자료는 통계청 통계지리정보서비스(SGIS)가 공공누리 제1유형(출처표시)으로
23
+ 개방한 행정동 경계입니다. 이 출처표시 의무는 가공 여부와 무관하게 유지되므로,
24
+ 본 데이터를 이용·재배포할 때 SGIS 출처표시를 반드시 보존해야 합니다.
25
+ 공공누리 제1유형: https://www.kogl.or.kr/info/licenseType1.do
26
+
27
+ The underlying boundaries originate from Statistics Korea (SGIS), released under
28
+ the Korea Open Government License (KOGL) Type 1 (attribution). This requirement
29
+ persists regardless of modification; SGIS attribution must be preserved.
30
+
31
+ 3. 출처 표기 / Required attribution
32
+
33
+ 본 데이터를 이용할 경우 아래 표기를 유지하시기 바랍니다.
34
+
35
+ "본 데이터는 통계청 통계지리정보서비스(SGIS, https://sgis.kostat.go.kr)에서
36
+ 공공누리 제1유형으로 개방한 행정동 경계를 가공한 것이며(가공: vuski/admdongkor,
37
+ https://github.com/vuski/admdongkor), CC BY 4.0으로 배포됩니다."
38
+
39
+ "This data is derived from administrative-dong boundaries released by Statistics
40
+ Korea SGIS (https://sgis.kostat.go.kr) under KOGL Type 1, modified by
41
+ vuski/admdongkor (https://github.com/vuski/admdongkor), distributed under CC BY 4.0."
42
+
43
+ 4. 면책 / Disclaimer
44
+
45
+ 본 데이터는 "있는 그대로(as is)" 제공되며 정확성·완전성을 보증하지 않습니다.
46
+ 원자료 제공기관(SGIS)은 이 저장소의 가공 과정에서 발생한 오류에 대해 책임지지 않습니다.
47
+ Provided "as is", without warranty. SGIS is not responsible for errors introduced
48
+ by this repository's processing.
@@ -0,0 +1,71 @@
1
+ [
2
+ {
3
+ "id": "kr-boundaries",
4
+ "title": "대한민국 행정동 경계 (2026-07-01)",
5
+ "creator": "통계청 통계지리정보서비스(SGIS); 가공: vuski/admdongkor",
6
+ "sources": [
7
+ "https://sgis.kostat.go.kr",
8
+ "https://github.com/vuski/admdongkor/tree/master/ver20260701"
9
+ ],
10
+ "licenses": [
11
+ {
12
+ "name": "공공누리 제1유형",
13
+ "url": "https://www.kogl.or.kr/info/licenseType1.do"
14
+ },
15
+ {
16
+ "name": "CC BY 4.0",
17
+ "url": "https://creativecommons.org/licenses/by/4.0/"
18
+ }
19
+ ],
20
+ "changes": "원본 경계를 시군구·시도로 병합하고 영상 지도에 맞춰 색상과 표시 범위를 구성했습니다. 경계 좌표를 단순화하지 않았습니다.",
21
+ "notice": "본 데이터는 통계청 통계지리정보서비스(SGIS, https://sgis.kostat.go.kr)에서 공공누리 제1유형으로 개방한 행정동 경계를 가공한 것이며(가공: vuski/admdongkor, https://github.com/vuski/admdongkor), CC BY 4.0으로 배포됩니다."
22
+ },
23
+ {
24
+ "id": "prk-boundaries",
25
+ "title": "Democratic People's Republic of Korea administrative boundary (2018)",
26
+ "creator": "World Food Programme (WFP), OCHA Regional Office for Asia and the Pacific; 배포: geoBoundaries",
27
+ "sources": [
28
+ "https://data.humdata.org/dataset/dpr-korea-administrative-boundaries",
29
+ "https://github.com/wmgeolab/geoBoundaries/tree/9469f09/releaseData/gbOpen/PRK/ADM0"
30
+ ],
31
+ "licenses": [
32
+ {
33
+ "name": "CC BY 3.0 IGO",
34
+ "url": "https://creativecommons.org/licenses/by/3.0/igo/"
35
+ }
36
+ ],
37
+ "changes": "경계 좌표를 유지하고 표시용 속성·색상을 정리하여 영상 지도로 구성했습니다."
38
+ },
39
+ {
40
+ "id": "natural-earth",
41
+ "title": "Natural Earth 1:10m Admin 0 — Countries, version 5.1.2",
42
+ "creator": "Natural Earth contributors",
43
+ "sources": [
44
+ "https://github.com/nvkelso/natural-earth-vector/blob/v5.1.2/geojson/ne_10m_admin_0_countries.geojson"
45
+ ],
46
+ "licenses": [
47
+ {
48
+ "name": "Public domain",
49
+ "url": "https://www.naturalearthdata.com/about/terms-of-use/"
50
+ }
51
+ ],
52
+ "changes": "동아시아 주변국의 경계 좌표를 유지하고 영상 지도에 맞춰 속성·색상을 구성했습니다."
53
+ },
54
+ {
55
+ "id": "ibm-plex",
56
+ "title": "IBM Plex Sans KR / IBM Plex Mono",
57
+ "creator": "IBM Corp. / IBM Plex contributors",
58
+ "sources": [
59
+ "https://github.com/IBM/plex",
60
+ "https://fontsource.org/fonts/ibm-plex-sans-kr",
61
+ "https://fontsource.org/fonts/ibm-plex-mono"
62
+ ],
63
+ "licenses": [
64
+ {
65
+ "name": "SIL Open Font License 1.1",
66
+ "url": "https://github.com/IBM/plex/blob/master/LICENSE.txt"
67
+ }
68
+ ],
69
+ "changes": "공식 Fontsource 배포본의 글꼴을 변경 없이 오프라인 영상 본문·시각 표시에 사용했습니다."
70
+ }
71
+ ]
@@ -0,0 +1,9 @@
1
+ # 공통 수신음
2
+
3
+ `notification.wav`는 이 프로젝트가 Tone.js로 직접 합성한 창작 알림음이다. 실제 재난 경보음을 재현하지 않는다. PCM16·48kHz·모노·0.55초. CC0-1.0.
4
+
5
+ 소스는 `notification.mjs`다. 패키지 루트에서 재생성한다.
6
+
7
+ ```sh
8
+ node dist/cli.js audio assets/audio/notification.mjs --duration 0.55 --channels 1 --seed 731 --out assets/audio/notification.wav --overwrite
9
+ ```
@@ -0,0 +1,10 @@
1
+ // Original notification sound, CC0-1.0. Not a reproduction of an official alert.
2
+ export default function ({Tone, duration}) {
3
+ const gain = new Tone.Gain(0).toDestination();
4
+ gain.gain.setValueAtTime(0, 0);
5
+ gain.gain.linearRampToValueAtTime(0.42, 0.025);
6
+ gain.gain.setValueAtTime(0.42, 0.34);
7
+ gain.gain.linearRampToValueAtTime(0, 0.42);
8
+ const osc = new Tone.Oscillator(680, 'sine').connect(gain).start(0).stop(duration);
9
+ osc.frequency.setValueAtTime(510, 0.16);
10
+ }
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,14 @@
1
+ # 작품 작업공간
2
+
3
+ `scenario.yaml`에 사건·문안·지도·연출을 작성한다. 창작 AI에게 사용자 범위에 설치한 `scenario-writing` 스킬을 사용하도록 요청한다. 형식과 참고자료는 [GitHub의 창작 스킬](https://github.com/neuwcodebox/disaster-broadcast-studio/tree/main/skills/scenario-writing)에 포함되어 있다. 이 작업공간은 스킬을 별도 복사하지 않는다.
4
+
5
+ ```sh
6
+ npx dbs validate scenario.yaml
7
+ npx dbs regions --search 철원
8
+ npx dbs frame scenario.yaml --frame 600 --out preview.png
9
+ npx dbs render scenario.yaml --out film.mp4
10
+ ```
11
+
12
+ 문자 도착 시 엔진의 공통 수신음이 재생된다. `alert.sound: false`로 끄거나 사용자 음원으로 바꾼다. `audio/`는 작품 고유 음원, `audio-code/`는 필요한 합성 코드를 두는 폴더다. [음향 가이드](https://github.com/neuwcodebox/disaster-broadcast-studio/blob/main/skills/scenario-writing/references/audio.md)를 참고한다.
13
+
14
+ 지역·기관·시각·문안을 작품에 맞게 바꾼다. 컷 내부는 실시간이며 시간 도약은 새 컷으로 지정한다. 결과와 함께 생성한 `.credits.txt`를 영상 게시 설명에 포함한다. 초기화는 npm 설치나 영상 게시를 수행하지 않는다.
@@ -0,0 +1,34 @@
1
+ version: 1
2
+ title: 새 작품
3
+ fictionNotice: 이 영상은 창작된 재난방송입니다. 실제 사건·재난문자·보도가 아닙니다.
4
+ timezone: Asia/Seoul
5
+ seed: 1
6
+ agencies:
7
+ city: 가상시
8
+ news: 가상뉴스
9
+ assets: {}
10
+ map:
11
+ camera:
12
+ center: [127.7, 36.0]
13
+ zoom: 6.2
14
+ cuts:
15
+ - id: first
16
+ duration: 30
17
+ storyTime: '2031-01-01T12:00:00+09:00'
18
+ events:
19
+ - id: headline-1
20
+ type: news
21
+ cut: first
22
+ at: 5
23
+ duration: 25
24
+ source: news
25
+ headline: 방송 시스템 점검…후속 안내 대기
26
+ - id: alert-1
27
+ type: alert
28
+ cut: first
29
+ at: 7
30
+ sender: city
31
+ level: 안전안내
32
+ text: 방송 점검 중입니다. 다음 안내를 기다려 주십시오.
33
+ # dbs regions --search 지역명 으로 실제 코드를 검색한다.
34
+ regions: []
@@ -0,0 +1,2 @@
1
+ export declare const packageRoot: string;
2
+ export declare function readBundledJson<T>(name: string): Promise<T>;
package/dist/assets.js ADDED
@@ -0,0 +1,9 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { gunzipSync } from 'node:zlib';
4
+ import path from 'node:path';
5
+ export const packageRoot = fileURLToPath(new URL('../', import.meta.url));
6
+ export async function readBundledJson(name) {
7
+ const bytes = await readFile(path.join(packageRoot, 'assets', name));
8
+ return JSON.parse((name.endsWith('.gz') ? gunzipSync(bytes) : bytes).toString('utf8'));
9
+ }
@@ -0,0 +1,13 @@
1
+ export type AudioConfig = {
2
+ duration: number;
3
+ sampleRate: number;
4
+ channels: number;
5
+ seed: number;
6
+ };
7
+ export type AudioProgram = (options: AudioConfig & {
8
+ Tone: typeof import('tone');
9
+ context: import('tone').OfflineContext;
10
+ random: () => number;
11
+ asset: (relativePath: string) => string;
12
+ }) => void | Promise<void>;
13
+ export declare function registerAudio(program: AudioProgram, config: AudioConfig): void;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Artifact, Composition, registerRoot, useDelayRender, cancelRender, staticFile } from 'remotion';
4
+ import { encodeWav, seededRandom } from './wav.js';
5
+ export function registerAudio(program, config) {
6
+ function OfflineSound() {
7
+ const { delayRender, continueRender } = useDelayRender();
8
+ const [handle] = useState(() => delayRender('Synthesizing offline Tone.js audio'));
9
+ const [result, setResult] = useState(null);
10
+ useEffect(() => {
11
+ (async () => {
12
+ Math.random = seededRandom(config.seed);
13
+ const Tone = await import('tone');
14
+ if (typeof program !== 'function')
15
+ throw Error('Audio module must default-export a function');
16
+ const buffer = await Tone.Offline((context) => program({ ...config, Tone, context, random: seededRandom(config.seed), asset: staticFile }), config.duration, config.channels, config.sampleRate);
17
+ const channels = Array.from({ length: buffer.numberOfChannels }, (_, i) => buffer.getChannelData(i));
18
+ setResult(encodeWav(channels, config.sampleRate));
19
+ buffer.dispose();
20
+ })().catch(cancelRender);
21
+ }, []);
22
+ useEffect(() => { if (result)
23
+ continueRender(handle); }, [result]);
24
+ if (!result)
25
+ return null;
26
+ const { wav, ...stats } = result;
27
+ return _jsxs(_Fragment, { children: [_jsx(Artifact, { filename: "sound.wav", content: wav }), _jsx(Artifact, { filename: "sound.json", content: JSON.stringify({ ...config, ...stats, browser: navigator.userAgent }) })] });
28
+ }
29
+ registerRoot(() => _jsx(Composition, { id: "Sound", component: OfflineSound, width: 16, height: 16, fps: 60, durationInFrames: 1 }));
30
+ }