censor_bear 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +80 -0
- data/Rakefile +18 -0
- data/app/assets/config/censor_bear_manifest.js +1 -0
- data/app/assets/stylesheets/censor_bear/application.css +15 -0
- data/app/assets/stylesheets/censor_bear/logs.css +4 -0
- data/app/assets/stylesheets/censor_bear/mod_logs.css +4 -0
- data/app/assets/stylesheets/censor_bear/stop_words.css +4 -0
- data/app/assets/stylesheets/censor_bear/tailwind.min.css +1 -0
- data/app/assets/stylesheets/scaffold.css +80 -0
- data/app/controllers/censor_bear/application_controller.rb +9 -0
- data/app/controllers/censor_bear/logs_controller.rb +62 -0
- data/app/controllers/censor_bear/mod_logs_controller.rb +87 -0
- data/app/controllers/censor_bear/stop_words_controller.rb +69 -0
- data/app/helpers/censor_bear/application_helper.rb +5 -0
- data/app/helpers/censor_bear/logs_helper.rb +4 -0
- data/app/helpers/censor_bear/mod_logs_helper.rb +4 -0
- data/app/helpers/censor_bear/stop_words_helper.rb +4 -0
- data/app/jobs/censor_bear/application_job.rb +4 -0
- data/app/mailers/censor_bear/application_mailer.rb +6 -0
- data/app/models/censor_bear/application_record.rb +5 -0
- data/app/models/censor_bear/log.rb +4 -0
- data/app/models/censor_bear/mod_log.rb +50 -0
- data/app/models/censor_bear/stop_word.rb +7 -0
- data/app/views/censor_bear/logs/_form.html.erb +37 -0
- data/app/views/censor_bear/logs/edit.html.erb +6 -0
- data/app/views/censor_bear/logs/index.html.erb +35 -0
- data/app/views/censor_bear/logs/new.html.erb +5 -0
- data/app/views/censor_bear/logs/show.html.erb +24 -0
- data/app/views/censor_bear/mod_logs/_form.html.erb +37 -0
- data/app/views/censor_bear/mod_logs/edit.html.erb +6 -0
- data/app/views/censor_bear/mod_logs/index.html.erb +44 -0
- data/app/views/censor_bear/mod_logs/new.html.erb +5 -0
- data/app/views/censor_bear/mod_logs/show.html.erb +24 -0
- data/app/views/censor_bear/stop_words/_form.html.haml +30 -0
- data/app/views/censor_bear/stop_words/_stop_word.html.haml +33 -0
- data/app/views/censor_bear/stop_words/destroy.turbo_stream.haml +1 -0
- data/app/views/censor_bear/stop_words/edit.html.haml +6 -0
- data/app/views/censor_bear/stop_words/index.html.haml +20 -0
- data/app/views/censor_bear/stop_words/new.html.haml +5 -0
- data/app/views/censor_bear/stop_words/show.html.haml +1 -0
- data/app/views/layouts/censor_bear/application.html.haml +18 -0
- data/config/cable.yml +9 -0
- data/config/initializers/censor_bear.rb +6 -0
- data/config/locales/censor_bear.yml +7 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20211126133758_create_censor_bear_stop_words.rb +16 -0
- data/db/migrate/20211129093508_create_censor_bear_logs.rb +12 -0
- data/db/migrate/20211129110218_create_censor_bear_mod_logs.rb +18 -0
- data/lib/censor_bear/censor.rb +64 -0
- data/lib/censor_bear/configuration.rb +12 -0
- data/lib/censor_bear/engine.rb +11 -0
- data/lib/censor_bear/version.rb +3 -0
- data/lib/censor_bear.rb +36 -0
- data/lib/tasks/censor_bear_tasks.rake +4 -0
- metadata +177 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
= turbo_frame_tag dom_id(stop_word) do
|
2
|
+
%div{class: "flex flex-col space-y-2 border rounded-md p-2 mt-2"}
|
3
|
+
%div{class: "flex justify-between text-xs"}
|
4
|
+
%span{class: "font-bold"}
|
5
|
+
= "##{stop_word.id}"
|
6
|
+
%span{class: "text-gray-500"}
|
7
|
+
= link_to stop_word.created_at, stop_word, data: {turbo: false}
|
8
|
+
%div{class: "space-y-0.5"}
|
9
|
+
%div{class: "text-xl font-meidum"}= stop_word.key
|
10
|
+
%div{class: "flex space-x-2"}
|
11
|
+
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
12
|
+
%div{class: "text-center"}=I18n.t("censor_log.action.#{stop_word.ugc}")
|
13
|
+
%div{class: "text-gray-500 text-xs text-center"} UGC内容处理
|
14
|
+
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
15
|
+
%div{class: "text-center"}=I18n.t("censor_log.action.#{stop_word.username}")
|
16
|
+
%div{class: "text-gray-500 text-xs text-center"} 用户名处理
|
17
|
+
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
18
|
+
%div{class: "text-center"}=I18n.t("censor_log.action.#{stop_word.nickname}")
|
19
|
+
%div{class: "text-gray-500 text-xs text-center"} 用户昵称处理
|
20
|
+
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
21
|
+
%div{class: "text-center"}=I18n.t("censor_log.action.#{stop_word.signature}")
|
22
|
+
%div{class: "text-gray-500 text-xs text-center"} 签名处理
|
23
|
+
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
24
|
+
%div{class: "text-center"}=I18n.t("censor_log.action.#{stop_word.dialog}")
|
25
|
+
%div{class: "text-gray-500 text-xs text-center"} 私信处理
|
26
|
+
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
27
|
+
%div{class: "text-center"}=stop_word.replacement
|
28
|
+
%div{class: "text-gray-500 text-xs text-center"} 过滤词替换
|
29
|
+
%div{class: "flex justify-end space-x-2 text-sm text-blue-600"}
|
30
|
+
%span
|
31
|
+
= link_to '编辑', edit_stop_word_path(stop_word)
|
32
|
+
%span
|
33
|
+
= button_to '删除', stop_word, method: :delete, data: { confirm: 'Are you sure?' }, class: "cursor-pointer bg-white text-red-600"
|
@@ -0,0 +1 @@
|
|
1
|
+
= turbo_stream.remove(@stop_word)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
%div{class: "flex flex-col space-y-2 justify-center"}
|
2
|
+
%div{class: "flex justify-between"}
|
3
|
+
%div
|
4
|
+
= form_with(url: stop_words_path, method: :get, class: "flex items-center") do |f|
|
5
|
+
%div{class: "space-x-0.5"}
|
6
|
+
= f.text_field :q, value: params[:q], placeholder: "关键词", class: "border rounded-md m py-0.5 px-1"
|
7
|
+
= f.submit "检索", class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer"
|
8
|
+
= link_to "重置", stop_words_path, class: "text-sm"
|
9
|
+
|
10
|
+
%div
|
11
|
+
= link_to '批量导入', "#", class: "text-sm"
|
12
|
+
= link_to '新增', new_stop_word_path, class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer"
|
13
|
+
%div
|
14
|
+
- if @stop_words.blank?
|
15
|
+
%div{class: "flex justify-center text-gray-500 p-8 border rounded-md"} 空空如也
|
16
|
+
- else
|
17
|
+
- @stop_words.each do |stop_word|
|
18
|
+
= render stop_word
|
19
|
+
%div{class: "flex justify-center"}
|
20
|
+
= raw pagy_nav(@pagy)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render @stop_word
|
@@ -0,0 +1,18 @@
|
|
1
|
+
!!! 5
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title 🐻 内容审核
|
5
|
+
= csrf_meta_tags
|
6
|
+
= csp_meta_tag
|
7
|
+
= stylesheet_link_tag "censor_bear/application", media: "all"
|
8
|
+
= javascript_include_tag "turbo", type: "module"
|
9
|
+
= yield :head
|
10
|
+
%body{class: "flex flex-col space-y-6 p-4"}
|
11
|
+
%ul{class: "flex justify-end items-center space-x-2 text-blue-600"}
|
12
|
+
%li= link_to "审查(#{CensorBear::ModLog.pending.count})", mod_logs_path
|
13
|
+
%li= link_to "敏感词", stop_words_path
|
14
|
+
%li= link_to "日志", logs_path
|
15
|
+
%li= link_to "回主站", "/"
|
16
|
+
%li= current_user.email
|
17
|
+
%div
|
18
|
+
= yield
|
data/config/cable.yml
ADDED
data/config/routes.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateCensorBearStopWords < ActiveRecord::Migration[6.1]
|
2
|
+
def change
|
3
|
+
create_table :censor_bear_stop_words do |t|
|
4
|
+
t.string :key
|
5
|
+
t.bigint :user_id
|
6
|
+
t.string :ugc
|
7
|
+
t.string :username
|
8
|
+
t.string :nickname
|
9
|
+
t.string :signature
|
10
|
+
t.string :dialog
|
11
|
+
t.string :replacement
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateCensorBearLogs < ActiveRecord::Migration[6.1]
|
2
|
+
def change
|
3
|
+
create_table :censor_bear_logs do |t|
|
4
|
+
t.text :original_content
|
5
|
+
t.string :action
|
6
|
+
t.text :filtered_content
|
7
|
+
t.string :mod_words, array: true, default: []
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateCensorBearModLogs < ActiveRecord::Migration[6.1]
|
2
|
+
def change
|
3
|
+
create_table :censor_bear_mod_logs do |t|
|
4
|
+
t.bigint :record_id
|
5
|
+
t.string :record_type
|
6
|
+
t.text :content
|
7
|
+
t.string :reason
|
8
|
+
t.string :mod_words, array: true, default: []
|
9
|
+
t.integer :status, default: 0
|
10
|
+
t.bigint :user_id
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
|
14
|
+
t.index %w[record_type record_id], using: :btree
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module CensorBear
|
2
|
+
class Result
|
3
|
+
attr_accessor :is_mod, :mod_words, :content
|
4
|
+
|
5
|
+
def initialize(content, is_mod = false, mod_words = [])
|
6
|
+
@is_mod = is_mod
|
7
|
+
@mod_words = mod_words
|
8
|
+
@content = content || ''
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Censor
|
13
|
+
def initialize(content, type = 'ugc')
|
14
|
+
@is_mod = false
|
15
|
+
@mod_words = []
|
16
|
+
@content = content
|
17
|
+
@type = type.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def check_text
|
21
|
+
return Result.new(@content) if @content.blank?
|
22
|
+
return Result.new(@content) unless CensorBear::StopWord::FIELDS.include?(@type)
|
23
|
+
|
24
|
+
local_check
|
25
|
+
|
26
|
+
# 用户相关类型直接封禁,速错
|
27
|
+
raise NotPassedException if @is_mod && %w[username signature dialog nickname].include?(@type)
|
28
|
+
|
29
|
+
Result.new(@content, @is_mod, @mod_words.uniq)
|
30
|
+
end
|
31
|
+
|
32
|
+
def local_check
|
33
|
+
original_content = @content.dup
|
34
|
+
stop_words = CensorBear::StopWord.where("#{@type} != 'IGNORE'")
|
35
|
+
stop_words.each do |word|
|
36
|
+
finder = Regexp.new(Regexp.escape(word.key))
|
37
|
+
action = word.send(@type.to_sym).upcase
|
38
|
+
next unless finder.match(@content)
|
39
|
+
@mod_words.push(word.key)
|
40
|
+
case action
|
41
|
+
when 'REPLACE'
|
42
|
+
@content = @content.gsub(finder, word.replacement)
|
43
|
+
CensorBear::Log.create(original_content: original_content, action: "#{@type}_#{action}", filtered_content: @content, mod_words: [word.key])
|
44
|
+
when 'MOD'
|
45
|
+
@is_mod = true
|
46
|
+
CensorBear::Log.create(original_content: original_content, action: "#{@type}_#{action}", filtered_content: nil, mod_words: [word.key])
|
47
|
+
when 'BANNED'
|
48
|
+
@is_mod = true
|
49
|
+
# 禁止的直接抛出异常
|
50
|
+
CensorBear::Log.create(original_content: original_content, action: "#{@type}_#{action}", filtered_content: nil, mod_words: [word.key])
|
51
|
+
raise NotPassedException
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def cloud_check() end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def tencent_check() end
|
61
|
+
|
62
|
+
def aliyun_check() end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module CensorBear
|
2
|
+
class Configuration
|
3
|
+
# class name of you User model, default: 'User'
|
4
|
+
attr_accessor :user_class
|
5
|
+
|
6
|
+
# current_user method name in your Controller, default: 'current_user'
|
7
|
+
attr_accessor :current_user_method
|
8
|
+
|
9
|
+
# user name method, default: "name"
|
10
|
+
attr_accessor :user_name_method
|
11
|
+
end
|
12
|
+
end
|
data/lib/censor_bear.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "censor_bear/version"
|
2
|
+
require "censor_bear/engine"
|
3
|
+
require "censor_bear/censor"
|
4
|
+
require "censor_bear/configuration"
|
5
|
+
|
6
|
+
require "hamlit"
|
7
|
+
require 'pagy'
|
8
|
+
|
9
|
+
module CensorBear
|
10
|
+
class NotPassedException < StandardError; end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def config
|
14
|
+
return @config if defined?(@config)
|
15
|
+
|
16
|
+
@config = Configuration.new
|
17
|
+
@config.user_class = 'User'
|
18
|
+
@config.current_user_method = 'current_user'
|
19
|
+
@config.user_name_method = 'name'
|
20
|
+
@config
|
21
|
+
end
|
22
|
+
|
23
|
+
def configure
|
24
|
+
yield(config)
|
25
|
+
end
|
26
|
+
|
27
|
+
def check_text(content, type = 'ugc')
|
28
|
+
Censor.new(content, type).check_text
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def action_options
|
33
|
+
I18n.t('censor_log.action').map { |k, v| [v, k.to_s] }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: censor_bear
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- 42up
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.1.4
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 6.1.4.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 6.1.4
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 6.1.4.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: hamlit
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: haml-rails
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: turbo-rails
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: pagy
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '5.6'
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '5.6'
|
89
|
+
description: Description of CensorBear.
|
90
|
+
email:
|
91
|
+
- foobar@v2up.com
|
92
|
+
executables: []
|
93
|
+
extensions: []
|
94
|
+
extra_rdoc_files: []
|
95
|
+
files:
|
96
|
+
- MIT-LICENSE
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- app/assets/config/censor_bear_manifest.js
|
100
|
+
- app/assets/stylesheets/censor_bear/application.css
|
101
|
+
- app/assets/stylesheets/censor_bear/logs.css
|
102
|
+
- app/assets/stylesheets/censor_bear/mod_logs.css
|
103
|
+
- app/assets/stylesheets/censor_bear/stop_words.css
|
104
|
+
- app/assets/stylesheets/censor_bear/tailwind.min.css
|
105
|
+
- app/assets/stylesheets/scaffold.css
|
106
|
+
- app/controllers/censor_bear/application_controller.rb
|
107
|
+
- app/controllers/censor_bear/logs_controller.rb
|
108
|
+
- app/controllers/censor_bear/mod_logs_controller.rb
|
109
|
+
- app/controllers/censor_bear/stop_words_controller.rb
|
110
|
+
- app/helpers/censor_bear/application_helper.rb
|
111
|
+
- app/helpers/censor_bear/logs_helper.rb
|
112
|
+
- app/helpers/censor_bear/mod_logs_helper.rb
|
113
|
+
- app/helpers/censor_bear/stop_words_helper.rb
|
114
|
+
- app/jobs/censor_bear/application_job.rb
|
115
|
+
- app/mailers/censor_bear/application_mailer.rb
|
116
|
+
- app/models/censor_bear/application_record.rb
|
117
|
+
- app/models/censor_bear/log.rb
|
118
|
+
- app/models/censor_bear/mod_log.rb
|
119
|
+
- app/models/censor_bear/stop_word.rb
|
120
|
+
- app/views/censor_bear/logs/_form.html.erb
|
121
|
+
- app/views/censor_bear/logs/edit.html.erb
|
122
|
+
- app/views/censor_bear/logs/index.html.erb
|
123
|
+
- app/views/censor_bear/logs/new.html.erb
|
124
|
+
- app/views/censor_bear/logs/show.html.erb
|
125
|
+
- app/views/censor_bear/mod_logs/_form.html.erb
|
126
|
+
- app/views/censor_bear/mod_logs/edit.html.erb
|
127
|
+
- app/views/censor_bear/mod_logs/index.html.erb
|
128
|
+
- app/views/censor_bear/mod_logs/new.html.erb
|
129
|
+
- app/views/censor_bear/mod_logs/show.html.erb
|
130
|
+
- app/views/censor_bear/stop_words/_form.html.haml
|
131
|
+
- app/views/censor_bear/stop_words/_stop_word.html.haml
|
132
|
+
- app/views/censor_bear/stop_words/destroy.turbo_stream.haml
|
133
|
+
- app/views/censor_bear/stop_words/edit.html.haml
|
134
|
+
- app/views/censor_bear/stop_words/index.html.haml
|
135
|
+
- app/views/censor_bear/stop_words/new.html.haml
|
136
|
+
- app/views/censor_bear/stop_words/show.html.haml
|
137
|
+
- app/views/layouts/censor_bear/application.html.haml
|
138
|
+
- config/cable.yml
|
139
|
+
- config/initializers/censor_bear.rb
|
140
|
+
- config/locales/censor_bear.yml
|
141
|
+
- config/routes.rb
|
142
|
+
- db/migrate/20211126133758_create_censor_bear_stop_words.rb
|
143
|
+
- db/migrate/20211129093508_create_censor_bear_logs.rb
|
144
|
+
- db/migrate/20211129110218_create_censor_bear_mod_logs.rb
|
145
|
+
- lib/censor_bear.rb
|
146
|
+
- lib/censor_bear/censor.rb
|
147
|
+
- lib/censor_bear/configuration.rb
|
148
|
+
- lib/censor_bear/engine.rb
|
149
|
+
- lib/censor_bear/version.rb
|
150
|
+
- lib/tasks/censor_bear_tasks.rake
|
151
|
+
homepage: https://github.com/42up/censor_bear
|
152
|
+
licenses:
|
153
|
+
- MIT
|
154
|
+
metadata:
|
155
|
+
homepage_uri: https://github.com/42up/censor_bear
|
156
|
+
source_code_uri: https://github.com/42up/censor_bear
|
157
|
+
changelog_uri: https://github.com/42up/censor_bear
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubygems_version: 3.2.22
|
174
|
+
signing_key:
|
175
|
+
specification_version: 4
|
176
|
+
summary: Summary of CensorBear.
|
177
|
+
test_files: []
|